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 →
{
"name": "My workflow",
"nodes": [
{
"parameters": {
"url": "=https://query1.finance.yahoo.com/v8/finance/chart/{{$json.symbol}}?interval=1d&range=200d",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
464,
-192
],
"id": "1caaa07f-edb7-440b-b8fa-7420ef65f546",
"name": "HTTP Request"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "a49c1fca-1396-4263-bf57-c2582ba5b557",
"leftValue": "={{ $json.isTriggered }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
912,
-192
],
"id": "56225452-2035-487e-9940-5dd83adfaeb0",
"name": "If"
},
{
"parameters": {
"method": "POST",
"url": "https://api.pushbullet.com/v2/pushes",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Access-Token",
"value": "o.9WQZfu7zv2N5cU0g0FwMTWNCau0Xd2Ya"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "type",
"value": "=note"
},
{
"name": "title",
"value": "=\u0e2b\u0e38\u0e49\u0e19 {{ $json.symbol }} \u0e40\u0e02\u0e49\u0e32\u0e40\u0e07\u0e37\u0e48\u0e2d\u0e19\u0e44\u0e02!"
},
{
"name": "body",
"value": "=\u0e23\u0e32\u0e04\u0e32: {{ $json.price }} US | RSI: {{ $json.rsi }}"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
1136,
-128
],
"id": "d876eb43-4cee-4540-85ac-152aa785f42e",
"name": "HTTP Request1"
},
{
"parameters": {},
"type": "n8n-nodes-base.wait",
"typeVersion": 1.1,
"position": [
240,
-192
],
"id": "b3c733c7-8cfe-4653-baa6-77de58cfe339",
"name": "Wait"
},
{
"parameters": {
"jsCode": "return [\n { json: { symbol: \"NFLX\" } },\n { json: { symbol: \"VTI\" } },\n { json: { symbol: \"VOO\" } },\n { json: { symbol: \"QQQM\" } },\n { json: { symbol: \"JEPQ\" } },\n { json: { symbol: \"NVDA\" } },\n { json: { symbol: \"ASML\" } },\n { json: { symbol: \"TSM\" } },\n];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-208,
-48
],
"id": "08fb22f9-6871-4233-b0ad-ef1e11de6857",
"name": "List Stocks"
},
{
"parameters": {
"options": {}
},
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
16,
-192
],
"id": "908d7a0e-4f24-4299-9569-c3ead1644d8a",
"name": "Loop Over Items"
},
{
"parameters": {
"jsCode": "// 1. \u0e43\u0e19\u0e42\u0e2b\u0e21\u0e14 Run Once For Each Item \u0e40\u0e23\u0e32\u0e08\u0e30\u0e43\u0e0a\u0e49 $input.item.json \u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e14\u0e36\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e02\u0e2d\u0e07 \"\u0e23\u0e2d\u0e1a\u0e19\u0e31\u0e49\u0e19\u0e46\"\nconst inputData = $input.item.json;\n\n// \u0e15\u0e23\u0e27\u0e08\u0e2a\u0e2d\u0e1a\u0e27\u0e48\u0e32\u0e21\u0e35\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e08\u0e32\u0e01 Yahoo Finance \u0e2b\u0e23\u0e37\u0e2d\u0e44\u0e21\u0e48\nif (!inputData || !inputData.chart || !inputData.chart.result) {\n return { json: { error: \"Data missing for this item\" } };\n}\n\nconst results = inputData.chart.result[0];\nconst symbol = results.meta.symbol;\nconst prices = results.indicators.quote[0].close.filter(p => p !== null);\n\n// 2. \u0e1f\u0e31\u0e07\u0e01\u0e4c\u0e0a\u0e31\u0e19\u0e04\u0e33\u0e19\u0e27\u0e13 SMA\nconst getSMA = (arr, window) => {\n if (arr.length < window) return null;\n return arr.slice(-window).reduce((a, b) => a + b, 0) / window;\n};\n\n// 3. \u0e1f\u0e31\u0e07\u0e01\u0e4c\u0e0a\u0e31\u0e19\u0e04\u0e33\u0e19\u0e27\u0e13 RSI\nconst getRSI = (arr, period = 14) => {\n if (arr.length <= period) return null;\n let gains = 0, losses = 0;\n for (let i = arr.length - period; i < arr.length; i++) {\n let diff = arr[i] - arr[i - 1];\n if (diff >= 0) gains += diff; else losses -= diff;\n }\n let rs = gains / (losses || 1);\n return 100 - (100 / (1 + rs));\n};\n\n// 4. \u0e04\u0e33\u0e19\u0e27\u0e13\u0e04\u0e48\u0e32\nconst currentPrice = prices[prices.length - 1];\nconst ma30 = getSMA(prices, 30);\nconst ma60 = getSMA(prices, 60);\nconst ma120 = getSMA(prices, 120);\nconst rsi = getRSI(prices, 14);\n\n// 5. \u0e15\u0e23\u0e27\u0e08\u0e2a\u0e2d\u0e1a\u0e40\u0e07\u0e37\u0e48\u0e2d\u0e19\u0e44\u0e02\nconst isHitMA = (currentPrice <= ma30 || currentPrice <= ma60 || currentPrice <= ma120);\nconst isRsiLow = (rsi !== null && rsi < 40);\n\n// \u0e2a\u0e48\u0e07\u0e2d\u0e2d\u0e01\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e17\u0e35\u0e25\u0e30 Item\nreturn {\n json: {\n symbol: symbol,\n price: currentPrice.toFixed(2),\n rsi: rsi ? rsi.toFixed(2) : \"N/A\",\n isTriggered: (isHitMA && isRsiLow)\n }\n};"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
688,
-192
],
"id": "5dabfc51-93f9-43d2-9493-25ac030384ad",
"name": "Code in JavaScript"
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "hours"
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.3,
"position": [
-432,
-48
],
"id": "4a083f80-6183-492d-93dc-b18c4a6ac35e",
"name": "Schedule Trigger2"
}
],
"connections": {
"HTTP Request": {
"main": [
[
{
"node": "Code in JavaScript",
"type": "main",
"index": 0
}
]
]
},
"If": {
"main": [
[
{
"node": "HTTP Request1",
"type": "main",
"index": 0
}
],
[
{
"node": "List Stocks",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request1": {
"main": [
[
{
"node": "List Stocks",
"type": "main",
"index": 0
}
]
]
},
"Wait": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"List Stocks": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[],
[
{
"node": "Wait",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger2": {
"main": [
[
{
"node": "List Stocks",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1",
"binaryMode": "separate",
"availableInMCP": false,
"timeSavedMode": "fixed",
"timezone": "Asia/Bangkok",
"callerPolicy": "workflowsFromSameOwner"
},
"versionId": "4d2c5068-b7f5-4c90-b910-2c73b46dd79b",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "QHLMWgDw1wBEKYFskliME",
"tags": []
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Track-Stocks. Uses httpRequest. Scheduled trigger; 8 nodes.
Source: https://gitlab.com/James28Dev/n8n-workflow-automation/-/blob/main/track-stocks.json — 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.
Birthday Automation - Production (Fixed). Uses stopAndError, httpRequest, emailSend, bannerbear. Scheduled trigger; 86 nodes.
This template runs two scheduled workflows to govern Microsoft Entra ID (Azure AD) guest accounts by detecting stale users via Microsoft Graph, staging deletions in SharePoint with a 72-hour window, n
Jira-Allure-Auto-Qa. Uses httpRequest, jira. Scheduled trigger; 68 nodes.
Spotify-Sync-Surrealdb-V1. Uses httpRequest, n8n-nodes-surrealdb, spotify. Scheduled trigger; 62 nodes.
As n8n instances scale, teams often lose track of sub-workflows—who uses them, where they are referenced, and whether they can be safely updated. This leads to inefficiencies like unnecessary copies o