// 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]) } // 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]) }