chore: Organize workspace structure - move docs, workflows, scripts to subdirectories
Organization: - Created docs/ with setup/, guides/, history/ subdirectories - Created workflows/ with trading/, analytics/, telegram/, archive/ subdirectories - Created scripts/ with docker/, setup/, testing/ subdirectories - Created tests/ for TypeScript test files - Created archive/ for unused reference files Moved files: - 17 documentation files → docs/ - 16 workflow JSON files → workflows/ - 10 shell scripts → scripts/ - 4 test files → tests/ - 5 unused files → archive/ Updated: - README.md with new file structure and documentation paths Deleted: - data/ (empty directory) - screenshots/ (empty directory) Critical files remain in root: - telegram_command_bot.py (active bot - used by Dockerfile) - watch-restart.sh (systemd service dependency) - All Dockerfiles and docker-compose files - All environment files Validation: Containers running (trading-bot-v4, telegram-trade-bot, postgres) API responding (positions endpoint tested) Telegram bot functional (/status command tested) All critical files present in root No code changes - purely organizational. System continues running without interruption. Recovery: git revert HEAD or git reset --hard cleanup-before
This commit is contained in:
171
workflows/analytics/n8n-daily-report.json
Normal file
171
workflows/analytics/n8n-daily-report.json
Normal file
@@ -0,0 +1,171 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
73
workflows/analytics/n8n-database-analytics.json
Normal file
73
workflows/analytics/n8n-database-analytics.json
Normal file
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"name": "Trading Database Analytics",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "7c2dbef4-8f5f-4c0e-9f3c-4e5c5d8f2a1b",
|
||||
"name": "When clicking 'Test workflow'",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [240, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"operation": "executeQuery",
|
||||
"query": "-- Get all closed trades with performance metrics\nSELECT \n id,\n symbol,\n direction,\n \"entryPrice\",\n \"exitPrice\",\n \"positionSizeUSD\",\n leverage,\n \"realizedPnL\",\n \"realizedPnLPercent\",\n \"holdTimeSeconds\",\n \"exitReason\",\n \"entryTime\",\n \"exitTime\",\n \"isTestTrade\",\n CASE \n WHEN \"realizedPnL\" > 0 THEN 'WIN'\n WHEN \"realizedPnL\" < 0 THEN 'LOSS'\n ELSE 'BREAKEVEN'\n END as trade_result\nFROM \"Trade\"\nWHERE status = 'closed'\n AND \"isTestTrade\" = false\nORDER BY \"exitTime\" DESC\nLIMIT 100;"
|
||||
},
|
||||
"id": "3f9c1d7b-2e4a-4c8f-9b1e-6d8e5c3f2a4b",
|
||||
"name": "Query Closed Trades",
|
||||
"type": "n8n-nodes-base.postgres",
|
||||
"typeVersion": 2.4,
|
||||
"position": [460, 300],
|
||||
"credentials": {
|
||||
"postgres": {
|
||||
"id": "1",
|
||||
"name": "Trading Bot Database"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "// Calculate trading statistics from closed trades\nconst trades = $input.all();\n\nif (trades.length === 0) {\n return [{\n json: {\n message: 'No closed trades found',\n totalTrades: 0\n }\n }];\n}\n\nconst wins = trades.filter(t => t.json.trade_result === 'WIN');\nconst losses = trades.filter(t => t.json.trade_result === 'LOSS');\n\nconst totalPnL = trades.reduce((sum, t) => sum + parseFloat(t.json.realizedPnL || 0), 0);\nconst avgWin = wins.length > 0 ? wins.reduce((sum, t) => sum + parseFloat(t.json.realizedPnL), 0) / wins.length : 0;\nconst avgLoss = losses.length > 0 ? losses.reduce((sum, t) => sum + parseFloat(t.json.realizedPnL), 0) / losses.length : 0;\nconst winRate = (wins.length / trades.length) * 100;\nconst profitFactor = avgLoss !== 0 ? Math.abs(avgWin / avgLoss) : 0;\n\n// Calculate average hold time\nconst avgHoldTime = trades.reduce((sum, t) => sum + parseInt(t.json.holdTimeSeconds || 0), 0) / trades.length;\n\n// Group by symbol\nconst bySymbol = {};\ntrades.forEach(t => {\n const symbol = t.json.symbol;\n if (!bySymbol[symbol]) {\n bySymbol[symbol] = { trades: 0, wins: 0, pnl: 0 };\n }\n bySymbol[symbol].trades++;\n if (t.json.trade_result === 'WIN') bySymbol[symbol].wins++;\n bySymbol[symbol].pnl += parseFloat(t.json.realizedPnL || 0);\n});\n\n// Group by direction\nconst longs = trades.filter(t => t.json.direction === 'long');\nconst shorts = trades.filter(t => t.json.direction === 'short');\n\nconst longWins = longs.filter(t => t.json.trade_result === 'WIN').length;\nconst shortWins = shorts.filter(t => t.json.trade_result === 'WIN').length;\n\n// Group by exit reason\nconst exitReasons = {};\ntrades.forEach(t => {\n const reason = t.json.exitReason || 'unknown';\n if (!exitReasons[reason]) {\n exitReasons[reason] = { count: 0, pnl: 0 };\n }\n exitReasons[reason].count++;\n exitReasons[reason].pnl += parseFloat(t.json.realizedPnL || 0);\n});\n\nreturn [{\n json: {\n summary: {\n totalTrades: trades.length,\n winningTrades: wins.length,\n losingTrades: losses.length,\n winRate: winRate.toFixed(2) + '%',\n totalPnL: '$' + totalPnL.toFixed(2),\n avgWin: '$' + avgWin.toFixed(2),\n avgLoss: '$' + avgLoss.toFixed(2),\n profitFactor: profitFactor.toFixed(2),\n avgHoldTimeMinutes: (avgHoldTime / 60).toFixed(1)\n },\n bySymbol,\n byDirection: {\n long: {\n total: longs.length,\n wins: longWins,\n winRate: longs.length > 0 ? ((longWins / longs.length) * 100).toFixed(2) + '%' : '0%'\n },\n short: {\n total: shorts.length,\n wins: shortWins,\n winRate: shorts.length > 0 ? ((shortWins / shorts.length) * 100).toFixed(2) + '%' : '0%'\n }\n },\n exitReasons,\n timestamp: new Date().toISOString()\n }\n}];"
|
||||
},
|
||||
"id": "8a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d",
|
||||
"name": "Calculate Statistics",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [680, 300]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"When clicking 'Test workflow'": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Query Closed Trades",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Query Closed Trades": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Calculate Statistics",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"pinData": {},
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"staticData": null,
|
||||
"tags": [],
|
||||
"triggerCount": 0,
|
||||
"updatedAt": "2025-10-27T00:00:00.000Z",
|
||||
"versionId": "1"
|
||||
}
|
||||
139
workflows/analytics/n8n-pattern-analysis.json
Normal file
139
workflows/analytics/n8n-pattern-analysis.json
Normal file
@@ -0,0 +1,139 @@
|
||||
{
|
||||
"name": "Pattern Analysis - Win Rate by Hour",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
|
||||
"name": "Manual Trigger",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [240, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"operation": "executeQuery",
|
||||
"query": "-- Win rate analysis by hour of day\nSELECT \n EXTRACT(HOUR FROM \"entryTime\") as hour,\n COUNT(*) as total_trades,\n COUNT(CASE WHEN \"realizedPnL\" > 0 THEN 1 END) as wins,\n COUNT(CASE WHEN \"realizedPnL\" < 0 THEN 1 END) as losses,\n ROUND(COUNT(CASE WHEN \"realizedPnL\" > 0 THEN 1 END)::numeric / NULLIF(COUNT(*), 0) * 100, 2) as win_rate_pct,\n ROUND(SUM(\"realizedPnL\")::numeric, 2) as total_pnl,\n ROUND(AVG(\"realizedPnL\")::numeric, 4) as avg_pnl\nFROM \"Trade\"\nWHERE status = 'closed'\n AND \"isTestTrade\" = false\n AND \"entryTime\" >= NOW() - INTERVAL '30 days'\nGROUP BY EXTRACT(HOUR FROM \"entryTime\")\nORDER BY hour;"
|
||||
},
|
||||
"id": "2b3c4d5e-6f7a-8b9c-0d1e-2f3a4b5c6d7e",
|
||||
"name": "Query Hourly Performance",
|
||||
"type": "n8n-nodes-base.postgres",
|
||||
"typeVersion": 2.4,
|
||||
"position": [460, 300],
|
||||
"credentials": {
|
||||
"postgres": {
|
||||
"id": "1",
|
||||
"name": "Trading Bot Database"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"operation": "executeQuery",
|
||||
"query": "-- Win rate by day of week\nSELECT \n EXTRACT(DOW FROM \"entryTime\") as day_of_week,\n CASE EXTRACT(DOW FROM \"entryTime\")\n WHEN 0 THEN 'Sunday'\n WHEN 1 THEN 'Monday'\n WHEN 2 THEN 'Tuesday'\n WHEN 3 THEN 'Wednesday'\n WHEN 4 THEN 'Thursday'\n WHEN 5 THEN 'Friday'\n WHEN 6 THEN 'Saturday'\n END as day_name,\n COUNT(*) as total_trades,\n COUNT(CASE WHEN \"realizedPnL\" > 0 THEN 1 END) as wins,\n ROUND(COUNT(CASE WHEN \"realizedPnL\" > 0 THEN 1 END)::numeric / NULLIF(COUNT(*), 0) * 100, 2) as win_rate_pct,\n ROUND(SUM(\"realizedPnL\")::numeric, 2) as total_pnl\nFROM \"Trade\"\nWHERE status = 'closed'\n AND \"isTestTrade\" = false\n AND \"entryTime\" >= NOW() - INTERVAL '30 days'\nGROUP BY EXTRACT(DOW FROM \"entryTime\")\nORDER BY day_of_week;"
|
||||
},
|
||||
"id": "3c4d5e6f-7a8b-9c0d-1e2f-3a4b5c6d7e8f",
|
||||
"name": "Query Daily Performance",
|
||||
"type": "n8n-nodes-base.postgres",
|
||||
"typeVersion": 2.4,
|
||||
"position": [460, 500],
|
||||
"credentials": {
|
||||
"postgres": {
|
||||
"id": "1",
|
||||
"name": "Trading Bot Database"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"operation": "executeQuery",
|
||||
"query": "-- Hold time vs profitability\nSELECT \n CASE \n WHEN \"holdTimeSeconds\" < 300 THEN '0-5 min'\n WHEN \"holdTimeSeconds\" < 900 THEN '5-15 min'\n WHEN \"holdTimeSeconds\" < 1800 THEN '15-30 min'\n WHEN \"holdTimeSeconds\" < 3600 THEN '30-60 min'\n WHEN \"holdTimeSeconds\" < 7200 THEN '1-2 hours'\n ELSE '2+ hours'\n END as hold_time_bucket,\n COUNT(*) as trades,\n COUNT(CASE WHEN \"realizedPnL\" > 0 THEN 1 END) as wins,\n ROUND(COUNT(CASE WHEN \"realizedPnL\" > 0 THEN 1 END)::numeric / NULLIF(COUNT(*), 0) * 100, 2) as win_rate_pct,\n ROUND(AVG(\"realizedPnL\")::numeric, 4) as avg_pnl,\n ROUND(SUM(\"realizedPnL\")::numeric, 2) as total_pnl\nFROM \"Trade\"\nWHERE status = 'closed'\n AND \"isTestTrade\" = false\n AND \"holdTimeSeconds\" IS NOT NULL\n AND \"entryTime\" >= NOW() - INTERVAL '30 days'\nGROUP BY \n CASE \n WHEN \"holdTimeSeconds\" < 300 THEN '0-5 min'\n WHEN \"holdTimeSeconds\" < 900 THEN '5-15 min'\n WHEN \"holdTimeSeconds\" < 1800 THEN '15-30 min'\n WHEN \"holdTimeSeconds\" < 3600 THEN '30-60 min'\n WHEN \"holdTimeSeconds\" < 7200 THEN '1-2 hours'\n ELSE '2+ hours'\n END\nORDER BY \n CASE \n WHEN hold_time_bucket = '0-5 min' THEN 1\n WHEN hold_time_bucket = '5-15 min' THEN 2\n WHEN hold_time_bucket = '15-30 min' THEN 3\n WHEN hold_time_bucket = '30-60 min' THEN 4\n WHEN hold_time_bucket = '1-2 hours' THEN 5\n ELSE 6\n END;"
|
||||
},
|
||||
"id": "4d5e6f7a-8b9c-0d1e-2f3a-4b5c6d7e8f9a",
|
||||
"name": "Query Hold Time Analysis",
|
||||
"type": "n8n-nodes-base.postgres",
|
||||
"typeVersion": 2.4,
|
||||
"position": [460, 700],
|
||||
"credentials": {
|
||||
"postgres": {
|
||||
"id": "1",
|
||||
"name": "Trading Bot Database"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const hourly = $('Query Hourly Performance').all().map(item => item.json);\nconst daily = $('Query Daily Performance').all().map(item => item.json);\nconst holdTime = $('Query Hold Time Analysis').all().map(item => item.json);\n\n// Find best and worst hours\nconst sortedHours = [...hourly].sort((a, b) => b.win_rate_pct - a.win_rate_pct);\nconst bestHours = sortedHours.slice(0, 3);\nconst worstHours = sortedHours.slice(-3).reverse();\n\n// Find best day\nconst sortedDays = [...daily].sort((a, b) => b.win_rate_pct - a.win_rate_pct);\nconst bestDay = sortedDays[0];\nconst worstDay = sortedDays[sortedDays.length - 1];\n\n// Find optimal hold time\nconst sortedHoldTime = [...holdTime].sort((a, b) => b.avg_pnl - a.avg_pnl);\nconst optimalHoldTime = sortedHoldTime[0];\n\n// Generate insights\nconst insights = {\n hourly: {\n bestHours: bestHours.map(h => `${h.hour}:00 (${h.win_rate_pct}% win rate, ${h.total_trades} trades)`),\n worstHours: worstHours.map(h => `${h.hour}:00 (${h.win_rate_pct}% win rate, ${h.total_trades} trades)`),\n recommendation: bestHours.length > 0 ? `Focus trading around ${bestHours[0].hour}:00-${bestHours[2].hour}:00` : 'Need more data'\n },\n daily: {\n bestDay: bestDay ? `${bestDay.day_name} (${bestDay.win_rate_pct}% win rate)` : 'N/A',\n worstDay: worstDay ? `${worstDay.day_name} (${worstDay.win_rate_pct}% win rate)` : 'N/A',\n recommendation: bestDay && worstDay ? `Trade more on ${bestDay.day_name}, avoid ${worstDay.day_name}` : 'Need more data'\n },\n holdTime: {\n optimal: optimalHoldTime ? `${optimalHoldTime.hold_time_bucket} (avg P&L: $${optimalHoldTime.avg_pnl})` : 'N/A',\n recommendation: optimalHoldTime ? `Target exits in ${optimalHoldTime.hold_time_bucket} range` : 'Need more data'\n },\n rawData: {\n hourly,\n daily,\n holdTime\n }\n};\n\nreturn [{ json: insights }];"
|
||||
},
|
||||
"id": "5e6f7a8b-9c0d-1e2f-3a4b-5c6d7e8f9a0b",
|
||||
"name": "Generate Insights",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [680, 300]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Manual Trigger": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Query Hourly Performance",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Query Daily Performance",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Query Hold Time Analysis",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Query Hourly Performance": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Generate Insights",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Query Daily Performance": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Generate Insights",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Query Hold Time Analysis": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Generate Insights",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"pinData": {},
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"staticData": null,
|
||||
"tags": [],
|
||||
"triggerCount": 0,
|
||||
"updatedAt": "2025-10-27T00:00:00.000Z",
|
||||
"versionId": "1"
|
||||
}
|
||||
139
workflows/analytics/n8n-stop-loss-analysis.json
Normal file
139
workflows/analytics/n8n-stop-loss-analysis.json
Normal file
@@ -0,0 +1,139 @@
|
||||
{
|
||||
"name": "Stop Loss Analysis - Which Stops Get Hit",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
|
||||
"name": "Manual Trigger",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [240, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"operation": "executeQuery",
|
||||
"query": "-- Exit reason breakdown\nSELECT \n \"exitReason\",\n COUNT(*) as count,\n ROUND(COUNT(*)::numeric / (SELECT COUNT(*) FROM \"Trade\" WHERE status = 'closed' AND \"isTestTrade\" = false) * 100, 2) as percentage,\n ROUND(AVG(\"realizedPnL\")::numeric, 4) as avg_pnl,\n ROUND(SUM(\"realizedPnL\")::numeric, 2) as total_pnl,\n ROUND(AVG(\"holdTimeSeconds\")::numeric / 60, 1) as avg_hold_minutes\nFROM \"Trade\"\nWHERE status = 'closed'\n AND \"isTestTrade\" = false\n AND \"entryTime\" >= NOW() - INTERVAL '30 days'\nGROUP BY \"exitReason\"\nORDER BY count DESC;"
|
||||
},
|
||||
"id": "2b3c4d5e-6f7a-8b9c-0d1e-2f3a4b5c6d7e",
|
||||
"name": "Query Exit Reasons",
|
||||
"type": "n8n-nodes-base.postgres",
|
||||
"typeVersion": 2.4,
|
||||
"position": [460, 300],
|
||||
"credentials": {
|
||||
"postgres": {
|
||||
"id": "1",
|
||||
"name": "Trading Bot Database"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"operation": "executeQuery",
|
||||
"query": "-- Stop loss effectiveness by distance\nSELECT \n CASE \n WHEN ABS((\"stopLossPrice\" - \"entryPrice\") / \"entryPrice\" * 100) < 0.5 THEN 'Very Tight (< 0.5%)'\n WHEN ABS((\"stopLossPrice\" - \"entryPrice\") / \"entryPrice\" * 100) < 1.0 THEN 'Tight (0.5-1%)'\n WHEN ABS((\"stopLossPrice\" - \"entryPrice\") / \"entryPrice\" * 100) < 1.5 THEN 'Normal (1-1.5%)'\n WHEN ABS((\"stopLossPrice\" - \"entryPrice\") / \"entryPrice\" * 100) < 2.0 THEN 'Wide (1.5-2%)'\n ELSE 'Very Wide (> 2%)'\n END as sl_distance,\n COUNT(*) as total_trades,\n COUNT(CASE WHEN \"exitReason\" LIKE '%stop%' THEN 1 END) as stopped_out,\n ROUND(COUNT(CASE WHEN \"exitReason\" LIKE '%stop%' THEN 1 END)::numeric / NULLIF(COUNT(*), 0) * 100, 2) as stop_hit_rate,\n ROUND(AVG(\"realizedPnL\")::numeric, 4) as avg_pnl\nFROM \"Trade\"\nWHERE status = 'closed'\n AND \"isTestTrade\" = false\n AND \"stopLossPrice\" IS NOT NULL\n AND \"entryPrice\" > 0\n AND \"entryTime\" >= NOW() - INTERVAL '30 days'\nGROUP BY \n CASE \n WHEN ABS((\"stopLossPrice\" - \"entryPrice\") / \"entryPrice\" * 100) < 0.5 THEN 'Very Tight (< 0.5%)'\n WHEN ABS((\"stopLossPrice\" - \"entryPrice\") / \"entryPrice\" * 100) < 1.0 THEN 'Tight (0.5-1%)'\n WHEN ABS((\"stopLossPrice\" - \"entryPrice\") / \"entryPrice\" * 100) < 1.5 THEN 'Normal (1-1.5%)'\n WHEN ABS((\"stopLossPrice\" - \"entryPrice\") / \"entryPrice\" * 100) < 2.0 THEN 'Wide (1.5-2%)'\n ELSE 'Very Wide (> 2%)'\n END\nORDER BY \n CASE \n WHEN sl_distance = 'Very Tight (< 0.5%)' THEN 1\n WHEN sl_distance = 'Tight (0.5-1%)' THEN 2\n WHEN sl_distance = 'Normal (1-1.5%)' THEN 3\n WHEN sl_distance = 'Wide (1.5-2%)' THEN 4\n ELSE 5\n END;"
|
||||
},
|
||||
"id": "3c4d5e6f-7a8b-9c0d-1e2f-3a4b5c6d7e8f",
|
||||
"name": "Query Stop Distance Analysis",
|
||||
"type": "n8n-nodes-base.postgres",
|
||||
"typeVersion": 2.4,
|
||||
"position": [460, 500],
|
||||
"credentials": {
|
||||
"postgres": {
|
||||
"id": "1",
|
||||
"name": "Trading Bot Database"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"operation": "executeQuery",
|
||||
"query": "-- Trades that got stopped out vs those that hit targets\nSELECT \n direction,\n symbol,\n COUNT(CASE WHEN \"exitReason\" LIKE '%stop%' THEN 1 END) as stopped_out,\n COUNT(CASE WHEN \"exitReason\" LIKE '%target%' OR \"exitReason\" LIKE '%TP%' THEN 1 END) as hit_targets,\n COUNT(CASE WHEN \"exitReason\" LIKE '%manual%' THEN 1 END) as manual_exits,\n ROUND(AVG(CASE WHEN \"exitReason\" LIKE '%stop%' THEN \"realizedPnL\" END)::numeric, 4) as avg_stop_loss,\n ROUND(AVG(CASE WHEN \"exitReason\" LIKE '%target%' OR \"exitReason\" LIKE '%TP%' THEN \"realizedPnL\" END)::numeric, 4) as avg_target_win\nFROM \"Trade\"\nWHERE status = 'closed'\n AND \"isTestTrade\" = false\n AND \"entryTime\" >= NOW() - INTERVAL '30 days'\nGROUP BY direction, symbol\nORDER BY stopped_out DESC;"
|
||||
},
|
||||
"id": "4d5e6f7a-8b9c-0d1e-2f3a-4b5c6d7e8f9a",
|
||||
"name": "Query Stop vs Target by Symbol",
|
||||
"type": "n8n-nodes-base.postgres",
|
||||
"typeVersion": 2.4,
|
||||
"position": [460, 700],
|
||||
"credentials": {
|
||||
"postgres": {
|
||||
"id": "1",
|
||||
"name": "Trading Bot Database"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const exitReasons = $('Query Exit Reasons').all().map(item => item.json);\nconst stopDistances = $('Query Stop Distance Analysis').all().map(item => item.json);\nconst symbolBreakdown = $('Query Stop vs Target by Symbol').all().map(item => item.json);\n\n// Calculate stop loss hit rate\nconst stopLossExits = exitReasons.filter(r => r.exitReason && r.exitReason.toLowerCase().includes('stop'));\nconst totalStopLosses = stopLossExits.reduce((sum, r) => sum + parseInt(r.count), 0);\nconst totalTrades = exitReasons.reduce((sum, r) => sum + parseInt(r.count), 0);\nconst stopHitRate = totalTrades > 0 ? (totalStopLosses / totalTrades * 100).toFixed(2) : 0;\n\n// Find optimal stop distance\nconst sortedByPnL = [...stopDistances].sort((a, b) => parseFloat(b.avg_pnl) - parseFloat(a.avg_pnl));\nconst optimalDistance = sortedByPnL[0];\nconst worstDistance = sortedByPnL[sortedByPnL.length - 1];\n\n// Calculate profit factor (avg win / avg loss)\nconst avgStopLoss = exitReasons\n .filter(r => r.exitReason && r.exitReason.toLowerCase().includes('stop'))\n .reduce((sum, r) => sum + parseFloat(r.avg_pnl) * parseInt(r.count), 0) / totalStopLosses;\n\nconst targetExits = exitReasons.filter(r => \n r.exitReason && (r.exitReason.toLowerCase().includes('target') || r.exitReason.toLowerCase().includes('tp'))\n);\nconst totalTargets = targetExits.reduce((sum, r) => sum + parseInt(r.count), 0);\nconst avgTarget = targetExits.reduce((sum, r) => sum + parseFloat(r.avg_pnl) * parseInt(r.count), 0) / totalTargets;\n\nconst insights = {\n summary: {\n stopHitRate: `${stopHitRate}%`,\n totalStopLosses,\n avgStopLoss: `$${avgStopLoss.toFixed(4)}`,\n avgTargetWin: `$${avgTarget.toFixed(4)}`,\n profitFactor: avgStopLoss !== 0 ? (Math.abs(avgTarget / avgStopLoss)).toFixed(2) : 'N/A'\n },\n optimalStopDistance: {\n distance: optimalDistance?.sl_distance || 'N/A',\n avgPnL: optimalDistance ? `$${optimalDistance.avg_pnl}` : 'N/A',\n stopHitRate: optimalDistance ? `${optimalDistance.stop_hit_rate}%` : 'N/A',\n recommendation: optimalDistance ? `Use ${optimalDistance.sl_distance} stop losses` : 'Need more data'\n },\n worstStopDistance: {\n distance: worstDistance?.sl_distance || 'N/A',\n avgPnL: worstDistance ? `$${worstDistance.avg_pnl}` : 'N/A',\n stopHitRate: worstDistance ? `${worstDistance.stop_hit_rate}%` : 'N/A'\n },\n recommendations: [\n stopHitRate > 50 ? '⚠️ High stop hit rate - consider wider stops or better entries' : '✅ Stop hit rate is acceptable',\n optimalDistance && worstDistance ? `💡 ${optimalDistance.sl_distance} performs ${((parseFloat(optimalDistance.avg_pnl) - parseFloat(worstDistance.avg_pnl)) / Math.abs(parseFloat(worstDistance.avg_pnl)) * 100).toFixed(1)}% better than ${worstDistance.sl_distance}` : '',\n Math.abs(avgStopLoss) > Math.abs(avgTarget) ? '⚠️ Average losses exceed average wins - adjust risk/reward' : '✅ Risk/reward ratio is positive'\n ].filter(Boolean),\n rawData: {\n exitReasons,\n stopDistances,\n symbolBreakdown\n }\n};\n\nreturn [{ json: insights }];"
|
||||
},
|
||||
"id": "5e6f7a8b-9c0d-1e2f-3a4b-5c6d7e8f9a0b",
|
||||
"name": "Analyze Stop Effectiveness",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [680, 300]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Manual Trigger": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Query Exit Reasons",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Query Stop Distance Analysis",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Query Stop vs Target by Symbol",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Query Exit Reasons": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Analyze Stop Effectiveness",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Query Stop Distance Analysis": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Analyze Stop Effectiveness",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Query Stop vs Target by Symbol": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Analyze Stop Effectiveness",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"pinData": {},
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"staticData": null,
|
||||
"tags": [],
|
||||
"triggerCount": 0,
|
||||
"updatedAt": "2025-10-27T00:00:00.000Z",
|
||||
"versionId": "1"
|
||||
}
|
||||
297
workflows/archive/n8n-trader-workflow-updated.json
Normal file
297
workflows/archive/n8n-trader-workflow-updated.json
Normal file
@@ -0,0 +1,297 @@
|
||||
{
|
||||
"name": "Trader - Trading Bot v4 Integration",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "3371ad7c-0866-4161-90a4-f251de4aceb8",
|
||||
"options": {}
|
||||
},
|
||||
"id": "683db7ad-2df6-44c7-afaa-d2f40705f268",
|
||||
"name": "Webhook",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1,
|
||||
"position": [500, 460],
|
||||
"webhookId": "3371ad7c-0866-4161-90a4-f251de4aceb8"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "signal",
|
||||
"stringValue": "={{ $json.body.split('|')[0].trim() }}"
|
||||
},
|
||||
{
|
||||
"name": "symbol",
|
||||
"stringValue": "={{ $json.body.includes('SOL') ? 'SOL-PERP' : ($json.body.includes('BTC') ? 'BTC-PERP' : ($json.body.includes('ETH') ? 'ETH-PERP' : 'SOL-PERP')) }}"
|
||||
},
|
||||
{
|
||||
"name": "direction",
|
||||
"stringValue": "={{ $json.signal.toLowerCase().includes('buy') || $json.signal.toLowerCase().includes('long') ? 'long' : 'short' }}"
|
||||
},
|
||||
{
|
||||
"name": "timeframe",
|
||||
"stringValue": "5"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "1844fbcb-282b-4b01-9744-b21adda235e9",
|
||||
"name": "Edit Fields",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [700, 460]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"url": "http://trading-bot-v4:3000/api/trading/check-risk",
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "httpHeaderAuth",
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Authorization",
|
||||
"value": "=Bearer {{ $env.API_SECRET_KEY }}"
|
||||
},
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={\n \"symbol\": \"{{ $json.symbol }}\",\n \"direction\": \"{{ $json.direction }}\"\n}",
|
||||
"options": {
|
||||
"timeout": 10000
|
||||
}
|
||||
},
|
||||
"id": "check-risk-node",
|
||||
"name": "Check Risk Limits",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.1,
|
||||
"position": [900, 460]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{ $json.allowed }}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "risk-check-condition",
|
||||
"name": "Risk Check Passed?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 1,
|
||||
"position": [1100, 460]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"url": "http://trading-bot-v4:3000/api/trading/execute",
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "httpHeaderAuth",
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Authorization",
|
||||
"value": "=Bearer {{ $env.API_SECRET_KEY }}"
|
||||
},
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={\n \"symbol\": \"{{ $('Edit Fields').item.json.symbol }}\",\n \"direction\": \"{{ $('Edit Fields').item.json.direction }}\",\n \"timeframe\": \"{{ $('Edit Fields').item.json.timeframe }}\",\n \"signalStrength\": \"strong\"\n}",
|
||||
"options": {
|
||||
"timeout": 30000
|
||||
}
|
||||
},
|
||||
"id": "execute-trade-node",
|
||||
"name": "Execute Trade on Bot",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.1,
|
||||
"position": [1300, 360]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{ $json.success }}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "trade-success-condition",
|
||||
"name": "Trade Successful?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 1,
|
||||
"position": [1500, 360]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "579304651",
|
||||
"text": "=🟢 TRADE EXECUTED SUCCESSFULLY\n\n{{ $json.signal }}\n\n📊 Symbol: {{ $('Edit Fields').item.json.symbol }}\n📈 Direction: {{ $('Edit Fields').item.json.direction.toUpperCase() }}\n💰 Entry: ${{ $json.entryPrice ? $json.entryPrice.toFixed(4) : 'N/A' }}\n💵 Size: ${{ $json.positionSize ? $json.positionSize.toFixed(2) : 'N/A' }}\n⚡ Leverage: {{ $json.leverage || '10' }}x\n\n🎯 Targets:\n SL: ${{ $json.stopLoss ? $json.stopLoss.toFixed(2) : 'N/A' }} ({{ $json.stopLossPercent || '-1.5' }}%)\n TP1: ${{ $json.takeProfit1 ? $json.takeProfit1.toFixed(2) : 'N/A' }} ({{ $json.tp1Percent || '+0.7' }}%)\n TP2: ${{ $json.takeProfit2 ? $json.takeProfit2.toFixed(2) : 'N/A' }} ({{ $json.tp2Percent || '+1.5' }}%)\n\n⏰ {{ new Date().toLocaleTimeString() }}\n\n✅ Position monitored automatically",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"id": "telegram-success",
|
||||
"name": "Telegram - Success",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [1700, 260],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "579304651",
|
||||
"text": "=🔴 TRADE EXECUTION FAILED\n\n{{ $('Edit Fields').item.json.signal }}\n\n📊 Symbol: {{ $('Edit Fields').item.json.symbol }}\n📈 Direction: {{ $('Edit Fields').item.json.direction.toUpperCase() }}\n\n❌ Error: {{ $json.error || $json.message || 'Unknown error' }}\n\n⏰ {{ new Date().toLocaleTimeString() }}\n\n⚠️ Check bot logs for details",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"id": "telegram-error",
|
||||
"name": "Telegram - Error",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [1700, 460],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "579304651",
|
||||
"text": "=⚠️ TRADE BLOCKED - RISK LIMITS\n\n{{ $('Edit Fields').item.json.signal }}\n\n📊 Symbol: {{ $('Edit Fields').item.json.symbol }}\n📈 Direction: {{ $('Edit Fields').item.json.direction.toUpperCase() }}\n\n🛑 Reason: {{ $('Check Risk Limits').item.json.reason || 'Risk limits exceeded' }}\n\n⏰ {{ new Date().toLocaleTimeString() }}\n\n✅ Trade will be allowed when conditions improve",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"id": "telegram-risk-blocked",
|
||||
"name": "Telegram - Risk Blocked",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [1300, 560],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"pinData": {},
|
||||
"connections": {
|
||||
"Webhook": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Edit Fields": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Check Risk Limits",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Check Risk Limits": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Risk Check Passed?",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Risk Check Passed?": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Execute Trade on Bot",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Telegram - Risk Blocked",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Execute Trade on Bot": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Trade Successful?",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Trade Successful?": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram - Success",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Telegram - Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": true,
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "updated-with-trading-bot-v4",
|
||||
"id": "Bg1iplLiwLdVexG1",
|
||||
"meta": {
|
||||
"instanceId": "e766d4f0b5def8ee8cb8561cd9d2b9ba7733e1907990b6987bca40175f82c379"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
100
workflows/archive/n8n-trader-workflow.json
Normal file
100
workflows/archive/n8n-trader-workflow.json
Normal file
@@ -0,0 +1,100 @@
|
||||
{
|
||||
"name": "Trader",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "3371ad7c-0866-4161-90a4-f251de4aceb8",
|
||||
"options": {}
|
||||
},
|
||||
"id": "683db7ad-2df6-44c7-afaa-d2f40705f268",
|
||||
"name": "Webhook",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
500,
|
||||
460
|
||||
],
|
||||
"webhookId": "3371ad7c-0866-4161-90a4-f251de4aceb8"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "579304651",
|
||||
"text": "={{ $json.signal.startsWith(\"Buy\") ? \"🟢 \" + $json.signal : \"🔴 \" + $json.signal }}\n",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"id": "e9caf28b-5731-46ba-bb31-b152fde4bae5",
|
||||
"name": "Telegram",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [
|
||||
1300,
|
||||
460
|
||||
],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "signal",
|
||||
"stringValue": "={{ $json.body.split('|')[0].trim() }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "1844fbcb-282b-4b01-9744-b21adda235e9",
|
||||
"name": "Edit Fields",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
860,
|
||||
460
|
||||
]
|
||||
}
|
||||
],
|
||||
"pinData": {},
|
||||
"connections": {
|
||||
"Webhook": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Edit Fields": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": true,
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "b35ed14e-bd11-4601-a304-6263832f11b4",
|
||||
"id": "Bg1iplLiwLdVexG1",
|
||||
"meta": {
|
||||
"instanceId": "e766d4f0b5def8ee8cb8561cd9d2b9ba7733e1907990b6987bca40175f82c379"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
300
workflows/archive/n8n-workflow-simple.json
Normal file
300
workflows/archive/n8n-workflow-simple.json
Normal file
@@ -0,0 +1,300 @@
|
||||
{
|
||||
"name": "TradingView → Trading Bot v4 (Simplified)",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "tradingview-webhook",
|
||||
"responseMode": "onReceived",
|
||||
"options": {}
|
||||
},
|
||||
"id": "webhook-tradingview",
|
||||
"name": "Webhook - TradingView Alert",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1,
|
||||
"position": [250, 300],
|
||||
"webhookId": "tradingview-webhook"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "// Parse TradingView alert data\nconst body = $input.item.json.body || $input.item.json;\n\n// Extract data from various TradingView formats\nlet symbol = body.symbol || body.ticker || 'SOLUSDT';\nlet action = (body.action || body.signal_type || body.order_action || '').toLowerCase();\nlet timeframe = body.timeframe || body.interval || '5';\nlet price = parseFloat(body.price || body.close || 0);\nlet timestamp = body.timestamp || body.time || new Date().toISOString();\n\n// Normalize symbol (remove exchanges, convert formats)\nsymbol = symbol.replace(/BINANCE:|COINBASE:|FTX:/gi, '');\nsymbol = symbol.replace(/-PERP$/i, '');\nsymbol = symbol.replace(/USDT$/i, 'USD');\nif (symbol === 'SOL') symbol = 'SOLUSDT';\nif (symbol === 'BTC') symbol = 'BTCUSD';\nif (symbol === 'ETH') symbol = 'ETHUSD';\n\n// Normalize action to long/short\nlet direction = 'long';\nif (action.includes('buy') || action.includes('long')) {\n direction = 'long';\n} else if (action.includes('sell') || action.includes('short')) {\n direction = 'short';\n}\n\n// Normalize timeframe (remove 'm' suffix, convert to minutes)\ntimeframe = timeframe.toString().replace(/m$/i, '');\nif (timeframe === '1h') timeframe = '60';\nif (timeframe === '4h') timeframe = '240';\nif (timeframe === '1d') timeframe = '1440';\n\n// Prepare payload for v4 API\nconst apiPayload = {\n symbol: symbol,\n direction: direction,\n timeframe: timeframe,\n signalStrength: body.strength || 'strong',\n signalPrice: price,\n strategy: body.strategy || 'tradingview_alert'\n};\n\nreturn {\n json: {\n rawAlert: body,\n apiPayload: apiPayload,\n parsedData: {\n symbol: symbol,\n direction: direction,\n timeframe: timeframe,\n price: price,\n timestamp: timestamp\n }\n }\n};"
|
||||
},
|
||||
"id": "parse-signal",
|
||||
"name": "Parse TradingView Signal",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [450, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"url": "={{ $env.TRADING_BOT_API_URL }}/api/trading/check-risk",
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "httpHeaderAuth",
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Authorization",
|
||||
"value": "=Bearer {{ $env.API_SECRET_KEY }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sendBody": true,
|
||||
"bodyParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "symbol",
|
||||
"value": "={{ $json.apiPayload.symbol }}"
|
||||
},
|
||||
{
|
||||
"name": "direction",
|
||||
"value": "={{ $json.apiPayload.direction }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {
|
||||
"timeout": 10000
|
||||
}
|
||||
},
|
||||
"id": "check-risk",
|
||||
"name": "Check Risk Limits",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4,
|
||||
"position": [650, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{ $json.allowed }}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "risk-check-condition",
|
||||
"name": "Risk Check Passed?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 1,
|
||||
"position": [850, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"url": "={{ $env.TRADING_BOT_API_URL }}/api/trading/execute",
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "httpHeaderAuth",
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Authorization",
|
||||
"value": "=Bearer {{ $env.API_SECRET_KEY }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={{ JSON.stringify($('Parse TradingView Signal').item.json.apiPayload) }}",
|
||||
"options": {
|
||||
"timeout": 30000
|
||||
}
|
||||
},
|
||||
"id": "execute-trade",
|
||||
"name": "Execute Trade on Drift",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4,
|
||||
"position": [1050, 200]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{ $json.success }}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "trade-success-condition",
|
||||
"name": "Trade Executed Successfully?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 1,
|
||||
"position": [1250, 200]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "// Format success message for Telegram\nconst trade = $input.item.json.trade || {};\nconst parsedData = $('Parse TradingView Signal').item.json.parsedData;\n\nconst message = `🟢 TRADE EXECUTED\n\n📊 Symbol: ${trade.symbol || parsedData.symbol}\n📈 Direction: ${(trade.direction || parsedData.direction).toUpperCase()}\n💰 Entry Price: $${(trade.entryPrice || parsedData.price).toFixed(4)}\n💵 Position Size: $${(trade.positionSize || trade.notionalValue || 500).toFixed(2)}\n⚡ Leverage: ${trade.leverage || 10}x\n\n🎯 Targets:\n Stop Loss: $${(trade.stopLoss || 0).toFixed(2)} (${trade.stopLossPercent || '-1.5'}%)\n TP1: $${(trade.takeProfit1 || 0).toFixed(2)} (${trade.tp1Percent || '+0.7'}%)\n TP2: $${(trade.takeProfit2 || 0).toFixed(2)} (${trade.tp2Percent || '+1.5'}%)\n\n📊 Slippage: ${(trade.slippage || 0).toFixed(3)}%\n⏰ Time: ${new Date().toLocaleString()}\n\n✅ Position is now being monitored automatically.\nAuto-exit at TP/SL levels.`;\n\nreturn { json: { message } };"
|
||||
},
|
||||
"id": "format-success",
|
||||
"name": "Format Success Message",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [1450, 100]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "// Format error message for Telegram\nconst error = $input.item.json.error || 'Unknown error occurred';\nconst parsedData = $('Parse TradingView Signal').item.json.parsedData;\n\nconst message = `🔴 TRADE EXECUTION FAILED\n\n📊 Symbol: ${parsedData.symbol}\n📈 Direction: ${parsedData.direction.toUpperCase()}\n💰 Price: $${parsedData.price.toFixed(4)}\n\n❌ Error: ${error}\n\n⏰ Time: ${new Date().toLocaleString()}\n\n⚠️ Please check bot logs and Drift account status.`;\n\nreturn { json: { message } };"
|
||||
},
|
||||
"id": "format-error",
|
||||
"name": "Format Error Message",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [1450, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "// Format risk blocked message for Telegram\nconst riskCheck = $('Check Risk Limits').item.json;\nconst parsedData = $('Parse TradingView Signal').item.json.parsedData;\n\nconst message = `⚠️ TRADE BLOCKED - RISK LIMITS\n\n📊 Symbol: ${parsedData.symbol}\n📈 Direction: ${parsedData.direction.toUpperCase()}\n💰 Price: $${parsedData.price.toFixed(4)}\n\n🛑 Reason: ${riskCheck.reason || 'Risk limits exceeded'}\n\n📈 Current Stats:\n Trades Today: ${riskCheck.stats?.tradesToday || 0}\n Daily P&L: ${riskCheck.stats?.dailyPnl || 0}%\n Last Trade: ${riskCheck.stats?.lastTradeMinutesAgo || 0} min ago\n\n⏰ Time: ${new Date().toLocaleString()}\n\n✅ Trade will be allowed when risk conditions improve.`;\n\nreturn { json: { message } };"
|
||||
},
|
||||
"id": "format-risk-blocked",
|
||||
"name": "Format Risk Blocked Message",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [1050, 400]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "={{ $env.TELEGRAM_CHAT_ID }}",
|
||||
"text": "={{ $json.message }}",
|
||||
"additionalFields": {
|
||||
"parse_mode": "Markdown"
|
||||
}
|
||||
},
|
||||
"id": "telegram-notification",
|
||||
"name": "Telegram - Send Notification",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1,
|
||||
"position": [1650, 200],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "1",
|
||||
"name": "Telegram Bot"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Webhook - TradingView Alert": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Parse TradingView Signal",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Parse TradingView Signal": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Check Risk Limits",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Check Risk Limits": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Risk Check Passed?",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Risk Check Passed?": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Execute Trade on Drift",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Format Risk Blocked Message",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Execute Trade on Drift": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Trade Executed Successfully?",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Trade Executed Successfully?": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Format Success Message",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Format Error Message",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Format Success Message": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram - Send Notification",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Format Error Message": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram - Send Notification",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Format Risk Blocked Message": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram - Send Notification",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"staticData": null,
|
||||
"tags": [],
|
||||
"triggerCount": 1,
|
||||
"updatedAt": "2025-10-23T00:00:00.000Z",
|
||||
"versionId": "1"
|
||||
}
|
||||
161
workflows/archive/telegram-listener-simple.json
Normal file
161
workflows/archive/telegram-listener-simple.json
Normal file
@@ -0,0 +1,161 @@
|
||||
{
|
||||
"name": "ADD THIS TO MONEY MACHINE - Manual Trade Listener",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"rule": {
|
||||
"interval": [
|
||||
{
|
||||
"triggerAtMinute": 10
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "schedule-check-telegram",
|
||||
"name": "Check Every 10 Seconds",
|
||||
"type": "n8n-nodes-base.scheduleTrigger",
|
||||
"typeVersion": 1.1,
|
||||
"position": [
|
||||
-1040,
|
||||
280
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"resource": "message",
|
||||
"operation": "getMany",
|
||||
"chatId": "579304651",
|
||||
"returnAll": false,
|
||||
"limit": 5
|
||||
},
|
||||
"id": "get-recent-messages",
|
||||
"name": "Get Recent Messages",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [
|
||||
-860,
|
||||
280
|
||||
],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"string": [
|
||||
{
|
||||
"value1": "={{ $json.text }}",
|
||||
"operation": "regex",
|
||||
"value2": "^(buy|sell|long|short)\\s+(SOL|BTC|ETH)"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "filter-commands",
|
||||
"name": "Is Trade Command?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
-680,
|
||||
280
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "symbol",
|
||||
"stringValue": "={{ $json.text.match(/\\b(SOL|BTC|ETH)\\b/i)[0].toUpperCase() }}-PERP"
|
||||
},
|
||||
{
|
||||
"name": "direction",
|
||||
"stringValue": "={{ $json.text.match(/^(sell|short)\\b/i) ? 'short' : 'long' }}"
|
||||
},
|
||||
{
|
||||
"name": "timeframe",
|
||||
"stringValue": "5"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "parse-trade",
|
||||
"name": "Parse Trade",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
-500,
|
||||
280
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mode": "raw",
|
||||
"jsonOutput": "={{ $json }}"
|
||||
},
|
||||
"id": "output-to-check-risk",
|
||||
"name": "➡️ Merge with Check Risk",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.3,
|
||||
"position": [
|
||||
-320,
|
||||
280
|
||||
],
|
||||
"notes": "Connect this to the SAME point where your TradingView webhook connects (before Check Risk node)"
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Check Every 10 Seconds": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Get Recent Messages",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Get Recent Messages": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Is Trade Command?",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Is Trade Command?": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Parse Trade",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Parse Trade": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "➡️ Merge with Check Risk",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
}
|
||||
}
|
||||
219
workflows/archive/telegram-n8n-listener.json
Normal file
219
workflows/archive/telegram-n8n-listener.json
Normal file
@@ -0,0 +1,219 @@
|
||||
{
|
||||
"name": "Telegram Manual Trade - ADD TO MONEY MACHINE",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "telegram-trade",
|
||||
"responseMode": "responseNode",
|
||||
"options": {}
|
||||
},
|
||||
"id": "webhook",
|
||||
"name": "Webhook",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1.1,
|
||||
"position": [200, 300],
|
||||
"webhookId": "telegram-trade-webhook"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"string": [
|
||||
{
|
||||
"value1": "={{ $json.body.message || $json.body.text || '' }}",
|
||||
"operation": "regex",
|
||||
"value2": "^(buy|sell|long|short)\\s+(sol|btc|eth)"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "filter-trades",
|
||||
"name": "Is Trade Command?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 1,
|
||||
"position": [400, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"values": {
|
||||
"string": [
|
||||
{
|
||||
"name": "symbol",
|
||||
"value": "={{ ($json.body.message || $json.body.text).match(/\\b(SOL|BTC|ETH)\\b/i)[0].toUpperCase() }}-PERP"
|
||||
},
|
||||
{
|
||||
"name": "direction",
|
||||
"value": "={{ ($json.body.message || $json.body.text).match(/^(sell|short)\\b/i) ? 'short' : 'long' }}"
|
||||
},
|
||||
{
|
||||
"name": "timeframe",
|
||||
"value": "5"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "parse-command",
|
||||
"name": "Parse Trade",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 1,
|
||||
"position": [600, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "={{ { status: 'received', symbol: $json.symbol, direction: $json.direction } }}"
|
||||
},
|
||||
"id": "webhook-response",
|
||||
"name": "Webhook Response",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1,
|
||||
"position": [600, 450]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "579304651",
|
||||
"text": "🤖 Manual Trade\n\n📊 {{ $json.symbol }}\n{{ $json.direction === 'long' ? '📈' : '📉' }} {{ $json.direction.toUpperCase() }}\n⏰ {{ $now.format('HH:mm:ss') }}\n\n✅ Executing...",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"id": "confirm",
|
||||
"name": "Send Confirmation",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [800, 300],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "output",
|
||||
"name": "➡️ Connect to Check Risk",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"typeVersion": 1,
|
||||
"position": [1000, 300],
|
||||
"notes": "Connect this to your Money Machine's Check Risk node"
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Webhook": {
|
||||
"main": [[
|
||||
{"node": "Is Trade Command?", "type": "main", "index": 0}
|
||||
]]
|
||||
},
|
||||
"Is Trade Command?": {
|
||||
"main": [[
|
||||
{"node": "Parse Trade", "type": "main", "index": 0}
|
||||
]]
|
||||
},
|
||||
"Parse Trade": {
|
||||
"main": [[
|
||||
{"node": "Webhook Response", "type": "main", "index": 0},
|
||||
{"node": "Send Confirmation", "type": "main", "index": 0}
|
||||
]]
|
||||
},
|
||||
"Send Confirmation": {
|
||||
"main": [[
|
||||
{"node": "➡️ Connect to Check Risk", "type": "main", "index": 0}
|
||||
]]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {},
|
||||
"versionId": "telegram-webhook-v2"
|
||||
}
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"string": [
|
||||
{
|
||||
"value1": "={{ $json.message.text }}",
|
||||
"operation": "regex",
|
||||
"value2": "^(buy|sell|long|short)\\s+(sol|btc|eth)$"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "filter-trades",
|
||||
"name": "Is Trade Command?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 1,
|
||||
"position": [400, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"values": {
|
||||
"string": [
|
||||
{
|
||||
"name": "symbol",
|
||||
"value": "={{ $json.message.text.match(/\\b(SOL|BTC|ETH)\\b/i)[0].toUpperCase() }}-PERP"
|
||||
},
|
||||
{
|
||||
"name": "direction",
|
||||
"value": "={{ $json.message.text.match(/^(sell|short)\\b/i) ? 'short' : 'long' }}"
|
||||
},
|
||||
{
|
||||
"name": "timeframe",
|
||||
"value": "5"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "parse-command",
|
||||
"name": "Parse Trade",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 1,
|
||||
"position": [600, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "579304651",
|
||||
"text": "🤖 Manual Trade\n\n📊 {{ $json.symbol }}\n{{ $json.direction === 'long' ? '📈' : '📉' }} {{ $json.direction.toUpperCase() }}\n⏰ {{ $now.format('HH:mm:ss') }}\n\n✅ Executing...",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"id": "confirm",
|
||||
"name": "Send Confirmation",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [800, 300],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "output",
|
||||
"name": "➡️ Connect to Check Risk",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"typeVersion": 1,
|
||||
"position": [1000, 300],
|
||||
"notes": "Connect this to your Money Machine's Check Risk node"
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Telegram Messages": {
|
||||
"main": [[{"node": "Is Trade Command?", "type": "main", "index": 0}]]
|
||||
},
|
||||
"Is Trade Command?": {
|
||||
"main": [[{"node": "Parse Trade", "type": "main", "index": 0}]]
|
||||
},
|
||||
"Parse Trade": {
|
||||
"main": [[{"node": "Send Confirmation", "type": "main", "index": 0}]]
|
||||
},
|
||||
"Send Confirmation": {
|
||||
"main": [[{"node": "➡️ Connect to Check Risk", "type": "main", "index": 0}]]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {},
|
||||
"versionId": "telegram-n8n-listener-v1"
|
||||
}
|
||||
178
workflows/archive/telegram-polling-addon.json
Normal file
178
workflows/archive/telegram-polling-addon.json
Normal file
@@ -0,0 +1,178 @@
|
||||
{
|
||||
"name": "Telegram Manual Trade (Polling) - Import to Money Machine",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"resource": "message",
|
||||
"operation": "get",
|
||||
"chatId": "579304651",
|
||||
"returnAll": false,
|
||||
"limit": 1,
|
||||
"options": {}
|
||||
},
|
||||
"id": "telegram-poll-messages",
|
||||
"name": "Poll Telegram Messages",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [
|
||||
-1020,
|
||||
460
|
||||
],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"string": [
|
||||
{
|
||||
"value1": "={{ $json.text }}",
|
||||
"operation": "regex",
|
||||
"value2": "\\b(buy|sell|long|short)\\b"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "filter-trade-commands",
|
||||
"name": "Filter Trade Commands",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
-840,
|
||||
460
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "rawMessage",
|
||||
"stringValue": "={{ $json.text }}"
|
||||
},
|
||||
{
|
||||
"name": "symbol",
|
||||
"stringValue": "={{ $json.text.match(/\\b(SOL|BTC|ETH)\\b/i) ? $json.text.match(/\\b(SOL|BTC|ETH)\\b/i)[0].toUpperCase() + '-PERP' : 'SOL-PERP' }}"
|
||||
},
|
||||
{
|
||||
"name": "direction",
|
||||
"stringValue": "={{ $json.text.match(/\\b(sell|short)\\b/i) ? 'short' : 'long' }}"
|
||||
},
|
||||
{
|
||||
"name": "timeframe",
|
||||
"stringValue": "5"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "parse-command",
|
||||
"name": "Parse Trade Command",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
-660,
|
||||
460
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "579304651",
|
||||
"text": "🤖 Manual trade:\n\n📊 {{ $json.symbol }}\n{{ $json.direction === 'long' ? '📈' : '📉' }} {{ $json.direction.toUpperCase() }}\n⏰ {{ $now.toFormat('HH:mm:ss') }}\n\n⏳ Processing...",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"id": "send-ack",
|
||||
"name": "Send Acknowledgment",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [
|
||||
-480,
|
||||
460
|
||||
],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mode": "raw",
|
||||
"jsonOutput": "={{ $json }}",
|
||||
"options": {}
|
||||
},
|
||||
"id": "output-node",
|
||||
"name": "➡️ Connect to Check Risk",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.3,
|
||||
"position": [
|
||||
-300,
|
||||
460
|
||||
],
|
||||
"notes": "Connect this node's output to Money Machine's Check Risk node"
|
||||
}
|
||||
],
|
||||
"pinData": {},
|
||||
"connections": {
|
||||
"Poll Telegram Messages": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Filter Trade Commands",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Filter Trade Commands": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Parse Trade Command",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Parse Trade Command": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Send Acknowledgment",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Send Acknowledgment": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "➡️ Connect to Check Risk",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "telegram-polling-v1",
|
||||
"meta": {
|
||||
"instanceId": "e766d4f0b5def8ee8cb8561cd9d2b9ba7733e1907990b6987bca40175f82c379"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
138
workflows/archive/telegram-trigger-addon.json
Normal file
138
workflows/archive/telegram-trigger-addon.json
Normal file
@@ -0,0 +1,138 @@
|
||||
{
|
||||
"name": "Telegram Trade Trigger (Import to Money Machine)",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "manual-telegram-trade",
|
||||
"options": {}
|
||||
},
|
||||
"id": "webhook-telegram-manual",
|
||||
"name": "Telegram Command Webhook",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
-840,
|
||||
460
|
||||
],
|
||||
"webhookId": "manual-telegram-trade-webhook"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "rawMessage",
|
||||
"stringValue": "={{ $json.body.message || $json.body.text || $json.body }}"
|
||||
},
|
||||
{
|
||||
"name": "symbol",
|
||||
"stringValue": "={{ ($json.body.message || $json.body.text || $json.body).toString().match(/\\b(SOL|BTC|ETH)\\b/i) ? ($json.body.message || $json.body.text || $json.body).toString().match(/\\b(SOL|BTC|ETH)\\b/i)[0].toUpperCase() + '-PERP' : 'SOL-PERP' }}"
|
||||
},
|
||||
{
|
||||
"name": "direction",
|
||||
"stringValue": "={{ ($json.body.message || $json.body.text || $json.body).toString().match(/\\b(sell|short)\\b/i) ? 'short' : 'long' }}"
|
||||
},
|
||||
{
|
||||
"name": "timeframe",
|
||||
"stringValue": "5"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "parse-telegram-manual",
|
||||
"name": "Parse Manual Command",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
-660,
|
||||
460
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "579304651",
|
||||
"text": "🤖 Manual trade command:\n\n📊 {{ $json.symbol }}\n📈 {{ $json.direction.toUpperCase() }}\n⏰ {{ $now.toFormat('HH:mm') }}\n\n⏳ Processing...",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"id": "ack-manual-command",
|
||||
"name": "Send Acknowledgment",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [
|
||||
-480,
|
||||
460
|
||||
],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mode": "raw",
|
||||
"jsonOutput": "={{ $json }}",
|
||||
"options": {}
|
||||
},
|
||||
"id": "ready-for-check-risk",
|
||||
"name": "➡️ Connect to Check Risk",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.3,
|
||||
"position": [
|
||||
-300,
|
||||
460
|
||||
],
|
||||
"notes": "Connect this output to the 'Check Risk' node in Money Machine"
|
||||
}
|
||||
],
|
||||
"pinData": {},
|
||||
"connections": {
|
||||
"Telegram Command Webhook": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Parse Manual Command",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Parse Manual Command": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Send Acknowledgment",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Send Acknowledgment": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "➡️ Connect to Check Risk",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "telegram-webhook-v1",
|
||||
"meta": {
|
||||
"instanceId": "e766d4f0b5def8ee8cb8561cd9d2b9ba7733e1907990b6987bca40175f82c379"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
155
workflows/telegram/telegram-manual-trade-FINAL.json
Normal file
155
workflows/telegram/telegram-manual-trade-FINAL.json
Normal file
@@ -0,0 +1,155 @@
|
||||
{
|
||||
"name": "Manual Trade Command - ADD TO MONEY MACHINE",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "manual-trade",
|
||||
"responseMode": "responseNode",
|
||||
"options": {}
|
||||
},
|
||||
"id": "webhook-manual-trade",
|
||||
"name": "Manual Trade Webhook",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1.1,
|
||||
"position": [
|
||||
-840,
|
||||
280
|
||||
],
|
||||
"webhookId": "manual-trade-webhook"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "command",
|
||||
"stringValue": "={{ $json.body.text || $json.body.message || $json.body }}"
|
||||
},
|
||||
{
|
||||
"name": "symbol",
|
||||
"stringValue": "={{ ($json.body.text || $json.body.message || $json.body).toString().match(/\\b(SOL|BTC|ETH)\\b/i) ? ($json.body.text || $json.body.message || $json.body).toString().match(/\\b(SOL|BTC|ETH)\\b/i)[0].toUpperCase() + '-PERP' : 'SOL-PERP' }}"
|
||||
},
|
||||
{
|
||||
"name": "direction",
|
||||
"stringValue": "={{ ($json.body.text || $json.body.message || $json.body).toString().match(/\\b(sell|short)\\b/i) ? 'short' : 'long' }}"
|
||||
},
|
||||
{
|
||||
"name": "timeframe",
|
||||
"stringValue": "5"
|
||||
},
|
||||
{
|
||||
"name": "source",
|
||||
"stringValue": "manual"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "parse-manual-command",
|
||||
"name": "Parse Command",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
-660,
|
||||
280
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "579304651",
|
||||
"text": "🤖 Manual Trade Command\n\n📊 {{ $json.symbol }}\n{{ $json.direction === 'long' ? '📈' : '📉' }} {{ $json.direction.toUpperCase() }}\n⏰ {{ $now.toFormat('HH:mm:ss') }}\n\n✅ Sending to bot...",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"id": "telegram-confirm",
|
||||
"name": "Send Telegram Confirmation",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [
|
||||
-480,
|
||||
280
|
||||
],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "={{ { \"status\": \"received\", \"symbol\": $json.symbol, \"direction\": $json.direction } }}"
|
||||
},
|
||||
"id": "webhook-response",
|
||||
"name": "Webhook Response",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
-480,
|
||||
380
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mode": "raw",
|
||||
"jsonOutput": "={{ { \"symbol\": $json.symbol, \"direction\": $json.direction, \"timeframe\": $json.timeframe } }}"
|
||||
},
|
||||
"id": "output-to-check-risk",
|
||||
"name": "➡️ Connect to Check Risk Node",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.3,
|
||||
"position": [
|
||||
-300,
|
||||
280
|
||||
],
|
||||
"notes": "Connect this node to your Money Machine's Check Risk node (same place as TradingView webhook)"
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Manual Trade Webhook": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Parse Command",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Parse Command": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Send Telegram Confirmation",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Webhook Response",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Send Telegram Confirmation": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "➡️ Connect to Check Risk Node",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
}
|
||||
}
|
||||
128
workflows/telegram/telegram-webhook-FINAL.json
Normal file
128
workflows/telegram/telegram-webhook-FINAL.json
Normal file
@@ -0,0 +1,128 @@
|
||||
{
|
||||
"name": "Telegram Manual Trade - ADD TO MONEY MACHINE",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "telegram-trade",
|
||||
"responseMode": "responseNode",
|
||||
"options": {}
|
||||
},
|
||||
"id": "webhook",
|
||||
"name": "Webhook Receiver",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1.1,
|
||||
"position": [200, 300],
|
||||
"webhookId": "telegram-trade-webhook"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"string": [
|
||||
{
|
||||
"value1": "={{ $json.body.message || $json.body.text || '' }}",
|
||||
"operation": "regex",
|
||||
"value2": "(buy|sell|long|short).*(sol|btc|eth)"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "filter-trades",
|
||||
"name": "Is Trade Command?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 1,
|
||||
"position": [400, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"values": {
|
||||
"string": [
|
||||
{
|
||||
"name": "symbol",
|
||||
"value": "={{ ($json.body.message || $json.body.text).toString().match(/\\b(SOL|BTC|ETH)\\b/i)[0].toUpperCase() }}-PERP"
|
||||
},
|
||||
{
|
||||
"name": "direction",
|
||||
"value": "={{ ($json.body.message || $json.body.text).toString().match(/\\b(sell|short)\\b/i) ? 'short' : 'long' }}"
|
||||
},
|
||||
{
|
||||
"name": "timeframe",
|
||||
"value": "5"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "parse-command",
|
||||
"name": "Parse Trade",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 1,
|
||||
"position": [600, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "={{ { \"status\": \"received\", \"symbol\": $json.symbol, \"direction\": $json.direction } }}"
|
||||
},
|
||||
"id": "webhook-response",
|
||||
"name": "Webhook Response",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1,
|
||||
"position": [800, 450]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "579304651",
|
||||
"text": "🤖 Manual Trade\\n\\n📊 {{ $json.symbol }}\\n{{ $json.direction === 'long' ? '📈' : '📉' }} {{ $json.direction.toUpperCase() }}\\n⏰ {{ $now.format('HH:mm:ss') }}\\n\\n✅ Executing...",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"id": "confirm",
|
||||
"name": "Send Telegram Confirm",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [800, 300],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "output",
|
||||
"name": "➡️ Connect to Check Risk",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"typeVersion": 1,
|
||||
"position": [1000, 300],
|
||||
"notes": "Connect this output to your Money Machine's Check Risk node"
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Webhook Receiver": {
|
||||
"main": [[
|
||||
{"node": "Is Trade Command?", "type": "main", "index": 0}
|
||||
]]
|
||||
},
|
||||
"Is Trade Command?": {
|
||||
"main": [[
|
||||
{"node": "Parse Trade", "type": "main", "index": 0}
|
||||
]]
|
||||
},
|
||||
"Parse Trade": {
|
||||
"main": [[
|
||||
{"node": "Webhook Response", "type": "main", "index": 0},
|
||||
{"node": "Send Telegram Confirm", "type": "main", "index": 0}
|
||||
]]
|
||||
},
|
||||
"Send Telegram Confirm": {
|
||||
"main": [[
|
||||
{"node": "➡️ Connect to Check Risk", "type": "main", "index": 0}
|
||||
]]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {},
|
||||
"versionId": "telegram-webhook-final"
|
||||
}
|
||||
486
workflows/trading/Money_Machine.json
Normal file
486
workflows/trading/Money_Machine.json
Normal file
@@ -0,0 +1,486 @@
|
||||
{
|
||||
"name": "Money Machine",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "3371ad7c-0866-4161-90a4-f251de4aceb8",
|
||||
"options": {}
|
||||
},
|
||||
"id": "35b54214-9761-49dc-97b6-df39543f0a7b",
|
||||
"name": "Webhook",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
-840,
|
||||
660
|
||||
],
|
||||
"webhookId": "3371ad7c-0866-4161-90a4-f251de4aceb8"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "rawMessage",
|
||||
"stringValue": "={{ $json.body }}"
|
||||
},
|
||||
{
|
||||
"name": "symbol",
|
||||
"stringValue": "={{ ($json.body || '').toString().match(/\\bSOL\\b/i) ? 'SOL-PERP' : (($json.body || '').toString().match(/\\bBTC\\b/i) ? 'BTC-PERP' : (($json.body || '').toString().match(/\\bETH\\b/i) ? 'ETH-PERP' : 'SOL-PERP')) }}"
|
||||
},
|
||||
{
|
||||
"name": "direction",
|
||||
"stringValue": "={{ ($json.body || '').toString().match(/\\b(sell|short)\\b/i) ? 'short' : 'long' }}"
|
||||
},
|
||||
{
|
||||
"name": "timeframe",
|
||||
"stringValue": "5"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "99336995-2326-4575-9970-26afcf957132",
|
||||
"name": "Parse Signal",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
-660,
|
||||
660
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "http://10.0.0.48:3001/api/trading/check-risk",
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "httpHeaderAuth",
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Authorization",
|
||||
"value": "Bearer 2a344f0149442c857fb56c038c0c7d1b113883b830bec792c76f1e0efa15d6bb"
|
||||
},
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={\n \"symbol\": \"{{ $json.symbol }}\",\n \"direction\": \"{{ $json.direction }}\"\n}",
|
||||
"options": {}
|
||||
},
|
||||
"id": "d42e7897-eadd-4202-8565-ac60759b46e1",
|
||||
"name": "Check Risk",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4,
|
||||
"position": [
|
||||
-340,
|
||||
660
|
||||
],
|
||||
"credentials": {
|
||||
"httpHeaderAuth": {
|
||||
"id": "MATuNdkZclq5ISbr",
|
||||
"name": "Header Auth account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{ $json.allowed }}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "a60bfecb-d2f4-4165-a609-e6ed437aa2aa",
|
||||
"name": "Risk Passed?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
-140,
|
||||
660
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "http://10.0.0.48:3001/api/trading/execute",
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "httpHeaderAuth",
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Authorization",
|
||||
"value": "Bearer 2a344f0149442c857fb56c038c0c7d1b113883b830bec792c76f1e0efa15d6bb"
|
||||
},
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={\n \"symbol\": \"{{ $('Parse Signal').item.json.symbol }}\",\n \"direction\": \"{{ $('Parse Signal').item.json.direction }}\",\n \"timeframe\": \"{{ $('Parse Signal').item.json.timeframe }}\",\n \"signalStrength\": \"strong\"\n}",
|
||||
"options": {
|
||||
"timeout": 120000
|
||||
}
|
||||
},
|
||||
"id": "95c46846-4b6a-4f9e-ad93-be223b73a618",
|
||||
"name": "Execute Trade",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4,
|
||||
"position": [
|
||||
60,
|
||||
560
|
||||
],
|
||||
"credentials": {
|
||||
"httpHeaderAuth": {
|
||||
"id": "MATuNdkZclq5ISbr",
|
||||
"name": "Header Auth account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{ $json.success }}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "18342642-e76f-484f-b532-d29846536a9c",
|
||||
"name": "Trade Success?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
260,
|
||||
560
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "message",
|
||||
"stringValue": "={{ `🟢 TRADE OPENED\n\n📊 Symbol: ${$('Parse Signal').item.json.symbol}\n${$('Parse Signal').item.json.direction === 'long' ? '📈' : '📉'} Direction: ${$('Parse Signal').item.json.direction.toUpperCase()}\n\n💵 Position: $${$('Execute Trade').item.json.positionSize}\n⚡ Leverage: ${$('Execute Trade').item.json.leverage}x\n\n💰 Entry: $${$('Execute Trade').item.json.entryPrice.toFixed(4)}\n🎯 TP1: $${$('Execute Trade').item.json.takeProfit1.toFixed(4)} (${$('Execute Trade').item.json.tp1Percent}%)\n🎯 TP2: $${$('Execute Trade').item.json.takeProfit2.toFixed(4)} (${$('Execute Trade').item.json.tp2Percent}%)\n🛑 SL: $${$('Execute Trade').item.json.stopLoss.toFixed(4)} (${$('Execute Trade').item.json.stopLossPercent}%)\n\n⏰ ${$now.toFormat('HH:mm:ss')}\n✅ Position monitored` }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "9da40e3d-b855-4c65-a032-c6fcf88245d4",
|
||||
"name": "Format Success",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
460,
|
||||
460
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "message",
|
||||
"stringValue": "🔴 TRADE FAILED\\n\\n{{ $('Parse Signal').item.json.rawMessage }}\\n\\n❌ Error: {{ $json.error || $json.message }}\\n⏰ {{ $now.toFormat('HH:mm') }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "500751c7-21bb-4351-8a6a-d43a1bfb9eaa",
|
||||
"name": "Format Error",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
460,
|
||||
660
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "message",
|
||||
"stringValue": "⚠️ TRADE BLOCKED\\n\\n{{ $('Parse Signal').item.json.rawMessage }}\\n\\n🛑 Risk limits exceeded\\n⏰ {{ $now.toFormat('HH:mm') }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "dec6cbc4-7550-40d3-9195-c4cc4f787b9b",
|
||||
"name": "Format Risk",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
60,
|
||||
760
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "579304651",
|
||||
"text": "={{ $json.message }}",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"id": "6267b604-d39b-4cb7-98a5-2342cdced33b",
|
||||
"name": "Telegram Success",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [
|
||||
660,
|
||||
460
|
||||
],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "579304651",
|
||||
"text": "{{ `🟢 TRADE OPENED\\n\\n📊 Symbol: ${$('Parse Signal').item.json.symbol}\\n${$('Parse Signal').item.json.direction === 'long' ? '📈' : '📉'} Direction: ${$('Parse Signal').item.json.direction.toUpperCase()}\\n\\n💰 Entry: $${$json.entryPrice.toFixed(4)}\\n🎯 TP1: $${$json.takeProfit1.toFixed(4)} (${$json.tp1Percent}%)\\n🎯 TP2: $${$json.takeProfit2.toFixed(4)} (${$json.tp2Percent}%)\\n🛑 SL: $${$json.stopLoss.toFixed(4)} (${$json.stopLossPercent}%)\\n\\n⏰ ${$now.toFormat('HH:mm:ss')}\\n✅ Position monitored` }}",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"id": "88224fac-ef7a-41ec-b68a-e4bc1a5e3f31",
|
||||
"name": "Telegram Error",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [
|
||||
660,
|
||||
660
|
||||
],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "579304651",
|
||||
"text": "={{ $json.message }}",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"id": "4eccaca4-a5e7-407f-aab9-663a98a8323b",
|
||||
"name": "Telegram Risk",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [
|
||||
260,
|
||||
760
|
||||
],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "579304651",
|
||||
"text": "={{ $json.signal.startsWith(\"Buy\") ? \"🟢 \" + $json.signal : \"🔴 \" + $json.signal }}\n",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"id": "5a8eda4d-8945-4144-8672-022c9ee68bf6",
|
||||
"name": "Telegram",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [
|
||||
-340,
|
||||
840
|
||||
],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "signal",
|
||||
"stringValue": "={{ $json.body.split('|')[0].trim() }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "cce16424-fbb1-4191-b719-79ccfd59ec12",
|
||||
"name": "Edit Fields",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
-660,
|
||||
840
|
||||
]
|
||||
}
|
||||
],
|
||||
"pinData": {},
|
||||
"connections": {
|
||||
"Webhook": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Parse Signal",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Parse Signal": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Check Risk",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Telegram",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Check Risk": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Risk Passed?",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Risk Passed?": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Execute Trade",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Format Risk",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Execute Trade": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Trade Success?",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Trade Success?": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Format Success",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Format Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Format Success": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram Success",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Format Error": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Format Risk": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram Risk",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Edit Fields": {
|
||||
"main": [
|
||||
[]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "2cc10693-953a-4b97-8c86-750b3063096b",
|
||||
"id": "xTCaxlyI02bQLxun",
|
||||
"meta": {
|
||||
"instanceId": "e766d4f0b5def8ee8cb8561cd9d2b9ba7733e1907990b6987bca40175f82c379"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
380
workflows/trading/n8n-complete-workflow.json
Normal file
380
workflows/trading/n8n-complete-workflow.json
Normal file
@@ -0,0 +1,380 @@
|
||||
{
|
||||
"name": "TradingView → Trading Bot v4",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "tradingview-bot-v4",
|
||||
"options": {}
|
||||
},
|
||||
"id": "webhook-node",
|
||||
"name": "Webhook",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1,
|
||||
"position": [240, 400],
|
||||
"webhookId": "tradingview-bot-v4"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "rawMessage",
|
||||
"stringValue": "={{ $json.body }}"
|
||||
},
|
||||
{
|
||||
"name": "symbol",
|
||||
"stringValue": "={{ $json.body.match(/\\bSOL\\b/i) ? 'SOL-PERP' : ($json.body.match(/\\bBTC\\b/i) ? 'BTC-PERP' : ($json.body.match(/\\bETH\\b/i) ? 'ETH-PERP' : 'SOL-PERP')) }}"
|
||||
},
|
||||
{
|
||||
"name": "direction",
|
||||
"stringValue": "={{ $json.body.match(/\\b(sell|short)\\b/i) ? 'short' : 'long' }}"
|
||||
},
|
||||
{
|
||||
"name": "timeframe",
|
||||
"stringValue": "5"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "parse-fields",
|
||||
"name": "Parse Signal",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [440, 400]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "http://10.0.0.48:3001/api/trading/check-risk",
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "httpHeaderAuth",
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Authorization",
|
||||
"value": "Bearer 2a344f0149442c857fb56c038c0c7d1b113883b830bec792c76f1e0efa15d6bb"
|
||||
},
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={\n \"symbol\": \"{{ $json.symbol }}\",\n \"direction\": \"{{ $json.direction }}\"\n}",
|
||||
"options": {}
|
||||
},
|
||||
"id": "check-risk",
|
||||
"name": "Check Risk",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4,
|
||||
"position": [640, 400]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{ $json.allowed }}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "risk-if",
|
||||
"name": "Risk Passed?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 1,
|
||||
"position": [840, 400]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "http://10.0.0.48:3001/api/trading/execute",
|
||||
"authentication": "genericCredentialType",
|
||||
"genericAuthType": "httpHeaderAuth",
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Authorization",
|
||||
"value": "Bearer 2a344f0149442c857fb56c038c0c7d1b113883b830bec792c76f1e0efa15d6bb"
|
||||
},
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={\n \"symbol\": \"{{ $('Parse Signal').item.json.symbol }}\",\n \"direction\": \"{{ $('Parse Signal').item.json.direction }}\",\n \"timeframe\": \"{{ $('Parse Signal').item.json.timeframe }}\",\n \"signalStrength\": \"strong\"\n}",
|
||||
"options": {
|
||||
"timeout": 30000
|
||||
}
|
||||
},
|
||||
"id": "execute-trade",
|
||||
"name": "Execute Trade",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4,
|
||||
"position": [1040, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{ $json.success }}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "trade-if",
|
||||
"name": "Trade Success?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 1,
|
||||
"position": [1240, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "message",
|
||||
"stringValue": "🟢 TRADE OPENED\\n\\n{{ $('Parse Signal').item.json.rawMessage }}\\n\\n📊 Symbol: {{ $('Parse Signal').item.json.symbol }}\\n📈 Direction: {{ $('Parse Signal').item.json.direction }}\\n⏰ {{ $now.toFormat('HH:mm') }}\\n\\n✅ Position monitored automatically"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "format-success",
|
||||
"name": "Format Success",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [1440, 200]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "message",
|
||||
"stringValue": "🔴 TRADE FAILED\\n\\n{{ $('Parse Signal').item.json.rawMessage }}\\n\\n❌ Error: {{ $json.error || $json.message }}\\n⏰ {{ $now.toFormat('HH:mm') }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "format-error",
|
||||
"name": "Format Error",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [1440, 400]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "message",
|
||||
"stringValue": "⚠️ TRADE BLOCKED\\n\\n{{ $('Parse Signal').item.json.rawMessage }}\\n\\n🛑 Risk limits exceeded\\n⏰ {{ $now.toFormat('HH:mm') }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "format-risk",
|
||||
"name": "Format Risk",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [1040, 500]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "579304651",
|
||||
"text": "={{ $json.message }}",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"id": "telegram-success",
|
||||
"name": "Telegram Success",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [1640, 200],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "579304651",
|
||||
"text": "={{ $json.message }}",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"id": "telegram-error",
|
||||
"name": "Telegram Error",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [1640, 400],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"chatId": "579304651",
|
||||
"text": "={{ $json.message }}",
|
||||
"additionalFields": {
|
||||
"appendAttribution": false
|
||||
}
|
||||
},
|
||||
"id": "telegram-risk",
|
||||
"name": "Telegram Risk",
|
||||
"type": "n8n-nodes-base.telegram",
|
||||
"typeVersion": 1.1,
|
||||
"position": [1240, 500],
|
||||
"credentials": {
|
||||
"telegramApi": {
|
||||
"id": "Csk5cg4HtaSqP5jJ",
|
||||
"name": "Telegram account"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Webhook": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Parse Signal",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Parse Signal": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Check Risk",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Check Risk": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Risk Passed?",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Risk Passed?": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Execute Trade",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Format Risk",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Execute Trade": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Trade Success?",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Trade Success?": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Format Success",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Format Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Format Success": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram Success",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Format Error": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Format Risk": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram Risk",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"pinData": {},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "1",
|
||||
"tags": []
|
||||
}
|
||||
Reference in New Issue
Block a user