{
  "id": "rKiTRgIQKUlss7fk",
  "meta": {
    "templateId": "8594",
    "templateCredsSetupCompleted": true
  },
  "name": "Smart Stock Trading Recommendations with GPT-4, TwelveData & NewsAPI Analysis",
  "tags": [],
  "nodes": [
    {
      "id": "e58d9c28-2f7f-4332-ab99-1431a2f1b68a",
      "name": "When chat message received",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "position": [
        112,
        288
      ],
      "parameters": {
        "options": {
          "responseMode": "responseNodes"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "d89ad9e2-7a74-44ff-b889-7cf8435f4481",
      "name": "4h trend",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        944,
        0
      ],
      "parameters": {
        "url": "https://api.twelvedata.com/time_series",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "symbol",
              "value": "={{ $json.message.content }}"
            },
            {
              "name": "interval",
              "value": "4h"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "bbce42d7-e50e-4b9e-a168-a0f2f68af753",
      "name": "1day trend",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        944,
        192
      ],
      "parameters": {
        "url": "https://api.twelvedata.com/time_series",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "symbol",
              "value": "={{ $json.message.content }}"
            },
            {
              "name": "interval",
              "value": "1day"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "27d3fd72-380f-412e-b004-bcf101af280d",
      "name": "1week trend",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        944,
        416
      ],
      "parameters": {
        "url": "https://api.twelvedata.com/time_series",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "symbol",
              "value": "={{ $json.message.content }}"
            },
            {
              "name": "interval",
              "value": "1week"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "0f22b55e-8c91-4694-9fde-8810d016fce6",
      "name": "Get News",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1568,
        640
      ],
      "parameters": {
        "url": "https://newsapi.org/v2/everything",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "q",
              "value": "={{ $('Convert to Stock Symbol').item.json.message.content }}"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "344af493-dad1-48f9-bdbe-d7754ca9c47e",
      "name": "News Sentiment Analyzer",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        1840,
        576
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini",
          "cachedResultName": "GPT-4.1-MINI"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=Analyze the following text and produce your JSON output: {{ JSON.stringify($json.articles) }}"
            },
            {
              "role": "system",
              "content": "=You are a financial market impact analyst. Your job is not to analyze the emotional tone of the text, but to predict the likely short-term impact on the stock price.\n\nRules for Analysis:\n1. MARKET IMPACT vs. EMOTION: Distinguish between news that is \"bad\" for society (e.g., layoffs, lawsuits) but potentially \"good\" or \"neutral\" for the stock price (e.g., cost reduction, settlement priced in).\n2. SCORE: Assign a score from -1.0 (Strong Sell Pressure) to +1.0 (Strong Buy Pressure).\n   - 0 is for neutral news or noise.\n   - High scores (>0.7) require concrete catalysts (earnings beat, new product, upgrades).\n3. RATIONALE: Be extremely concise. Focus on the \"Why\" regarding price movement.\n\nOutput strictly valid JSON:\n{\n  \"category\": \"Bullish\" | \"Bearish\" | \"Neutral\",\n  \"score\": number, // between -1.0 and 1.0\n  \"rationale\": \"string\" // Max 1 sentence explaining the price impact.\n}"
            }
          ]
        },
        "jsonOutput": true
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "fb4954a2-9203-4574-8332-2053ec97c3bb",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        1392,
        224
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "905c0187-c652-468e-9081-bff1cfde5b2f",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        1232,
        224
      ],
      "parameters": {
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "d7d5bb3f-8364-4cb7-9653-1ebf30d037c9",
      "name": "Technical Data AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2768,
        384
      ],
      "parameters": {
        "text": "==Analyze this stock: {{ $('Convert to Stock Symbol').item.json.message.content }}\n\n### 1. TECHNICAL DATA:\n{{ JSON.stringify($('Code').item.json.candles) }}\n\n### 2. NEWS SENTIMENT (24h Context):\n* **Category:** {{ $json.data[1].message.content.category }}\n* **Score:** {{ $json.data[1].message.content.score }} (Scale: -1 to +1)\n* **Rationale:** {{ $json.data[1].message.content.rationale }}\n\n### 3. LIVE & VISUAL TASKS:\n* Use `Get Stock Sentiment` to find the *very latest* rumors or earnings news for **{{ $('Convert to Stock Symbol').item.json.message.content }}**.\n* Use `Get Chart Image` to display the chart for **{{ $('Convert to Stock Symbol').item.json.message.content }}**.\n\nBased on the above, provide your recommendation.",
        "options": {
          "systemMessage": "=You are a Senior Quantitative Strategist at a top-tier hedge fund. Your goal is to synthesize technical data, news sentiment, and live market context to produce a high-probability trade setup.\n\n### OPERATIONAL PROTOCOL (Must Follow Order):\n1. **LIVE SENTIMENT CHECK (Mandatory):**\n   - You MUST use the `Get Stock Sentiment` tool immediately to check for real-time catalysts (e.g., Earnings calls today, Fed speeches, Breaking rumors) that older news might have missed.\n   - *Reasoning:* Technicals fail during high-impact news events.\n\n2. **VISUAL CONFIRMATION (Mandatory):**\n   - You MUST use the `Get Chart Image` tool to render the 1-week chart.\n   - Analyze the visual trend to confirm your numeric data.\n\n3. **SYNTHESIS & DECISION:**\n   - **Bullish Signal:** Requires Price > 20-Day MA AND (News Score > 0.2 OR Live Sentiment is Positive).\n   - **Bearish Signal:** Requires Price < 20-Day MA AND (News Score < -0.2 OR Live Sentiment is Negative).\n   - **Neutral/Hold:** If Technicals conflict with Sentiment (e.g., Uptrending price but bad news), default to HOLD unless the risk/reward is > 1:3.\n\n4. **RISK MANAGEMENT:**\n   - Stop Loss: MUST be below Support (for Buy) or above Resistance (for Sell).\n   - Target: Must offer at least 2.0x reward relative to risk.\n\n### OUTPUT FORMAT (Strict Markdown):\nDo not output generic text. Use this exact structure:\n\n##Analysis: [Symbol]\n**The Verdict:** [BUY / SELL / HOLD] (Confidence: X/10)\n\n**Rationale:**\n* **Technical Reality:** [1 sentence on the trend/MAs]\n* **Sentiment Context:** [1 sentence integrating NewsAPI + Live Perplexity findings]\n* **Conflict Resolution:** [Explain how you weighed conflicting signals, if any]\n\n**Trade Setup:**\n* **Entry Zone:** [Price]\n* **Stop Loss:** [Price]\n* **Target:** [Price]\n* **Risk/Reward:** [Ratio]\n\n[The Chart Image Tool output will appear here automatically]"
        },
        "promptType": "define"
      },
      "typeVersion": 2.2
    },
    {
      "id": "09d9912b-cdbb-41ac-9f5b-2d92cadddb9e",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2576,
        592
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o",
          "cachedResultName": "gpt-4o"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "36d679d0-5b6d-4c2e-873b-1c0822093a84",
      "name": "Code",
      "type": "n8n-nodes-base.code",
      "position": [
        1904,
        128
      ],
      "parameters": {
        "jsCode": "// n8n Code Node for transforming stock data\n\n// Get the input data - handle different possible structures\nlet inputData;\n\nif ($input.all()[0].json.data && Array.isArray($input.all()[0].json.data)) {\n  // If data is already an array\n  inputData = $input.all()[0].json.data;\n} else if ($input.all()[0].json.data[0] && $input.all()[0].json.data[0].data) {\n  // If data has nested data property\n  inputData = $input.all()[0].json.data[0].data;\n} else {\n  // Try the raw input\n  inputData = $input.all()[0].json;\n}\n\n// Log for debugging (remove after testing)\nconsole.log(\"Input structure:\", JSON.stringify(inputData).substring(0, 200));\n\nif (!Array.isArray(inputData) || inputData.length === 0) {\n  throw new Error(\"Could not find valid data array in input\");\n}\n\nconst output = {\n  stock_symbol: inputData[0].meta.symbol,\n  candles: {\n    \"4h\": [],\n    \"1day\": [],\n    \"1week\": []\n  }\n};\n\n// Process each interval type\ninputData.forEach(intervalData => {\n  const interval = intervalData.meta.interval;\n  \n  if (output.candles[interval]) {\n    intervalData.values.forEach(candle => {\n      output.candles[interval].push({\n        datetime: candle.datetime,\n        open: parseFloat(candle.open),\n        close: parseFloat(candle.close),\n        high: parseFloat(candle.high),\n        low: parseFloat(candle.low),\n        volume: parseInt(candle.volume)\n      });\n    });\n  }\n});\n\nreturn output;"
      },
      "typeVersion": 2
    },
    {
      "id": "e1b272a7-2de0-47cd-a7ed-66adee5205f4",
      "name": "Think",
      "type": "@n8n/n8n-nodes-langchain.toolThink",
      "position": [
        2784,
        640
      ],
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "64480805-811b-4ab3-871e-13cee359226a",
      "name": "Get Stock Sentiment",
      "type": "n8n-nodes-base.perplexityTool",
      "position": [
        2944,
        656
      ],
      "parameters": {
        "options": {},
        "messages": {
          "message": [
            {
              "content": "=Give me recent sentiment about this stock: {{ $('When chat message received').item.json.chatInput }}"
            }
          ]
        },
        "requestOptions": {}
      },
      "credentials": {
        "perplexityApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "799885b8-c23b-44f3-a0d3-ac2a31051230",
      "name": "Check Twelvedata API Success",
      "type": "n8n-nodes-base.switch",
      "position": [
        1616,
        224
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Success",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "24b4ab24-3435-42a1-8a43-80c32f41b938",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $('4h trend').item.json.status }}",
                    "rightValue": "ok"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Error",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "df95719f-22f3-4af3-9886-f3dfae4fde71",
                    "operator": {
                      "type": "string",
                      "operation": "notEquals"
                    },
                    "leftValue": "={{ $('4h trend').item.json.status }}",
                    "rightValue": "ok"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "8a313633-398e-454c-8f18-bb4b2a665fd1",
      "name": "Get Chart Image for Stock",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        3392,
        768
      ],
      "parameters": {
        "url": "https://api.chart-img.com/v2/tradingview/advanced-chart/storage",
        "method": "POST",
        "options": {
          "response": {}
        },
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "height",
              "value": "300"
            },
            {
              "name": "theme",
              "value": "dark"
            },
            {
              "name": "interval",
              "value": "1W"
            },
            {
              "name": "style",
              "value": "baseline"
            },
            {
              "name": "symbol",
              "value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('parameters4_Value', `set tradingview symbol EXCHANGE:SYMBOL. Example - NASDAQ:MSFT`, 'string') }}"
            }
          ]
        },
        "genericAuthType": "httpHeaderAuth",
        "toolDescription": "Get Chart Image for a Stock for the last 1 week"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "ced4c850-4182-451c-ba54-7c4bc00d40a3",
      "name": "Respond with Error",
      "type": "@n8n/n8n-nodes-langchain.chat",
      "position": [
        1904,
        368
      ],
      "parameters": {
        "message": "=There was an error:  {{ $json.data[0].message }}",
        "options": {},
        "waitUserReply": false
      },
      "typeVersion": 1
    },
    {
      "id": "66370ec1-4c88-4e92-b10e-3302d11488cf",
      "name": "Respond to Chat",
      "type": "@n8n/n8n-nodes-langchain.chat",
      "position": [
        3232,
        384
      ],
      "parameters": {
        "message": "={{ $json.output }}",
        "options": {},
        "waitUserReply": false
      },
      "typeVersion": 1
    },
    {
      "id": "c9c3f88f-8ed6-4413-a4db-d1861b575b84",
      "name": "Convert to Stock Symbol",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        416,
        288
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini",
          "cachedResultName": "GPT-4.1-MINI"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=I will give you a stock name, just return me the stock symbol. Strictly - Nothing else at all.\n\nStock Name: {{ $json.chatInput }}"
            }
          ]
        }
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "26bc4bf6-cae8-4478-8b8a-96033c5fb50d",
      "name": "Merge News & Technical",
      "type": "n8n-nodes-base.merge",
      "position": [
        2192,
        384
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "07b32114-e812-4020-97cf-e71eac41afea",
      "name": "Aggregate to a single list",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        2416,
        384
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "5930faea-8e92-4279-9595-eee74b2963e0",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        784,
        -176
      ],
      "parameters": {
        "color": 5,
        "width": 384,
        "height": 768,
        "content": "## STOCK PRICE TREND\n* Fetch using TwelveData APIs\n* Get your free API Key from here: https://twelvedata.com/\n* Replace your API Key under the Credentials"
      },
      "typeVersion": 1
    },
    {
      "id": "bcceb836-7cbf-4bee-9e1b-a4a49b319c70",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1488,
        464
      ],
      "parameters": {
        "color": 4,
        "width": 288,
        "height": 352,
        "content": "## NEWS API\n* Get your free API key from here: https://newsapi.org/\n* Replace your API Key under the Credentials"
      },
      "typeVersion": 1
    },
    {
      "id": "7689378b-b357-4105-aef2-e81eb619322d",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3216,
        624
      ],
      "parameters": {
        "color": 4,
        "width": 432,
        "height": 352,
        "content": "## CHART-IMG API\n* Get your free API key from here: http://chart-img.com/\n* Replace your API Key under the Credential\n* Optional Step. You can even delete this"
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "settings": {},
  "versionId": "0a3130fd-b0ff-4670-b07b-b2206a433bd2",
  "connections": {
    "Code": {
      "main": [
        [
          {
            "node": "Merge News & Technical",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Think": {
      "ai_tool": [
        [
          {
            "node": "Technical Data AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "4h trend": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get News": {
      "main": [
        [
          {
            "node": "News Sentiment Analyzer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "Check Twelvedata API Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1day trend": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "1week trend": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Respond to Chat": {
      "main": [
        []
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Technical Data AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Get Stock Sentiment": {
      "ai_tool": [
        [
          {
            "node": "Technical Data AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Merge News & Technical": {
      "main": [
        [
          {
            "node": "Aggregate to a single list",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert to Stock Symbol": {
      "main": [
        [
          {
            "node": "4h trend",
            "type": "main",
            "index": 0
          },
          {
            "node": "1day trend",
            "type": "main",
            "index": 0
          },
          {
            "node": "1week trend",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get News",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "News Sentiment Analyzer": {
      "main": [
        [
          {
            "node": "Merge News & Technical",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Technical Data AI Agent": {
      "main": [
        [
          {
            "node": "Respond to Chat",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Chart Image for Stock": {
      "ai_tool": [
        [
          {
            "node": "Technical Data AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate to a single list": {
      "main": [
        [
          {
            "node": "Technical Data AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When chat message received": {
      "main": [
        [
          {
            "node": "Convert to Stock Symbol",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Twelvedata API Success": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond with Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}