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