AutomationFlowsAI & RAG › Binance Futures TA Analysis & Telegram Alerts

Binance Futures TA Analysis & Telegram Alerts

Original n8n title: Analyze Binance Futures Markets with Ta Indicators, Openai News Checks, and Telegram Alerts

ByVadim Mubi @mubivadim on n8n.io

This workflow acts as an automated market analyst for educational purposes. It scans Binance Futures (Testnet) for high-volume pairs, applies custom technical analysis (RSI, Bollinger Bands, EMA, ATR) using JavaScript, and uses AI to validate trends against recent news sentiment.

Cron / scheduled trigger★★★★☆ complexityAI-powered29 nodesHTTP RequestCryptoTelegramOpenRouter ChatChain Llm
AI & RAG Trigger: Cron / scheduled Nodes: 29 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #13011 — we link there as the canonical source.

This workflow follows the Chainllm → 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 →

Download .json
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "5ac7aafc-4b76-49c9-ba48-4f938ddc4688",
      "name": "Get Exchange Rules",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -176,
        144
      ],
      "parameters": {
        "url": "https://fapi.binance.com/fapi/v1/exchangeInfo?symbol={{ $json.symbol }}",
        "options": {}
      },
      "typeVersion": 4.3
    },
    {
      "id": "45b21da7-88e5-4a78-9e57-c74f57154675",
      "name": "\ud83d\udee1 RSI Safety Check.",
      "type": "n8n-nodes-base.code",
      "position": [
        -1520,
        64
      ],
      "parameters": {
        "jsCode": "// --- RSI SAFETY FILTER ---\n// Settings are now dynamic, but logic remains local for speed\nconst RSI_MAX = 70; \nconst RSI_MIN = 30; \n\nconst input = $input.first().json;\nconst rsi = parseFloat(input.rsi || input.RSI); \nconst signal = input.signal; \n\nif (!rsi) return { json: input }; \n\nlet isSafe = true;\n\n// 1. Long Check\nif (signal === 'LONG' && rsi > RSI_MAX) isSafe = false;\n\n// 2. Short Check\nif (signal === 'SHORT' && rsi < RSI_MIN) isSafe = false;\n\n// --- RESULT ---\nif (isSafe) {\n    return { json: input };\n} else {\n    return []; // Stop execution\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "a62ad409-0869-43bb-a44b-984d45f6ba43",
      "name": "Execute (Paper Trading)",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        720,
        160
      ],
      "parameters": {
        "url": "=https://testnet.binancefuture.com{{ $json.endpoint }}?{{ $json.queryString }}&signature={{ $json.signature }}",
        "method": "POST",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "X-MBX-APIKEY",
              "value": "={{ $json.apiKey }}"
            }
          ]
        }
      },
      "typeVersion": 4.1
    },
    {
      "id": "8277823b-cb18-47e2-a988-9aa93f265763",
      "name": "\ud83d\udd10 Sign Request",
      "type": "n8n-nodes-base.crypto",
      "position": [
        544,
        160
      ],
      "parameters": {
        "type": "SHA256",
        "value": "={{ $json.queryString }}",
        "action": "hmac",
        "secret": "YOUR_CREDENTIAL_HERE",
        "dataPropertyName": "signature"
      },
      "typeVersion": 1
    },
    {
      "id": "33abbdf9-3dea-4857-a020-b1e959dfa785",
      "name": "\ud83d\udd04 Loop (SplitBatch)",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        352,
        144
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "21554eeb-da99-48ff-ae96-bd843ea7db50",
      "name": "Loop Connector",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -176,
        320
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "b1b7dce3-9bbe-440b-9ebe-447e9149ed48",
      "name": "\ud83d\udce2 Notify Telegram",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -416,
        224
      ],
      "parameters": {
        "text": "=\ud83d\ude80 <b>#{{ $json.symbol }}</b> | <b>{{ $json.signal }}</b> {{ $json.emoji }}\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\ud83d\udeaa Entry: <code>{{ $json.price }}</code> \n\ud83d\udcb0 Target: <code>{{ $json.calc_tp }}</code> \n\ud83d\udee1 Stop: <code>{{ $json.calc_sl }}</code>\n\n\ud83d\udcc8 <b>Analytics:</b>\n\u2022 Trend: <b>{{ $json.trend }}</b>\n\u2022 R/R Ratio: <b>{{ $json.rr_ratio }}</b>\n\u2022 RSI: {{ $json.rsi }} ({{ $json.rsi_status }})\n\u2022 Volatility: {{ $json.bb_width }}%\n\n\ud83e\udd16 <b>AI Risk Check:</b> {{ $json.ai_reason }}\n\ud83d\udce2 <i>Paper Trading / Educational</i>",
        "chatId": "={{ $('\ud83d\udcdd MAIN CONFIG').first().json.TELEGRAM_CHANNEL_ID }}",
        "additionalFields": {
          "parse_mode": "HTML",
          "appendAttribution": false
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "49291e69-cc20-4278-a255-307d4a6bdd1e",
      "name": "\ud83d\udee0\ufe0f Merge & Clean Data",
      "type": "n8n-nodes-base.code",
      "position": [
        -720,
        64
      ],
      "parameters": {
        "jsCode": "// 1. Get AI Output\nconst inputItem = $input.first();\nconst aiRaw = inputItem ? (inputItem.json.text || \"{}\") : \"{}\";\n\nlet marketData = {};\ntry {\n    marketData = $('\ud83e\udde0 Analyze Logic').item.json;\n} catch(e) {\n    marketData = { symbol: \"ERROR\", price: 0 };\n}\n\n// 2. Clean JSON from Markdown\nlet aiReason = \"CONFIRM: Analysis confirmed.\";\nlet cleanAi = aiRaw.replace(/```json/g, '').replace(/```/g, '').trim();\n\nconst firstBrace = cleanAi.indexOf('{');\nconst lastBrace = cleanAi.lastIndexOf('}');\n\nif (firstBrace !== -1 && lastBrace !== -1) {\n    try {\n        const parsed = JSON.parse(cleanAi.substring(firstBrace, lastBrace + 1));\n        if (parsed.reason) {\n            aiReason = parsed.reason;\n        }\n    } catch (e) {\n        aiReason = \"CHECK: \" + cleanAi.substring(0, 200);\n    }\n} else if (cleanAi.length > 5) {\n    aiReason = cleanAi.substring(0, 250);\n}\n\nreturn {\n    json: {\n        ...marketData,\n        ai_reason: aiReason,\n        processed_at: new Date().toISOString()\n    }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "9ea585cf-ba43-4861-a118-a52d770c9316",
      "name": "OpenRouter/OpenAI Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        -976,
        224
      ],
      "parameters": {
        "model": "openai/gpt-3.5-turbo",
        "options": {
          "temperature": 0.2
        }
      },
      "typeVersion": 1
    },
    {
      "id": "413e695e-d4ea-4245-b092-a79e303bcf67",
      "name": "\ud83e\udd16 AI Analysis",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        -976,
        64
      ],
      "parameters": {
        "text": "=You are the Risk Manager of an algorithmic hedge fund.\nYour job is to protect capital from trading during high-risk news events.\n\nINPUT DATA:\n1. Ticker: {{ $json.symbol }}\n2. Strategy Signal: {{ $json.signal }} (LONG = Buy, SHORT = Sell)\n3. RECENT NEWS:\n{{ $json.news_context }}\n\nINSTRUCTIONS:\nAnalyze the headlines. Look ONLY for critical threats to the current signal.\n- Threats for LONG: Hacks, Delisting, Lawsuits, FUD, Massive outflows.\n- Threats for SHORT: Partnerships, Listings, Mainnet launch, Hardfork, Pumps.\n\nRESPONSE FORMAT (STRICT JSON):\nIf news is neutral or confirms the signal:\n{ \"reason\": \"CONFIRM: Neutral or Positive news. No obstacles.\" }\n\nIf CRITICAL THREAT detected (Contradiction):\n{ \"reason\": \"SKIP: High risk detected! (Brief explanation)\" }\n\nIMPORTANT:\n1. Use \"SKIP\" only for real threats.\n2. Use \"CONFIRM\" if clear.",
        "batching": {},
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "424080ed-d729-4dc1-9579-c9da41012f8a",
      "name": "\ud83d\udcdd Format Context",
      "type": "n8n-nodes-base.code",
      "position": [
        -1120,
        64
      ],
      "parameters": {
        "jsCode": "const newsData = $input.first()?.json?.Data || [];\nlet newsText = \"No recent news found.\";\nif (newsData.length > 0) {\n    const headlines = newsData.slice(0, 3).map(n => `- ${n.title}`).join('\\n');\n    newsText = `Latest News:\\n${headlines}`;\n}\nconst techData = $('\ud83e\udde0 Analyze Logic').first().json;\n\nreturn {\n    json: {\n        ...techData,\n        news_context: newsText\n    }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "3da47f7d-8061-4c55-865f-4423469777ec",
      "name": "\ud83d\udcf0 Get News",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1280,
        64
      ],
      "parameters": {
        "url": "https://min-api.cryptocompare.com/data/v2/news/",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "categories",
              "value": "={{ $('\ud83e\udde0 Analyze Logic').first().json.symbol.replace('USDT', '') }}"
            },
            {
              "name": "lang",
              "value": "EN"
            }
          ]
        }
      },
      "typeVersion": 4.1
    },
    {
      "id": "bd5f25f7-75d2-4610-8e6e-d266f023a283",
      "name": "\ud83d\udea6 Signal Check",
      "type": "n8n-nodes-base.if",
      "position": [
        -1696,
        144
      ],
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{ $json.hasSignal }}",
              "value2": true
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "6863704f-ca57-4b7f-91b6-e74f0600bd39",
      "name": "\ud83e\udde0 Analyze Logic",
      "type": "n8n-nodes-base.code",
      "position": [
        -1888,
        144
      ],
      "parameters": {
        "jsCode": "// --- STRATEGY SETTINGS ---\nconst MIN_VOL_X = 1.2; // Volume multiplier threshold\nconst DEDUP_TIMEOUT_MS = 60 * 60 * 1000; // 1 Hour cooldown per coin\n\nconst staticData = $getWorkflowStaticData('global');\nif (!staticData.lastSignals) staticData.lastSignals = {};\n\nconst items = $input.all();\nconst klines = items.map(i => i.json);\nlet symbol = \"UNKNOWN\";\ntry { symbol = $('SplitInBatches').first().json.symbol; } catch(e) {}\nconst noSignal = () => ({ json: { hasSignal: false, symbol } });\n\n// Need at least 200 candles for EMA calculation\nif (klines.length < 200) return noSignal(); \n\nconst closes = klines.map(k => parseFloat(k[4]));\nconst highs = klines.map(k => parseFloat(k[2]));\nconst lows = klines.map(k => parseFloat(k[3]));\nconst volumes = klines.map(k => parseFloat(k[5]));\n\nconst lastIdx = closes.length - 2; // Closed candle\nconst prevIdx = lastIdx - 1;     // Previous candle\n\nconst currentClose = closes[lastIdx];\nconst currentVol = volumes[lastIdx];\n\n// --- 1. EMA 200 (Trend Filter) ---\nfunction calculateEMA(data, period) {\n    const k = 2 / (period + 1);\n    let ema = data[0];\n    for (let i = 1; i < data.length; i++) {\n        ema = (data[i] * k) + (ema * (1 - k));\n    }\n    return ema;\n}\nconst ema200 = calculateEMA(closes.slice(0, lastIdx + 1), 200);\nconst isUpTrend = currentClose > ema200;\n\n// --- 2. BOLLINGER BANDS ---\nconst bbPeriod = 20;\nconst sliceBB = closes.slice(lastIdx - bbPeriod + 1, lastIdx + 1);\nconst smaBB = sliceBB.reduce((a, b) => a + b, 0) / bbPeriod;\nconst stdDev = Math.sqrt(sliceBB.map(x => Math.pow(x - smaBB, 2)).reduce((a, b) => a + b, 0) / bbPeriod);\nconst upperBand = smaBB + (stdDev * 2);\nconst lowerBand = smaBB - (stdDev * 2);\nconst bbWidth = ((upperBand - lowerBand) / smaBB * 100).toFixed(2);\n\n// --- 3. RSI (14) ---\nfunction getRSI(data, endIdx) {\n    let gains = 0, losses = 0;\n    const period = 14;\n    for (let i = endIdx - period; i < endIdx; i++) {\n        let diff = data[i+1] - data[i];\n        if (diff >= 0) gains += diff;\n        else losses -= diff;\n    }\n    let rs = (losses === 0) ? 100 : gains / losses;\n    return 100 - (100 / (1 + rs));\n}\nconst rsi = getRSI(closes, lastIdx);\nconst prevRsi = getRSI(closes, prevIdx);\n\nlet rsiStatus = rsi < 35 ? \"Oversold\" : (rsi > 65 ? \"Overbought\" : \"Neutral\");\n\n// --- 4. VOLUME ANALYSIS ---\nconst avgVol = volumes.slice(lastIdx - 20, lastIdx).reduce((a, b) => a + b, 0) / 20;\nconst volFactor = currentVol / avgVol;\n\n// --- 5. ENTRY LOGIC ---\nlet signal = null;\n\n// LONG Logic\nif (isUpTrend && currentClose < lowerBand && rsi > prevRsi && rsi < 45 && volFactor > MIN_VOL_X) {\n    signal = \"Long\";\n} \n// SHORT Logic\nelse if (!isUpTrend && currentClose > upperBand && rsi < prevRsi && rsi > 55 && volFactor > MIN_VOL_X) {\n    signal = \"Short\";\n}\n\nif (!signal) return noSignal();\n\n// --- 6. RISK/REWARD CALC ---\nlet tpMultiplier = 2.5; \nif (parseFloat(bbWidth) > 3 || volFactor > 2.0) {\n    tpMultiplier = 3.5; // Target higher for volatile assets\n}\n\n// --- 7. ATR & SL/TP ---\nlet trSum = 0;\nfor (let i = lastIdx - 14; i <= lastIdx; i++) {\n    trSum += Math.max(highs[i]-lows[i], Math.abs(highs[i]-(closes[i-1]||0)), Math.abs(lows[i]-(closes[i-1]||0)));\n}\nconst atr = trSum / 14;\nconst prec = currentClose > 10 ? 2 : 5;\n\n// Deduplication check\nconst now = Date.now();\nif (now - (staticData.lastSignals[symbol] || 0) < DEDUP_TIMEOUT_MS) return noSignal();\nstaticData.lastSignals[symbol] = now;\n\nreturn {\n    json: {\n        hasSignal: true,\n        symbol,\n        price: currentClose,\n        signal,\n        emoji: signal === \"Long\" ? \"\ud83d\udfe2\" : \"\ud83d\udd34\",\n        rsi: rsi.toFixed(1),\n        rsi_status: rsiStatus,\n        vol_x: volFactor.toFixed(1),\n        bb_width: bbWidth,\n        trend: isUpTrend ? \"Bullish \ud83d\udcc8\" : \"Bearish \ud83d\udcc9\",\n        rr_ratio: `1:${tpMultiplier}`,\n        calc_sl: (signal === \"Long\" ? currentClose - atr * 1.5 : currentClose + atr * 1.5).toFixed(prec),\n        calc_tp: (signal === \"Long\" ? currentClose + atr * tpMultiplier : currentClose - atr * tpMultiplier).toFixed(prec)\n    }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "c0dbde9d-13e9-46e2-bbc6-da93427a6472",
      "name": "Get Klines",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -2064,
        144
      ],
      "parameters": {
        "url": "https://fapi.binance.com/fapi/v1/klines",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "symbol",
              "value": "={{ $('SplitInBatches').first().json.symbol }}"
            },
            {
              "name": "interval",
              "value": "15m"
            },
            {
              "name": "limit",
              "value": "300"
            }
          ]
        }
      },
      "typeVersion": 4.1
    },
    {
      "id": "d6881a0b-7448-4395-bc64-448dae9cebcb",
      "name": "\u23f8\ufe0f Wait 1s",
      "type": "n8n-nodes-base.wait",
      "position": [
        -2336,
        144
      ],
      "parameters": {
        "unit": "seconds",
        "amount": 0.2
      },
      "typeVersion": 1
    },
    {
      "id": "462c756d-51c1-4afd-89d7-8265f0cb5725",
      "name": "SplitInBatches",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -2544,
        128
      ],
      "parameters": {
        "options": {},
        "batchSize": 10
      },
      "typeVersion": 3
    },
    {
      "id": "b2e2f395-3ad7-430b-bf2b-dca99c79a5b8",
      "name": "\ud83d\udd0d Filter Candidates",
      "type": "n8n-nodes-base.code",
      "position": [
        -2736,
        128
      ],
      "parameters": {
        "jsCode": "// --- CONFIGURATION LOAD ---\n// We get the blacklist string from the new Config Node\nconst rawBlacklist = $('\ud83d\udcdd MAIN CONFIG').first().json.BLACKLIST || \"\";\nconst BLACKLIST = rawBlacklist.split(',').map(s => s.trim());\n\n// 1. Filter USDT Pairs only\nlet pairs = $input.all().map(i => i.json).filter(i => i.symbol.endsWith('USDT'));\n\n// 2. Sort by Quote Volume (High liquidity first)\npairs.sort((a, b) => parseFloat(b.quoteVolume) - parseFloat(a.quoteVolume));\n\n// 3. Remove Blacklisted symbols\npairs = pairs.filter(p => !BLACKLIST.includes(p.symbol));\n\n// 4. Select TOP Candidates (e.g., Rank 10 to 150 to avoid stablecoins usually at top)\nreturn pairs.slice(10, 150).map(c => ({ json: { symbol: c.symbol } }));"
      },
      "typeVersion": 2
    },
    {
      "id": "adeb4fa8-fc95-4c54-b022-32e3b9bfd2db",
      "name": "Get All Tickers",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -2912,
        128
      ],
      "parameters": {
        "url": "https://fapi.binance.com/fapi/v1/ticker/24hr",
        "options": {}
      },
      "typeVersion": 4.1
    },
    {
      "id": "d367f61e-54eb-472d-8cf6-6f1136efe7d7",
      "name": "\ud83d\udcdd MAIN CONFIG",
      "type": "n8n-nodes-base.set",
      "position": [
        -3152,
        128
      ],
      "parameters": {
        "values": {
          "number": [
            {
              "name": "TRADE_AMOUNT_USDT",
              "value": 100
            },
            {
              "name": "LEVERAGE",
              "value": 1
            }
          ],
          "string": [
            {
              "name": "BINANCE_API_KEY",
              "value": "INSERT_TESTNET_KEY_HERE"
            },
            {
              "name": "BINANCE_SECRET",
              "value": "INSERT_TESTNET_SECRET_HERE"
            },
            {
              "name": "TELEGRAM_CHANNEL_ID",
              "value": "@your_channel"
            },
            {
              "name": "BLACKLIST",
              "value": "USDCUSDT,BUSDUSDT,USDPUSDT"
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 2
    },
    {
      "id": "d9c49044-507d-4749-9516-42af5b0a0717",
      "name": "\u23f1\ufe0f Every 15 mins",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -3360,
        128
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "*/15 * * * *"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "42a98e69-920b-4d45-86fd-0f43d07c4f2e",
      "name": "Main Sticky",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3872,
        -32
      ],
      "parameters": {
        "color": 2,
        "width": 400,
        "height": 580,
        "content": "# \ud83e\udd16 Crypto market analyzer & Paper trader\n\nThis workflow demonstrates advanced market analysis logic using n8n.\n\n### How it works\n1. **Scan:** Filters top pairs by volume on Binance.\n2. **Analyze:** Calculates EMA, BB, and RSI using pure JavaScript.\n3. **Validate:** Uses AI to check news sentiment for the selected asset.\n4. **Paper Trade:** Places a test order on Binance Testnet using signed requests.\n\n### Setup steps\n1. **Credentials:** Set up Telegram Bot & OpenRouter creds.\n2. **Configuration:** Open the `\ud83d\udcdd MAIN CONFIG` node and set your Testnet keys."
      },
      "typeVersion": 1
    },
    {
      "id": "de42408e-ab7d-4f78-b07e-057fd7a7dc67",
      "name": "Warning Sticky",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3200,
        -16
      ],
      "parameters": {
        "color": 7,
        "width": 188,
        "height": 340,
        "content": "\u26a0\ufe0f **CONFIGURATION**\nInsert Binance TESTNET keys here."
      },
      "typeVersion": 1
    },
    {
      "id": "6860e9ec-48f2-4991-b364-357cede9c2cb",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        96,
        -16
      ],
      "parameters": {
        "color": 7,
        "width": 852,
        "height": 416,
        "content": "## 5. Paper Trading Execution Loop\nPrepares parameters, signs the request (HMAC SHA256), and executes on Binance Testnet."
      },
      "typeVersion": 1
    },
    {
      "id": "b2eda8c6-b036-4fc3-90b0-28d01f93810a",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1344,
        -16
      ],
      "parameters": {
        "color": 7,
        "width": 808,
        "height": 412,
        "content": "## 3. AI Sentiment Filter\nScrapes news and uses LLM to validate the trade against risk factors."
      },
      "typeVersion": 1
    },
    {
      "id": "92836ae0-a2ed-4901-a0a1-c3c90b1e3361",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -496,
        -16
      ],
      "parameters": {
        "color": 7,
        "width": 548,
        "height": 549,
        "content": "## 4. Telegram Notification\nSends analysis and alerts to your channel."
      },
      "typeVersion": 1
    },
    {
      "id": "45e4c4c9-dcc9-45c6-85cb-be69920353c5",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2144,
        -16
      ],
      "parameters": {
        "color": 7,
        "width": 764,
        "height": 332,
        "content": "## 2. Technical Analysis Core\nCalculates EMA, Bollinger Bands, RSI, and Volume anomalies via JS."
      },
      "typeVersion": 1
    },
    {
      "id": "2251fc2a-8c09-49ba-9af4-cb8ea7bf227d",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2992,
        -16
      ],
      "parameters": {
        "color": 7,
        "width": 804,
        "height": 332,
        "content": "## 1. Market Data Collection\nFetches top volume pairs, filters stablecoins, and prepares candidates."
      },
      "typeVersion": 1
    },
    {
      "id": "78632b28-2570-449e-9d43-2531cea2ee23",
      "name": "\ud83d\udcdd Prep String",
      "type": "n8n-nodes-base.code",
      "position": [
        144,
        144
      ],
      "parameters": {
        "jsCode": "// --- CONFIGURATION LOAD ---\nconst config = $('\ud83d\udcdd MAIN CONFIG').first().json;\n\nconst API_KEY = config.BINANCE_API_KEY;\nconst USDT_AMOUNT = parseFloat(config.TRADE_AMOUNT_USDT);\nconst LEVERAGE = parseInt(config.LEVERAGE);\nconst TRAILING_CALLBACK = 2.0;\n\n// --- LOGIC BELOW ---\nconst marketData = $('\ud83d\udee0\ufe0f Merge & Clean Data').item.json;\nconst symbol = marketData.symbol;\n\nconst allExchangeRules = $input.first().json;\nconst symbolInfo = allExchangeRules.symbols.find(s => s.symbol === symbol);\n\nif (!symbolInfo) {\n    throw new Error(`Symbol ${symbol} not found on Binance.`);\n}\n\n// Precision Calc\nconst priceFilter = symbolInfo.filters.find(f => f.filterType === 'PRICE_FILTER');\nconst lotFilter = symbolInfo.filters.find(f => f.filterType === 'LOT_SIZE');\n\nconst getPrecision = (step) => {\n    const s = parseFloat(step).toString();\n    return s.includes('.') ? s.split('.')[1].length : 0;\n};\n\nconst pPrec = getPrecision(priceFilter.tickSize);\nconst qPrec = getPrecision(lotFilter.stepSize);\n\nconst toB = (val, prec) => {\n    if (!val || isNaN(val)) return \"0\";\n    const factor = Math.pow(10, prec);\n    const rounded = Math.floor(parseFloat(val) * factor) / factor;\n    return rounded.toFixed(prec).replace(/\\.?0+$/, \"\");\n};\n\n// Prices\nconst currentPrice = parseFloat(marketData.price);\nlet sl = parseFloat(marketData.calc_sl);\nlet tp = parseFloat(marketData.calc_tp);\n\nif (!sl || sl === 0) sl = marketData.signal === 'LONG' ? currentPrice * 0.98 : currentPrice * 1.02;\nif (!tp || tp === 0) tp = marketData.signal === 'LONG' ? currentPrice * 1.04 : currentPrice * 0.96;\n\nconst slPrice = toB(sl, pPrec);\nconst tpPrice = toB(tp, pPrec);\nconst totalQty = toB((USDT_AMOUNT * LEVERAGE) / currentPrice, qPrec);\n\nif (parseFloat(totalQty) <= 0) return []; \n\nconst side = marketData.signal === 'LONG' ? 'BUY' : 'SELL';\nconst closeSide = marketData.signal === 'LONG' ? 'SELL' : 'BUY';\nconst timestamp = Date.now();\n\nfunction makeQuery(p) { return Object.keys(p).map(k => `${k}=${p[k]}`).join('&'); }\n\n// Order Construction\nreturn [\n    { json: { queryString: makeQuery({symbol, marginType: 'ISOLATED', timestamp}), endpoint: \"/fapi/v1/marginType\", apiKey: API_KEY, type: \"MARGIN\" } },\n    { json: { queryString: makeQuery({symbol, leverage: LEVERAGE, timestamp}), endpoint: \"/fapi/v1/leverage\", apiKey: API_KEY, type: \"LEVERAGE\" } },\n    { json: { queryString: makeQuery({symbol, side, type: 'MARKET', quantity: totalQty, timestamp}), endpoint: \"/fapi/v1/order\", apiKey: API_KEY, type: \"ENTRY\" } },\n    { json: { queryString: makeQuery({symbol, side: closeSide, type: 'STOP_MARKET', stopPrice: slPrice, closePosition: 'true', timestamp}), endpoint: \"/fapi/v1/order\", apiKey: API_KEY, type: \"SL\" } },\n    { json: { queryString: makeQuery({symbol, side: closeSide, type: 'TAKE_PROFIT_MARKET', stopPrice: tpPrice, quantity: toB(parseFloat(totalQty)/2, qPrec), reduceOnly: 'true', timestamp}), endpoint: \"/fapi/v1/order\", apiKey: API_KEY, type: \"TP\" } },\n    { json: { queryString: makeQuery({symbol, side: closeSide, type: 'TRAILING_STOP_MARKET', quantity: toB(parseFloat(totalQty)/2, qPrec), callbackRate: TRAILING_CALLBACK, activationPrice: tpPrice, reduceOnly: 'true', timestamp}), endpoint: \"/fapi/v1/order\", apiKey: API_KEY, type: \"TRAILING\" } }\n];"
      },
      "typeVersion": 2
    }
  ],
  "connections": {
    "Get Klines": {
      "main": [
        [
          {
            "node": "\ud83e\udde0 Analyze Logic",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcf0 Get News": {
      "main": [
        [
          {
            "node": "\ud83d\udcdd Format Context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Connector": {
      "main": [
        [
          {
            "node": "SplitInBatches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SplitInBatches": {
      "main": [
        [],
        [
          {
            "node": "\u23f8\ufe0f Wait 1s",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u23f8\ufe0f Wait 1s": {
      "main": [
        [
          {
            "node": "Get Klines",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get All Tickers": {
      "main": [
        [
          {
            "node": "\ud83d\udd0d Filter Candidates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcdd MAIN CONFIG": {
      "main": [
        [
          {
            "node": "Get All Tickers",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcdd Prep String": {
      "main": [
        [
          {
            "node": "\ud83d\udd04 Loop (SplitBatch)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83e\udd16 AI Analysis": {
      "main": [
        [
          {
            "node": "\ud83d\udee0\ufe0f Merge & Clean Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd10 Sign Request": {
      "main": [
        [
          {
            "node": "Execute (Paper Trading)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udea6 Signal Check": {
      "main": [
        [
          {
            "node": "\ud83d\udee1 RSI Safety Check.",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Loop Connector",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Exchange Rules": {
      "main": [
        [
          {
            "node": "\ud83d\udcdd Prep String",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83e\udde0 Analyze Logic": {
      "main": [
        [
          {
            "node": "\ud83d\udea6 Signal Check",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcdd Format Context": {
      "main": [
        [
          {
            "node": "\ud83e\udd16 AI Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u23f1\ufe0f Every 15 mins": {
      "main": [
        [
          {
            "node": "\ud83d\udcdd MAIN CONFIG",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udce2 Notify Telegram": {
      "main": [
        [
          {
            "node": "Loop Connector",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd04 Loop (SplitBatch)": {
      "main": [
        [],
        [
          {
            "node": "\ud83d\udd10 Sign Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd0d Filter Candidates": {
      "main": [
        [
          {
            "node": "SplitInBatches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udee1 RSI Safety Check.": {
      "main": [
        [
          {
            "node": "\ud83d\udcf0 Get News",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute (Paper Trading)": {
      "main": [
        [
          {
            "node": "\ud83d\udd04 Loop (SplitBatch)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter/OpenAI Model": {
      "ai_languageModel": [
        [
          {
            "node": "\ud83e\udd16 AI Analysis",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udee0\ufe0f Merge & Clean Data": {
      "main": [
        [
          {
            "node": "Get Exchange Rules",
            "type": "main",
            "index": 0
          },
          {
            "node": "\ud83d\udce2 Notify Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow acts as an automated market analyst for educational purposes. It scans Binance Futures (Testnet) for high-volume pairs, applies custom technical analysis (RSI, Bollinger Bands, EMA, ATR) using JavaScript, and uses AI to validate trends against recent news sentiment.

Source: https://n8n.io/workflows/13011/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Job seekers who want to automate their entire job search pipeline — from discovering new listings to generating tailored resumes and cover letters — without manually browsing LinkedIn every day.

HTTP Request, Chain Llm, Google Sheets +6
AI & RAG

This workflow automatically generates stock market insights for selected tickers (e.g. GAZP, SBER, LKOH) using historical data, technical indicators, and an AI model. The results are then sent to Tele

Agent, OpenRouter Chat, Telegram Trigger +5
AI & RAG

Automate Blog Creation and Publishing with Ultra-Low Cost AI

Chain Llm, WordPress, HTTP Request +6
AI & RAG

Template Google Sheets: Click here to open

Google Sheets, HTTP Request, Chain Llm +3
AI & RAG

Complete PostgreSQL-backed system: Keyword scoring → AI research → Multi-part content generation → fal.ai Nano Banana image generation → WordPress publishing

WordPress, OpenAI, Perplexity +8