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
This commit is contained in:
131
prisma/schema.prisma
Normal file
131
prisma/schema.prisma
Normal file
@@ -0,0 +1,131 @@
|
||||
// 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"
|
||||
|
||||
// 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])
|
||||
}
|
||||
Reference in New Issue
Block a user