Commit Graph

311 Commits

Author SHA1 Message Date
mindesbunister
c37a9a37d3 fix: Implement Associated Token Account for USDC withdrawals
- Fixed PublicKey undefined error (derive from DRIFT_WALLET_PRIVATE_KEY)
- Implemented ATA resolution using @solana/spl-token
- Added comprehensive debug logging for withdrawal flow
- Fixed AccountOwnedByWrongProgram error (need ATA not wallet address)
- Successfully tested .58 withdrawal with on-chain confirmation
- Updated .env with TOTAL_WITHDRAWN and LAST_WITHDRAWAL_TIME tracking

Key changes:
- lib/drift/withdraw.ts: Added getAssociatedTokenAddress() for USDC ATA
- tsconfig.json: Excluded archive folders from compilation
- package.json: Added bn.js as direct dependency

Transaction: 4drNfMR1xBosGCQtfJ2a4r6oEawUByrT6L7Thyqu6QQWz555hX3QshFuJqiLZreL7KrheSgTdCEqMcXP26fi54JF
Wallet: 3dG7wayp7b9NBMo92D2qL2sy1curSC4TTmskFpaGDrtA
USDC ATA: 8ZEMwErnwxPNNNHJigUcMfrkBG14LCREDdKbqKm49YY7
2025-11-19 20:35:32 +01:00
mindesbunister
8d53c4bbad critical: Fix withdrawal statistics to use actual Drift deposits
- Query Drift Protocol's cumulativeDeposits for ground truth
- Discovered user deposited ,440.61 (not hardcoded 46)
- Previous withdrawals: ~26.78 (not tracked in ENV)
- Database P&L -.01 is correct
- Reconciliation: ,440.61 deposits - .01 P&L - 26.78 withdrawn = 11.82 current
- Available profit now shows current balance (includes all trading results)
- Created /api/drift/account-summary endpoint for account reconciliation
- Statistics now mathematically consistent and trustworthy
2025-11-19 19:25:59 +01:00
mindesbunister
9cd317887a fix: Correct BN import for withdrawal system
Changed from '@project-serum/anchor' to 'bn.js' to match
other Drift SDK integrations. Fixes 'Cannot read properties
of undefined (reading '_bn')' error.

User can now test withdrawal with $5 minimum.
2025-11-19 18:39:45 +01:00
mindesbunister
1c79178aac fix: TypeScript errors in withdrawal system
- Fixed LAST_WITHDRAWAL_TIME type (null | string)
- Removed parseFloat on health.freeCollateral (already number)
- Fixed getDriftClient() → getClient() method name
- Build now compiles successfully

Deployed: Withdrawal system now live on dashboard
2025-11-19 18:25:54 +01:00
mindesbunister
ca7b49f745 feat: Add automated profit withdrawal system
- UI page: /withdrawals with stats dashboard and config form
- Settings API: GET/POST for .env configuration
- Stats API: Real-time profit and withdrawal calculations
- Execute API: Safe withdrawal with Drift SDK integration
- Drift service: withdrawFromDrift() with USDC spot market (index 0)
- Safety checks: Min withdrawal amount, min account balance, profit-only
- Telegram notifications: Withdrawal alerts with Solscan links
- Dashboard navigation: Added Withdrawals card (3-card grid)

User goal: 10% of profits automatically withdrawn on schedule
Current: Manual trigger ready, scheduled automation pending
Files: 5 new (withdrawals page, 3 APIs, Drift service), 2 modified
2025-11-19 18:07:07 +01:00
mindesbunister
c42bf94c1f fix: Clarify 40 is from deposits, not trading profits
Corrected misleading statement that implied 5.1x trading gains.
Reality: 46 total invested (06 + 40 deposits), 40 current = - trading P&L

Changes:
- Removed '5.1x in 8 days!' claim (was deposit-driven, not trading)
- Added 'Total Invested' line showing 46 actual capital input
- Added 'Trading P&L: -' to show early testing results
- Clarified losses from v6/v7 indicator testing before v8 optimization

Honesty matters - deposits ≠ profits. System is in proof phase.
2025-11-19 17:42:38 +01:00
mindesbunister
a6794d00dc docs: Update roadmap with 40 current capital and latest system improvements
Financial Updates:
- Current capital: 7.55 → 40 USDC (with deposits)
- Starting capital: 06 (Nov 11) + 40 deposits
- Phase 1 target: ,500 (4.6x growth from current)
- Monthly return target: 20-30% → 15-20% (more achievable with larger base)
- Risk tolerance: EXTREME → HIGH (increased capital cushion)
- Notional position size: ~,463 → ~,100 (at 15x leverage)

Recent Improvements (Nov 19, 2025):
 v8 Money Line Sticky Trend (0.6% flip threshold, anti-whipsaw)
 ATR-based TP/SL system (adaptive to volatility)
 ADX-based runner positioning (trend-strength adaptive SL)
 Multi-timeframe price tracking (15min/1H/4H/Daily data collection)
 Quality score increased to 81 (filters small chop trades)
 60/40 TP1/Runner split (captures runners on strong trends)
 Automated MFE/MAE analysis (30-minute tracking per signal)

System Status:
- Readiness: READY → PRODUCTION
- Confidence: HIGH → VERY HIGH
- Multi-timeframe: Fully operational, 2 signals tracked
- Background tracker: Runs every 5 minutes autonomously
- Next milestone: ,000 account (1.85x from current)
- Days to first withdrawal: ~60 days (Early January 2026)

