Created
October 22, 2025 16:34
-
-
Save vitqst/1017f9841f5d5fd27689ccec062de06a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "name": "Layer 1 - BB Trend Detection", | |
| "nodes": [ | |
| { | |
| "parameters": { | |
| "rule": { | |
| "interval": [ | |
| { | |
| "field": "cronExpression", | |
| "expression": "*/1 * * * *" | |
| } | |
| ] | |
| } | |
| }, | |
| "id": "schedule-trigger-1min", | |
| "name": "Every 1 Minute", | |
| "type": "n8n-nodes-base.scheduleTrigger", | |
| "typeVersion": 1.2, | |
| "position": [250, 300] | |
| }, | |
| { | |
| "parameters": { | |
| "assignments": { | |
| "assignments": [ | |
| { | |
| "id": "symbol-config", | |
| "name": "symbol", | |
| "value": "BTCUSDT", | |
| "type": "string" | |
| }, | |
| { | |
| "id": "bb-period", | |
| "name": "bb_period", | |
| "value": 20, | |
| "type": "number" | |
| }, | |
| { | |
| "id": "bb-deviation", | |
| "name": "bb_deviation", | |
| "value": 2, | |
| "type": "number" | |
| }, | |
| { | |
| "id": "volume-multiplier", | |
| "name": "volume_multiplier", | |
| "value": 1.5, | |
| "type": "number" | |
| } | |
| ] | |
| } | |
| }, | |
| "id": "config-node", | |
| "name": "Configuration", | |
| "type": "n8n-nodes-base.set", | |
| "typeVersion": 3.4, | |
| "position": [470, 300] | |
| }, | |
| { | |
| "parameters": { | |
| "method": "GET", | |
| "url": "=https://api.binance.com/api/v3/klines", | |
| "authentication": "none", | |
| "sendQuery": true, | |
| "queryParameters": { | |
| "parameters": [ | |
| { | |
| "name": "symbol", | |
| "value": "={{ $json.symbol }}" | |
| }, | |
| { | |
| "name": "interval", | |
| "value": "1m" | |
| }, | |
| { | |
| "name": "limit", | |
| "value": "50" | |
| } | |
| ] | |
| }, | |
| "options": {} | |
| }, | |
| "id": "binance-1m-klines", | |
| "name": "Binance 1m Klines", | |
| "type": "n8n-nodes-base.httpRequest", | |
| "typeVersion": 4.2, | |
| "position": [690, 300] | |
| }, | |
| { | |
| "parameters": { | |
| "mode": "runOnceForAllItems", | |
| "language": "javaScript", | |
| "jsCode": "// Get configuration from previous node\nconst config = $input.first().json;\nconst symbol = config.symbol;\nconst bb_period = config.bb_period || 20;\nconst bb_deviation = config.bb_deviation || 2;\nconst volume_multiplier = config.volume_multiplier || 1.5;\n\n// Get klines data from Binance\nconst klines = $input.item.json;\n\n// Parse klines data\nconst candles = klines.map(k => ({\n openTime: k[0],\n open: parseFloat(k[1]),\n high: parseFloat(k[2]),\n low: parseFloat(k[3]),\n close: parseFloat(k[4]),\n volume: parseFloat(k[5]),\n closeTime: k[6]\n}));\n\n// Calculate Bollinger Bands\nfunction calculateBollingerBands(prices, period, deviation) {\n const result = [];\n \n for (let i = period - 1; i < prices.length; i++) {\n // Calculate SMA (Simple Moving Average)\n const slice = prices.slice(i - period + 1, i + 1);\n const sma = slice.reduce((sum, val) => sum + val, 0) / period;\n \n // Calculate Standard Deviation\n const squaredDiffs = slice.map(val => Math.pow(val - sma, 2));\n const variance = squaredDiffs.reduce((sum, val) => sum + val, 0) / period;\n const stdDev = Math.sqrt(variance);\n \n // Calculate bands\n const upperBand = sma + (deviation * stdDev);\n const lowerBand = sma - (deviation * stdDev);\n const middleBand = sma;\n \n result.push({\n index: i,\n upperBand,\n middleBand,\n lowerBand,\n stdDev\n });\n }\n \n return result;\n}\n\n// Extract close prices\nconst closePrices = candles.map(c => c.close);\nconst volumes = candles.map(c => c.volume);\n\n// Calculate BB values\nconst bbValues = calculateBollingerBands(closePrices, bb_period, bb_deviation);\n\n// Get current (latest) values\nconst currentCandle = candles[candles.length - 1];\nconst previousCandle = candles[candles.length - 2];\nconst currentBB = bbValues[bbValues.length - 1];\nconst previousBB = bbValues[bbValues.length - 2];\n\n// Calculate average volume\nconst recentVolumes = volumes.slice(-bb_period);\nconst avgVolume = recentVolumes.reduce((sum, v) => sum + v, 0) / bb_period;\nconst volumeSurge = currentCandle.volume > (avgVolume * volume_multiplier);\n\n// Detect BB cross and trend\nlet signal = null;\nlet crossType = null;\n\n// Check for LONG signal (price crosses below lower band)\nif (previousCandle.close > previousBB.lowerBand && \n currentCandle.close < currentBB.lowerBand &&\n volumeSurge) {\n signal = 'LONG';\n crossType = 'BB_LOWER_CROSS';\n}\n\n// Check for SHORT signal (price crosses above upper band)\nif (previousCandle.close < previousBB.upperBand && \n currentCandle.close > currentBB.upperBand &&\n volumeSurge) {\n signal = 'SHORT';\n crossType = 'BB_UPPER_CROSS';\n}\n\n// Return result\nreturn [{\n json: {\n layer: 1,\n symbol: symbol,\n timeframe: '1m',\n timestamp: currentCandle.closeTime,\n signal: signal,\n crossType: crossType,\n price: {\n current: currentCandle.close,\n open: currentCandle.open,\n high: currentCandle.high,\n low: currentCandle.low\n },\n bollingerBands: {\n upper: currentBB.upperBand,\n middle: currentBB.middleBand,\n lower: currentBB.lowerBand,\n stdDev: currentBB.stdDev\n },\n volume: {\n current: currentCandle.volume,\n average: avgVolume,\n multiplier: (currentCandle.volume / avgVolume).toFixed(2),\n surge: volumeSurge\n },\n conditions: {\n bb_cross: signal !== null,\n volume_confirmed: volumeSurge,\n ready_for_layer2: signal !== null && volumeSurge\n }\n }\n}];" | |
| }, | |
| "id": "calculate-bb-volume", | |
| "name": "Calculate BB + Volume", | |
| "type": "n8n-nodes-base.code", | |
| "typeVersion": 2, | |
| "position": [910, 300] | |
| }, | |
| { | |
| "parameters": { | |
| "conditions": { | |
| "options": { | |
| "caseSensitive": true, | |
| "leftValue": "", | |
| "typeValidation": "strict" | |
| }, | |
| "conditions": [ | |
| { | |
| "id": "signal-exists", | |
| "leftValue": "={{ $json.signal }}", | |
| "rightValue": "", | |
| "operator": { | |
| "type": "string", | |
| "operation": "notEmpty" | |
| } | |
| }, | |
| { | |
| "id": "volume-confirmed", | |
| "leftValue": "={{ $json.volume.surge }}", | |
| "rightValue": true, | |
| "operator": { | |
| "type": "boolean", | |
| "operation": "true" | |
| } | |
| } | |
| ], | |
| "combinator": "and" | |
| }, | |
| "options": {} | |
| }, | |
| "id": "check-signal-conditions", | |
| "name": "Check Signal Conditions", | |
| "type": "n8n-nodes-base.if", | |
| "typeVersion": 2.1, | |
| "position": [1130, 300] | |
| }, | |
| { | |
| "parameters": { | |
| "assignments": { | |
| "assignments": [ | |
| { | |
| "id": "layer1-complete", | |
| "name": "layer1_status", | |
| "value": "SIGNAL_DETECTED", | |
| "type": "string" | |
| }, | |
| { | |
| "id": "proceed-layer2", | |
| "name": "proceed_to_layer2", | |
| "value": true, | |
| "type": "boolean" | |
| }, | |
| { | |
| "id": "alert-message", | |
| "name": "alert_message", | |
| "value": "=Layer 1: {{ $json.signal }} signal detected for {{ $json.symbol }} at {{ $json.price.current }}. BB Cross: {{ $json.crossType }}. Volume surge: {{ $json.volume.multiplier }}x average.", | |
| "type": "string" | |
| } | |
| ] | |
| } | |
| }, | |
| "id": "signal-detected", | |
| "name": "Signal Detected ✅", | |
| "type": "n8n-nodes-base.set", | |
| "typeVersion": 3.4, | |
| "position": [1350, 200] | |
| }, | |
| { | |
| "parameters": { | |
| "assignments": { | |
| "assignments": [ | |
| { | |
| "id": "no-signal", | |
| "name": "layer1_status", | |
| "value": "NO_SIGNAL", | |
| "type": "string" | |
| }, | |
| { | |
| "id": "no-proceed", | |
| "name": "proceed_to_layer2", | |
| "value": false, | |
| "type": "boolean" | |
| }, | |
| { | |
| "id": "no-alert", | |
| "name": "alert_message", | |
| "value": "=Layer 1: No signal for {{ $json.symbol }}. Current price: {{ $json.price.current }}", | |
| "type": "string" | |
| } | |
| ] | |
| } | |
| }, | |
| "id": "no-signal-detected", | |
| "name": "No Signal ❌", | |
| "type": "n8n-nodes-base.set", | |
| "typeVersion": 3.4, | |
| "position": [1350, 400] | |
| } | |
| ], | |
| "connections": { | |
| "Every 1 Minute": { | |
| "main": [ | |
| [ | |
| { | |
| "node": "Configuration", | |
| "type": "main", | |
| "index": 0 | |
| } | |
| ] | |
| ] | |
| }, | |
| "Configuration": { | |
| "main": [ | |
| [ | |
| { | |
| "node": "Binance 1m Klines", | |
| "type": "main", | |
| "index": 0 | |
| } | |
| ] | |
| ] | |
| }, | |
| "Binance 1m Klines": { | |
| "main": [ | |
| [ | |
| { | |
| "node": "Calculate BB + Volume", | |
| "type": "main", | |
| "index": 0 | |
| } | |
| ] | |
| ] | |
| }, | |
| "Calculate BB + Volume": { | |
| "main": [ | |
| [ | |
| { | |
| "node": "Check Signal Conditions", | |
| "type": "main", | |
| "index": 0 | |
| } | |
| ] | |
| ] | |
| }, | |
| "Check Signal Conditions": { | |
| "main": [ | |
| [ | |
| { | |
| "node": "Signal Detected ✅", | |
| "type": "main", | |
| "index": 0 | |
| } | |
| ], | |
| [ | |
| { | |
| "node": "No Signal ❌", | |
| "type": "main", | |
| "index": 0 | |
| } | |
| ] | |
| ] | |
| } | |
| }, | |
| "pinData": {} | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment