Commit Graph

22 Commits

Author SHA1 Message Date
mindesbunister
93dd950821 critical: Fix ghost detection P&L compounding - delete from Map BEFORE check
Bug: Multiple monitoring loops detect ghost simultaneously
- Loop 1: has(tradeId) → true → proceeds
- Loop 2: has(tradeId) → true → ALSO proceeds (race condition)
- Both send Telegram notifications with compounding P&L

Real incident (Dec 2, 2025):
- Manual SHORT at $138.84
- 23 duplicate notifications
- P&L compounded: -$47.96 → -$1,129.24 (23× accumulation)
- Database shows single trade with final compounded value

Fix: Map.delete() returns true if key existed, false if already removed
- Call delete() FIRST
- Check return value
 proceeds
- All other loops get false → skip immediately
- Atomic operation prevents race condition

Pattern: This is variant of Common Pitfalls #48, #49, #59, #60, #61
- All had "check then delete" pattern
- All vulnerable to async timing issues
- Solution: "delete then check" pattern
- Map.delete() is synchronous and atomic

Files changed:
- lib/trading/position-manager.ts lines 390-410

Related: DUPLICATE PREVENTED message was working but too late
2025-12-02 18:25:56 +01:00
mindesbunister
0ec2896c5d fix: Resolve variable hoisting error in version comparison API
Critical Bug Fix:
- archivedVersions was used before declaration (line 147 vs line 165)
- Caused 'Cannot access before initialization' error
- Moved versionDescriptions and archivedVersions declarations to top
- Now defined BEFORE usage in resultsWithArchived.map()

Impact: Analytics page was completely broken (stuck on loading)
Resolution: API now returns data correctly, UI functional

Error: ReferenceError: Cannot access 'g' before initialization
Fix: Proper variable ordering in route.ts
2025-11-22 15:02:43 +01:00
mindesbunister
bba91c1df8 feat: Archive old indicator versions, focus on v8 production system
Version Management:
- v8 Money Line: PRODUCTION (8 trades, 57.1% WR, +$262.70, quality ≥95 = 100% wins)
- v5/v6/v7: ARCHIVED (historical baseline for future v9 comparison)

API Changes (app/api/analytics/version-comparison/route.ts):
- Added 'archived' flag to version stats
- Added 'production' field pointing to v8
- Updated sort order: v8 first, then archived versions
- Enhanced descriptions with PRODUCTION/ARCHIVED labels

UI Changes (app/analytics/page.tsx):
- v8 highlighted with blue gradient + 🚀 PRODUCTION badge
- Archived versions greyed out (60% opacity) + ARCHIVED badge
- Updated header: 'Indicator Versions (v8 Production)'
- Data collection notice: v8 shows 8/50 trades progress
- Kept comparison infrastructure for future v9 development

Documentation (.github/copilot-instructions.md):
- Updated Indicator Version Tracking section
- Documented perfect quality separation (≥95 = 100% wins)
- Clarified v8 production status, archived versions purpose
- Analytics UI behavior documented

Purpose: Keep comparison infrastructure for statistical validation
and future v9 testing while focusing user attention on v8 results.
2025-11-22 14:45:48 +01:00
mindesbunister
60fc571aa6 feat: Automated multi-timeframe price tracking system
Implemented comprehensive price tracking for multi-timeframe signal analysis.

**Components Added:**
- lib/analysis/blocked-signal-tracker.ts - Background job tracking prices
- app/api/analytics/signal-tracking/route.ts - Status/metrics endpoint

**Features:**
- Automatic price tracking at 1min, 5min, 15min, 30min intervals
- TP1/TP2/SL hit detection using ATR-based targets
- Max favorable/adverse excursion tracking (MFE/MAE)
- Analysis completion after 30 minutes
- Background job runs every 5 minutes
- Entry price captured from signal time

