{ "name": "Daily Trading Report", "nodes": [ { "parameters": { "rule": { "interval": [ { "triggerAtHour": 0, "triggerAtMinute": 5 } ] } }, "id": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d", "name": "Every Day at Midnight", "type": "n8n-nodes-base.scheduleTrigger", "typeVersion": 1.2, "position": [240, 300] }, { "parameters": { "operation": "executeQuery", "query": "-- Get yesterday's trading activity\nSELECT \n COUNT(*) as total_trades,\n COUNT(CASE WHEN \"realizedPnL\" > 0 THEN 1 END) as winning_trades,\n COUNT(CASE WHEN \"realizedPnL\" < 0 THEN 1 END) as losing_trades,\n SUM(\"realizedPnL\") as total_pnl,\n AVG(\"realizedPnL\") as avg_pnl,\n MAX(\"realizedPnL\") as best_trade,\n MIN(\"realizedPnL\") as worst_trade,\n AVG(\"holdTimeSeconds\") / 60 as avg_hold_time_minutes\nFROM \"Trade\"\nWHERE status = 'closed'\n AND \"isTestTrade\" = false\n AND \"exitTime\" >= CURRENT_DATE - INTERVAL '1 day'\n AND \"exitTime\" < CURRENT_DATE;" }, "id": "2b3c4d5e-6f7a-8b9c-0d1e-2f3a4b5c6d7e", "name": "Query Yesterday Stats", "type": "n8n-nodes-base.postgres", "typeVersion": 2.4, "position": [460, 300], "credentials": { "postgres": { "id": "1", "name": "Trading Bot Database" } } }, { "parameters": { "operation": "executeQuery", "query": "-- Get breakdown by symbol\nSELECT \n symbol,\n COUNT(*) as trades,\n SUM(\"realizedPnL\") as pnl\nFROM \"Trade\"\nWHERE status = 'closed'\n AND \"isTestTrade\" = false\n AND \"exitTime\" >= CURRENT_DATE - INTERVAL '1 day'\n AND \"exitTime\" < CURRENT_DATE\nGROUP BY symbol\nORDER BY pnl DESC;" }, "id": "3c4d5e6f-7a8b-9c0d-1e2f-3a4b5c6d7e8f", "name": "Query Symbol Breakdown", "type": "n8n-nodes-base.postgres", "typeVersion": 2.4, "position": [460, 500], "credentials": { "postgres": { "id": "1", "name": "Trading Bot Database" } } }, { "parameters": { "operation": "insert", "schema": { "__rl": true, "value": "public", "mode": "list", "cachedResultName": "public" }, "table": { "__rl": true, "value": "DailyStats", "mode": "list", "cachedResultName": "DailyStats" }, "columns": { "mappingMode": "defineBelow", "value": { "date": "={{ $json.date }}", "tradesCount": "={{ $json.total_trades }}", "winningTrades": "={{ $json.winning_trades }}", "losingTrades": "={{ $json.losing_trades }}", "totalPnL": "={{ $json.total_pnl }}", "totalPnLPercent": "0", "winRate": "={{ $json.win_rate }}", "avgWin": "={{ $json.avg_win }}", "avgLoss": "={{ $json.avg_loss }}", "profitFactor": "={{ $json.profit_factor }}", "maxDrawdown": "0", "sharpeRatio": "0" } } }, "id": "4d5e6f7a-8b9c-0d1e-2f3a-4b5c6d7e8f9a", "name": "Save Daily Stats", "type": "n8n-nodes-base.postgres", "typeVersion": 2.4, "position": [900, 300], "credentials": { "postgres": { "id": "1", "name": "Trading Bot Database" } } }, { "parameters": { "jsCode": "const stats = $('Query Yesterday Stats').first().json;\nconst symbols = $('Query Symbol Breakdown').all();\n\nconst winRate = stats.total_trades > 0 ? (stats.winning_trades / stats.total_trades) * 100 : 0;\nconst avgWin = stats.winning_trades > 0 ? stats.total_pnl / stats.winning_trades : 0;\nconst avgLoss = stats.losing_trades > 0 ? Math.abs(stats.total_pnl / stats.losing_trades) : 0;\nconst profitFactor = avgLoss !== 0 ? avgWin / avgLoss : 0;\n\nconst yesterday = new Date();\nyesterday.setDate(yesterday.getDate() - 1);\nyesterday.setHours(0, 0, 0, 0);\n\nreturn [{\n json: {\n date: yesterday.toISOString(),\n total_trades: parseInt(stats.total_trades) || 0,\n winning_trades: parseInt(stats.winning_trades) || 0,\n losing_trades: parseInt(stats.losing_trades) || 0,\n total_pnl: parseFloat(stats.total_pnl) || 0,\n win_rate: winRate,\n avg_win: avgWin,\n avg_loss: avgLoss,\n profit_factor: profitFactor,\n symbols: symbols.map(s => s.json)\n }\n}];" }, "id": "5e6f7a8b-9c0d-1e2f-3a4b-5c6d7e8f9a0b", "name": "Process Data", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [680, 300] } ], "connections": { "Every Day at Midnight": { "main": [ [ { "node": "Query Yesterday Stats", "type": "main", "index": 0 }, { "node": "Query Symbol Breakdown", "type": "main", "index": 0 } ] ] }, "Query Yesterday Stats": { "main": [ [ { "node": "Process Data", "type": "main", "index": 0 } ] ] }, "Query Symbol Breakdown": { "main": [ [ { "node": "Process Data", "type": "main", "index": 0 } ] ] }, "Process Data": { "main": [ [ { "node": "Save Daily Stats", "type": "main", "index": 0 } ] ] } }, "pinData": {}, "settings": { "executionOrder": "v1" }, "staticData": null, "tags": [], "triggerCount": 0, "updatedAt": "2025-10-27T00:00:00.000Z", "versionId": "1" }