{
  "id": "tPBS4o6KFeFMZuxJ",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "AI Trading Alert Bot",
  "tags": [],
  "nodes": [
    {
      "id": "df58effa-87e1-49b9-97ea-61f70e0df077",
      "name": "Sticky Note - Main Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2128,
        48
      ],
      "parameters": {
        "width": 820,
        "height": 720,
        "content": "## AI Trading Alert Bot\n\nAutomates market data fetching, technical analysis, and AI-powered buy/sell signal generation. Monitors multiple cryptocurrencies and stocks in real-time, analyzes price trends, and delivers actionable trading alerts.\n\n## How it works\n\n1. **Trigger** \u2014 Runs every 15 minutes or on manual trigger\n2. **Fetch Market Data** \u2014 Retrieves real-time price data from multiple sources\n3. **Technical Analysis** \u2014 Calculates indicators (RSI, MACD, Moving Averages)\n4. **AI Signal Generation** \u2014 Uses machine learning to predict buy/sell signals\n5. **Alert Processing** \u2014 Validates signals and filters false positives\n6. **Notifications** \u2014 Sends alerts via Email, Slack, and SMS\n7. **Database Storage** \u2014 Logs all signals and trade history\n\n## Setup steps\n\n1. **API Keys** \u2014 Configure CoinGecko, Alpha Vantage, or your preferred market data provider\n2. **Database** \u2014 Set up PostgreSQL table for trade history and signals\n3. **Notifications** \u2014 Configure Slack webhook, email SMTP, and SMS provider credentials\n4. **AI Model** \u2014 Replace AI endpoint with your trained model API\n5. **Trading Symbols** \u2014 Update symbol list (BTC, ETH, AAPL, GOOGL, etc.)\n6. **Test** \u2014 Run manually to verify all connections and validate signals"
      },
      "typeVersion": 1
    },
    {
      "id": "e241f436-9465-4416-987e-c1bd09529e25",
      "name": "Sticky Note - Group 1: Trigger",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1216,
        144
      ],
      "parameters": {
        "color": 3,
        "width": 468,
        "height": 465,
        "content": "## 1. Trigger\n\nAutomatically runs every 15 minutes to fetch fresh market data and generate trading signals"
      },
      "typeVersion": 1
    },
    {
      "id": "a0b528ba-0f7a-40d8-a39d-e0be3723646f",
      "name": "Sticky Note - Group 2: Data Collection",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -704,
        160
      ],
      "parameters": {
        "color": 4,
        "width": 668,
        "height": 353,
        "content": "## 2. Fetch & Prepare Data\n\nCollects real-time market data from APIs and prepares it for technical analysis in parallel"
      },
      "typeVersion": 1
    },
    {
      "id": "0a5bcdee-af88-48d6-af7c-39caad584c53",
      "name": "Sticky Note - Group 3: Analysis & AI",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -16,
        -160
      ],
      "parameters": {
        "color": 7,
        "width": 684,
        "height": 905,
        "content": "## 3. Analysis & Signal Generation\n\nCalculates technical indicators and uses AI/ML model to generate buy/sell signals with confidence scores"
      },
      "typeVersion": 1
    },
    {
      "id": "947d885d-6a03-41ed-a63e-baf777e03785",
      "name": "Sticky Note - Group 4: Alert & Execute",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        704,
        32
      ],
      "parameters": {
        "color": 6,
        "width": 960,
        "height": 697,
        "content": "## 4. Validate, Alert & Store\n\nFilters signals, sends notifications across multiple channels, logs trades, and stores in database"
      },
      "typeVersion": 1
    },
    {
      "id": "e3fc0d75-1aba-4ff4-b964-3a442811c1fc",
      "name": "Market Data Trigger - Every 15 minutes",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1088,
        352
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "*/15 * * * *"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "60e75270-eef8-440f-ae79-dd86ad82e51e",
      "name": "Fetch cryptocurrency prices from CoinGecko",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -864,
        256
      ],
      "parameters": {
        "url": "https://api.coingecko.com/api/v3/simple/price",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "d1da9648-5725-4cd0-924c-a830e03b45e3",
      "name": "Fetch stock prices from Alpha Vantage",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -864,
        448
      ],
      "parameters": {
        "url": "https://www.alphavantage.co/query",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "0472f691-42f8-42c8-9d76-bf9994a211c6",
      "name": "Combine crypto and stock market data",
      "type": "n8n-nodes-base.merge",
      "position": [
        -640,
        352
      ],
      "parameters": {
        "mode": "combine",
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "0b9f2def-882f-4cee-8045-d336f27e16c6",
      "name": "Calculate technical indicators",
      "type": "n8n-nodes-base.code",
      "position": [
        -416,
        352
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Calculate technical indicators for trading signals\nconst data = $input.item.json;\n\n// Mock historical price data (in real scenario, fetch from database)\nconst historicalPrices = {\n  'bitcoin': [42000, 42500, 41800, 43200, 43500, 42900, 43100, 43400],\n  'ethereum': [2200, 2250, 2180, 2300, 2350, 2280, 2320, 2380],\n  'AAPL': [150, 151, 149, 152, 153, 151, 152, 154],\n  'GOOGL': [100, 101, 99, 102, 103, 101, 102, 104]\n};\n\nconst currentPrice = data.price || 0;\nconst symbol = data.symbol || 'UNKNOWN';\nconst priceHistory = historicalPrices[symbol.toLowerCase()] || [currentPrice];\n\n// Calculate Simple Moving Average (SMA)\nconst calculateSMA = (prices, period) => {\n  if (prices.length < period) return null;\n  const sum = prices.slice(-period).reduce((a, b) => a + b, 0);\n  return sum / period;\n};\n\n// Calculate Exponential Moving Average (EMA)\nconst calculateEMA = (prices, period) => {\n  if (prices.length < period) return null;\n  const k = 2 / (period + 1);\n  let ema = prices.slice(0, period).reduce((a, b) => a + b, 0) / period;\n  for (let i = period; i < prices.length; i++) {\n    ema = prices[i] * k + ema * (1 - k);\n  }\n  return ema;\n};\n\n// Calculate RSI (Relative Strength Index)\nconst calculateRSI = (prices, period = 14) => {\n  if (prices.length < period + 1) return null;\n  const deltas = [];\n  for (let i = 1; i < prices.length; i++) {\n    deltas.push(prices[i] - prices[i - 1]);\n  }\n  \n  let gains = 0, losses = 0;\n  for (let i = 0; i < period; i++) {\n    if (deltas[i] > 0) gains += deltas[i];\n    else losses -= deltas[i];\n  }\n  \n  let avgGain = gains / period;\n  let avgLoss = losses / period;\n  \n  for (let i = period; i < deltas.length; i++) {\n    if (deltas[i] > 0) gains = deltas[i];\n    else gains = 0;\n    if (deltas[i] < 0) losses = -deltas[i];\n    else losses = 0;\n    avgGain = (avgGain * (period - 1) + gains) / period;\n    avgLoss = (avgLoss * (period - 1) + losses) / period;\n  }\n  \n  const rs = avgGain / (avgLoss || 1);\n  return 100 - (100 / (1 + rs));\n};\n\n// Calculate MACD (Moving Average Convergence Divergence)\nconst calculateMACD = (prices) => {\n  const ema12 = calculateEMA(prices, 12);\n  const ema26 = calculateEMA(prices, 26);\n  if (!ema12 || !ema26) return null;\n  return { macd: ema12 - ema26, signal: (ema12 - ema26) * 0.7 };\n};\n\n// Calculate Bollinger Bands\nconst calculateBollingerBands = (prices, period = 20, stdDev = 2) => {\n  if (prices.length < period) return null;\n  const sma = calculateSMA(prices, period);\n  const slice = prices.slice(-period);\n  const variance = slice.reduce((sum, p) => sum + Math.pow(p - sma, 2), 0) / period;\n  const stdev = Math.sqrt(variance);\n  return {\n    upper: sma + (stdev * stdDev),\n    middle: sma,\n    lower: sma - (stdev * stdDev)\n  };\n};\n\nconst sma50 = calculateSMA(priceHistory, 50) || calculateSMA(priceHistory, Math.min(priceHistory.length - 1, 50));\nconst sma200 = calculateSMA(priceHistory, 200) || calculateSMA(priceHistory, Math.min(priceHistory.length - 1, 200));\nconst ema12 = calculateEMA(priceHistory, 12) || calculateEMA(priceHistory, Math.min(priceHistory.length - 1, 12));\nconst rsi = calculateRSI(priceHistory) || 50;\nconst macd = calculateMACD(priceHistory) || { macd: 0, signal: 0 };\nconst bollingerBands = calculateBollingerBands(priceHistory) || { upper: currentPrice * 1.05, middle: currentPrice, lower: currentPrice * 0.95 };\n\nconst priceChange24h = data.change_24h || 0;\nconst volume24h = data.volume_24h || 0;\nconst marketCap = data.market_cap || 0;\n\nreturn {\n  json: {\n    symbol: symbol,\n    currentPrice: currentPrice,\n    priceChange24h: priceChange24h,\n    volume24h: volume24h,\n    marketCap: marketCap,\n    \n    // Technical Indicators\n    technicalIndicators: {\n      sma50: sma50 ? parseFloat(sma50.toFixed(2)) : null,\n      sma200: sma200 ? parseFloat(sma200.toFixed(2)) : null,\n      ema12: ema12 ? parseFloat(ema12.toFixed(2)) : null,\n      rsi: parseFloat(rsi.toFixed(2)),\n      macd: parseFloat(macd.macd.toFixed(2)),\n      macdSignal: parseFloat(macd.signal.toFixed(2)),\n      bollingerUpper: parseFloat(bollingerBands.upper.toFixed(2)),\n      bollingerMiddle: parseFloat(bollingerBands.middle.toFixed(2)),\n      bollingerLower: parseFloat(bollingerBands.lower.toFixed(2))\n    },\n    \n    // Trend Analysis\n    trend: {\n      shortTerm: currentPrice > sma50 ? 'BULLISH' : 'BEARISH',\n      longTerm: sma50 > sma200 ? 'BULLISH' : 'BEARISH',\n      rsiStatus: rsi > 70 ? 'OVERBOUGHT' : rsi < 30 ? 'OVERSOLD' : 'NEUTRAL',\n      macdTrend: macd.macd > macd.signal ? 'BULLISH' : 'BEARISH'\n    },\n    \n    // Timestamp\n    timestamp: new Date().toISOString(),\n    analysisDate: new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "3fac4998-d581-4eb8-915d-cef725e0ab8b",
      "name": "Call AI model for signal prediction",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -192,
        352
      ],
      "parameters": {
        "url": "https://api.example.com/ai/predict-signal",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "symbol",
              "value": "={{ $json.symbol }}"
            },
            {
              "name": "currentPrice",
              "value": "={{ $json.currentPrice }}"
            },
            {
              "name": "technicalIndicators",
              "value": "={{ $json.technicalIndicators }}"
            },
            {
              "name": "trend",
              "value": "={{ $json.trend }}"
            },
            {
              "name": "volume24h",
              "value": "={{ $json.volume24h }}"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "57960c95-154b-461f-b4c1-b4a470ded867",
      "name": "Analyze AI signals and confidence",
      "type": "n8n-nodes-base.code",
      "position": [
        32,
        352
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Analyze AI signals and calculate confidence scores\nconst aiResponse = $input.item.json;\nconst signal = aiResponse.signal || 'HOLD';\nconst confidence = aiResponse.confidence || 0.5;\nconst reasoning = aiResponse.reasoning || 'Insufficient data';\n\n// Thresholds\nconst buyThreshold = 0.65;\nconst sellThreshold = 0.65;\nconst holdConfidence = 0.5;\n\n// Determine action based on confidence\nlet action = 'HOLD';\nlet actionConfidence = 0;\nlet riskLevel = 'MEDIUM';\n\nif (signal === 'BUY' && confidence >= buyThreshold) {\n  action = 'BUY';\n  actionConfidence = confidence;\n  riskLevel = confidence > 0.85 ? 'LOW' : 'MEDIUM';\n} else if (signal === 'SELL' && confidence >= sellThreshold) {\n  action = 'SELL';\n  actionConfidence = confidence;\n  riskLevel = confidence > 0.85 ? 'LOW' : 'MEDIUM';\n} else {\n  action = 'HOLD';\n  actionConfidence = confidence;\n  riskLevel = 'LOW';\n}\n\n// Recommended position size based on confidence\nconst positionSize = action === 'HOLD' ? 0 : Math.round(actionConfidence * 100);\n\n// Alert level\nlet alertLevel = 'INFO';\nif (action !== 'HOLD' && actionConfidence > 0.80) {\n  alertLevel = 'CRITICAL';\n} else if (action !== 'HOLD' && actionConfidence > 0.70) {\n  alertLevel = 'HIGH';\n} else if (action !== 'HOLD') {\n  alertLevel = 'MEDIUM';\n}\n\nconst timestamp = new Date().toISOString();\nconst signalId = `SIG-${new Date().getTime()}-${Math.random().toString(36).substr(2, 9)}`;\n\nreturn {\n  json: {\n    signalId: signalId,\n    symbol: aiResponse.symbol,\n    currentPrice: aiResponse.currentPrice,\n    action: action,\n    confidence: parseFloat(actionConfidence.toFixed(4)),\n    riskLevel: riskLevel,\n    positionSize: positionSize,\n    alertLevel: alertLevel,\n    aiReasoning: reasoning,\n    \n    // Recommendation details\n    recommendation: {\n      action: action,\n      entryPrice: aiResponse.currentPrice,\n      targetPrice: action === 'BUY' ? aiResponse.currentPrice * 1.05 : action === 'SELL' ? aiResponse.currentPrice * 0.95 : aiResponse.currentPrice,\n      stopLoss: action === 'BUY' ? aiResponse.currentPrice * 0.98 : action === 'SELL' ? aiResponse.currentPrice * 1.02 : aiResponse.currentPrice,\n      profitTarget: action === 'BUY' ? aiResponse.currentPrice * 1.10 : action === 'SELL' ? aiResponse.currentPrice * 0.90 : aiResponse.currentPrice,\n      timeframe: '15m-1h'\n    },\n    \n    // Validation flags\n    isValidSignal: action !== 'HOLD',\n    shouldAlert: action !== 'HOLD' && actionConfidence >= holdConfidence,\n    shouldExecute: action !== 'HOLD' && actionConfidence >= 0.75,\n    \n    timestamp: timestamp,\n    originalAIResponse: aiResponse\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "617614c7-0653-4794-b391-ff61f23daf70",
      "name": "Validate signal strength and filter",
      "type": "n8n-nodes-base.filter",
      "position": [
        256,
        352
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "signal-validation",
              "operator": {
                "type": "boolean",
                "operation": "true"
              },
              "leftValue": "={{ $json.shouldAlert }}"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "6e7fe960-95fd-42de-89a6-481b0f626327",
      "name": "Store trade signal in PostgreSQL",
      "type": "n8n-nodes-base.postgres",
      "position": [
        480,
        352
      ],
      "parameters": {
        "table": "trading_signals",
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "ccb1db3e-3a2e-47f2-aa8c-3e625ab4dba5",
      "name": "Route by signal action",
      "type": "n8n-nodes-base.switch",
      "position": [
        704,
        352
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "BUY Signal",
              "conditions": {
                "options": {
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.action }}",
                    "rightValue": "BUY"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "SELL Signal",
              "conditions": {
                "options": {
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.action }}",
                    "rightValue": "SELL"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "80d775b9-32e2-4524-a10b-32c5a33ad281",
      "name": "Generate trading alert message",
      "type": "n8n-nodes-base.code",
      "position": [
        928,
        352
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Generate formatted trading alert message\nconst signal = $input.item.json;\nconst action = signal.action;\nconst emoji = action === 'BUY' ? '\ud83d\udcc8' : action === 'SELL' ? '\ud83d\udcc9' : '\u23f8\ufe0f';\n\nconst slackMessage = `${emoji} *TRADING ALERT \u2014 ${action}*\\n\\n` +\n  `*Symbol:* ${signal.symbol}\\n` +\n  `*Action:* ${action}\\n` +\n  `*Confidence:* ${(signal.confidence * 100).toFixed(1)}%\\n` +\n  `*Current Price:* \\$${signal.currentPrice.toFixed(2)}\\n\\n` +\n  `*Recommendations:*\\n` +\n  `Entry: \\$${signal.recommendation.entryPrice.toFixed(2)}\\n` +\n  `Target: \\$${signal.recommendation.targetPrice.toFixed(2)}\\n` +\n  `Stop Loss: \\$${signal.recommendation.stopLoss.toFixed(2)}\\n` +\n  `Take Profit: \\$${signal.recommendation.profitTarget.toFixed(2)}\\n\\n` +\n  `*Position Size:* ${signal.positionSize}%\\n` +\n  `*Risk Level:* ${signal.riskLevel}\\n` +\n  `*Signal ID:* ${signal.signalId}\\n` +\n  `*AI Reasoning:* ${signal.aiReasoning}\\n\\n` +\n  `*Timeframe:* ${signal.recommendation.timeframe}`;\n\nconst emailSubject = `\ud83d\ude80 ${emoji} Trading Alert: ${action} ${signal.symbol} @ ${signal.currentPrice} - ${(signal.confidence * 100).toFixed(1)}% Confidence`;\n\nconst emailBody = `\n<h2>${emoji} Trading Alert - ${action} Signal</h2>\n<p><strong>Symbol:</strong> ${signal.symbol}</p>\n<p><strong>Action:</strong> ${action}</p>\n<p><strong>Confidence:</strong> ${(signal.confidence * 100).toFixed(1)}%</p>\n<p><strong>Current Price:</strong> $${signal.currentPrice.toFixed(2)}</p>\n\n<h3>\ud83d\udcca Recommendations</h3>\n<ul>\n  <li>Entry Price: $${signal.recommendation.entryPrice.toFixed(2)}</li>\n  <li>Target Price: $${signal.recommendation.targetPrice.toFixed(2)}</li>\n  <li>Stop Loss: $${signal.recommendation.stopLoss.toFixed(2)}</li>\n  <li>Take Profit: $${signal.recommendation.profitTarget.toFixed(2)}</li>\n  <li>Position Size: ${signal.positionSize}%</li>\n  <li>Risk Level: ${signal.riskLevel}</li>\n  <li>Timeframe: ${signal.recommendation.timeframe}</li>\n</ul>\n\n<h3>\ud83e\udd16 AI Analysis</h3>\n<p>${signal.aiReasoning}</p>\n\n<p><strong>Signal ID:</strong> ${signal.signalId}</p>\n<p><strong>Generated:</strong> ${signal.timestamp}</p>\n`;\n\nconst smsMessage = `${emoji} ${action} ${signal.symbol} @ $${signal.currentPrice.toFixed(2)} - Confidence: ${(signal.confidence * 100).toFixed(1)}% - ID: ${signal.signalId}`;\n\nreturn {\n  json: {\n    ...signal,\n    alertMessages: {\n      slack: slackMessage,\n      email: {\n        subject: emailSubject,\n        body: emailBody\n      },\n      sms: smsMessage\n    }\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "4df28f21-bcf8-4a76-bfc1-ef2ba9175c7b",
      "name": "Send Slack notification",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1152,
        160
      ],
      "parameters": {
        "url": "YOUR_SLACK_WEBHOOK_URL",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"text\": \"{{ $json.action }} Signal Alert\",\n  \"blocks\": [\n    {\n      \"type\": \"section\",\n      \"text\": {\n        \"type\": \"mrkdwn\",\n        \"text\": \"{{ $json.alertMessages.slack }}\"\n      }\n    }\n  ]\n}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.2
    },
    {
      "id": "007071f0-fc96-4b3e-9f91-1a5724f162fa",
      "name": "Send Email alert",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        1152,
        352
      ],
      "parameters": {
        "html": "={{ $json.alertMessages.email.body }}",
        "options": {},
        "subject": "={{ $json.alertMessages.email.subject }}",
        "toEmail": "user@example.com",
        "fromEmail": "user@example.com"
      },
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "794e696c-8471-4c44-b5cd-af540408ed39",
      "name": "Send SMS alert (Twilio)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1152,
        544
      ],
      "parameters": {
        "url": "https://api.twilio.com/2010-04-01/Accounts/YOUR_ACCOUNT_SID/Messages.json",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "From",
              "value": "+1234567890"
            },
            {
              "name": "To",
              "value": "+1234567890"
            },
            {
              "name": "Body",
              "value": "={{ $json.alertMessages.sms }}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "79e9381e-dbe8-4e3c-8114-29e9bd56c1a7",
      "name": "Log trade execution and success",
      "type": "n8n-nodes-base.code",
      "position": [
        1376,
        352
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Log successful trade signal execution\nconst timestamp = new Date().toISOString();\nconst signal = $input.item.json;\n\nconsole.log(`\u2705 TRADE SIGNAL EXECUTED: ${signal.signalId} | ${signal.action} ${signal.symbol} @ $${signal.currentPrice} | Confidence: ${(signal.confidence * 100).toFixed(1)}% | Risk: ${signal.riskLevel} | Time: ${timestamp}`);\n\n// Cumulative statistics\nconst stats = $getWorkflowStaticData('global').stats || {\n  totalSignals: 0,\n  buySignals: 0,\n  sellSignals: 0,\n  totalAlerts: 0,\n  lastSignal: null,\n  averageConfidence: 0\n};\n\nif (signal.action === 'BUY') stats.buySignals++;\nelse if (signal.action === 'SELL') stats.sellSignals++;\nstats.totalSignals++;\nstats.totalAlerts++;\nstats.lastSignal = timestamp;\nstats.averageConfidence = (stats.averageConfidence + signal.confidence) / 2;\n\n$getWorkflowStaticData('global').stats = stats;\n\nreturn {\n  json: {\n    success: true,\n    signalId: signal.signalId,\n    action: signal.action,\n    symbol: signal.symbol,\n    currentPrice: signal.currentPrice,\n    confidence: signal.confidence,\n    timestamp: timestamp,\n    cumulativeStats: stats,\n    alertsSent: {\n      slack: true,\n      email: true,\n      sms: true\n    }\n  }\n};"
      },
      "typeVersion": 2
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "77ade8bc-49da-4a50-91ad-650b7eb95cef",
  "connections": {
    "Send Email alert": {
      "main": [
        [
          {
            "node": "Log trade execution and success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by signal action": {
      "main": [
        [
          {
            "node": "Generate trading alert message",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Generate trading alert message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send SMS alert (Twilio)": {
      "main": [
        [
          {
            "node": "Log trade execution and success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Slack notification": {
      "main": [
        [
          {
            "node": "Log trade execution and success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate technical indicators": {
      "main": [
        [
          {
            "node": "Call AI model for signal prediction",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate trading alert message": {
      "main": [
        [
          {
            "node": "Send Slack notification",
            "type": "main",
            "index": 0
          },
          {
            "node": "Send Email alert",
            "type": "main",
            "index": 0
          },
          {
            "node": "Send SMS alert (Twilio)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Store trade signal in PostgreSQL": {
      "main": [
        [
          {
            "node": "Route by signal action",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze AI signals and confidence": {
      "main": [
        [
          {
            "node": "Validate signal strength and filter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Call AI model for signal prediction": {
      "main": [
        [
          {
            "node": "Analyze AI signals and confidence",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate signal strength and filter": {
      "main": [
        [
          {
            "node": "Store trade signal in PostgreSQL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine crypto and stock market data": {
      "main": [
        [
          {
            "node": "Calculate technical indicators",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch stock prices from Alpha Vantage": {
      "main": [
        [
          {
            "node": "Combine crypto and stock market data",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Market Data Trigger - Every 15 minutes": {
      "main": [
        [
          {
            "node": "Fetch cryptocurrency prices from CoinGecko",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch stock prices from Alpha Vantage",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch cryptocurrency prices from CoinGecko": {
      "main": [
        [
          {
            "node": "Combine crypto and stock market data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}