This workflow follows the Execute Workflow Trigger → HTTP Request recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "dca",
"nodes": [
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$json.action}}",
"value2": "BUY"
}
]
}
},
"id": "ad12524b-bb69-4c23-b29f-f408d15814dd",
"name": "Should Execute Trade?",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
656,
176
],
"alwaysOutputData": false
},
{
"parameters": {
"jsCode": "const data = $json;\n\n// Binance order parameters\nconst orderParams = {\n side: data.action,\n quoteOrderQty: data.amount,\n symbol: data.symbol,\n type: 'MARKET',\n timestamp: Date.now(),\n recvWindow: 30000\n};\n\nconsole.log('Order Calculation:', orderParams);\n\n// Generate query string for signature\nconst queryString = Object.entries(orderParams)\n .map(([key, value]) => `${key}=${value}`)\n .join('&');\n\nreturn [{\n json: {\n dcaParams: data,\n orderParams,\n queryString, \n }\n}];"
},
"id": "0c40c93c-a6d1-4cf8-b00c-35f2cb1e107f",
"name": "Prepare Order Parameters",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
880,
-240
]
},
{
"parameters": {
"jsCode": "// Generate HMAC SHA256 signature for order\nconst crypto = require('crypto');\n\n// Check if environment variables are set\nif (!$env.BINANCE_SECRET_KEY) {\n throw new Error('BINANCE_SECRET_KEY environment variable not set');\n}\n\nconst API_SECRET = $env.BINANCE_SECRET_KEY;\nconst queryString = $json.queryString;\nconsole.log('Order signature query string:', queryString);\n\nconst signature = crypto.createHmac('sha256', API_SECRET)\n .update(queryString)\n .digest('hex');\n\nconsole.log('Generated order signature:', signature);\n\nreturn [{\n json: {\n dcaParams: $json.dcaParams,\n orderParams: {\n ...$json.orderParams,\n signature\n }\n }\n}];"
},
"id": "32c2c388-0e2d-4ca7-ac46-ef2bf0e4c23c",
"name": "Sign Order",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1168,
-240
]
},
{
"parameters": {
"method": "POST",
"url": "={{ $env.BINANCE_API_BASE_URL }}/api/v3/order",
"sendQuery": true,
"specifyQuery": "json",
"jsonQuery": "={\n \"side\": \"{{ $json.orderParams.side }}\",\n \"quoteOrderQty\": {{ $json.orderParams.quoteOrderQty }},\n \"symbol\": \"{{ $json.orderParams.symbol }}\",\n \"type\": \"{{ $json.orderParams.type }}\", \n \"timestamp\": {{ $json.orderParams.timestamp }},\n \"recvWindow\": {{ $json.orderParams.recvWindow }},\n \"signature\": \"{{ $json.orderParams.signature }}\"\n}",
"sendHeaders": true,
"specifyHeaders": "json",
"jsonHeaders": "={\n \"X-MBX-APIKEY\": \"{{ $env.BINANCE_API_KEY }}\"\n}",
"options": {
"timeout": 10000
}
},
"id": "262fa2dd-6839-4e3e-b096-68db27d59388",
"name": "Execute Trade on Binance",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 3,
"position": [
1440,
-240
],
"alwaysOutputData": false,
"notesInFlow": false,
"onError": "continueErrorOutput"
},
{
"parameters": {
"chatId": "={{$env.TELEGRAM_CHAT_ID}}",
"text": "={{$json.formattedMessage}}",
"additionalFields": {
"parse_mode": "Markdown"
}
},
"id": "84727dc8-4100-4c81-aa4a-5216c313b586",
"name": "Send Telegram Notification",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
2160,
192
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Format DCA Alert Message\nconst workflowInput = $node['workflow-input'].json;\nconst data = $json;\nconst dcaParams = data.dcaParams;\nconst orderParams = data.orderParams;\nconst error = data.error;\n\n// Debug log to see what we're receiving\nconsole.log('\ud83d\udd0d Debug - Raw data received:', JSON.stringify(data, null, 2));\n\n// Format numbers with proper decimals\nconst formatNumber = (num, decimals = 6) => {\n if (num === null || num === undefined || num === '' || isNaN(num)) return 'None';\n return new Intl.NumberFormat(\"en-US\", {\n minimumFractionDigits: 0,\n maximumFractionDigits: decimals\n}).format(num);\n};\n\nreturn {\n formattedMessage: `\u274c *DCA Execution Failed*\n\n\u2757\ufe0f Error status: ${error.status}\n\u2757\ufe0f Error code: ${error.code}\n\u2757\ufe0f Error message: ${error.message}\n\n\ud83d\udcb0 ${workflowInput.targetSymbol} Price: $${formatNumber(dcaParams.targetPrice)}\n\ud83d\udcb0 ${workflowInput.targetSymbol} AVG Price: $${formatNumber(dcaParams.avgPrice)}\n\ud83c\udfaf Action: ${dcaParams.action || 'None'}\n\ud83d\udcb5 ${workflowInput.sourceSymbol} amount: $${formatNumber(dcaParams.amount)}\n\ud83d\udcb2 ${workflowInput.sourceSymbol} available: $${formatNumber(dcaParams.amountAvailable)}\n\u23f0 Time: ${new Date(orderParams.timestamp).toLocaleString('ES')}\n`\n};\n"
},
"id": "fbcbb388-2f6d-43c2-9cb0-a1b5cb02ab10",
"name": "Format Error Message",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1680,
-16
]
},
{
"parameters": {
"jsCode": "// Format DCA Alert Message\nconst workflowInput = $node['workflow-input'].json;\nconst dcaParams = $json;\n\n// Debug log to see what we're receiving\nconsole.log('\ud83d\udd0d Debug - Raw data received:', JSON.stringify(dcaParams, null, 2));\n\n// Format numbers with proper decimals\nconst formatNumber = (num, decimals = 6) => {\n if (num === null || num === undefined || num === '' || isNaN(num)) return 'None';\n return new Intl.NumberFormat(\"en-US\", {\n minimumFractionDigits: 0,\n maximumFractionDigits: decimals\n}).format(num);\n};\n\nreturn {\n formattedMessage: `\ud83e\udd1a *DCA On Hold*\n\n\ud83d\udcb0 ${workflowInput.targetSymbol} Price: $${formatNumber(dcaParams.targetPrice)}\n\ud83d\udcb0 ${workflowInput.targetSymbol} AVG Price: $${formatNumber(dcaParams.avgPrice)}\n\ud83c\udfaf Action: ${dcaParams.action || 'None'}\n\ud83e\udd1a Action reason: ${dcaParams.actionReason}\n\ud83d\udcb5 ${workflowInput.sourceSymbol} amount: $${formatNumber(dcaParams.amount)}\n\ud83d\udcb2 ${workflowInput.sourceSymbol} available: $${formatNumber(dcaParams.amountAvailable)}\n\u23f0 Time: ${new Date().toLocaleString('ES')}`\n};"
},
"id": "6fa03666-ca5f-47fb-b0f1-0c7bfece97b9",
"name": "Format Hold Message",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1040,
192
]
},
{
"parameters": {
"jsCode": "// Format DCA Alert Message\nconst workflowInput = $node['workflow-input'].json;\nconst data = $node[\"Execute Trade on Binance\"].json;\nconst orderFills = data.fills[0];\nconst dcaParams = $node[\"Sign Order\"].json.dcaParams;\n\nlet avgPrice = null;\ntry {\n avgPrice = parseFloat($node[\"get-avg-price-after-order\"].json.avgPrice);\n} catch (e) {}\n \n\n// Debug log to see what we're receiving\nconsole.log('\ud83d\udd0d Debug - Raw data received:', JSON.stringify(data, null, 2));\n\n// Format numbers with proper decimals\nconst formatNumber = (num, decimals = 6) => {\n if (num === null || num === undefined || num === '' || isNaN(num)) return 'None';\n return new Intl.NumberFormat(\"en-US\", {\n minimumFractionDigits: 0,\n maximumFractionDigits: decimals\n}).format(num);\n};\n\nreturn {\n formattedMessage: `\u2705 *DCA Executed Successfully*\n\n\ud83d\udcca Status: ${data.status}\n\ud83c\udfea Type: ${data.type}\n\n\ud83d\udcb0 ${workflowInput.targetSymbol} Price: $${formatNumber(orderFills.price)}\n\ud83d\udcb0 ${workflowInput.targetSymbol} AVG Price: $${formatNumber(avgPrice)}\n\ud83e\udd11 Order quantity: ${formatNumber(orderFills.qty)} BTC\n\ud83d\udcb8 Order commission: ${formatNumber(orderFills.commission)} ${orderFills.commissionAsset}\n\ud83c\udfaf Action: ${data.side || 'None'}\n\ud83d\udcb5 ${workflowInput.sourceSymbol} amount: $${formatNumber(data.origQuoteOrderQty)}\n\ud83d\udcb2 ${workflowInput.sourceSymbol} available: $${formatNumber(dcaParams.amountAvailable - data.origQuoteOrderQty)}\n\u23f0 Time: ${new Date(data.transactTime).toLocaleString('ES')}\n`\n};"
},
"id": "c4225a46-c4c9-4d87-b42d-ebdda69297b9",
"name": "Format Success Message",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1904,
-256
]
},
{
"parameters": {
"workflowId": {
"__rl": true,
"value": "qhGDV6b3XcjmL6Bc",
"mode": "list",
"cachedResultUrl": "/workflow/qhGDV6b3XcjmL6Bc",
"cachedResultName": "get-balance-on-spot"
},
"workflowInputs": {
"mappingMode": "defineBelow",
"value": {
"symbol": "={{ $('workflow-input').item.json.sourceSymbol }}",
"amount": "={{ $('workflow-input').item.json.sourceAmount }}"
},
"matchingColumns": [],
"schema": [
{
"id": "symbol",
"displayName": "symbol",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"type": "string"
},
{
"id": "amount",
"displayName": "amount",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"type": "number"
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": true
},
"options": {}
},
"type": "n8n-nodes-base.executeWorkflow",
"typeVersion": 1.3,
"position": [
-384,
160
],
"id": "6fcaff96-c2fc-4de0-8ccd-0d0ce94428b2",
"name": "get-balance-on-spot"
},
{
"parameters": {
"url": "={{ $env.BINANCE_API_BASE_URL }}/api/v3/klines?symbol=BTCUSDC&interval=1d&limit=20",
"options": {
"timeout": 10000
}
},
"id": "4c64a471-86a6-4a1e-828c-ee73197fb26a",
"name": "get-btc-20-day-ma",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 3,
"position": [
-736,
-112
],
"alwaysOutputData": false
},
{
"parameters": {
"jsCode": "const workflowInput = $node['workflow-input'].json;\nconst getPriceNode = $node[\"get-price\"].json;\nconst getBalanceOnSpotNode = $node[\"get-balance-on-spot\"].json;\nconst targetPrice = parseFloat(getPriceNode.price);\nconst amount = workflowInput.sourceAmount; // TODO: recalculate this value depending on the current Price and the avg buy price. If currentPrice < avgBuyPrice, then increase amount, otherwise decrease\nconst amountAvailable = getBalanceOnSpotNode.amountAvailable\n\nlet avgPrice = null;\ntry {\n avgPrice = parseFloat($node[\"get-avg-price\"].json.avgPrice);\n} catch (e) {}\n\n\nlet action = 'BUY';\nlet actionReason = null;\nif(avgPrice != null && targetPrice > avgPrice) {\n action = 'HOLD';\n actionReason = `Current ${workflowInput.targetSymbol} price is greater than your avg price.`;\n}\n\nreturn result = { \n action: action,\n actionReason: actionReason,\n amount: amount,\n symbol: `${workflowInput.targetSymbol}${workflowInput.sourceSymbol}`,\n targetPrice: targetPrice,\n amountAvailable: amountAvailable,\n avgPrice: avgPrice\n};\n"
},
"id": "685ae862-ab70-4bc7-aecb-0f64582aca8f",
"name": "dca-logic",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
416,
176
]
},
{
"parameters": {
"inputSource": "jsonExample",
"jsonExample": "{\n \"targetSymbol\": \"BTC\",\n \"sourceSymbol\": \"USDC\",\n \"sourceAmount\": 10,\n \"onlyIfPriceBelowAvgPrice\": false,\n \"avgPriceFrom\": \"2026-01-29T18:48:55.496Z\"\n}"
},
"type": "n8n-nodes-base.executeWorkflowTrigger",
"typeVersion": 1.1,
"position": [
-928,
160
],
"id": "4532fb27-6baf-49b4-8baa-407ccab49632",
"name": "workflow-input"
},
{
"parameters": {
"url": "={{ $env.BINANCE_API_BASE_URL }}/api/v3/ticker/price?symbol={{$json.targetSymbol}}{{$json.sourceSymbol}}",
"options": {
"timeout": 10000
}
},
"id": "58ddc7e1-6667-429a-a1b4-0f8ee6cfb9be",
"name": "get-price",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 3,
"position": [
-656,
160
]
},
{
"parameters": {
"workflowId": {
"__rl": true,
"value": "iYMeKoezdxGXpy0l",
"mode": "list",
"cachedResultUrl": "/workflow/iYMeKoezdxGXpy0l",
"cachedResultName": "get-avg-price"
},
"workflowInputs": {
"mappingMode": "defineBelow",
"value": {
"targetSymbol": "={{ $('workflow-input').item.json.targetSymbol }}",
"sourceSymbol": "={{ $('workflow-input').item.json.sourceSymbol }}",
"startTime": "={{ $('workflow-input').item.json.avgPriceFrom }}"
},
"matchingColumns": [],
"schema": [
{
"id": "targetSymbol",
"displayName": "targetSymbol",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"type": "string",
"removed": false
},
{
"id": "sourceSymbol",
"displayName": "sourceSymbol",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"type": "string",
"removed": false
},
{
"id": "startTime",
"displayName": "startTime",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"type": "string",
"removed": false
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": true
},
"options": {}
},
"type": "n8n-nodes-base.executeWorkflow",
"typeVersion": 1.3,
"position": [
128,
-128
],
"id": "0f57349c-8c8a-4b9d-a91b-400ae52b11fb",
"name": "get-avg-price",
"alwaysOutputData": false
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "d0ea373b-57c3-47ab-99e9-5a7b1bad1da8",
"leftValue": "={{ $('workflow-input').item.json.onlyIfPriceBelowAvgPrice }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
},
{
"id": "4274d8eb-4596-481e-a08b-ce6f3943207e",
"leftValue": "={{ $('workflow-input').item.json.avgPriceFrom }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-176,
160
],
"id": "3c20f273-799f-4f15-8bba-f1e1c3733a7e",
"name": "If",
"alwaysOutputData": false
},
{
"parameters": {
"workflowId": {
"__rl": true,
"value": "iYMeKoezdxGXpy0l",
"mode": "list",
"cachedResultUrl": "/workflow/iYMeKoezdxGXpy0l",
"cachedResultName": "get-avg-price"
},
"workflowInputs": {
"mappingMode": "defineBelow",
"value": {
"targetSymbol": "={{ $('workflow-input').item.json.targetSymbol }}",
"sourceSymbol": "={{ $('workflow-input').item.json.sourceSymbol }}",
"startTime": "={{ $('workflow-input').item.json.avgPriceFrom }}"
},
"matchingColumns": [],
"schema": [
{
"id": "targetSymbol",
"displayName": "targetSymbol",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"type": "string",
"removed": false
},
{
"id": "sourceSymbol",
"displayName": "sourceSymbol",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"type": "string",
"removed": false
},
{
"id": "startTime",
"displayName": "startTime",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"type": "string",
"removed": false
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": true
},
"options": {}
},
"type": "n8n-nodes-base.executeWorkflow",
"typeVersion": 1.3,
"position": [
1680,
-432
],
"id": "f72ae6d1-2c91-4ede-bef4-82acccaea7dc",
"name": "get-avg-price-after-order",
"alwaysOutputData": false
}
],
"connections": {
"Should Execute Trade?": {
"main": [
[
{
"node": "Prepare Order Parameters",
"type": "main",
"index": 0
}
],
[
{
"node": "Format Hold Message",
"type": "main",
"index": 0
}
]
]
},
"Prepare Order Parameters": {
"main": [
[
{
"node": "Sign Order",
"type": "main",
"index": 0
}
]
]
},
"Sign Order": {
"main": [
[
{
"node": "Execute Trade on Binance",
"type": "main",
"index": 0
}
]
]
},
"Execute Trade on Binance": {
"main": [
[
{
"node": "get-avg-price-after-order",
"type": "main",
"index": 0
}
],
[
{
"node": "Format Error Message",
"type": "main",
"index": 0
}
]
]
},
"Format Error Message": {
"main": [
[
{
"node": "Send Telegram Notification",
"type": "main",
"index": 0
}
]
]
},
"Format Hold Message": {
"main": [
[
{
"node": "Send Telegram Notification",
"type": "main",
"index": 0
}
]
]
},
"Format Success Message": {
"main": [
[
{
"node": "Send Telegram Notification",
"type": "main",
"index": 0
}
]
]
},
"get-balance-on-spot": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"get-btc-20-day-ma": {
"main": [
[]
]
},
"dca-logic": {
"main": [
[
{
"node": "Should Execute Trade?",
"type": "main",
"index": 0
}
]
]
},
"workflow-input": {
"main": [
[
{
"node": "get-price",
"type": "main",
"index": 0
}
]
]
},
"get-price": {
"main": [
[
{
"node": "get-balance-on-spot",
"type": "main",
"index": 0
}
]
]
},
"get-avg-price": {
"main": [
[
{
"node": "dca-logic",
"type": "main",
"index": 0
}
]
]
},
"If": {
"main": [
[
{
"node": "get-avg-price",
"type": "main",
"index": 0
}
],
[
{
"node": "dca-logic",
"type": "main",
"index": 0
}
]
]
},
"get-avg-price-after-order": {
"main": [
[
{
"node": "Format Success Message",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "7aa13cda-77ae-4f7d-8380-287f4bff7943",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "9Vv6fuCH1BIlYnX0",
"tags": []
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
telegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
dca. Uses httpRequest, telegram, executeWorkflowTrigger. Event-driven trigger; 16 nodes.
Source: https://github.com/luis901101/n8n/blob/0239052cbcf52682e1494538f1fd4d133b75d8d8/workflows/binance/dca.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
03 - Command Handler. Uses executeWorkflowTrigger, telegram, executeCommand, postgres. Event-driven trigger; 53 nodes.
Deal-Finder. Uses executeWorkflowTrigger, googleSheets, perplexity, httpRequest. Event-driven trigger; 49 nodes.
This workflow provides a complete solution for handling Telegram Stars payments, invoicing and refunds using n8n. It automates the process of sending invoices, managing pre-checkout approvals, recordi
VIVID v5.0 — Chapter Sub-workflow. Uses executeWorkflowTrigger, executeCommand, itemLists, httpRequest. Event-driven trigger; 21 nodes.
[HUB] Жора Action. Uses executeWorkflowTrigger, supabase, telegram, httpRequest. Event-driven trigger; 19 nodes.