**Database Changes:**
- Added entryPrice field to BlockedSignal (for price tracking baseline)
- Added maxFavorablePrice, maxAdversePrice fields
- Added maxFavorableExcursion, maxAdverseExcursion fields

**Integration:**
- Auto-starts on container startup
- Tracks all DATA_COLLECTION_ONLY signals
- Uses same TP/SL calculation as live trades (ATR-based)
- Calculates profit % based on direction (long vs short)

**API Endpoints:**
- GET /api/analytics/signal-tracking - View tracking status and metrics
- POST /api/analytics/signal-tracking - Manually trigger update (auth required)

**Purpose:**
Enables data-driven multi-timeframe comparison. After 50+ signals per
timeframe, can analyze which timeframe (5min vs 15min vs 1H vs 4H vs Daily)
has best win rate, profit potential, and signal quality.

**What It Tracks:**
- Price at 1min, 5min, 15min, 30min after signal
- Would TP1/TP2/SL have been hit?
- Maximum profit/loss during 30min window
- Complete analysis of signal profitability

**How It Works:**
1. Signal comes in (15min, 1H, 4H, Daily) → saved to BlockedSignal
2. Background job runs every 5min
3. Queries current price from Pyth
4. Calculates profit % from entry
5. Checks if TP/SL thresholds crossed
6. Updates MFE/MAE if new highs/lows
7. After 30min, marks analysisComplete=true

**Future Analysis:**
After 50+ signals per timeframe:
- Compare TP1 hit rates across timeframes
- Identify which timeframe has highest win rate
- Determine optimal signal frequency vs quality trade-off
- Switch production to best-performing timeframe

User requested: "i want all the bells and whistles. lets make the
powerhouse more powerfull. i cant see any reason why we shouldnt"
2025-11-19 17:18:47 +01:00
mindesbunister
54012ec402 fix: Analytics now shows current runner size instead of original position size
- Modified /api/analytics/last-trade to extract currentSize from configSnapshot.positionManagerState
- For open positions (exitReason === null), displays runner size after TP1 instead of original positionSizeUSD
- Falls back to original positionSizeUSD for closed positions or when Position Manager state unavailable
- Fixes UI showing 2.54 when actual runner is 2.59
- Provides accurate exposure visibility on analytics dashboard

Example: Position opens at 2.54, TP1 closes 70% → runner 2.59 → UI now shows 2.59
2025-11-15 23:14:17 +01:00
mindesbunister
25776413d0 feat: Add signalSource field to identify manual vs TradingView trades
- Set signalSource='manual' for Telegram trades, 'tradingview' for TradingView
- Updated analytics queries to exclude manual trades from indicator analysis
- getTradingStats() filters manual trades (TradingView performance only)
- Version comparison endpoint filters manual trades
- Created comprehensive filtering guide: docs/MANUAL_TRADE_FILTERING.md
- Ensures clean data for indicator optimization without contamination
2025-11-14 22:55:14 +01:00
mindesbunister
3cc3f1b871 fix: correct database column name in version comparison query
- Changed 'pricePosition' to 'pricePositionAtEntry' in extreme positions query
- Fixed database error: column "pricePosition" does not exist

Context:
- API was failing with Error 42703 (column not found)
- Database schema uses 'pricePositionAtEntry', not 'pricePosition'
- Version comparison section now loads correctly in analytics dashboard
2025-11-14 13:38:33 +01:00
mindesbunister
3aa704801e fix: resolve TypeScript errors in version comparison API
- Fixed extremePositionStats type to match actual SQL query fields
- Changed .count to .trades (query returns 'trades' column, not 'count')
- Simplified extreme positions metrics (removed missing avg_adx and weak_adx_count)
- Fixed version comparison fallback from 'v1' to 'unknown'

