Files
trading_bot_v4/prisma/schema.prisma
mindesbunister db52299b55 feat: Enhancement #6 data collection + #1 implementation plan
Enhancement #6 - SL Distance Validation (Data Collection Phase):
- Added slDistanceAtEntry field to StopHunt schema
- Calculates distance from revenge entry to stop zone (LONG vs SHORT logic)
- Logs distance in dollars + × ATR multiplier
- Purpose: Collect 20+ revenge trade samples for optimal multiplier analysis
- Created comprehensive analysis guide with SQL queries
- Decision deferred until empirical data collected

Enhancement #1 - ADX Confirmation (Implementation Plan):
- Documented complete 1-minute TradingView alert strategy
- Storage analysis: 19.44 MB/month for 3 symbols (negligible)
- Two-phase approach: Cache-only MVP → Optional DB persistence
- Provided TradingView Pine Script (ready to use)
- Cost breakdown: Pro subscription $49.95/month required
- Benefits: Real-time ADX, pattern recognition, ML features
- Implementation checklist with validation phases

Files Changed:
- prisma/schema.prisma: +1 field (slDistanceAtEntry)
- lib/trading/stop-hunt-tracker.ts: +10 lines (distance calculation + logging)
- docs/1MIN_MARKET_DATA_IMPLEMENTATION.md: NEW (comprehensive plan)
- docs/ENHANCEMENT_6_ANALYSIS_GUIDE.md: NEW (SQL queries + decision matrix)

Status:
 Enhancement #4 and #10 deployed (previous commit)
 Enhancement #6 data collection enabled (this commit)
   Awaiting 20+ revenge trades for Enhancement #6 decision
2025-11-27 08:26:45 +01:00

286 lines
10 KiB
Plaintext

