This workflow corresponds to n8n.io template #13651 — we link there as the canonical source.
This workflow follows the Emailsend → 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 →
{
"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
}
]
]
}
}
}
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.
postgressmtp
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Automates real-time market monitoring, technical analysis, AI-powered signal generation for cryptocurrencies (and stocks), filters high-confidence trades, and delivers actionable alerts via multiple channels. Runs every 5–30 minutes (configurable trigger) to catch fresh market…
Source: https://n8n.io/workflows/13651/ — 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.
Disparador 1.8. Uses itemLists, postgres, emailSend, httpRequest. Scheduled trigger; 85 nodes.
This n8n workflow runs daily to analyze active customer behavior, engineers relevant features from usage and transaction data, applies a machine learning or AI-based model to predict churn probability
This n8n workflow automates continuous compliance monitoring across IT, OT, and cloud environments by aggregating security controls, validating policies (ISO 27001, NIST, GDPR, SOC2), detecting anomal
Scheduled processes retrieve customer feedback from multiple channels. The system performs sentiment analysis to classify tone, then uses OpenAI models to extract themes, topics, and urgency indicator
Recordatorio de Citas - 24 horas antes. Uses postgres, emailSend, httpRequest. Scheduled trigger; 5 nodes.