Updated both TRADING_GOALS.md and copilot-instructions.md
2025-11-19 17:40:54 +01:00
mindesbunister
c450a78456 docs: Add multi-timeframe tracking and Docker maintenance to copilot instructions
- Multi-Timeframe Price Tracking System section (Nov 19, 2025)
  - Purpose and architecture overview
  - BlockedSignalTracker background job details
  - Database schema with price tracking fields
  - API endpoints and integration points
  - How it works (step-by-step flow)
  - Analysis queries for cross-timeframe comparison
  - Decision-making criteria for timeframe optimization
  - Current status: 2 signals tracked, pending 4H/Daily alerts

- Docker Maintenance section (Item #13 in When Making Changes)
  - Cleanup commands: image prune, builder prune, volume prune
  - When to run: After builds, weekly, on disk warnings
  - Space savings: 2-5GB images, 40-50GB cache, 0.5-1GB volumes
  - Safety guidelines: What to delete vs keep
  - Why critical: Prevent disk full from build cache accumulation

User requested: 'document in the copilot instructions with the latest updates'
Both sections provide complete reference for future AI agents
2025-11-19 17:27:12 +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
e1bce56065 fix: Correct v8 P&L values in database
Two P&L corrections for v8 trades:
1. First losing trade: Updated from -7.88 to -9.93 (matches Drift UI)
2. Phantom trade bug: Updated from /bin/bash.00 to 4.19 (TP1 + runner combined)

Corrected v8 stats:
- 5 trades, 80% win rate
- Total P&L: 1.06 (was 6.87 before corrections)
- Average: 4.21 per trade
- System recovered all previous losses and turned profitable

Related: Common Pitfall #49 (P&L compounding) and #53 (phantom detection)
caused the /bin/bash.00 entry. Database now reflects actual Drift results.
2025-11-19 15:52:10 +01:00
mindesbunister
eccecf7aaa critical: Fix container restart killing positions + phantom detection
Two critical bugs caused by container restart:

1. **Startup order restore failure:**
   - Wrong field names: takeProfit1OrderTx → tp1OrderTx
   - Caused: Prisma error, orders not restored, position unprotected
   - Impact: Container restart left position with NO TP/SL backup

2. **Phantom detection killing runners:**
   - Bug: Flagged runners after TP1 as phantom trades
   - Logic: (currentSize / positionSize) < 0.5
   - Example: $3,317 runner / $8,325 original = 40% = PHANTOM!
   - Result: Set P&L to $0.00 on profitable runner exit

Fixes:
- Use correct DB field names (tp1OrderTx, tp2OrderTx, slOrderTx)
- Phantom detection only checks BEFORE TP1 hit
- Runner P&L calculated on currentSize, not originalPositionSize
- If TP1 hit, we're closing the RUNNER (currentSize)
- If TP1 not hit, we're closing FULL position (originalPositionSize)

Real Impact (Nov 19, 2025):
- SHORT $138.355 → Runner trailing at $136.72 (peak)
- Container restart → Orders failed to restore
 Closed with $0.00 P&L
- Actual profit from Drift: ~$54.41 (TP1 + runner combined)

Prevention:
- Next restart will restore orders correctly
- Runners will calculate P&L properly
- No more premature closures from schema errors
2025-11-19 15:03:15 +01:00
mindesbunister
b2cb6a3ecd critical: Fix ADX-based runner SL in on-chain fill detection path
The ADX-based runner SL logic was only applied in the direct price
check path (lines 1065-1086) but NOT in the on-chain fill detection
path (lines 590-650).

When TP1 fills via on-chain order (most common), the system was using
hard-coded breakeven SL instead of ADX-based positioning.

Bug Impact:
- ADX 20.0 trade got breakeven SL ($138.355) instead of -0.3% ($138.77)
- Runner has $0.42 less room to breathe than intended
- Weak trends protected correctly but moderate/strong trends not

Fix:
- Applied same ADX-based logic to on-chain fill detection
- Added detailed logging for each ADX tier
- Runner SL now correct regardless of TP1 trigger path

Current trade (cmi5zpx5s0000lo07ncba1kzh):
- Already hit TP1 via old code (breakeven SL active)
- New ADX-based SL will apply to NEXT trade
- Current position: SHORT $138.3550, runner at breakeven

Code paths with ADX logic:
1. Direct price check (lines 1050-1100) 
2. On-chain fill detection (lines 607-642)  FIXED
2025-11-19 14:56:24 +01:00
mindesbunister
57790d04d6 docs: Document ADX-based adaptive runner SL system
Updated copilot-instructions.md with Nov 19, 2025 enhancement:

Architecture Overview - Exit Strategy:
- Added runner SL section with ADX-based positioning
- Documented three-tier system: <20 (0%), 20-25 (-0.3%), >25 (-0.55%)
- Explained rationale: Entry at candle close = natural pullbacks
- Risk management: Only accept drawdown on strong trends
- Example outcomes: ADX 18 → +$38.70, ADX 29 → +$22.20 worst case

Position Manager Section:
- Replaced "Dynamic SL adjustments: breakeven" with ADX-based logic
- Implementation details: Checks trade.adxAtEntry in TP1 handler
- Logging format: "🔒 ADX-based runner SL: 29.3 → -0.55%"
- Data collection phase: 50-100 trades for threshold optimization
- Noted TP1 default is 60% (not 75% - old value)

Key points documented:
- Adaptive vs fixed approach (capital preservation on weak trends)
- Integration with ADX trailing stop multiplier (both trend-adaptive)
- Natural retracement tolerance (entry at top requires -1% room)
- Future optimization plan (adjust 20/25 thresholds based on data)

Related commits:
- 66b2922: Implementation
- 7cf00cf: Fixed runner SL to -0.55% (replaced by ADX-based)
- d09838d: ADX trailing stop multiplier
2025-11-19 13:12:16 +01:00
mindesbunister
66b292246b feat: ADX-based adaptive runner SL positioning after TP1
Implements intelligent runner protection based on trend strength:

ADX-based SL positioning (Nov 19, 2025):
- ADX < 20: SL at 0% (breakeven) - Weak trend, preserve capital
- ADX 20-25: SL at -0.3% - Moderate trend, some retracement room
- ADX > 25: SL at -0.55% - Strong trend, full retracement tolerance

Rationale:
- User observation: Entry at candle close = always at top
- Screenshots showed -1% to -1.5% pullbacks even on valid trends
- Fixed -0.55% SL would cause unnecessary losses on weak trends
- Adaptive approach: Protect capital when trend weak, give room when strong

Benefits:
1. Capital preservation: Weak trends (ADX <20) get breakeven SL
2. Optimized risk/reward: Only risk runner drawdown on high-probability setups
3. Data-driven thresholds: Based on historical ADX distribution (18-32 range)
4. Complements ADX trailing stop multiplier (also trend-strength adaptive)

Example scenarios:
- ADX 18 (weak): TP1 +$38.70, Runner SL at breakeven → Total: +$38.70
- ADX 29 (strong): TP1 +$38.70, Runner SL at -0.55% → Survives pullback, captures big move

Logging:
- Shows ADX value and selected SL percentage
- Format: "🔒 ADX-based runner SL: 29.3 → -0.55% (60% closed, 40% remaining): $139.23"

Data collection phase:
- After 50-100 trades, will analyze optimal ADX thresholds
- May adjust breakpoints (20/25) based on actual performance
- Tracks runner stop-out rate vs ADX for optimization

Files changed:
- lib/trading/position-manager.ts: ADX-based SL calculation in TP1 handler
- Replaces fixed PROFIT_LOCK_AFTER_TP1_PERCENT with dynamic logic
- Uses trade.adxAtEntry (already tracked in database)
2025-11-19 13:10:10 +01:00
mindesbunister
7cf00cf7cb feat: Set runner SL to -0.55% after TP1 for retracement room
Changed PROFIT_LOCK_AFTER_TP1_PERCENT from 0.3% to -0.55%

Reasoning based on user's chart analysis:
- Entry signals trigger on candle close = always entering at top
- Price naturally retraces below entry (screenshots show -1% to -1.5%)
- Old 0.3% profit lock would stop runner out on normal retracements
- New -0.55% allows breathing room while TP1 profit already banked

Risk/Reward:
- 60% already closed at TP1 profit (guaranteed)
- 40% runner can handle -0.55% pullback without stopping out
- Worst case: -0.55% on 40% = -0.22% total position loss
- Best case: Runner catches 38% MFE moves with ADX trailing stop

Example (entry at $140):
- TP1: $140.86 → 60% closed 
- Runner SL: $139.23 (-0.55%)
- Allows pullback to $139.30-139.50 (typical retracement)
- TP2 trigger: $141.72 → ADX trail activates
- Captures big trend moves instead of premature runner stops
2025-11-19 12:30:26 +01:00
mindesbunister
6515e1054b docs: Document ADX-based trailing stop multiplier system
Added comprehensive documentation for Nov 19, 2025 enhancement:

Architecture Overview:
- Updated Exit Strategy section with ADX multiplier details
- Documented graduated system (>30: 1.5, 25-30: 1.25×, <25: 1.0×)
- Explained profit acceleration (>2%: 1.3× additional)
- Noted backward compatibility (trades without ADX use base)

Position Manager Section:
- Added detailed ADX multiplier calculation logic
- Documented combined effect examples (ADX 29.3 + 2% profit = 1.95×)
- Explained purpose (capture more of 38% MFE trades)
- Noted trail distance clamping for safety

When Making Changes Section:
- Added item #11 for trailing stop modifications
- Documented verification logs to watch for
- Listed ActiveTrade interface requirement (adxAtEntry field)
- Included example log output for validation

Related commit: d09838d (implementation)
2025-11-19 12:03:06 +01:00
mindesbunister
d09838d1dc feat: Add ADX-based trend strength multiplier for trailing stops
Implements graduated trailing stop widening based on ADX at entry:
- ADX > 30: 1.5x wider trail (very strong trends)
- ADX 25-30: 1.25x wider trail (strong trends)
- ADX < 25: Base trail (weak/moderate trends)

Also adds profit acceleration:
- Profit > 2%: Additional 1.3x multiplier
- Combines with ADX for maximum trail width

Purpose: Capture more of massive trend moves (like 38% MFE trades)
- Current system exits at ~1% with tight 0.67% trail
- ADX 29.3 + 2% profit: Trail widens to ~1.1-1.3%
- Expected improvement: 50%+ better profit capture on big moves

Example impact (Nov 19 trade):
- Entry: $140.17, MFE: 38.12%, Captured: 0.99%
- With ADX multiplier: Would capture ~1.5-2% (50%+ improvement)

Changes:
- lib/trading/position-manager.ts: Added adxAtEntry to ActiveTrade interface
- Trail calculation now checks trade.adxAtEntry and applies multipliers
- Backward compatible: Trades without ADX use base multiplier
- Logs show: "Strong trend (ADX 29.3): Trail multiplier 1.5x → 1.88x"

Data-driven decision based on:
- 4 recent v8 trades with ADX: 29.3, 20.8, 21.4, 18.3
- Nov 19 trade: ADX 29.3, MFE 38.12%, only captured 0.99%
- System needed wider trail for strong trends
2025-11-19 11:57:21 +01:00
mindesbunister
cd16ef896d chore: Remove n8n workflow comparison file
Deleted money machine compare.json after verifying n8n workflow updates.
Multi-timeframe data collection now fully configured:
- Parse Signal Enhanced with indicator version extraction (default v8)
- Execute Trade sends all metrics (atr, adx, rsi, volumeRatio, pricePosition, indicatorVersion)
- Check Risk includes indicatorVersion for proper validation
- Flow: Webhook → Parse → Check Risk → Execute → Telegram
- 5min signals execute trades, 15m/1h/4h/daily save to BlockedSignal

Workflow tested and operational in n8n UI.
2025-11-19 10:47:33 +01:00
mindesbunister
0558111ded feat: Update Money Machine workflow for multi-timeframe data collection
- Replaced Parse Signal node with enhanced version (regex supports buy 5, buy 15, buy 1h, buy 4h, buy D)
- Updated Execute Trade jsonBody to include all metrics: atr, adx, rsi, volumeRatio, pricePosition, indicatorVersion
- Removed 5min Chart Only filter - execute endpoint now handles routing automatically
- Flow: Webhook → Parse Signal Enhanced → Execute Trade → Telegram
- 5min signals execute trades, 15m/1h/4h/daily save to BlockedSignal for analysis
- User will manually update n8n nodes after JSON changes
2025-11-19 10:42:47 +01:00
mindesbunister
f65af9530f feat: Enhanced timeframe extraction for multi-timeframe data collection
Updated n8n Parse Signal Enhanced to support multiple timeframe formats:
- 5m, 15m timeframes (buy 5, buy 15)
- Hourly: buy 60, buy 1h → 60
- 4-hour: buy 240, buy 4h → 240
- Daily: buy D, buy 1d → D
- Weekly/Monthly: buy W, buy M

Fixes:
- Default timeframe changed from '15' to '5' (5min is production)
- Added indicator version extraction (IND:v8)
- Proper conversion of hour/day notation to minutes
- Case-insensitive matching for D/W/M

Related: Multi-timeframe data collection system (execute endpoint saves
non-5min signals to BlockedSignal for cross-timeframe analysis). Now
15min signals from TradingView will be properly parsed and saved.

Files:
- workflows/trading/parse_signal_enhanced.json (updated regex + conversion)
- .github/copilot-instructions.md (documented supported formats)
2025-11-19 10:33:12 +01:00
mindesbunister
df6c388639 fix: Update POST endpoint to use MIN_SIGNAL_QUALITY_SCORE
Forgot to update the POST endpoint variable name. Both GET and POST
now use MIN_SIGNAL_QUALITY_SCORE consistently.
2025-11-19 09:59:11 +01:00
mindesbunister
0d546dc267 fix: Correct MIN_QUALITY_SCORE to MIN_SIGNAL_QUALITY_SCORE
Settings UI was using wrong variable name (MIN_QUALITY_SCORE) while
code reads MIN_SIGNAL_QUALITY_SCORE. This caused quality score changes
in settings UI to have no effect.

Fixed:
- Settings API now reads/writes MIN_SIGNAL_QUALITY_SCORE
- Updated .env file to use correct variable name
- User's quality score increase to 81 will now work

Related: User increased min quality from 60 to 81 to filter out
small chop trades (avoiding -$99 trade with quality score 80).
2025-11-19 09:53:49 +01:00
mindesbunister
96f5cfae77 docs: Add Common Pitfall #51 - TP1 detection for fast on-chain fills
Documents the TP1 detection bug where on-chain limit orders fill faster
than Position Manager monitoring loop can detect. When both TP1 (75%)
and runner (25%) close before next monitoring cycle, PM doesn't know
TP1 filled first, marks entire closure as 'SL' instead of 'TP1'.

Fix uses profit percentage thresholds instead of state flags:
- >1.2%: TP2 range
- 0.3-1.2%: TP1 range
- <0.3%: SL range

Simpler and more reliable than tracking order fill state.
2025-11-19 09:09:53 +01:00
mindesbunister
de57c9634c fix: Correct TP1 detection for on-chain order fills
Problem: When TP1 order fills on-chain and runner closes quickly,
Position Manager detects entire position gone but doesn't know TP1 filled.
Result: Marks trade as 'SL' instead of 'TP1', closes 100% instead of partial.

Root cause: Position Manager monitoring loop only knows about trade state
flags (tp1Hit), not actual Drift order fill history. When both TP1 and
runner close before next monitoring cycle, tp1Hit=false but position gone.

Fix: Use profit percentage to infer exit reason instead of trade flags
- Profit >1.2%: TP2 range
- Profit 0.3-1.2%: TP1 range
- Profit <0.3%: SL/breakeven range

Always calculate P&L on full originalPositionSize for external closures.
Exit reason logic determines what actually triggered based on P&L amount.

Example from Nov 19 08:40 CET trade:
- Entry $140.17, Exit $140.85 = 0.48% profit
- Old: Marked as 'SL' (tp1Hit=false, didn't know TP1 filled)
- New: Will mark as 'TP1' (profit in TP1 range)

Lines changed: lib/trading/position-manager.ts:760-835
2025-11-19 09:03:12 +01:00
mindesbunister
120a4b499e docs: Mark P&L compounding bug as RESOLVED
Common Pitfall #50 updated with resolution details:
- Bug fixed: Removed previouslyRealized from external closure calculations
- Database corrected: 3 v8 trades updated with accurate P&L values
- System operational: New trade executed successfully at 08:40 CET
- Analytics baseline established: -$8.74 total P&L, 66.7% WR, 3 trades

Historical data gap (~3 trades) explains difference between
analytics (-$8.74) and Drift UI (~-$52). All future trades
will track accurately with fixed calculation.

Ready for Phase 1: Collect 50+ v8 trades for statistical validation.
2025-11-19 08:50:22 +01:00
mindesbunister
7833686b7b critical: Fix P&L compounding in external closure detection
Root cause: trade.realizedPnL was reading from in-memory ActiveTrade object
which could have stale/mutated values from previous detection cycles.

Bug sequence:
1. External closure detected, calculates P&L including previouslyRealized
2. Updates database with totalRealizedPnL
3. Same closure detected again (due to race condition or rate limits)
4. Reads previouslyRealized from same in-memory object (now has accumulated value)
5. Adds MORE P&L to it, compounds 2x, 5x, 10x

Real impact: 9 expected P&L became 81 (10x inflation)

Fix: Remove previouslyRealized from calculation entirely for external closures.
External closures calculate ONLY the current position P&L, not cumulative.
Database will have correct cumulative value if TP1 was processed separately.

Lines changed: lib/trading/position-manager.ts:785-803
- Removed: const previouslyRealized = trade.realizedPnL
- Removed: previouslyRealized + runnerRealized
- Now: totalRealizedPnL = runnerRealized (ONLY this closure's P&L)

Tested: Build completed successfully, container deployed and monitoring positions
2025-11-19 08:41:10 +01:00
mindesbunister
a69d2b51a5 docs: Document Nov 19 critical findings - database/Drift mismatch and P&L inflation
- Database shows only 3 v8 trades when Drift UI shows 6 trades
- One trade has 10x inflated P&L (81 vs 9 expected)
- Bot receiving ZERO API requests after 06:51 restart despite n8n executions succeeding
- Real v8 performance: ~2 LOSS (from Drift), database shows 20 profit (WRONG)
- Two issues: P&L compounding bug still active + n8n→bot connection broken
- Need to verify n8n workflow endpoints and fix external closure P&L calculation
- Common Pitfall #50 added to copilot-instructions.md
2025-11-19 08:33:03 +01:00
mindesbunister
01427ce3eb fix: Display MAE/MFE as dollars not percentages in analytics UI
- Changed 'Avg MFE: +X.XX%' to 'Avg MFE: +$X.XX'
- Changed 'Avg MAE: -X.XX%' to 'Avg MAE: -$X.XX'
- Database already stores dollar values (fixed Nov 19)
- UI was incorrectly displaying dollars with % suffix
- V8 trades: Avg MFE $34.23, Avg MAE -$11.06 (correct)
- Part of MAE/MFE data corruption fix series

Also corrected existing v8 trade in database:
- Before: MFE 19.73% (account %), MAE -1.53% (account %)
- After: MFE $95.11, MAE -$7.39 (actual dollars)
- SQL: UPDATE based on maxFavorablePrice/maxAdversePrice
2025-11-19 07:57:17 +01:00
mindesbunister
89f30ab704 fix: Remove accountPnL reference in log statement
- TypeScript error: Cannot find name 'accountPnL'
- Removed account percentage from monitoring logs
- Now shows: MFE/MAE in dollars (not percentages)
- Part of Nov 19 MAE/MFE dollar fix
2025-11-19 07:47:56 +01:00
mindesbunister
267456f699 critical: Fix MAE/MFE storing percentages instead of dollars + duplicate Telegram notifications
CRITICAL BUGS FIXED (Nov 19, 2025):

1. MAE/MFE Bug:
   - Was storing: account percentage (profit % × leverage)
   - Example: 1.31% move × 15x = 19.73% stored as MFE
   - Should store: actual dollar P&L (81 not 19.73%)
   - Impact: Telegram shows 'Max Gain: +19.73%' instead of '+.XX'
   - Fix: Changed from accountPnL (leverage-adjusted %) to currentPnLDollars
   - Lines 964-987: Removed accountPnL calculation, use currentPnLDollars

2. Duplicate Notification Bug:
   - handleExternalClosure() was checking if trade removed AFTER removal
   - Result: 16 duplicate Telegram notifications with compounding P&L
   - Example: 6 → 2 → 11 → ... → 81 (16 notifications for 1 close)
   - Fix: Check if trade already removed BEFORE processing
   - Lines 382-391: Move duplicate check to START of function
   - Early return prevents notification send if already processed

3. Database Compounding (NOT A BUG):
   - Nov 17 fix (Common Pitfall #49) still working correctly
   - Only 1 database record with 81 P&L
   - Issue was notification duplication, not DB duplication

IMPACT:
- MAE/MFE data now usable for TP/SL optimization
- Telegram notifications accurate (1 per close, correct P&L)
- Database analytics will show real dollar movements
- Next trade will have correct Max Gain/Drawdown display

FILES:
- lib/trading/position-manager.ts: MAE/MFE calculation + duplicate check
2025-11-19 07:45:58 +01:00
mindesbunister
5146f37acc docs: Add multi-timeframe data collection documentation
- Updated copilot instructions with data collection system overview
- Documents 5min execute vs 15min/1H/4H/Daily collect pattern
- Explains zero-risk parallel data collection approach
- Notes SQL analysis capability for timeframe optimization
- References implementation location in execute endpoint
- Part of v8 indicator testing and optimization strategy
2025-11-18 20:39:08 +01:00
mindesbunister
9b9d80779d fix: Use signalPrice instead of currentPrice in CreateBlockedSignalParams
- TypeScript build error: currentPrice not in interface
- Correct field name is signalPrice (already defined)
- Fixes multi-timeframe data collection compilation
2025-11-18 20:30:07 +01:00
mindesbunister
325f8d0482 feat: Add multi-timeframe data collection to execute endpoint
- Only 5min signals execute trades (production)
- 15min/1H/4H/Daily signals saved to BlockedSignal table for analysis
- Enables cross-timeframe performance comparison
- Zero financial risk - non-5min signals just collect data
- blockReason: 'DATA_COLLECTION_ONLY' for easy filtering
- Returns HTTP 200 (not 400) since this is expected behavior
- Prepares for future timeframe optimization decisions
2025-11-18 20:24:26 +01:00
mindesbunister
c330c60d88 docs: Add v8 Money Line indicator documentation to copilot instructions
- Added v8 to indicator version tracking section (Common Pitfall #26)
- Created comprehensive indicator comparison section (v6/v7/v8)
- Documented v8 improvements: flip threshold, momentum confirmation, stickier multipliers
- Added A/B testing expectations and visual backtest results
- Referenced README.md lines 48-120 for user-facing documentation
- Noted v7 deprecation (no fundamental improvements over v6)
2025-11-18 15:57:14 +01:00
mindesbunister
d309eb783c docs: Update roadmaps with v8 indicator progress
- Added v8 Money Line indicator status to master roadmap
- Updated signal quality roadmap with v8 deployment (Nov 18)
- Ready for live testing and v6 vs v8 comparison
- Awaiting first signals with indicatorVersion='v8' tracking
2025-11-18 14:10:06 +01:00
mindesbunister
74bd0f9535 docs: Add Money Line v8 indicator explanation to README
Added comprehensive section explaining:
- How the indicator works (simple terms)
- What creates the line (ATR, multiplier, HalfTrend)
- v8 improvements (flip threshold, entry buffer, stickier bands)
- Simple analogy (traffic light for trading)
- Version comparison (v6/v7/v8)

Makes it easy to explain the system to others
2025-11-18 11:44:48 +01:00
mindesbunister
067b0f7e6f feat: Add momentum confirmation to v8 - filter rapid flip-flops
V8 improvements to handle small bounces in strong trends:
- Increased flip threshold: 0.5% → 0.8% (stronger move required)
- Added confirmBars: 2 bars required after threshold breach
- Momentum tracking: Counts consecutive bars in new direction
- Anti-whipsaw: Flip only after 3 consecutive bars (confirmBars+1) beyond threshold

Example: In downtrend, price must close >0.8% above line for 3 bars before flipping bullish
This filters 1-2 bar bounces that don't change the macro trend

Result: Far fewer false reversals during strong directional moves
2025-11-18 11:23:17 +01:00
mindesbunister
039363d5b5 fix: Update v8 indicator version tracking and comments
- Changed indicatorVer from 'v6' to 'v8' for database tracking
- Updated comments to reflect sticky trend logic
- Ready for TradingView alert setup
2025-11-18 11:14:32 +01:00
mindesbunister
c9ba24f6eb feat: Create v8 indicator with sticky trend detection
V8 Changes (fundamental improvements, not just filter toggles):
- Increased ATR multipliers across all timeframes (stickier line)
  - Minutes: 3.3→3.8
  - Hours: 3.0→3.5
  - Daily: 2.8→3.2
  - Weekly: 2.5→3.0
- NEW flip threshold (0.5%): Requires price to move beyond line by % before color changes
- Entry buffer enabled by default (0.20 ATR vs 0.15)
- ADX minimum increased to 18 (from 14) for stronger trend requirement
- Core HalfTrend logic modified to require threshold breach before flip

Goal: Reduce flip-flops while maintaining high-quality trend signals
Test against v6 (filtered) and v7 (pure flips) for comparison
2025-11-18 11:11:52 +01:00
mindesbunister
cc0d754b9a feat: Add Money Line v7 with pure line flip signals
- Created moneyline_v7_line_flips.pinescript
- Signals fire on EVERY line color change (red↔green)
- All filters removed - line flip IS the signal
- confirmBars = 0 for immediate flip bar signals
- Risk management via ATR-based TP/SL (bot-side)

- Restored v6 to original filtered mode
- v6: Conservative with all filters (ADX, volume, RSI, etc)
- v7: Aggressive pure flips for maximum accuracy

Rationale: Chart analysis shows ~100% accuracy on line flips
Every green section = price up, every red section = price down
ATR-based stops handle risk, no need for entry filters
2025-11-18 10:57:37 +01:00
mindesbunister
6f85fee1da critical: Fix test endpoint violating database-first pattern (Common Pitfall #29)
- Moved positionManager.addTrade() to AFTER database save succeeds
- Changed database error handling to return HTTP 500 (not silent fail)
- Test endpoint now enforces same pattern as execute endpoint
- Prevents untracked positions when database save fails
- Root cause of trade manual-1763391075992 compounding to -19.43

Before: Test endpoint added to Position Manager first, saved to DB after
After: Test endpoint saves to DB first, only adds to PM if DB succeeds
Impact: No more untracked positions from test trades with failed DB saves
2025-11-17 16:47:07 +01:00
mindesbunister
becd5631e7 docs: Add Common Pitfall #49 - P&L exponential compounding bug
Documents the critical P&L compounding bug fixed in commit 6156c0f where
trade.realizedPnL mutation during external closure detection caused 15-20x
inflation of actual profit/loss values.

Includes:
- Root cause: Mutating trade.realizedPnL in monitoring loop
- Real incident: $6 actual profit → $92.46 in database
- Bug mechanism with code examples
- Why previous fixes (Common Pitfalls #27, #48) didn't prevent this
- Fix: Don't mutate shared state during calculations
- Related to other P&L compounding variants for cross-reference
2025-11-17 15:34:22 +01:00
mindesbunister
6156c0f958 critical: Fix P&L compounding bug in external closure detection
- CRITICAL BUG: trade.realizedPnL was being mutated during each external closure detection
- This caused exponential compounding: $6 → $12 → $24 → $48 → $96
- Each time monitoring loop detected closure, it added previouslyRealized + runnerRealized
- But previouslyRealized was the ALREADY ACCUMULATED value from previous iteration
- Result: P&L compounded 15-20x on actual value

ROOT CAUSE (line 797):
  const totalRealizedPnL = previouslyRealized + runnerRealized
  trade.realizedPnL = totalRealizedPnL  // ← BUG: Mutates in-memory trade object

Next detection cycle:
  const previouslyRealized = trade.realizedPnL  // ← Gets ACCUMULATED value
  const totalRealizedPnL = previouslyRealized + runnerRealized  // ← Adds AGAIN

FIX:
- Don't mutate trade.realizedPnL during external closure detection
- Calculate totalRealizedPnL locally, use for database update only
- trade.realizedPnL stays immutable after initial DB save
- Log message clarified: 'P&L calculation' not 'P&L snapshot'

IMPACT:
- Every external closure (TP/SL on-chain orders) affected
- With rate limiting, closure detected 15-20 times before removal
- Real example: $6 actual profit showed as $92.46 in database
- This is WORSE than duplicate notification bug - corrupts financial data

FILES CHANGED:
- lib/trading/position-manager.ts: Removed trade.realizedPnL mutation (line 799)
- Database manually corrected: $92.46 → $6.00 for affected trade

RELATED BUGS:
- Common Pitfall #48: closingInProgress flag prevents some duplicates
- But doesn't help if monitoring loop runs DURING external closure detection
- Need both fixes: closingInProgress + no mutation of trade.realizedPnL
2025-11-17 15:28:08 +01:00
mindesbunister
3aeb00f998 critical: Fix P&L calculation and TP1 false detection bugs
- Add originalPositionSize tracking to prevent stale size usage
- Add price validation to TP1 detection (prevents manual closes misidentified as TP1)
- Fix external closure P&L to use originalPositionSize not currentSize
- Add handleManualClosure method for proper exit reason detection
- Add isPriceAtTarget helper for TP/SL price validation (0.2% tolerance)
- Update all ActiveTrade creation points (execute, test, sync-positions, test-db)

Bug fixes:
- Manual close at 42.34 was detected as TP1 (target 40.71) - FIXED
- P&L showed -$1.71 instead of actual -$2.92 - FIXED
- Exit reason showed SL instead of manual - FIXED

Root cause: Position Manager detected size reduction without validating
price was actually at TP1 level. Used stale currentSize for P&L calculation.

Files modified:
- lib/trading/position-manager.ts (core fixes)
- app/api/trading/execute/route.ts
- app/api/trading/test/route.ts
- app/api/trading/sync-positions/route.ts
- app/api/trading/test-db/route.ts
2025-11-17 15:10:15 +01:00
mindesbunister
84bd2e27f0 docs: Add comprehensive ATR-based risk management documentation
- Document ATR × multiplier system (2.0/4.0/3.0 for TP1/TP2/SL)
- Add calculation formula and example with SOL at $140
- Document safety bounds (MIN/MAX percentages)
- Include data-driven ATR values (SOL median 0.43 from 162 trades)
- Document ENV configuration variables
- Add regime-agnostic benefits explanation
- Update Exit Strategy section with ATR-based details
- Update Telegram manual trade presets with accurate ATR
- Add TradingView integration requirements
- Update 'When Making Changes' with ATR modification guidance
- Explain performance analysis and expected improvements

Why: Major system upgrade (Nov 17, 2025) requires complete documentation
for future AI agents and developers. ATR-based targets solve bull/bear
optimization bias by adapting to actual market volatility.
2025-11-17 12:36:44 +01:00
mindesbunister
b6437295b6 feat: Update Telegram bot ATR to match actual SOL data
Data Analysis (162 SOL trades):
- Average ATR: 0.407 absolute
- Median ATR: 0.43 absolute (~0.32% of price)
- Range: 0.24-0.66 absolute

Updated MANUAL_METRICS:
- Old: atr = 0.45 (estimated)
- New: atr = 0.43 (data-driven median)

Impact on manual Telegram trades:
- TP1: 0.43 × 2.0 = 0.86% (vs 0.90%)
- TP2: 0.43 × 4.0 = 1.72% (vs 1.80%)
- SL: 0.43 × 3.0 = 1.29% (vs 1.35%)

Slightly tighter but more accurate to actual SOL volatility.
2025-11-17 12:28:42 +01:00
mindesbunister
8c937dd818 fix: Update calculateDynamicTp2 to use new atrMultiplierTp2 field name
- Changed atrMultiplierForTp2 → atrMultiplierTp2 to match new interface
- Marked function as LEGACY for backward compatibility
- Resolves TypeScript build error
2025-11-17 11:55:39 +01:00
mindesbunister
141022243a feat: Implement ATR-based TP/SL system for regime-agnostic trading
CRITICAL UPGRADE - Nov 17, 2025

Problem Solved:
- v6 shorts averaging +20.74% MFE but TP exits at +0.7% (leaving 95% on table)
- Fixed % targets don't adapt to bull/bear regime changes
- User must manually adjust settings when sentiment flips
- Market-regime bias in optimization (bearish now ≠ bullish later)

Solution - ATR-Based Dynamic TP/SL:
- TP1 = ATR × 2.0 (adaptive to volatility)
- TP2 = ATR × 4.0 (captures extended moves)
- SL = ATR × 3.0 (proportional risk)
- Safety bounds prevent extremes (min/max caps)

Example with SOL ATR = 0.45%:
- TP1: 0.45% × 2.0 = 0.90% (vs old fixed 0.4%)
- TP2: 0.45% × 4.0 = 1.80% (vs old fixed 0.7%)
- SL: 0.45% × 3.0 = 1.35% (vs old fixed 1.5%)

Benefits:
 Adapts automatically to bull/bear regime changes
 Asset-agnostic (SOL vs BTC have different ATR)
 Captures more profit in volatile conditions
 Tighter risk in calm conditions
 No manual intervention when sentiment shifts
 Consistent with existing ATR-based trailing stop

Implementation:
- Added TradingConfig fields: atrMultiplierTp1/Tp2/Sl with min/max bounds
- New calculatePercentFromAtr() helper function
- Execute endpoint calculates dynamic % from ATR, falls back to fixed % if unavailable
- ENV variables: ATR_MULTIPLIER_TP1/TP2/SL, MIN_TP1/TP2/SL_PERCENT, MAX_TP1/TP2/SL_PERCENT
- Updated .env with new defaults based on v6 MAE/MFE analysis

Configuration:
- USE_ATR_BASED_TARGETS=true (enabled by default)
- Runner: 40% (TAKE_PROFIT_1_SIZE_PERCENT=60)
- Trailing: 1.3x ATR (existing system, unchanged)
- Legacy fixed % used as fallback when ATR unavailable

Files Modified:
- config/trading.ts (interface + defaults + ENV reading)
- app/api/trading/execute/route.ts (ATR calculation logic)
- .env (new ATR multiplier variables)

Expected Impact:
- Capture 2-3x more profit per winning trade
- Maintain same risk management rigor
- Perform well in BOTH bull and bear markets
- Fix v6 underperformance (-$47.70 → positive)

Testing Required:
- Monitor first 10 trades with ATR-based targets
- Verify TP/SL prices match ATR calculations in logs
- Compare P&L to historical fixed-% performance
2025-11-17 11:41:13 +01:00
mindesbunister
9dfc6da449 feat: Optimize v6 indicator settings for better signal quality
- Moved confirmBars to separate 'Signal Timing' section (no longer under optional filters)
- Made timing setting always-active status clear in UI with improved tooltip
- Updated default settings based on backtesting analysis:
  * confirmBars: 0 → 1 (wait one bar for confirmation, reduces false signals)
  * ADX filter: Enabled by default (was disabled)
  * ADX Length: 14 → 16 (better trend detection)
  * ADX minimum: 20 → 14 (catches trends earlier)
  * Volume filter: Enabled by default (was disabled)
  * Volume max: 3.0x → 3.5x (allows bigger breakout moves)
  * RSI filter: Enabled by default (was disabled)
  * RSI long minimum: 45 → 35 (catches momentum earlier)
  * RSI short maximum: 55 → 70 (CRITICAL: allows shorts during breakdowns)

Why these changes matter:
- Old RSI short max of 55-61 blocked profitable breakdown entries (RSI 62-70 range)
- ADX 21 minimum missed early trend starts, lowering to 14 catches them
- Volume max 3.5x allows high-volume breakouts (was blocking with 3.0x)
- confirmBars=1 reduces wick flips while still catching good moves

Expected impact: Should fix v6 underperformance (-$47.70 over 25 trades)
Target: Positive P&L and 50%+ win rate over next 20-30 trades

Files modified:
- workflows/trading/moneyline_v6_improved.pinescript
2025-11-17 09:57:44 +01:00
mindesbunister
be2410c639 critical: Auto-restore missing on-chain orders on startup
PROBLEM (Nov 16, 22:03):
- Ghost position closed with -$6.77 loss
- Validator cleanup removed orders
- Position existed on Drift with NO on-chain TP/SL
- Only Position Manager software protection active
- If bot crashes, position completely unprotected

FIX:
- Added restoreOrdersIfMissing() to startup validator
- Checks every verified position for orders
- Automatically places TP/SL if missing
- Updates database with order transaction IDs

BEHAVIOR:
- Runs on every container startup
- Validates all open positions
- Logs: ' {symbol} has X on-chain orders'
- Or: '⚠️ {symbol} has NO orders - restoring...'
- Provides dual-layer protection always

Impact: Eliminates unprotected position risk after
validator cleanups, container restarts, or order issues.
2025-11-16 22:18:56 +01:00