// Prisma Schema for Trading Bot v4
// Database: PostgreSQL
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// Trade records for analysis and performance tracking
model Trade {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Trade identification
positionId String @unique // Transaction signature from entry order
symbol String // e.g., "SOL-PERP"
direction String // "long" or "short"
// Entry details
entryPrice Float
entryTime DateTime
entrySlippage Float?
positionSizeUSD Float // NOTIONAL position size (with leverage)
collateralUSD Float? // ACTUAL margin/collateral used (positionSizeUSD / leverage)
leverage Float
// Exit targets (planned)
stopLossPrice Float
softStopPrice Float? // Dual stop: soft stop-limit trigger
hardStopPrice Float? // Dual stop: hard stop-market trigger
takeProfit1Price Float
takeProfit2Price Float
tp1SizePercent Float
tp2SizePercent Float
// Exit details (actual)
exitPrice Float?
exitTime DateTime?
exitReason String? // "TP1", "TP2", "SL", "SOFT_SL", "HARD_SL", "manual", "emergency"
// Performance metrics
realizedPnL Float?
realizedPnLPercent Float?
holdTimeSeconds Int?
maxDrawdown Float? // Peak to valley during trade
maxGain Float? // Peak gain reached
// MAE/MFE Analysis (Maximum Adverse/Favorable Excursion)
maxFavorableExcursion Float? // Best profit % reached during trade
maxAdverseExcursion Float? // Worst drawdown % during trade
maxFavorablePrice Float? // Best price hit (direction-aware)
maxAdversePrice Float? // Worst price hit (direction-aware)
// Exit details - which levels actually filled
tp1Filled Boolean @default(false)
tp2Filled Boolean @default(false)
softSlFilled Boolean @default(false)
hardSlFilled Boolean @default(false)
tp1FillPrice Float?
tp2FillPrice Float?
slFillPrice Float?
// Timing metrics
timeToTp1 Int? // Seconds from entry to TP1 fill
timeToTp2 Int? // Seconds from entry to TP2 fill
timeToSl Int? // Seconds from entry to SL hit
// Market context at entry
atrAtEntry Float? // ATR% when trade opened
adxAtEntry Float? // ADX trend strength (0-50)
rsiAtEntry Float? // RSI momentum (0-100)
volumeAtEntry Float? // Volume relative to MA
pricePositionAtEntry Float? // Price position in range (0-100%)
signalQualityScore Int? // Calculated quality score (0-100)
signalQualityVersion String? @default("v4") // Tracks which scoring logic was used
indicatorVersion String? // Pine Script version (v5, v6, etc.)
fundingRateAtEntry Float? // Perp funding rate at entry
basisAtEntry Float? // Perp-spot basis at entry
// Slippage tracking
expectedEntryPrice Float? // Target entry from signal
entrySlippagePct Float? // Actual slippage %
expectedExitPrice Float? // Which TP/SL should have hit
exitSlippagePct Float? // Exit slippage %
// Order signatures
entryOrderTx String
tp1OrderTx String?
tp2OrderTx String?
slOrderTx String?
softStopOrderTx String? // Dual stop: soft stop tx
hardStopOrderTx String? // Dual stop: hard stop tx
exitOrderTx String?
// Configuration snapshot
configSnapshot Json // Store settings used for this trade
// Signal data
signalSource String? // "tradingview", "manual", etc.
signalStrength String? // "strong", "moderate", "weak"
timeframe String? // "5", "15", "60"
// Status
status String @default("open") // "open", "closed", "failed", "phantom"
isTestTrade Boolean @default(false) // Flag test trades for exclusion from analytics
// Phantom trade detection
isPhantom Boolean @default(false) // Position opened but size mismatch >50%
expectedSizeUSD Float? // Expected position size (when phantom)
actualSizeUSD Float? // Actual position size from Drift (when phantom)
phantomReason String? // "ORACLE_PRICE_MISMATCH", "PARTIAL_FILL", "ORDER_REJECTED"
// Relations
priceUpdates PriceUpdate[]
@@index([symbol])
@@index([createdAt])
@@index([status])
@@index([exitReason])
}
// Real-time price updates during trade (for analysis)
model PriceUpdate {
id String @id @default(cuid())
createdAt DateTime @default(now())
tradeId String
trade Trade @relation(fields: [tradeId], references: [id], onDelete: Cascade)
price Float
pnl Float
pnlPercent Float
@@index([tradeId])
@@index([createdAt])
}
// System events and errors
model SystemEvent {
id String @id @default(cuid())
createdAt DateTime @default(now())
eventType String // "error", "warning", "info", "trade_executed", etc.
message String
details Json?
@@index([eventType])
@@index([createdAt])
}
// Blocked signals for analysis (signals that didn't pass quality checks)
model BlockedSignal {
id String @id @default(cuid())
createdAt DateTime @default(now())
// Signal identification
symbol String // e.g., "SOL-PERP"
direction String // "long" or "short"
timeframe String? // "5", "15", "60"
// Price at signal time
signalPrice Float // Price when signal was generated
// Market metrics at signal time
atr Float? // ATR% at signal
adx Float? // ADX trend strength
rsi Float? // RSI momentum
volumeRatio Float? // Volume relative to average
pricePosition Float? // Position in range (0-100%)
// Quality scoring
signalQualityScore Int // 0-100 score
signalQualityVersion String? // Which scoring version
scoreBreakdown Json? // Detailed breakdown of score components
minScoreRequired Int // What threshold was used (e.g., 65)
indicatorVersion String? // Pine Script version (v5, v6, etc.)
// Block reason
blockReason String // "QUALITY_SCORE_TOO_LOW", "DUPLICATE", "COOLDOWN", "DATA_COLLECTION_ONLY", etc.
blockDetails String? // Human-readable details
// Entry tracking (for multi-timeframe analysis)
entryPrice Float @default(0) // Price at signal time
// For later analysis: track if it would have been profitable
priceAfter1Min Float? // Price 1 minute after (filled by monitoring job)
priceAfter5Min Float? // Price 5 minutes after
priceAfter15Min Float? // Price 15 minutes after
priceAfter30Min Float? // Price 30 minutes after
wouldHitTP1 Boolean? // Would TP1 have been hit?
wouldHitTP2 Boolean? // Would TP2 have been hit?
wouldHitSL Boolean? // Would SL have been hit?
// Max favorable/adverse excursion (mirror Trade model)
maxFavorablePrice Float? // Price at max profit
maxAdversePrice Float? // Price at max loss
maxFavorableExcursion Float? // Best profit % during tracking
maxAdverseExcursion Float? // Worst loss % during tracking
analysisComplete Boolean @default(false) // Has post-analysis been done?
@@index([symbol])
@@index([createdAt])
@@index([signalQualityScore])
@@index([blockReason])
}
// Stop Hunt Revenge Tracker (Nov 20, 2025)
// Tracks high-quality stop-outs and auto re-enters when stop hunt reverses
model StopHunt {
id String @id @default(cuid())
createdAt DateTime @default(now())
// Original trade that got stopped out
originalTradeId String // References Trade.id
symbol String // e.g., "SOL-PERP"
direction String // "long" or "short"
// Stop hunt details
stopHuntPrice Float // Price where we got stopped out
originalEntryPrice Float // Where we originally entered
originalQualityScore Int // Must be 85+ to qualify
originalADX Float? // Trend strength at entry
originalATR Float? // Volatility at entry
stopLossAmount Float // How much we lost
stopHuntTime DateTime // When stop hunt occurred
// Revenge tracking
revengeTradeId String? // References Trade.id if revenge executed
revengeExecuted Boolean @default(false)
revengeEntryPrice Float? // Where revenge trade entered
revengeTime DateTime? // When revenge executed
revengeWindowExpired Boolean @default(false)
revengeExpiresAt DateTime // 4 hours after stop hunt
slDistanceAtEntry Float? // Distance from entry to stop zone (for Enhancement #6 analysis)
// Monitoring state
highestPriceAfterStop Float? // Track if stop hunt reverses
lowestPriceAfterStop Float? // Track if stop hunt reverses
// Zone tracking persistence (Nov 27, 2025 - Enhancement #10)
firstCrossTime DateTime? // When price entered revenge zone
lowestInZone Float? // Lowest price while in zone (LONG)
highestInZone Float? // Highest price while in zone (SHORT)
zoneResetCount Int @default(0) // How many times price left zone
// Revenge outcome tracking (Nov 27, 2025 - Enhancement #4)
revengeOutcome String? // "TP1", "TP2", "SL", "TRAILING_SL", null (pending)
revengePnL Float? // Realized P&L from revenge trade
revengeFailedReason String? // Why revenge failed: "stopped_again", "chop", "insufficient_capital"
@@index([symbol])
@@index([revengeExecuted])
@@index([revengeWindowExpired])
@@index([stopHuntTime])
@@index([revengeOutcome])
}
// Performance analytics (daily aggregates)
model DailyStats {
id String @id @default(cuid())
date DateTime @unique
tradesCount Int
winningTrades Int
losingTrades Int
totalPnL Float
totalPnLPercent Float
winRate Float
avgWin Float
avgLoss Float
profitFactor Float
maxDrawdown Float
sharpeRatio Float?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([date])
}