This workflow corresponds to n8n.io template #9771 — we link there as the canonical source.
This workflow follows the Emailsend → Google Sheets 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": "50mjsFfAXxLpbQ3w",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Predict Next 5-Day Stock Trends with Twelve Data API",
"tags": [],
"nodes": [
{
"id": "6c2c2e16-b520-4af8-864a-3081f53dc594",
"name": "Daily Market Close Trigger\t",
"type": "n8n-nodes-base.cron",
"position": [
16,
144
],
"parameters": {
"triggerTimes": {
"item": [
{
"hour": 21
}
]
}
},
"typeVersion": 1
},
{
"id": "6dc56381-e0a4-498d-a98c-abf7545e862f",
"name": "Read Stock Symbols\t",
"type": "n8n-nodes-base.googleSheets",
"position": [
240,
144
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "id",
"value": "=1649252791"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "=1eO0pcfO3SFEofhUXjRy8Ps_XqfNpVnu5W8fwVSAy4Ds"
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"name": "<your credential>"
}
},
"typeVersion": 4.3
},
{
"id": "7cd655b6-edbf-4afd-84af-5465868ce748",
"name": "Set Configuration Variables\t",
"type": "n8n-nodes-base.set",
"position": [
464,
144
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "api-key-assignment",
"name": "twelvedata_api_key",
"type": "string",
"value": "=YOUR_ACTUAL_API_KEY"
},
{
"id": "symbols-assignment",
"name": "stock_symbols",
"type": "string",
"value": "={{ $json.symbol }}"
},
{
"id": "email-recipient",
"name": "email_recipient",
"type": "string",
"value": "{{ YOUR_ACTUAL_EMAIL_ADDRESS }}"
},
{
"id": "a5906884-6805-4e0a-bcad-21fe4ff7864c",
"name": "",
"type": "string",
"value": ""
}
]
}
},
"typeVersion": 3.4
},
{
"id": "c0ced112-9d1d-4714-88f6-c08e2b5be76d",
"name": "Fetch 5-Day Stock Data\t",
"type": "n8n-nodes-base.httpRequest",
"position": [
688,
144
],
"parameters": {
"url": "=https://api.twelvedata.com/time_series?symbol={{ $json.stock_symbols }}&interval=1day&outputsize=5&apikey={{ $json.twelvedata_api_key }}",
"options": {
"timeout": 30000
}
},
"typeVersion": 4.2
},
{
"id": "ce8941d6-5974-49c2-8b83-2442ba9e7ee3",
"name": "Analyze Stock Trends\t",
"type": "n8n-nodes-base.code",
"position": [
912,
144
],
"parameters": {
"jsCode": "// Process 5-day stock data and predict trends\nconst stockData = $input.first().json;\nlet processedStocks = [];\n\n// Check for API error\nif (stockData.error) {\n throw new Error(`Twelve Data API Error: ${stockData.error.message}`);\n}\n\n// Handle multiple stock responses (array of stock objects)\nconst quotes = Array.isArray(stockData) ? stockData : [stockData];\n\nfor (let stock of quotes) {\n if (stock && stock.meta && stock.values && Array.isArray(stock.values)) {\n const symbol = stock.meta.symbol;\n const currency = stock.meta.currency || stock.meta.currency_quote || 'USD';\n const prices = stock.values.map(v => parseFloat(v.close)).filter(p => !isNaN(p));\n \n // Calculate 5-day trend (simple moving average slope)\n const trendSlope = prices.length >= 2 ? (prices[0] - prices[prices.length - 1]) / prices.length : 0;\n const avgPrice = prices.length > 0 ? prices.reduce((sum, p) => sum + p, 0) / prices.length : 0;\n const predictedChange = trendSlope * 5; // Extrapolate for next 5 days\n const prediction = predictedChange > 0 ? 'Up' : predictedChange < 0 ? 'Down' : 'Neutral';\n const absPredictedChange = Math.abs(predictedChange);\n \n processedStocks.push({\n symbol: symbol,\n name: stock.meta.currency_base || stock.meta.symbol,\n currency: currency,\n five_day_data: stock.values.map(v => ({\n date: v.datetime,\n close: parseFloat(v.close) || null,\n high: parseFloat(v.high) || null,\n low: parseFloat(v.low) || null,\n volume: parseInt(v.volume) || null\n })),\n avg_price: avgPrice.toFixed(2),\n predicted_trend: prediction,\n predicted_change: absPredictedChange.toFixed(2),\n percent_change: prices.length >= 2 ? ((prices[0] - prices[prices.length - 1]) / prices[prices.length - 1] * 100).toFixed(2) : '0.00'\n });\n }\n}\n\nconst currentDate = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });\n\nreturn [{\n json: {\n date: currentDate,\n total_stocks: processedStocks.length,\n stock_analysis: processedStocks\n }\n}];"
},
"typeVersion": 2
},
{
"id": "a1c27b1a-ccb7-46c6-8cc3-6c7d043db17f",
"name": "Update Google Sheet\t",
"type": "n8n-nodes-base.googleSheets",
"position": [
1136,
64
],
"parameters": {
"columns": {
"value": {},
"schema": [],
"mappingMode": "autoMapInputData",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "id",
"value": "=juy6t543wsadv"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "=asdfvsdfcdsasdfv"
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"name": "<your credential>"
}
},
"typeVersion": 4.3
},
{
"id": "d7bc71d1-d405-4ef2-8ac3-ebb12697d705",
"name": "Format Email Report\t",
"type": "n8n-nodes-base.code",
"position": [
1136,
224
],
"parameters": {
"jsCode": "// Generate HTML Email content\nconst data = $input.first().json;\nlet htmlContent = `<!DOCTYPE html><html><head><style>body { font-family: Arial, sans-serif; margin: 20px; background-color: #f5f5f5; }.container { max-width: 600px; margin: 0 auto; background: white; padding: 20px; border-radius: 10px; }.header { text-align: center; border-bottom: 2px solid #007bff; padding-bottom: 10px; }.section { margin-bottom: 20px; }.stock-table { width: 100%; border-collapse: collapse; }.stock-table th, .stock-table td { padding: 10px; text-align: left; border-bottom: 1px solid #ddd; }.stock-table th { background-color: #f8f9fa; }.gain { color: #28a745; }.loss { color: #dc3545; }.symbol { font-weight: bold; color: #007bff; }</style></head><body><div class=\"container\"><div class=\"header\"><h2>\ud83d\udcc8 Stock Trend Analysis Report</h2><p><strong>Date:</strong> ${data.date}</p></div><div class=\"section\"><h3>Stock Analysis (Last 5 Days & Predictions)</h3><table class=\"stock-table\"><thead><tr><th>Symbol</th><th>Avg Price</th><th>5-Day % Change</th><th>Predicted Trend</th><th>Predicted Change ($)</th></tr></thead><tbody>`;\ndata.stock_analysis.forEach(stock => {\n htmlContent += `<tr><td class=\"symbol\">${stock.symbol}</td><td>$${stock.avg_price}</td><td class=\"${stock.percent_change > 0 ? 'gain' : 'loss'}\">${stock.percent_change}%</td><td>${stock.predicted_trend}</td><td>$${stock.predicted_change}</td></tr>`;\n});\nhtmlContent += `</tbody></table></div><div style=\"text-align: center; margin-top: 20px; color: #666;\"><p>\u26a1 Generated by Stock Trend Predictor</p><p><small>Data provided by Twelve Data API</small></p></div></body></html>`;\nconst plainText = `STOCK TREND ANALYSIS REPORT\\nDate: ${data.date}\\nStocks Analyzed: ${data.total_stocks}\\n\\nSTOCK ANALYSIS:\\n${data.stock_analysis.map((stock, i) => `${i+1}. ${stock.symbol}: Avg $${stock.avg_price}, 5-Day Change: ${stock.percent_change}%, Predicted Trend: ${stock.predicted_trend} ($${stock.predicted_change})`).join('\\n')}\\n\\nGenerated by Stock Trend Predictor`;\nreturn [{ json: { email_html: htmlContent, email_text: plainText, email_subject: `Stock Trend Report - ${data.date}` } }];"
},
"typeVersion": 2
},
{
"id": "c57230f1-5204-4d8c-9d79-e46d3f4c7663",
"name": "Send Email Report\t",
"type": "n8n-nodes-base.emailSend",
"position": [
1360,
224
],
"parameters": {
"html": "={{ $json.email_html }}",
"options": {},
"subject": "={{ $json.email_subject }}",
"toEmail": "=abc@gmail.com",
"fromEmail": "user@example.com",
"emailFormat": "html"
},
"credentials": {
"smtp": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "32f22649-c65d-40a0-bf3c-9855dc759090",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
0
],
"parameters": {
"width": 160,
"height": 300,
"content": "Triggers daily at 9:00 PM (after market close) Monday-Friday.\n"
},
"typeVersion": 1
},
{
"id": "4fb6d2c7-a176-4061-ab77-59f3f3cf9346",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
208,
0
],
"parameters": {
"color": 3,
"width": 170,
"height": 300,
"content": "Reads stock symbols from Google Sheet.\n"
},
"typeVersion": 1
},
{
"id": "9541a2ed-f97d-4d28-8b34-98bcd51e0155",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
416,
0
],
"parameters": {
"color": 4,
"width": 170,
"height": 300,
"content": "Sets API key and stock symbols.\n"
},
"typeVersion": 1
},
{
"id": "e8055a14-a549-4433-b4cb-c4424eec657b",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
640,
0
],
"parameters": {
"color": 5,
"width": 170,
"height": 300,
"content": "Fetches 5-day stock data from Twelve Data API.\n"
},
"typeVersion": 1
},
{
"id": "fc86755b-d63c-4546-9147-05356ca4fc9b",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
864,
0
],
"parameters": {
"color": 6,
"width": 170,
"height": 300,
"content": "Analyzes trends and predicts next 5-day movement.\n"
},
"typeVersion": 1
},
{
"id": "36bcd40b-c972-4428-86e7-7b1d05e3fe94",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1104,
0
],
"parameters": {
"color": 2,
"width": 170,
"height": 300,
"content": "Updates Google Sheet and sends email report.\n"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "f7ed1f84-39d4-42f1-b857-bc78d3ee4454",
"connections": {
"Read Stock Symbols\t": {
"main": [
[
{
"node": "Set Configuration Variables\t",
"type": "main",
"index": 0
}
]
]
},
"Format Email Report\t": {
"main": [
[
{
"node": "Send Email Report\t",
"type": "main",
"index": 0
}
]
]
},
"Analyze Stock Trends\t": {
"main": [
[
{
"node": "Update Google Sheet\t",
"type": "main",
"index": 0
},
{
"node": "Format Email Report\t",
"type": "main",
"index": 0
}
]
]
},
"Fetch 5-Day Stock Data\t": {
"main": [
[
{
"node": "Analyze Stock Trends\t",
"type": "main",
"index": 0
}
]
]
},
"Daily Market Close Trigger\t": {
"main": [
[
{
"node": "Read Stock Symbols\t",
"type": "main",
"index": 0
}
]
]
},
"Set Configuration Variables\t": {
"main": [
[
{
"node": "Fetch 5-Day Stock Data\t",
"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.
googleApismtp
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This automated n8n workflow fetches stock data from the Twelve Data API after market close, predicts 5-day trends using AI analysis, updates Google Sheets with the results, and sends an email summary report. This process helps users stay informed about stock movements and make…
Source: https://n8n.io/workflows/9771/ — 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.
Security teams, DevOps engineers, vulnerability analysts, and automation builders who want to eliminate repetitive Nessus scan parsing, AI-based risk triage, and manual reporting. Designed for orgs fo
This n8n workflow automatically finds apartments for rent in Germany, filters them by your city, rent budget, and number of rooms, and applies to them via email. Each application includes: A personali
👤 Who it’s for Blue Team leads, CISOs, and SOC managers who want automated visibility into threat metrics, endpoint alerts, and response actions — without needing a full SIEM or BI platform.
Workflow Overview Zoom Attendance Evaluator with Follow-up is an n8n automation workflow that automatically evaluates Zoom meeting attendance and sends follow-up emails to no-shows and early leavers w
This workflow automatically monitors Amazon product prices, tracks price changes, and sends alerts when significant price fluctuations occur. Built with ScrapeOps' structured data API, it provides a r