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:
123
prisma/migrations/20251026200052_init/migration.sql
Normal file
123
prisma/migrations/20251026200052_init/migration.sql
Normal file
@@ -0,0 +1,123 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "Trade" (
|
||||
"id" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"positionId" TEXT NOT NULL,
|
||||
"symbol" TEXT NOT NULL,
|
||||
"direction" TEXT NOT NULL,
|
||||
"entryPrice" DOUBLE PRECISION NOT NULL,
|
||||
"entryTime" TIMESTAMP(3) NOT NULL,
|
||||
"entrySlippage" DOUBLE PRECISION,
|
||||
"positionSizeUSD" DOUBLE PRECISION NOT NULL,
|
||||
"leverage" DOUBLE PRECISION NOT NULL,
|
||||
"stopLossPrice" DOUBLE PRECISION NOT NULL,
|
||||
"softStopPrice" DOUBLE PRECISION,
|
||||
"hardStopPrice" DOUBLE PRECISION,
|
||||
"takeProfit1Price" DOUBLE PRECISION NOT NULL,
|
||||
"takeProfit2Price" DOUBLE PRECISION NOT NULL,
|
||||
"tp1SizePercent" DOUBLE PRECISION NOT NULL,
|
||||
"tp2SizePercent" DOUBLE PRECISION NOT NULL,
|
||||
"exitPrice" DOUBLE PRECISION,
|
||||
"exitTime" TIMESTAMP(3),
|
||||
"exitReason" TEXT,
|
||||
"realizedPnL" DOUBLE PRECISION,
|
||||
"realizedPnLPercent" DOUBLE PRECISION,
|
||||
"holdTimeSeconds" INTEGER,
|
||||
"maxDrawdown" DOUBLE PRECISION,
|
||||
"maxGain" DOUBLE PRECISION,
|
||||
"entryOrderTx" TEXT NOT NULL,
|
||||
"tp1OrderTx" TEXT,
|
||||
"tp2OrderTx" TEXT,
|
||||
"slOrderTx" TEXT,
|
||||
"softStopOrderTx" TEXT,
|
||||
"hardStopOrderTx" TEXT,
|
||||
"exitOrderTx" TEXT,
|
||||
"configSnapshot" JSONB NOT NULL,
|
||||
"signalSource" TEXT,
|
||||
"signalStrength" TEXT,
|
||||
"timeframe" TEXT,
|
||||
"status" TEXT NOT NULL DEFAULT 'open',
|
||||
|
||||
CONSTRAINT "Trade_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "PriceUpdate" (
|
||||
"id" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"tradeId" TEXT NOT NULL,
|
||||
"price" DOUBLE PRECISION NOT NULL,
|
||||
"pnl" DOUBLE PRECISION NOT NULL,
|
||||
"pnlPercent" DOUBLE PRECISION NOT NULL,
|
||||
|
||||
CONSTRAINT "PriceUpdate_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "SystemEvent" (
|
||||
"id" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"eventType" TEXT NOT NULL,
|
||||
"message" TEXT NOT NULL,
|
||||
"details" JSONB,
|
||||
|
||||
CONSTRAINT "SystemEvent_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "DailyStats" (
|
||||
"id" TEXT NOT NULL,
|
||||
"date" TIMESTAMP(3) NOT NULL,
|
||||
"tradesCount" INTEGER NOT NULL,
|
||||
"winningTrades" INTEGER NOT NULL,
|
||||
"losingTrades" INTEGER NOT NULL,
|
||||
"totalPnL" DOUBLE PRECISION NOT NULL,
|
||||
"totalPnLPercent" DOUBLE PRECISION NOT NULL,
|
||||
"winRate" DOUBLE PRECISION NOT NULL,
|
||||
"avgWin" DOUBLE PRECISION NOT NULL,
|
||||
"avgLoss" DOUBLE PRECISION NOT NULL,
|
||||
"profitFactor" DOUBLE PRECISION NOT NULL,
|
||||
"maxDrawdown" DOUBLE PRECISION NOT NULL,
|
||||
"sharpeRatio" DOUBLE PRECISION,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "DailyStats_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Trade_positionId_key" ON "Trade"("positionId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Trade_symbol_idx" ON "Trade"("symbol");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Trade_createdAt_idx" ON "Trade"("createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Trade_status_idx" ON "Trade"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Trade_exitReason_idx" ON "Trade"("exitReason");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "PriceUpdate_tradeId_idx" ON "PriceUpdate"("tradeId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "PriceUpdate_createdAt_idx" ON "PriceUpdate"("createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "SystemEvent_eventType_idx" ON "SystemEvent"("eventType");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "SystemEvent_createdAt_idx" ON "SystemEvent"("createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "DailyStats_date_key" ON "DailyStats"("date");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "DailyStats_date_idx" ON "DailyStats"("date");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "PriceUpdate" ADD CONSTRAINT "PriceUpdate_tradeId_fkey" FOREIGN KEY ("tradeId") REFERENCES "Trade"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
3
prisma/migrations/migration_lock.toml
Normal file
3
prisma/migrations/migration_lock.toml
Normal file
@@ -0,0 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (e.g., Git)
|
||||
provider = "postgresql"
|
||||
Reference in New Issue
Block a user