N
n8n Store
Workflow Market
AI Powered Stock Setiment Analyzer

AI Powered Stock Setiment Analyzer

by jiteshdugar0 views

説明

Categories

🤖 AI & Machine Learning

Nodes Used

n8n-nodes-base.coden8n-nodes-base.mergen8n-nodes-base.mergen8n-nodes-base.switchn8n-nodes-base.aggregaten8n-nodes-base.aggregaten8n-nodes-base.stickyNoten8n-nodes-base.stickyNoten8n-nodes-base.stickyNoten8n-nodes-base.httpRequest
Price無料
Views0
最終更新11/28/2025
workflow.json
{
  "id": "INwMUl3OdeqFBlkr",
  "meta": {
    "instanceId": "e56288a9b12ad2dc7c19cc4170f20f7abcacaad5fb3972dd882c9ce4f34e7668",
    "templateCredsSetupCompleted": true
  },
  "name": "AI Powered Stock Setiment Analyzer",
  "tags": [],
  "nodes": [
    {
      "id": "e58d9c28-2f7f-4332-ab99-1431a2f1b68a",
      "name": "When chat message received",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "position": [
        -896,
        -64
      ],
      "webhookId": "1659fe58-d78d-40dc-92fa-76f3bf599df8",
      "parameters": {
        "options": {
          "responseMode": "responseNodes"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "d89ad9e2-7a74-44ff-b889-7cf8435f4481",
      "name": "4h trend",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -176,
        -256
      ],
      "parameters": {
        "url": "https://api.twelvedata.com/time_series",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpQueryAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "symbol",
              "value": "={{ $json.message.content }}"
            },
            {
              "name": "interval",
              "value": "4h"
            }
          ]
        }
      },
      "credentials": {
        "httpQueryAuth": {
          "id": "R3Dc1LmQu7W6Hpmy",
          "name": "Twelvedata API Key Auth"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "bbce42d7-e50e-4b9e-a168-a0f2f68af753",
      "name": "1day trend",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -176,
        -64
      ],
      "parameters": {
        "url": "https://api.twelvedata.com/time_series",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpQueryAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "symbol",
              "value": "={{ $json.message.content }}"
            },
            {
              "name": "interval",
              "value": "1day"
            }
          ]
        }
      },
      "credentials": {
        "httpQueryAuth": {
          "id": "R3Dc1LmQu7W6Hpmy",
          "name": "Twelvedata API Key Auth"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "27d3fd72-380f-412e-b004-bcf101af280d",
      "name": "1week trend",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -176,
        128
      ],
      "parameters": {
        "url": "https://api.twelvedata.com/time_series",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpQueryAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "symbol",
              "value": "={{ $json.message.content }}"
            },
            {
              "name": "interval",
              "value": "1week"
            }
          ]
        }
      },
      "credentials": {
        "httpQueryAuth": {
          "id": "R3Dc1LmQu7W6Hpmy",
          "name": "Twelvedata API Key Auth"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "0f22b55e-8c91-4694-9fde-8810d016fce6",
      "name": "Get News",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        768,
        -48
      ],
      "parameters": {
        "url": "https://newsapi.org/v2/everything",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpQueryAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "q",
              "value": "={{ $json.message.content }}"
            }
          ]
        }
      },
      "credentials": {
        "httpQueryAuth": {
          "id": "gZ6BKf8OJSsy6Jph",
          "name": "NewsAPI API Key"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "344af493-dad1-48f9-bdbe-d7754ca9c47e",
      "name": "News Sentiment Analyzer",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        1104,
        -48
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini",
          "cachedResultName": "GPT-4.1-MINI"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=You are a highly intelligent and accurate sentiment analyzer specializing in the financial markets. Analyze the sentiment of the provided text\n\n- Evaluate the immediate market reaction, recent news impact, and technical volatility.\n- Determine a sentiment category: \"Positive\", \"Neutral\", or \"Negative\".\n- Calculate a numerical score between -1 (extremely negative) and 1 (extremely positive).\n- Provide a concise rationale explaining the short-term sentiment (give a detailed response with appropriate headlines for major events.\n\nYour output must be exactly a JSON object. The value must be an object with three keys: \"category\", \"score\", and \"rationale\". Do not output any additional text.\n\nFor example, your output should look like:\n\n{\n  \"category\": \"Positive\",\n  \"score\": 0.7,\n  \"rationale\": \"...\"\n}\n\nNow, analyze the following text and produce your JSON output: {{ JSON.stringify($json.articles) }}"
            }
          ]
        },
        "jsonOutput": true
      },
      "credentials": {
        "openAiApi": {
          "id": "5n856jvI80lSEErZ",
          "name": "Klinsman OpenAI"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "fb4954a2-9203-4574-8332-2053ec97c3bb",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        320,
        -64
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "905c0187-c652-468e-9081-bff1cfde5b2f",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        144,
        -80
      ],
      "parameters": {
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "26bc4bf6-cae8-4478-8b8a-96033c5fb50d",
      "name": "Merge1",
      "type": "n8n-nodes-base.merge",
      "position": [
        1392,
        -160
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "07b32114-e812-4020-97cf-e71eac41afea",
      "name": "Aggregate1",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        1568,
        -160
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "d7d5bb3f-8364-4cb7-9653-1ebf30d037c9",
      "name": "Technical Data AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1808,
        -160
      ],
      "parameters": {
        "text": "=Data Sources\nTechnical Data (Price Action):\n{{ JSON.stringify($json.data[0]) }}\n\nSentiment Analysis (based on news):\nCategory: {{ $json.data[1].message.content.category }}\nScore: {{ $json.data[1].message.content.score }}\nRationale: {{ $json.data[1].message.content.rationale }}\n\n\"Score\" Assignment is between -1 (extremely negative) and 1 (extremely positive)\n\nUse the *Get Stock Sentiment* to additionally get the sentiment about the tool and base your results on the overall sentiment.\n\nAlso - use the *Chat Image for a Stock* tool to get the stock chart image and send it in the output",
        "options": {
          "systemMessage": "=You are a professional algorithmic trader with expertise in multi-timeframe analysis and sentiment integration. Your task is to analyze the provided technical and sentiment data to generate a single, actionable trade recommendation.\n\nAnalysis Framework\n1. Technical Analysis Priority\n\nPrimary Timeframe (4h): Entry/exit timing, immediate trend direction\nSecondary Timeframe (1d): Trend confirmation, key support/resistance levels\nTertiary Timeframe (1w): Overall market context, major trend direction\n\n2. Key Technical Indicators to Evaluate\n\nPrice action patterns (candlestick formations, support/resistance)\nTrend analysis (higher highs/lows, moving average relationships)\nMomentum indicators (RSI overbought/oversold conditions)\nVolume confirmation\nRisk/reward ratio (minimum 1:2 ratio required)\n\n3. Sentiment Integration Rules\n\nBullish sentiment + bullish technicals = Strong BUY signal\nBearish sentiment + bearish technicals = Strong SELL signal\nConflicting signals = HOLD (wait for alignment)\nExtreme sentiment readings = Consider contrarian approach\n\n4. Risk Management Requirements\n\nStop-loss must be placed beyond significant technical levels\nPosition sizing should account for volatility\nMaximum risk per trade: 2% of account\nTarget should provide minimum 1:2 risk/reward ratio\n\nDecision Process\n\nTrend Identification: Determine primary trend across all timeframes\nEntry Signal: Identify optimal entry based on 4h price action\nConfirmation: Validate with 1d trend and volume\nContext Check: Ensure alignment with 1w trend direction\nSentiment Filter: Apply sentiment data to strengthen or weaken signal\nRisk Calculation: Set stop-loss and target based on technical levels\n\nCritical Rules\nOnly recommend BUY/SELL when all timeframes align or when risk/reward is exceptional (>1:3)\nDefault to HOLD when signals are mixed or unclear\nAlways prioritize capital preservation over profit maximization\nEntry price must be actionable (near current market price)\nAll price levels must be justified by technical analysis\n\nOutput Format (STRICT - No additional text)\nTechnical Recommendation: [BUY|SELL|HOLD]\nEntry Price: [specific price level or N/A]\nStop-Loss: [specific price level or N/A]\nTarget Price: [specific price level or N/A]\nRisk/Reward Ratio: [ratio or N/A]\nConfidence Level: [High|Medium|Low|N/A]\nDo not include rationale. \n\nIn the output, only return 'N/A' if no info is known, should be the last resort."
        },
        "promptType": "define"
      },
      "typeVersion": 2.2
    },
    {
      "id": "09d9912b-cdbb-41ac-9f5b-2d92cadddb9e",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1568,
        64
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o",
          "cachedResultName": "gpt-4o"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "5n856jvI80lSEErZ",
          "name": "Klinsman OpenAI"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "36d679d0-5b6d-4c2e-873b-1c0822093a84",
      "name": "Code",
      "type": "n8n-nodes-base.code",
      "position": [
        1152,
        -256
      ],
      "parameters": {
        "jsCode": "// n8n JavaScript Code for Stock Data Transformation - With Price Trends\n// Comprehensive output including trend analysis for LLMs\n\nfunction calculateMovingAverage(prices, period) {\n  if (prices.length < period) return null;\n  const sum = prices.slice(0, period).reduce((a, b) => a + b, 0);\n  return Math.round((sum / period) * 100) / 100;\n}\n\nfunction calculateTrendDirection(prices) {\n  if (prices.length < 3) return 'INSUFFICIENT_DATA';\n  \n  const recent = prices.slice(0, 3);\n  const older = prices.slice(3, 6);\n  \n  const recentAvg = recent.reduce((a, b) => a + b, 0) / recent.length;\n  const olderAvg = older.length > 0 ? older.reduce((a, b) => a + b, 0) / older.length : recentAvg;\n  \n  const change = ((recentAvg - olderAvg) / olderAvg) * 100;\n  \n  if (change > 2) return 'STRONG_UPTREND';\n  if (change > 0.5) return 'UPTREND';\n  if (change < -2) return 'STRONG_DOWNTREND';\n  if (change < -0.5) return 'DOWNTREND';\n  return 'SIDEWAYS';\n}\n\nfunction identifySupportResistance(prices, highs, lows) {\n  const sortedPrices = [...prices].sort((a, b) => a - b);\n  const maxPrice = Math.max(...highs);\n  const minPrice = Math.min(...lows);\n  \n  return {\n    resistance: maxPrice,\n    support: minPrice,\n    median: sortedPrices[Math.floor(sortedPrices.length / 2)]\n  };\n}\n\nfunction transformStockDataForLLM(stockData) {\n  const result = {\n    symbol: '',\n    overview: {},\n    price_trends: {},\n    technical_analysis: {},\n    multi_timeframe: {},\n    llm_summary: ''\n  };\n  \n  let dailyData = null;\n  let weeklyData = null;\n  let intraDayData = null;\n  \n  // Separate data by timeframes\n  stockData.forEach(dataSet => {\n    const meta = dataSet.meta;\n    const interval = meta.interval;\n    \n    result.symbol = meta.symbol;\n    \n    if (interval === '1day') dailyData = dataSet;\n    if (interval === '1week') weeklyData = dataSet;\n    if (interval === '4h') intraDayData = dataSet;\n  });\n  \n  if (!dailyData || !dailyData.values.length) {\n    throw new Error('No daily data found');\n  }\n  \n  const dailyValues = dailyData.values;\n  const latest = dailyValues[0];\n  \n  // Basic overview\n  result.overview = {\n    symbol: result.symbol,\n    current_price: parseFloat(latest.close),\n    date: latest.datetime,\n    daily_change: dailyValues[1] ? parseFloat(latest.close) - parseFloat(dailyValues[1].close) : 0,\n    daily_change_percent: dailyValues[1] ? \n      Math.round(((parseFloat(latest.close) - parseFloat(dailyValues[1].close)) / parseFloat(dailyValues[1].close)) * 100 * 100) / 100 : 0,\n    volume: parseInt(latest.volume),\n    day_range: `$${latest.low} - $${latest.high}`\n  };\n  \n  // Extract price arrays for analysis\n  const closePrices = dailyValues.map(d => parseFloat(d.close));\n  const highPrices = dailyValues.map(d => parseFloat(d.high));\n  const lowPrices = dailyValues.map(d => parseFloat(d.low));\n  const volumes = dailyValues.map(d => parseInt(d.volume));\n  \n  // Price trends analysis\n  result.price_trends = {\n    trend_direction: calculateTrendDirection(closePrices),\n    moving_averages: {\n      ma_5: calculateMovingAverage(closePrices, 5),\n      ma_10: calculateMovingAverage(closePrices, 10),\n      ma_20: calculateMovingAverage(closePrices, 20)\n    },\n    price_position: {\n      above_ma5: closePrices[0] > calculateMovingAverage(closePrices, 5),\n      above_ma10: closePrices[0] > calculateMovingAverage(closePrices, 10),\n      above_ma20: closePrices[0] > calculateMovingAverage(closePrices, 20)\n    },\n    recent_performance: {\n      last_5_days: dailyValues.slice(0, 5).map(d => ({\n        date: d.datetime,\n        close: parseFloat(d.close),\n        change_from_prev: dailyValues.indexOf(d) < dailyValues.length - 1 ? \n          parseFloat(d.close) - parseFloat(dailyValues[dailyValues.indexOf(d) + 1].close) : 0,\n        volume: parseInt(d.volume)\n      })),\n      weekly_change: closePrices.length >= 7 ? \n        Math.round(((closePrices[0] - closePrices[6]) / closePrices[6]) * 100 * 100) / 100 : 0,\n      monthly_change: closePrices.length >= 30 ? \n        Math.round(((closePrices[0] - closePrices[29]) / closePrices[29]) * 100 * 100) / 100 : 0\n    }\n  };\n  \n  // Technical analysis\n  const supportResistance = identifySupportResistance(closePrices.slice(0, 30), highPrices.slice(0, 30), lowPrices.slice(0, 30));\n  const avgVolume = volumes.slice(0, 20).reduce((a, b) => a + b, 0) / Math.min(20, volumes.length);\n  \n  result.technical_analysis = {\n    support_resistance: supportResistance,\n    volume_analysis: {\n      current_volume: volumes[0],\n      average_volume_20d: Math.round(avgVolume),\n      volume_ratio: Math.round((volumes[0] / avgVolume) * 100) / 100,\n      volume_trend: volumes[0] > avgVolume * 1.5 ? 'HIGH' : volumes[0] < avgVolume * 0.5 ? 'LOW' : 'NORMAL'\n    },\n    volatility: {\n      daily_volatility: Math.round(((parseFloat(latest.high) - parseFloat(latest.low)) / parseFloat(latest.close)) * 100 * 100) / 100,\n      recent_volatility: Math.round((Math.max(...highPrices.slice(0, 10)) - Math.min(...lowPrices.slice(0, 10))) / closePrices[0] * 100 * 100) / 100\n    },\n    momentum_indicators: {\n      price_vs_support: Math.round(((closePrices[0] - supportResistance.support) / supportResistance.support) * 100 * 100) / 100,\n      price_vs_resistance: Math.round(((supportResistance.resistance - closePrices[0]) / closePrices[0]) * 100 * 100) / 100\n    }\n  };\n  \n  // Multi-timeframe analysis\n  result.multi_timeframe = {\n    daily: {\n      trend: result.price_trends.trend_direction,\n      last_close: closePrices[0]\n    }\n  };\n  \n  // Add weekly analysis if available\n  if (weeklyData && weeklyData.values.length > 1) {\n    const weeklyPrices = weeklyData.values.map(d => parseFloat(d.close));\n    result.multi_timeframe.weekly = {\n      trend: calculateTrendDirection(weeklyPrices),\n      weekly_change: Math.round(((weeklyPrices[0] - weeklyPrices[1]) / weeklyPrices[1]) * 100 * 100) / 100\n    };\n  }\n  \n  // Add intraday analysis if available\n  if (intraDayData && intraDayData.values.length > 1) {\n    const intradayPrices = intraDayData.values.map(d => parseFloat(d.close));\n    result.multi_timeframe.intraday = {\n      trend: calculateTrendDirection(intradayPrices),\n      recent_sessions: intraDayData.values.slice(0, 6).map(d => ({\n        datetime: d.datetime,\n        close: parseFloat(d.close)\n      }))\n    };\n  }\n  \n  // Generate comprehensive LLM summary\n  const ma5 = result.price_trends.moving_averages.ma_5;\n  const ma20 = result.price_trends.moving_averages.ma_20;\n  const trendStrength = result.price_trends.trend_direction;\n  const volumeStatus = result.technical_analysis.volume_analysis.volume_trend;\n  \n  result.llm_summary = `${result.symbol} Technical Analysis Summary:\n  \nCURRENT STATUS: Trading at $${result.overview.current_price} (${result.overview.daily_change >= 0 ? '+' : ''}${result.overview.daily_change_percent}% today)\n\nTREND ANALYSIS:\n- Overall Trend: ${trendStrength}\n- Price vs 5-day MA ($${ma5}): ${closePrices[0] > ma5 ? 'ABOVE' : 'BELOW'}\n- Price vs 20-day MA ($${ma20}): ${closePrices[0] > ma20 ? 'ABOVE' : 'BELOW'}\n- Weekly Performance: ${result.price_trends.recent_performance.weekly_change >= 0 ? '+' : ''}${result.price_trends.recent_performance.weekly_change}%\n\nTECHNICAL LEVELS:\n- Support: $${supportResistance.support}\n- Resistance: $${supportResistance.resistance}\n- Distance to Support: ${result.technical_analysis.momentum_indicators.price_vs_support}%\n\nVOLUME & MOMENTUM:\n- Volume: ${volumeStatus} (${result.technical_analysis.volume_analysis.volume_ratio}x average)\n- Daily Volatility: ${result.technical_analysis.volatility.daily_volatility}%\n\nKEY INSIGHT: Stock is ${trendStrength.toLowerCase()}, trading ${closePrices[0] > ma20 ? 'above' : 'below'} key moving averages with ${volumeStatus.toLowerCase()} volume activity.`;\n  \n  return result;\n}\n\n// Main execution for n8n\ntry {\n  if (!$json || !$json.data || !Array.isArray($json.data)) {\n    throw new Error('Expected input format: { \"data\": [...] }');\n  }\n  \n  const transformedData = transformStockDataForLLM($json.data);\n  \n  return {\n    json: transformedData\n  };\n  \n} catch (error) {\n  return {\n    json: {\n      error: \"Data transformation failed\",\n      details: error.message,\n      expected_format: \"{ data: [{ meta: {...}, values: [...] }] }\"\n    }\n  };\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "e1b272a7-2de0-47cd-a7ed-66adee5205f4",
      "name": "Think",
      "type": "@n8n/n8n-nodes-langchain.toolThink",
      "position": [
        1776,
        80
      ],
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "64480805-811b-4ab3-871e-13cee359226a",
      "name": "Get Stock Sentiment",
      "type": "n8n-nodes-base.perplexityTool",
      "position": [
        1952,
        256
      ],
      "parameters": {
        "model": "sonar",
        "options": {},
        "messages": {
          "message": [
            {
              "content": "=Give me recent sentiment about this stock: {{ $('When chat message received').item.json.chatInput }}"
            }
          ]
        },
        "requestOptions": {}
      },
      "credentials": {
        "perplexityApi": {
          "id": "zHQXY3xprUQicrpf",
          "name": "Perplexity account 2"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "799885b8-c23b-44f3-a0d3-ac2a31051230",
      "name": "Check Twelvedata API Success",
      "type": "n8n-nodes-base.switch",
      "position": [
        480,
        -64
      ],
      "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": [
        2368,
        192
      ],
      "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": {
          "id": "2vjana55vzbcPaWS",
          "name": "Chart Img API Key"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "ced4c850-4182-451c-ba54-7c4bc00d40a3",
      "name": "Respond with Error",
      "type": "@n8n/n8n-nodes-langchain.chat",
      "position": [
        768,
        240
      ],
      "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": [
        2384,
        -160
      ],
      "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": [
        -656,
        -64
      ],
      "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": {
          "id": "5n856jvI80lSEErZ",
          "name": "Klinsman OpenAI"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "a647a054-5cb3-4d80-8895-08da67ac6f4e",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -320,
        -416
      ],
      "parameters": {
        "color": 5,
        "width": 384,
        "height": 736,
        "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": "a9d0f2b6-a89c-4872-be86-418ce8d3bb49",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        672,
        -224
      ],
      "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": "5d09c698-c92b-430e-ac93-664fcb47951b",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2192,
        16
      ],
      "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": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "3ec964d2-dd25-48ab-a4df-eb5011e5873b",
  "connections": {
    "Code": {
      "main": [
        [
          {
            "node": "Merge1",
            "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
          }
        ]
      ]
    },
    "Merge1": {
      "main": [
        [
          {
            "node": "Aggregate1",
            "type": "main",
            "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
          }
        ]
      ]
    },
    "Aggregate1": {
      "main": [
        [
          {
            "node": "Technical Data AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "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
          }
        ]
      ]
    },
    "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
          }
        ]
      ]
    },
    "News Sentiment Analyzer": {
      "main": [
        [
          {
            "node": "Merge1",
            "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
          }
        ]
      ]
    },
    "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": "Get News",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond with Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

相关工作流