Technical:
- SQL query only returns: version, trades, wins, total_pnl, avg_quality_score
- Code was trying to access non-existent fields causing TypeScript errors
- Build now succeeds, container deployed
2025-11-14 13:28:08 +01:00
mindesbunister
2cda751dc4 fix: update analytics UI to show TradingView indicator versions correctly
- Changed section title: 'Signal Quality Logic Versions' → 'TradingView Indicator Versions'
- Updated current version marker: v3 → v6
- Added version sorting: v6 first, then v5, then unknown
- Updated description to reflect indicator strategy comparison

Context:
- User clarified: V4 display = v6 data, V1 display = v5 data
- Dashboard now shows indicator versions in proper order
- 154 unknown (pre-tracking), 15 v6 (HalfTrend), 4 v5 (Buy/Sell)
2025-11-14 13:15:30 +01:00
mindesbunister
6e8da10f7d fix: switch version comparison to use indicatorVersion instead of signalQualityVersion
- Changed SQL queries to use indicatorVersion (TradingView strategy versions)
- Updated version descriptions to only show v5/v6/unknown
- v5 = Buy/Sell Signal strategy (pre-Nov 12)
- v6 = HalfTrend + BarColor strategy (Nov 12+)
- unknown = Pre-version-tracking trades

Context:
- User clarified: 'v4 is v6. the version reflects the moneyline version'
- Dashboard should show indicator strategy versions, not scoring logic versions
2025-11-14 13:12:30 +01:00
mindesbunister
08ee899164 feat: update analytics version descriptions
- Added v4 description: 'Frequency penalties + blocked signals tracking (Nov 11-14)'
- Added v5 description: 'Buy/Sell Signal strategy (pre-Nov 12)'
- Added v6 description: 'HalfTrend + BarColor strategy (Nov 12+)'

Context:
- v1-v4 = signalQualityVersion (scoring logic evolution)
- v5-v6 = indicatorVersion (TradingView strategy versions)
- Dashboard will now correctly label both types of versions
2025-11-14 13:07:01 +01:00
mindesbunister
28c1110a85 feat: Integrate dynamic ATR analysis into TP/SL optimization endpoint
- Added dynamicATRAnalysis section to /api/analytics/tp-sl-optimization
- Analyzes v6 trades with ATR data to compare fixed vs dynamic targets
- Dynamic targets: TP2=2x ATR, SL=1.5x ATR (from config)
- Shows +39.8% advantage with 14 trades (.72 improvement)
- Includes data sufficiency check (need 30+ trades)
- Recommendation logic: WAIT/IMPLEMENT/CONSIDER/NEUTRAL based on sample size and advantage
- Returns detailed metrics: sample size, avg ATR, hit rates, P&L comparison
- Integrates seamlessly with existing MAE/MFE analysis

Current status: 14/30 trades collected, insufficient for implementation
Expected: Frontend will display this data to track progress toward 30-trade threshold
2025-11-14 09:03:15 +01:00
mindesbunister
77a9437d26 feat: add price movement context to flip-flop detection
Improved flip-flop penalty logic to distinguish between:
- Chop (bad): <2% price move from opposite signal → -25 penalty
- Reversal (good): ≥2% price move from opposite signal → allowed

Changes:
- lib/database/trades.ts: getRecentSignals() now returns oppositeDirectionPrice
- lib/trading/signal-quality.ts: Added currentPrice parameter, price movement check
- app/api/trading/check-risk/route.ts: Added currentPrice to RiskCheckRequest interface
- app/api/trading/execute/route.ts: Pass openResult.fillPrice as currentPrice
- app/api/analytics/reentry-check/route.ts: Pass currentPrice from metrics

Example scenarios:
- ETH $170 SHORT → $153 LONG (10% move) = reversal allowed 
- ETH $154.50 SHORT → $154.30 LONG (0.13% move) = chop blocked ⚠️

Deployed: 09:18 CET Nov 14, 2025
Container: trading-bot-v4
2025-11-14 07:46:28 +01:00
mindesbunister
111e3ed12a feat: implement signal frequency penalties for flip-flop detection
PHASE 1 IMPLEMENTATION:
Signal quality scoring now checks database for recent trading patterns
and applies penalties to prevent overtrading and flip-flop losses.

