diff --git a/lib/trading/position-manager.ts b/lib/trading/position-manager.ts index 3403087..d0319e4 100644 --- a/lib/trading/position-manager.ts +++ b/lib/trading/position-manager.ts @@ -282,6 +282,9 @@ export class PositionManager { // Position closed externally (by on-chain TP/SL order) console.log(`āš ļø Position ${trade.symbol} was closed externally (by on-chain order)`) + // Save currentSize before it becomes 0 + const sizeBeforeClosure = trade.currentSize + // Determine exit reason based on price let exitReason: 'TP1' | 'TP2' | 'SL' | 'SOFT_SL' | 'HARD_SL' = 'SL' @@ -304,14 +307,14 @@ export class PositionManager { } } - // Calculate final P&L + // Calculate final P&L using size BEFORE closure const profitPercent = this.calculateProfitPercent( trade.entryPrice, currentPrice, trade.direction ) const accountPnL = profitPercent * trade.leverage - const realizedPnL = (trade.currentSize * accountPnL) / 100 + const realizedPnL = (sizeBeforeClosure * accountPnL) / 100 // Update database const holdTimeSeconds = Math.floor((Date.now() - trade.entryTime) / 1000) diff --git a/workflows/trading/Money_Machine.json b/workflows/trading/Money_Machine.json index 8a6cb83..b6f293f 100644 --- a/workflows/trading/Money_Machine.json +++ b/workflows/trading/Money_Machine.json @@ -4,18 +4,18 @@ { "parameters": { "httpMethod": "POST", - "path": "3371ad7c-0866-4161-90a4-f251de4aceb8", + "path": "tradingview-bot-v4", "options": {} }, - "id": "35b54214-9761-49dc-97b6-df39543f0a7b", + "id": "c762618c-fac7-4689-9356-8a78fc7160a8", "name": "Webhook", "type": "n8n-nodes-base.webhook", "typeVersion": 1, "position": [ - -840, - 660 + -980, + 680 ], - "webhookId": "3371ad7c-0866-4161-90a4-f251de4aceb8" + "webhookId": "tradingview-bot-v4" }, { "parameters": { @@ -27,27 +27,48 @@ }, { "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')) }}" + "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 || '').toString().match(/\\b(sell|short)\\b/i) ? 'short' : 'long' }}" + "stringValue": "={{ $json.body.match(/\\b(sell|short)\\b/i) ? 'short' : 'long' }}" }, { "name": "timeframe", - "stringValue": "5" + "stringValue": "={{ $json.body.match(/\\.P\\s+(\\d+)/)?.[1] || '15' }}" } ] }, "options": {} }, - "id": "99336995-2326-4575-9970-26afcf957132", + "id": "97d5b0ad-d078-411f-8f34-c9a81d18d921", "name": "Parse Signal", "type": "n8n-nodes-base.set", "typeVersion": 3.2, "position": [ - -660, - 660 + -780, + 680 + ] + }, + { + "parameters": { + "conditions": { + "string": [ + { + "value1": "={{ $json.timeframe }}", + "operation": "equals", + "value2": "15" + } + ] + } + }, + "id": "2e0bf241-9fb6-40bd-89f6-2dceafe34ef9", + "name": "15min Chart Only?", + "type": "n8n-nodes-base.if", + "typeVersion": 1, + "position": [ + -560, + 540 ] }, { @@ -74,12 +95,12 @@ "jsonBody": "={\n \"symbol\": \"{{ $json.symbol }}\",\n \"direction\": \"{{ $json.direction }}\"\n}", "options": {} }, - "id": "d42e7897-eadd-4202-8565-ac60759b46e1", + "id": "c1165de4-2095-4f5f-b9b1-18e76fd8c47b", "name": "Check Risk", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4, "position": [ - -340, + -280, 660 ], "credentials": { @@ -100,12 +121,12 @@ ] } }, - "id": "a60bfecb-d2f4-4165-a609-e6ed437aa2aa", + "id": "b9fa2b47-2acd-4be0-9d50-3f0348e04ec6", "name": "Risk Passed?", "type": "n8n-nodes-base.if", "typeVersion": 1, "position": [ - -140, + -80, 660 ] }, @@ -135,7 +156,7 @@ "timeout": 120000 } }, - "id": "95c46846-4b6a-4f9e-ad93-be223b73a618", + "id": "c2ec5f8c-42d1-414f-bdd6-0a440bc8fea9", "name": "Execute Trade", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4, @@ -161,7 +182,7 @@ ] } }, - "id": "18342642-e76f-484f-b532-d29846536a9c", + "id": "16dbf434-a07c-4666-82f2-cdc8814fe216", "name": "Trade Success?", "type": "n8n-nodes-base.if", "typeVersion": 1, @@ -182,7 +203,7 @@ }, "options": {} }, - "id": "9da40e3d-b855-4c65-a032-c6fcf88245d4", + "id": "79ab6122-cbd3-4aac-97d7-6b54f64e29b5", "name": "Format Success", "type": "n8n-nodes-base.set", "typeVersion": 3.2, @@ -203,7 +224,7 @@ }, "options": {} }, - "id": "500751c7-21bb-4351-8a6a-d43a1bfb9eaa", + "id": "41a0a8be-5004-4e6d-bdc5-9c7edf04eb51", "name": "Format Error", "type": "n8n-nodes-base.set", "typeVersion": 3.2, @@ -224,7 +245,7 @@ }, "options": {} }, - "id": "dec6cbc4-7550-40d3-9195-c4cc4f787b9b", + "id": "da462967-0548-4d57-a6de-cb783c96ac07", "name": "Format Risk", "type": "n8n-nodes-base.set", "typeVersion": 3.2, @@ -241,7 +262,7 @@ "appendAttribution": false } }, - "id": "6267b604-d39b-4cb7-98a5-2342cdced33b", + "id": "254280fd-f547-4302-97a5-30b44d851e12", "name": "Telegram Success", "type": "n8n-nodes-base.telegram", "typeVersion": 1.1, @@ -259,12 +280,12 @@ { "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` }}", + "text": "={{ $json.message }}", "additionalFields": { "appendAttribution": false } }, - "id": "88224fac-ef7a-41ec-b68a-e4bc1a5e3f31", + "id": "4ea066c9-4971-408f-b6e2-7d704c13ef55", "name": "Telegram Error", "type": "n8n-nodes-base.telegram", "typeVersion": 1.1, @@ -287,7 +308,7 @@ "appendAttribution": false } }, - "id": "4eccaca4-a5e7-407f-aab9-663a98a8323b", + "id": "ee6be7be-1735-4fa3-bd33-6b3fde9414d3", "name": "Telegram Risk", "type": "n8n-nodes-base.telegram", "typeVersion": 1.1, @@ -304,46 +325,23 @@ }, { "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": [ + "conditions": { + "string": [ { - "name": "signal", - "stringValue": "={{ $json.body.split('|')[0].trim() }}" + "value1": "={{ $json.timeframe }}", + "operation": "equals", + "value2": "5" } ] - }, - "options": {} + } }, - "id": "cce16424-fbb1-4191-b719-79ccfd59ec12", - "name": "Edit Fields", - "type": "n8n-nodes-base.set", - "typeVersion": 3.2, + "id": "8c680565-120d-47dc-83b2-58dcd397168b", + "name": "5min Chart Only?1", + "type": "n8n-nodes-base.if", + "typeVersion": 1, "position": [ - -660, - 840 + -560, + 800 ] } ], @@ -364,12 +362,12 @@ "main": [ [ { - "node": "Check Risk", + "node": "15min Chart Only?", "type": "main", "index": 0 }, { - "node": "Telegram", + "node": "5min Chart Only?1", "type": "main", "index": 0 } @@ -467,18 +465,35 @@ ] ] }, - "Edit Fields": { + "15min Chart Only?": { "main": [ - [] + [ + { + "node": "Check Risk", + "type": "main", + "index": 0 + } + ] + ] + }, + "5min Chart Only?1": { + "main": [ + [ + { + "node": "Check Risk", + "type": "main", + "index": 0 + } + ] ] } }, - "active": false, + "active": true, "settings": { "executionOrder": "v1" }, - "versionId": "2cc10693-953a-4b97-8c86-750b3063096b", - "id": "xTCaxlyI02bQLxun", + "versionId": "1376fb3b-08fb-4d96-a038-371249d36eda", + "id": "gUDqTiHyHSfRUXv6", "meta": { "instanceId": "e766d4f0b5def8ee8cb8561cd9d2b9ba7733e1907990b6987bca40175f82c379" },