Commit Graph

29 Commits

Author SHA1 Message Date
mindesbunister
4e286c91ef fix: harden drift verifier and validation flow 2025-12-10 15:05:44 +01:00
mindesbunister
302511293c feat: Add production logging gating (Phase 1, Task 1.1)
- Created logger utility with environment-based gating (lib/utils/logger.ts)
- Replaced 517 console.log statements with logger.log (71% reduction)
- Fixed import paths in 15 files (resolved comment-trapped imports)
- Added DEBUG_LOGS=false to .env
- Achieves 71% immediate log reduction (517/731 statements)
- Expected 90% reduction in production when deployed

Impact: Reduced I/O blocking, lower log volume in production
Risk: LOW (easy rollback, non-invasive)
Phase: Phase 1, Task 1.1 (Quick Wins - Console.log Production Gating)

Files changed:
- NEW: lib/utils/logger.ts (production-safe logging)
- NEW: scripts/replace-console-logs.js (automation tool)
- Modified: 15 lib/*.ts files (console.log → logger.log)
- Modified: .env (DEBUG_LOGS=false)

Next: Task 1.2 (Image Size Optimization)
2025-12-05 00:32:41 +01:00
mindesbunister
5f7702469e remove: V10 momentum system - backtest proved it adds no value
- Removed v10 TradingView indicator (moneyline_v10_momentum_dots.pinescript)
- Removed v10 penalty system from signal-quality.ts (-30/-25 point penalties)
- Removed backtest result files (sweep_*.csv)
- Updated copilot-instructions.md to remove v10 references
- Simplified direction-specific quality thresholds (LONG 90+, SHORT 80+)

Rationale:
- 1,944 parameter combinations tested in backtest
- All top results IDENTICAL (568 trades, $498 P&L, 61.09% WR)
- Momentum parameters had ZERO impact on trade selection
- Profit factor 1.027 too low (barely profitable after fees)
- Max drawdown -$1,270 vs +$498 profit = terrible risk-reward
- v10 penalties were blocking good trades (bug: applied to wrong positions)

Keeping v9 as production system - simpler, proven, effective.
2025-11-28 22:35:32 +01:00
mindesbunister
9d7932ff2f feat: Add distinction between regular SL and trailing SL
User Request: Distinguish between SL and Trailing SL in analytics overview

Changes:
1. Position Manager:
   - Updated ExitResult interface to include 'TRAILING_SL' exit reason
   - Modified trailing stop exit (line 1457) to use 'TRAILING_SL' instead of 'SL'
   - Enhanced external closure detection (line 937) to identify trailing stops
   - Updated handleManualClosure to detect trailing SL at price target

2. Database:
   - Updated UpdateTradeExitParams interface to accept 'TRAILING_SL'

3. Frontend Analytics:
   - Updated last trade display to show 'Trailing SL' with special formatting
   - Purple background/border for TRAILING_SL vs blue for regular SL
   - Runner emoji (🏃) prefix for trailing stops

Impact:
- Users can now see when trades exit via trailing stop vs regular SL
- Better understanding of runner system performance
- Trailing stops visually distinct in analytics dashboard

Files Modified:
- lib/trading/position-manager.ts (4 locations)
- lib/database/trades.ts (UpdateTradeExitParams interface)
- app/analytics/page.tsx (exit reason display)
- .github/copilot-instructions.md (Common Pitfalls #61, #62)
2025-11-24 08:40:09 +01:00
mindesbunister
a07485c21f feat: Add comprehensive database save protection system
INVESTIGATION RESULT: No database failure occurred - trade was saved correctly.
However, implemented 5-layer protection against future failures:

1. Persistent File Logger (lib/utils/persistent-logger.ts)
   - Survives container restarts
   - Logs to /app/logs/errors.log
   - Daily rotation, 30-day retention

2. Database Save Retry Logic (lib/database/trades.ts)
   - 3 retry attempts with exponential backoff (1s, 2s, 4s)
   - Immediate verification query after each create
   - Persistent logging of all attempts

3. Orphan Position Detection (lib/startup/init-position-manager.ts)
   - Runs on every container startup
   - Queries Drift for positions without database records
   - Creates retroactive Trade records
   - Sends Telegram alerts
   - Restores Position Manager monitoring

4. Critical Logging (app/api/trading/execute/route.ts)
   - Database failures logged with full trade details
   - Stack traces preserved for debugging

5. Infrastructure (logs directory + Docker volume)
   - Mounted at /home/icke/traderv4/logs
   - Configured in docker-compose.yml

Trade from Nov 21 00:40:14 CET:
- Found in database: cmi82qg590001tn079c3qpw4r
- SHORT SOL-PERP 33.69 → 34.67 SL
- P&L: -9.17
- Closed at 01:17:03 CET (37 minutes duration)
- No database failure occurred

Future Protection:
- Retry logic catches transient failures
- Verification prevents silent failures
- Orphan detection catches anything missed
- Persistent logs enable post-mortem analysis
- System now bulletproof for 16 → 00k journey
2025-11-21 09:47:00 +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
b813a38ae9 fix: Handle multiple DB trades for single Drift position in validator
PROBLEM (User identified):
- Analytics showed 3 open trades when Drift UI showed only 1 position
- Database had 3 separate trade records all marked as 'open'
- Root cause: Drift has 1 POSITION + 3 ORDERS (TP/SL exit orders)
- Validator was incorrectly treating each as separate position

SOLUTION:
- Group database trades by symbol before validation
- If multiple DB trades exist for one Drift position, keep only MOST RECENT
- Close older duplicate trades with exitReason='DUPLICATE_CLEANUP'
- Properly handles: 1 Drift position → 1 DB trade (correct state)

RESULT:
- Database: 1 open trade (matches Drift reality)
- Analytics: Shows accurate position count
- Runs automatically every 10 minutes + manual trigger available
2025-11-16 21:36:21 +01:00
mindesbunister
66c3c42547 feat: Add automated database sync validator for ghost position detection
PROBLEM:
- Analytics page showed 3 open trades when only 1 actually open on Drift
- Ghost positions in database (realizedPnL set but exitReason = NULL)
- Happens when on-chain orders fill but database update fails
- Manual cleanup required = unreliable dashboard

SOLUTION: Automated Database Sync Validator
1. Runs every 10 minutes (independent of Position Manager)
2. Validates ALL 'open' database trades against actual Drift positions
3. Auto-fixes ghost positions (marks as closed with exitReason)
4. Provides manual validation endpoint: GET /api/admin/validate-db

FEATURES:
- Detects ghost positions (DB open, Drift closed)
- Detects orphan positions (DB closed, Drift open)
- Provides detailed validation reports
- Runs on server startup + periodic intervals
- Zero manual intervention required

FILES:
- lib/database/sync-validator.ts: Core validation logic
- app/api/admin/validate-db/route.ts: Manual validation endpoint
- instrumentation.ts: Auto-start on server initialization

RESULT: Reliable dashboard data - always matches Drift reality
2025-11-16 21:30:29 +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
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
7f9dcc00e2 feat: add indicatorVersion to CreateTradeParams interface and createTrade function 2025-11-12 08:29:40 +01:00
mindesbunister
ba13c20c60 feat: implement blocked signals tracking system
- Add BlockedSignal table with 25 fields for comprehensive signal analysis
- Track all blocked signals with metrics (ATR, ADX, RSI, volume, price position)
- Store quality scores, block reasons, and detailed breakdowns
- Include future fields for automated price analysis (priceAfter1/5/15/30Min)
- Restore signalQualityVersion field to Trade table

Database changes:
- New table: BlockedSignal with indexes on symbol, createdAt, score, blockReason
- Fixed schema drift from manual changes

API changes:
- Modified check-risk endpoint to save blocked signals automatically
- Fixed hasContextMetrics variable scope (moved to line 209)
- Save blocks for: quality score too low, cooldown period, hourly limit
- Use config.minSignalQualityScore instead of hardcoded 60

Database helpers:
- Added createBlockedSignal() function with try/catch safety
- Added getRecentBlockedSignals(limit) for queries
- Added getBlockedSignalsForAnalysis(olderThanMinutes) for automation

Documentation:
- Created BLOCKED_SIGNALS_TRACKING.md with SQL queries and analysis workflow
- Created SIGNAL_QUALITY_OPTIMIZATION_ROADMAP.md with 5-phase plan
- Documented data-first approach: collect 10-20 signals before optimization

Rationale:
Only 2 historical trades scored 60-64 (insufficient sample size for threshold decision).
Building data collection infrastructure before making premature optimizations.

Phase 1 (current): Collect blocked signals for 1-2 weeks
Phase 2 (next): Analyze patterns and make data-driven threshold decision
Phase 3-5 (future): Automation and ML optimization
2025-11-11 11:49:21 +01:00
mindesbunister
988fdb9ea4 Fix runner system + strengthen anti-chop filter
Three critical bugs fixed:
1. P&L calculation (65x inflation) - now uses collateralUSD not notional
2. handlePostTp1Adjustments() - checks tp2SizePercent===0 for runner mode
3. JavaScript || operator bug - changed to ?? for proper 0 handling

Signal quality improvements:
- Added anti-chop filter: price position <40% + ADX <25 = -25 points
- Prevents range-bound flip-flops (caught all 3 today)
- Backtest: 43.8% → 55.6% win rate, +86% profit per trade

Changes:
- lib/trading/signal-quality.ts: RANGE-BOUND CHOP penalty
- lib/drift/orders.ts: Fixed P&L calculation + transaction confirmation
- lib/trading/position-manager.ts: Runner system logic
- app/api/trading/execute/route.ts: || to ?? for tp2SizePercent
- app/api/trading/test/route.ts: || to ?? for tp1/tp2SizePercent
- prisma/schema.prisma: Added collateralUSD field
- scripts/fix_pnl_calculations.sql: Historical P&L correction
2025-11-10 15:36:51 +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
625dc44c59 Add signal quality version tracking to database
- Added signalQualityVersion field to Trade model
- Tracks which scoring logic version was used for each trade
- v1: Original logic (price position < 5% threshold)
- v2: Added volume compensation for low ADX
- v3: CURRENT - Stricter logic requiring ADX > 18 for extreme positions (< 15%)

This enables future analysis to:
- Compare performance between logic versions
- Filter trades by scoring algorithm
- Data-driven improvements based on clean datasets

All new trades will be marked as v3. Old trades remain null/v1 for comparison.
2025-11-07 12:56:35 +01:00
mindesbunister
a100945864 Enhance trailing stop with ATR-based sizing 2025-11-05 15:28:12 +01:00
mindesbunister
8bc08955cc feat: Add phantom trade detection and database tracking
- Detect position size mismatches (>50% variance) after opening
- Save phantom trades to database with expectedSizeUSD, actualSizeUSD, phantomReason
- Return error from execute endpoint to prevent Position Manager tracking
- Add comprehensive documentation of phantom trade issue and solution
- Enable data collection for pattern analysis and future optimization

Fixes oracle price lag issue during volatile markets where transactions
confirm but positions don't actually open at expected size.
2025-11-04 10:34:38 +01:00
mindesbunister
0ed2e89c7e feat: implement per-symbol cooldown period
CRITICAL: Cooldown was global across ALL symbols, causing missed opportunities
Example: ETH trade at 10:00 blocked SOL trade at 10:04 (5min cooldown)

Changes:
- Added getLastTradeTimeForSymbol() function to query last trade per symbol
- Updated check-risk endpoint to use symbol-specific cooldown
- Each coin (SOL/ETH/BTC) now has independent cooldown timer
- Cooldown message shows symbol: 'Must wait X min before next SOL-PERP trade'

Result: Can trade ETH and SOL simultaneously without interference
Example: ETH LONG at 10:00, SOL SHORT at 10:01 = both allowed
2025-11-03 08:01:30 +01:00
mindesbunister
090b79a07f Store signal quality score in database for future analysis
- Add signalQualityScore field to Trade model (0-100)
- Calculate quality score in execute endpoint using same logic as check-risk
- Save score with every trade for correlation analysis
- Create database migration for new field
- Enables future analysis: score vs win rate, P&L, etc.

This allows data-driven decisions on dynamic position sizing
2025-10-31 11:12:07 +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
830468d524 Implement signal quality scoring system
- Updated execute endpoint to store context metrics in database
- Updated CreateTradeParams interface with 5 context metrics
- Updated Prisma schema with rsiAtEntry and pricePositionAtEntry
- Ran migration: add_rsi_and_price_position_metrics
- Complete flow: TradingView → n8n → check-risk (scores) → execute (stores)
2025-10-30 19:31:32 +01:00
mindesbunister
7c4adff4e4 Implement risk checks: cooldown, hourly limit, and daily drawdown
Implemented 3 critical risk checks in /api/trading/check-risk:

1. Daily Drawdown Check
   - Blocks trades if today's P&L < maxDailyDrawdown
   - Prevents catastrophic daily losses
   - Currently: -0 limit (configurable via MAX_DAILY_DRAWDOWN)

2. Hourly Trade Limit
   - Blocks trades if tradesInLastHour >= maxTradesPerHour
   - Prevents overtrading / algorithm malfunction
   - Currently: 20 trades/hour (configurable via MAX_TRADES_PER_HOUR)

3. Cooldown Period
   - Blocks trades if timeSinceLastTrade < minTimeBetweenTrades
   - Enforces breathing room between trades
   - Uses minutes (not seconds) thanks to previous commit
   - Currently: 0 min = disabled (configurable via MIN_TIME_BETWEEN_TRADES)

Added database helper functions:
- getLastTradeTime() - Returns timestamp of most recent trade
- getTradesInLastHour() - Counts trades in last 60 minutes
- getTodayPnL() - Sums realized P&L since midnight

All checks include detailed logging with values and thresholds.
Risk check called by n8n workflow before every trade execution.
2025-10-30 10:50:08 +01:00
mindesbunister
25d31ff75a Fix: Save MAE/MFE values when trades exit
Bug: MAE/MFE was tracked in memory during trades but not saved to database on exit
Cause: updateTradeExit() wasn't receiving or saving MAE/MFE parameters

Changes:
- Added MAE/MFE fields to UpdateTradeExitParams interface
- Modified updateTradeExit() to save maxFavorableExcursion, maxAdverseExcursion, maxFavorablePrice, maxAdversePrice
- Updated both updateTradeExit() calls in Position Manager to pass MAE/MFE values
- Enhanced exit logging to show final MAE/MFE percentages

Impact: Future trades will now properly save MAE/MFE data for analytics
Note: Past 2 trades (from before this fix) don't have MAE/MFE saved
2025-10-30 07:37:10 +01:00
mindesbunister
e068c5f2e6 Phase 2: Market context capture at entry
- Added getFundingRate() method to DriftService
- Capture expectedEntryPrice from oracle before order execution
- Capture fundingRateAtEntry from Drift Protocol
- Save market context fields to database (expectedEntryPrice, fundingRateAtEntry)
- Calculate entry slippage percentage in createTrade()
- Fixed template literal syntax errors in execute endpoint

Database fields populated:
- expectedEntryPrice: Oracle price before order
- entrySlippagePct: Calculated from entrySlippage
- fundingRateAtEntry: Current funding rate from Drift

Next: Phase 3 (analytics API) or test market context on next trade
2025-10-29 20:51:46 +01:00
mindesbunister
65e6a8efed Phase 1: Add MAE/MFE tracking and analytics schema
- Added 20+ analytics fields to Trade model (MAE/MFE, fill tracking, timing, market context, slippage)
- Implemented real-time MAE/MFE tracking in Position Manager (updates every 5s)
- Enhanced database schema with comprehensive trade analytics
- Updated all API endpoints to initialize MAE/MFE fields
- Modified updateTradeState() to persist MAE/MFE in configSnapshot

Database changes:
- maxFavorableExcursion/maxAdverseExcursion track best/worst profit %
- maxFavorablePrice/maxAdversePrice track exact price levels
- Fill tracking: tp1Filled, tp2Filled, softSlFilled, hardSlFilled
- Timing metrics: timeToTp1, timeToTp2, timeToSl
- Market context: atrAtEntry, adxAtEntry, volumeAtEntry, fundingRateAtEntry, basisAtEntry
- Slippage tracking: expectedEntryPrice, entrySlippagePct, expectedExitPrice, exitSlippagePct

Position Manager changes:
- Track MAE/MFE on every price check (2s interval)
- Throttled database updates (5s interval) via updateTradeMetrics()
- Persist MAE/MFE in trade state snapshots for recovery

Next: Phase 2 (market context capture) or Phase 3 (analytics API)
2025-10-29 20:34:03 +01:00
mindesbunister
d3c04ea9c9 feat: Position Manager persistence + order cleanup + improved stop loss
- Add Position Manager state persistence to survive restarts
  - Auto-restore open trades from database on startup
  - Save state after TP1, SL adjustments, profit locks
  - Persist to configSnapshot JSON field

- Add automatic order cancellation
  - Cancel all TP/SL orders when position fully closed
  - New cancelAllOrders() function in drift/orders.ts
  - Prevents orphaned orders after manual closes

- Improve stop loss management
  - Move SL to +0.35% after TP1 (was +0.15%)
  - Gives more breathing room for retracements
  - Still locks in half of TP1 profit

- Add database sync when Position Manager closes trades
  - Auto-update Trade record with exit data
  - Save P&L, exit reason, hold time
  - Fix analytics showing stale data

- Add trade state management functions
  - updateTradeState() for Position Manager persistence
  - getOpenTrades() for startup restoration
  - getInitializedPositionManager() for async init

- Create n8n database analytics workflows
  - Daily report workflow (automated at midnight)
  - Pattern analysis (hourly/daily performance)
  - Stop loss effectiveness analysis
  - Database analytics query workflow
  - Complete setup guide (N8N_DATABASE_SETUP.md)
2025-10-27 10:39:05 +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
mindesbunister
d64f6d84c4 feat: implement dual stop system and database tracking
- Add PostgreSQL database with Prisma ORM
  - Trade model: tracks entry/exit, P&L, order signatures, config snapshots
  - PriceUpdate model: tracks price movements for drawdown analysis
  - SystemEvent model: logs errors and system events
  - DailyStats model: aggregated performance metrics

- Implement dual stop loss system (enabled by default)
  - Soft stop (TRIGGER_LIMIT) at -1.5% to avoid wicks
  - Hard stop (TRIGGER_MARKET) at -2.5% to guarantee exit
  - Configurable via USE_DUAL_STOPS, SOFT_STOP_PERCENT, HARD_STOP_PERCENT
  - Backward compatible with single stop modes

- Add database service layer (lib/database/trades.ts)
  - createTrade(): save new trades with all details
  - updateTradeExit(): close trades with P&L calculations
  - addPriceUpdate(): track price movements during trade
  - getTradeStats(): calculate win rate, profit factor, avg win/loss
  - logSystemEvent(): log errors and system events

- Update execute endpoint to use dual stops and save to database
  - Calculate dual stop prices when enabled
  - Pass dual stop parameters to placeExitOrders
  - Save complete trade record to database after execution

- Add test trade button to settings page
  - New /api/trading/test endpoint for executing test trades
  - Displays detailed results including dual stop prices
  - Confirmation dialog before execution
  - Shows entry price, position size, stops, and TX signature

- Generate Prisma client in Docker build
- Update DATABASE_URL for container networking
2025-10-26 21:29:27 +01:00