NEW PENALTIES:
1. Overtrading: 3+ signals in 30min → -20 points
   - Detects consolidation zones where system generates excessive signals
   - Counts both executed trades AND blocked signals

2. Flip-flop: Opposite direction in last 15min → -25 points
   - Prevents rapid long→short→long whipsaws
   - Example: SHORT at 10:00, LONG at 10:12 = blocked

3. Alternating pattern: Last 3 trades flip directions → -30 points
   - Detects choppy market conditions
   - Pattern like long→short→long = system getting chopped

DATABASE INTEGRATION:
- New function: getRecentSignals() in lib/database/trades.ts
- Queries last 30min of trades + blocked signals
- Checks last 3 executed trades for alternating pattern
- Zero performance impact (fast indexed queries)

ARCHITECTURE:
- scoreSignalQuality() now async (requires database access)
- All callers updated: check-risk, execute, reentry-check
- skipFrequencyCheck flag available for special cases
- Frequency penalties included in qualityResult breakdown

EXPECTED IMPACT:
- Eliminate overnight flip-flop losses (like SOL $141-145 chop)
- Reduce overtrading during sideways consolidation
- Better capital preservation in non-trending markets
- Should improve win rate by 5-10% by avoiding worst setups

TESTING:
- Deploy and monitor next 5 signals in choppy markets
- Check logs for frequency penalty messages
- Analyze if blocked signals would have been losers

Files changed:
- lib/database/trades.ts: Added getRecentSignals()
- lib/trading/signal-quality.ts: Made async, added frequency checks
- app/api/trading/check-risk/route.ts: await + symbol parameter
- app/api/trading/execute/route.ts: await + symbol parameter
- app/api/analytics/reentry-check/route.ts: await + skipFrequencyCheck
2025-11-14 06:41:03 +01:00
mindesbunister
03e91fc18d feat: ATR-based trailing stop + rate limit monitoring
MAJOR FIXES:
- ATR-based trailing stop for runners (was fixed 0.3%, now adapts to volatility)
- Fixes runners with +7-9% MFE exiting for losses
- Typical improvement: 2.24x more room (0.3% → 0.67% at 0.45% ATR)
- Enhanced rate limit logging with database tracking
- New /api/analytics/rate-limits endpoint for monitoring

DETAILS:
- Position Manager: Calculate trailing as (atrAtEntry / price × 100) × multiplier
- Config: TRAILING_STOP_ATR_MULTIPLIER=1.5, MIN=0.25%, MAX=0.9%
- Settings UI: Added ATR multiplier controls
- Rate limits: Log hits/recoveries/exhaustions to SystemEvent table
- Documentation: ATR_TRAILING_STOP_FIX.md + RATE_LIMIT_MONITORING.md

