- 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
133 lines
3.4 KiB
Plaintext
133 lines
3.4 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
|
|
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
|
|
|
|
// 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"
|
|
isTestTrade Boolean @default(false) // Flag test trades for exclusion from analytics
|
|
|
|
// 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])
|
|
}
|