IMPACT:
- Runners can now capture big moves (like morning's $172→$162 SOL drop)
- Rate limit visibility prevents silent failures
- Data-driven optimization for RPC endpoint health
2025-11-11 14:51:41 +01:00
mindesbunister
9b767342dc feat: Implement re-entry analytics system with fresh TradingView data
- Add market data cache service (5min expiry) for storing TradingView metrics
- Create /api/trading/market-data webhook endpoint for continuous data updates
- Add /api/analytics/reentry-check endpoint for validating manual trades
- Update execute endpoint to auto-cache metrics from incoming signals
- Enhance Telegram bot with pre-execution analytics validation
- Support --force flag to override analytics blocks
- Use fresh ADX/ATR/RSI data when available, fallback to historical
- Apply performance modifiers: -20 for losing streaks, +10 for winning
- Minimum re-entry score 55 (vs 60 for new signals)
- Fail-open design: proceeds if analytics unavailable
- Show data freshness and source in Telegram responses
- Add comprehensive setup guide in docs/guides/REENTRY_ANALYTICS_QUICKSTART.md

Phase 1 implementation for smart manual trade validation.
2025-11-07 20:40:07 +01:00
mindesbunister
6983f37a59 Fix Prisma Decimal type handling in version comparison API
- Changed numeric fields from typed as number to 'any' in raw query results
- Properly convert Prisma Decimal/BigInt types to JavaScript numbers
- Fixes TypeError: e.totalPnL.toFixed is not a function
- All numeric values (totalPnL, avgPnL, avgADX, etc.) now converted with Number()

Issue: Prisma returns Decimal objects from aggregation queries which don't have
toFixed() method. Frontend expects plain numbers for .toFixed(2) formatting.
2025-11-07 13:11:04 +01:00
mindesbunister
711ff9aaf4 Add signal quality version comparison to analytics dashboard
- Created /api/analytics/version-comparison endpoint
- Shows performance metrics for v1, v2, v3 scoring logic
- Compares: trade count, win rate, P&L, quality scores, MFE/MAE
- Special focus on extreme positions (< 15% or > 85% range)
- Tracks weak ADX count (< 18) for each version
- Visual indicators for current version (v3)
- Data collection progress notice for v3 (need 20+ trades)
- Legend explaining MFE, MAE, extreme positions, weak ADX

Enables data-driven optimization by comparing algorithm performance
with clean, version-tagged datasets.
2025-11-07 13:05:48 +01:00
mindesbunister
3c79ecbe55 Display signal quality score on analytics dashboard
- Add signalQualityScore to LastTrade interface
- Display quality score badge in last trade section (0-100)
- Color-coded: green (80+), yellow (70-79), orange (60-69)
- Shows 'Excellent', 'Good', or 'Marginal' label
- Gracefully handles null values (old trades without scores)
- Better layout when quality score is present
2025-10-31 11:34:46 +01:00
mindesbunister
aecdc108f6 Add last trade details to analytics dashboard
- Add getLastTrade() function to database service
- Create /api/analytics/last-trade endpoint
- Display last trade with full details on analytics page
- Show entry/exit prices, P&L, position size, targets
- Visual indicators for trade direction and exit reason
- Helps quickly diagnose where trades went (TP1, TP2, or SL)
2025-10-31 10:47:19 +01:00
mindesbunister
da72b5de04 Phase 3: TP/SL Optimization Analytics API
- Created /api/analytics/tp-sl-optimization endpoint
- Analyzes historical trades using MAE/MFE data
- Calculates optimal TP1/TP2/SL levels based on percentiles
- Provides win rate, profit factor, and hit rate analysis
- Shows money left on table (MFE - realized P&L)
- Projects impact of optimal levels on future performance

Analytics calculated:
- MAE analysis: avg, median, percentiles, worst
- MFE analysis: avg, median, percentiles, best
- Current level performance: TP1/TP2/SL hit rates
- Optimal recommendations: TP1=50% of avg MFE, TP2=80%, SL=70% of avg MAE
- Projected improvements: win rate change, profit factor, total P&L

Requires 10+ closed trades with MAE/MFE data to generate recommendations
Test script: scripts/test-analytics.sh

Next: Phase 4 (visual dashboard) or wait for trades with MAE/MFE data
2025-10-29 21:11:23 +01:00
mindesbunister
8e5c592cac Fix database persistence and add analytics
- Fixed Prisma client not being available in Docker container
- Added isTestTrade flag to exclude test trades from analytics
- Created analytics views for net positions (matches Drift UI netting)
- Added API endpoints: /api/analytics/positions and /api/analytics/stats
- Added test trade endpoint: /api/trading/test-db
- Updated Dockerfile to properly copy Prisma client from builder stage
- Database now successfully stores all trades with full details
- Supports position netting calculations to match Drift perpetuals behavior
2025-10-27 09:35:01 +01:00