AutomationFlowsAI & RAG › Generate Weekly AI Equity Research Reports with Google Sheets, Fmp, Newsapi,…

Generate Weekly AI Equity Research Reports with Google Sheets, Fmp, Newsapi,…

Original n8n title: Generate Weekly AI Equity Research Reports with Google Sheets, Fmp, Newsapi, Openai, and Gmail

ByRahul Joshi @rahul08 on n8n.io

This workflow automatically generates professional equity research reports for selected companies using financial data, market news, and AI analysis. It is designed for analysts, founders, and finance teams who want consistent, data-backed equity insights without manual…

Cron / scheduled trigger★★★★★ complexityAI-powered31 nodesGoogle SheetsHTTP RequestOpenAI ChatAgentN8N Nodes HtmlcsstopdfGmail
AI & RAG Trigger: Cron / scheduled Nodes: 31 Complexity: ★★★★★ AI nodes: yes Added:
Generate Weekly AI Equity Research Reports with Google Sheets, Fmp, Newsapi,… — n8n workflow card showing Google Sheets, HTTP Request, OpenAI Chat integration

This workflow corresponds to n8n.io template #12949 — we link there as the canonical source.

This workflow follows the Agent → Gmail 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 →

Download .json
{
  "id": "UeiBg6dNaaXiBihb",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Turn Financial Statements and News into Weekly AI Equity Research Reports",
  "tags": [],
  "nodes": [
    {
      "id": "8ba91d18-01b8-426f-a48f-cd431ebd5ec7",
      "name": "Weekly Equity Research Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -96,
        0
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 8
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "3c5ba0e3-ee70-4a08-9022-368dc51ef413",
      "name": "Fetch Company List",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        112,
        0
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1378200588,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Mz-woYDtXtzF2bA9IqpdYh28IPA76nFx46WHgDJOZoI/edit#gid=1378200588",
          "cachedResultName": "companies"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1Mz-woYDtXtzF2bA9IqpdYh28IPA76nFx46WHgDJOZoI",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Mz-woYDtXtzF2bA9IqpdYh28IPA76nFx46WHgDJOZoI/edit?usp=drivesdk",
          "cachedResultName": "NEWS IMPACT TRACKER"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "1628fc88-b809-4ac3-a5c4-eb7a8dfaca42",
      "name": "Fetch Income Statement",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1072,
        -224
      ],
      "parameters": {
        "url": "=https://financialmodelingprep.com/stable/income-statement",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "period",
              "value": "annual"
            },
            {
              "name": "limit",
              "value": "5"
            },
            {
              "name": "apikey",
              "value": "your_api_key"
            },
            {
              "name": "symbol",
              "value": "={{ $json.ticker }}"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "4a3bd331-1c82-47f4-aa48-e2a44e37e8bd",
      "name": "Fetch Balance Sheet",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1056,
        -16
      ],
      "parameters": {
        "url": "=https://financialmodelingprep.com/stable/balance-sheet-statement",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "period",
              "value": "annual"
            },
            {
              "name": "limit",
              "value": "5"
            },
            {
              "name": "apikey",
              "value": "your_api_key"
            },
            {
              "name": "symbol",
              "value": "={{ $json.ticker }}"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "cc3dd95e-cec9-4326-99ee-e118f6efe1ae",
      "name": "Fetch Cash Flow",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1040,
        208
      ],
      "parameters": {
        "url": "=https://financialmodelingprep.com/stable/cash-flow-statement",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "period",
              "value": "annual"
            },
            {
              "name": "limit",
              "value": "5"
            },
            {
              "name": "apikey",
              "value": "your_api_key"
            },
            {
              "name": "symbol",
              "value": "={{ $json.ticker }}"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "8713c97c-84e1-4fa1-ae93-8e2f674a0649",
      "name": "Fetch Market Data",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1040,
        448
      ],
      "parameters": {
        "url": "https://newsapi.org/v2/everything",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "q",
              "value": "={{ $json.ticker }}"
            },
            {
              "name": "language",
              "value": "=en"
            },
            {
              "name": "sortBy",
              "value": "publishedAt"
            },
            {
              "name": "pageSize",
              "value": "10"
            },
            {
              "name": "apiKey",
              "value": "your_newsapi_key"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "d7ebfa69-69d7-4543-93c4-8132a34b555f",
      "name": "Parse Risks and Growth Output",
      "type": "n8n-nodes-base.code",
      "position": [
        2672,
        224
      ],
      "parameters": {
        "jsCode": "let raw = $json.output;\nlet parsed = {};\n\ntry {\n  parsed = JSON.parse(raw);\n} catch (e) {\n  parsed = {\n    risks: [],\n    growth_outlook: \"\"\n  };\n}\n\nreturn [\n  {\n    json: parsed\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "d9606f85-e284-4a04-896e-e1877d778854",
      "name": "Build Equity Research Report",
      "type": "n8n-nodes-base.code",
      "position": [
        3248,
        96
      ],
      "parameters": {
        "jsCode": "const {\n  strengths = [],\n  weaknesses = [],\n  opportunities = [],\n  threats = [],\n  risks = [],\n  growth_outlook = \"\"\n} = $json;\n\n// Helper to render bullet lists\nconst renderList = (items) =>\n  items.map(item => `<li>${item}</li>`).join(\"\");\n\n// Build HTML report\nconst html = `\n<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"UTF-8\" />\n  <style>\n    body {\n      font-family: Arial, sans-serif;\n      line-height: 1.6;\n      color: #222;\n      padding: 24px;\n    }\n    h1 {\n      color: #0b5ed7;\n      border-bottom: 2px solid #eee;\n      padding-bottom: 8px;\n    }\n    h2 {\n      color: #333;\n      margin-top: 24px;\n    }\n    ul {\n      margin-left: 20px;\n    }\n    li {\n      margin-bottom: 6px;\n    }\n    .section {\n      margin-bottom: 24px;\n    }\n  </style>\n</head>\n<body>\n\n<h1>AI-Generated Equity Research Report</h1>\n\n<div class=\"company\">\n<h2> Symbol : </h2><span>${ $('Iterate Companies').item.json.ticker }</span>\n</div>\n\n<div class=\"section\">\n  <h2>Strengths</h2>\n  <ul>${renderList(strengths)}</ul>\n</div>\n\n<div class=\"section\">\n  <h2>Weaknesses</h2>\n  <ul>${renderList(weaknesses)}</ul>\n</div>\n\n<div class=\"section\">\n  <h2>Opportunities</h2>\n  <ul>${renderList(opportunities)}</ul>\n</div>\n\n<div class=\"section\">\n  <h2>Threats</h2>\n  <ul>${renderList(threats)}</ul>\n</div>\n\n<div class=\"section\">\n  <h2>Key Risks</h2>\n  <ul>${renderList(risks)}</ul>\n</div>\n\n<div class=\"section\">\n  <h2>Growth Outlook (12\u201324 Months)</h2>\n  <p>${growth_outlook}</p>\n</div>\n\n</body>\n</html>\n`;\n\nreturn [\n  {\n    json: {\n      report_html: html\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "8fe6ee7c-1af0-44d5-9c9d-c1d166a7149c",
      "name": "Filter Enabled Companies",
      "type": "n8n-nodes-base.if",
      "position": [
        320,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "8c7418be-b1e2-41bc-8850-f3b25b9665db",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.enabled }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "7c0d21eb-d7d3-4627-984a-34298c5a1d22",
      "name": "Iterate Companies",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        576,
        -16
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "c336316a-32f2-4dce-ac59-3bbe7543aabf",
      "name": "Normalize Income Statement Data",
      "type": "n8n-nodes-base.code",
      "position": [
        1280,
        -224
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\n\nconst normalized = items.slice(0, 5).map(item => {\n  const s = item.json;\n  return {\n    fiscal_year: s.fiscalYear,\n    revenue: s.revenue,\n    gross_profit: s.grossProfit,\n    operating_income: s.operatingIncome,\n    ebitda: s.ebitda,\n    net_income: s.netIncome,\n    eps_diluted: s.epsDiluted\n  };\n});\n\nreturn [\n  {\n    json: {\n      income_statement: normalized\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "96fd276d-882f-4977-be51-7f5bfc72d4e7",
      "name": "Normalize Balance Sheet Data",
      "type": "n8n-nodes-base.code",
      "position": [
        1296,
        -16
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\n\nconst normalized = items.slice(0, 5).map(item => {\n  const s = item.json;\n  return {\n    fiscal_year: s.fiscalYear,\n    assets: {\n      cash_and_equivalents: s.cashAndCashEquivalents,\n      total_current_assets: s.totalCurrentAssets,\n      total_assets: s.totalAssets\n    },\n    liabilities: {\n      total_current_liabilities: s.totalCurrentLiabilities,\n      short_term_debt: s.shortTermDebt,\n      long_term_debt: s.longTermDebt,\n      total_liabilities: s.totalLiabilities\n    },\n    debt: {\n      total_debt: s.totalDebt,\n      net_debt: s.netDebt\n    },\n    equity: {\n      total_equity: s.totalEquity\n    }\n  };\n});\n\nreturn [\n  {\n    json: {\n      balance_sheet: normalized\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "7473b880-a93d-4fcd-a41c-b3ce0d52d113",
      "name": "Normalize Cash Flow Data",
      "type": "n8n-nodes-base.code",
      "position": [
        1280,
        208
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\n\nconst normalized = items.slice(0, 5).map(item => {\n  const s = item.json;\n  return {\n    fiscal_year: s.fiscalYear,\n    cash_generation: {\n      operating_cash_flow: s.operatingCashFlow,\n      free_cash_flow: s.freeCashFlow,\n      capital_expenditure: s.capitalExpenditure\n    },\n    earnings_to_cash: {\n      net_income: s.netIncome,\n      depreciation_and_amortization: s.depreciationAndAmortization,\n      change_in_working_capital: s.changeInWorkingCapital\n    },\n    capital_allocation: {\n      dividends_paid: s.netDividendsPaid,\n      stock_repurchased: s.commonStockRepurchased,\n      net_debt_issuance: s.netDebtIssuance\n    }\n  };\n});\n\nreturn [\n  {\n    json: {\n      cash_flow: normalized\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "5c365c91-e0c8-4268-bb17-edbcc6d98640",
      "name": "Normalize Market News Data",
      "type": "n8n-nodes-base.code",
      "position": [
        1280,
        448
      ],
      "parameters": {
        "jsCode": "// NewsAPI response structure: { status, totalResults, articles }\nconst articles = $json.articles || [];\n\n// Normalize and limit articles\nconst normalized = articles.slice(0, 5).map(a => ({\n  title: a.title,\n  summary: a.description,\n  source: a.source?.name || null,\n  published_at: a.publishedAt,\n  url: a.url\n}));\n\nreturn {\n  news: normalized\n};\n"
      },
      "typeVersion": 2
    },
    {
      "id": "1b2300e2-164a-41ed-8702-b6746d4e2ad5",
      "name": "Merge Financials and News",
      "type": "n8n-nodes-base.merge",
      "position": [
        1808,
        64
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition",
        "numberInputs": 4
      },
      "typeVersion": 3.2
    },
    {
      "id": "ef44be38-7acb-4e8b-a3a9-2b8bb5350ff4",
      "name": "Compute Financial and Market Signals",
      "type": "n8n-nodes-base.code",
      "position": [
        2016,
        96
      ],
      "parameters": {
        "jsCode": "const data = $json;\n\nconst income = data.income_statement;\nconst balance = data.balance_sheet;\nconst cash = data.cash_flow;\n\n// Latest vs oldest for trends\nconst latestIncome = income[0];\nconst oldestIncome = income[income.length - 1];\n\nconst revenueGrowth =\n  (latestIncome.revenue - oldestIncome.revenue) / oldestIncome.revenue;\n\nconst margin =\n  latestIncome.operating_income / latestIncome.revenue;\n\nconst latestBalance = balance[0];\nconst debtToEquity =\n  latestBalance.debt.total_debt / latestBalance.equity.total_equity;\n\nconst latestCash = cash[0];\nconst fcfMargin =\n  latestCash.cash_generation.free_cash_flow / latestIncome.revenue;\n\nreturn {\n  swot_signals: {\n    revenue_growth_5y: revenueGrowth,\n    operating_margin: margin,\n    debt_to_equity: debtToEquity,\n    fcf_margin: fcfMargin,\n    stock_buybacks: latestCash.capital_allocation.stock_repurchased,\n    news : data.news,\n    news_count: data.news.length\n  },\n  original_data: data\n};\n"
      },
      "typeVersion": 2
    },
    {
      "id": "ed0d6bf4-3b0e-4efc-ac24-b3db27bd118f",
      "name": "LLM \u2013 SWOT Analysis Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2304,
        48
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "e6bc944b-fbc4-4cc8-8997-53bbc8cf0086",
      "name": "Generate SWOT Analysis",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2304,
        -128
      ],
      "parameters": {
        "text": "=You are an equity research analyst.\n\nInput :  {{ $json.toJsonString() }}\n\nInput contains:\n- Quantitative SWOT signals\n- Clean financial statements\n- Recent news headlines\n\nRules:\n- Use the signals to determine SWOT categories\n- Do NOT invent data\n- Base each point on either:\n  (a) a numeric signal\n  (b) a news item\n- Be concise and factual\n\nReturn ONLY valid JSON in this format:\n\n{\n  \"strengths\": [],\n  \"weaknesses\": [],\n  \"opportunities\": [],\n  \"threats\": []\n}\n",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "f17c2007-0500-4b81-ad6e-28ce901ccb14",
      "name": "Parse SWOT Output",
      "type": "n8n-nodes-base.code",
      "position": [
        2672,
        -128
      ],
      "parameters": {
        "jsCode": "let raw = $json.output;\nlet parsed = {};\n\ntry {\n  parsed = JSON.parse(raw);\n} catch (e) {\n  parsed = {\n    strengths: [],\n    weaknesses: [],\n    opportunities: [],\n    threats: []\n  };\n}\n\nreturn [\n  {\n    json: parsed\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "afe5d9bd-8a0f-412c-996a-b9b8ada81223",
      "name": "LLM \u2013 Risk and Growth Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2320,
        400
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "0b183d35-b6ad-4dc4-8ad5-b936f716c1da",
      "name": "Generate Risks and Growth Outlook",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2320,
        224
      ],
      "parameters": {
        "text": "=You are an equity research analyst.\n\nSwot signals : {{ $json.swot_signals.toJsonString() }}\n\noriginal_data : {{ $json.original_data.toJsonString() }}\n\nInput contains:\n- Calculated financial signals under \"swot_signals\"\n- Full normalized financial and news data under \"original_data\"\n\nTasks:\n1. Identify key business and financial risks\n2. Provide a 12\u201324 month growth outlook\n\nRules:\n- Base analysis on the provided data only\n- Use signals where applicable (leverage, margins, cash flow)\n- Do not invent facts\n\nReturn ONLY valid JSON in this format:\n\n{\n  \"risks\": [],\n  \"growth_outlook\": \"\"\n}\n",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "06fd7960-2806-4c4f-b595-f52fa79977d8",
      "name": "Merge All AI Insights",
      "type": "n8n-nodes-base.merge",
      "position": [
        2992,
        96
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "44902b8c-483f-44fd-83ac-a9ee67b7e0f7",
      "name": "Render Research Report to PDF",
      "type": "n8n-nodes-htmlcsstopdf.htmlcsstopdf",
      "position": [
        3520,
        96
      ],
      "parameters": {
        "html_content": "={{ $json.report_html }}"
      },
      "credentials": {
        "htmlcsstopdfApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "c3f4e60c-9786-4153-9c41-c8519dab017b",
      "name": "Validate PDF Generation",
      "type": "n8n-nodes-base.if",
      "position": [
        3728,
        96
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "8e7309e6-ef35-4ff5-abde-a1ee86f100aa",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.success }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "110a466a-abd8-4b4e-a69b-1b9c651effc8",
      "name": "Log Report Metadata",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        4096,
        -48
      ],
      "parameters": {
        "columns": {
          "value": {
            "Company": "={{ $('Iterate Companies').item.json.ticker }}",
            "PDF URL": "={{$json.pdf_url}}",
            "Timestamp": "={{$now}}",
            "Expiry Date": "={{$json.file_deletion_date}}",
            "Report Type": "AI Equity Research",
            "File Size (KB)": "={{ Math.round($json.file_size_bytes / 1024) }}"
          },
          "schema": [
            {
              "id": "Timestamp",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Company",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Report Type",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Report Type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "File Size (KB)",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "File Size (KB)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "PDF URL",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "PDF URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Expiry Date",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Expiry Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1571135394,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Mz-woYDtXtzF2bA9IqpdYh28IPA76nFx46WHgDJOZoI/edit#gid=1571135394",
          "cachedResultName": "AI Equity Research Report"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1Mz-woYDtXtzF2bA9IqpdYh28IPA76nFx46WHgDJOZoI",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Mz-woYDtXtzF2bA9IqpdYh28IPA76nFx46WHgDJOZoI/edit?usp=drivesdk",
          "cachedResultName": "NEWS IMPACT TRACKER"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "e90a99b4-3609-4d8d-8a69-186d1b011adb",
      "name": "Send Email Equity Research Report",
      "type": "n8n-nodes-base.gmail",
      "position": [
        4080,
        224
      ],
      "parameters": {
        "sendTo": "your_email_id",
        "message": "=<p>Hello,</p>  <p>Your <strong>AI-generated Equity Research Report</strong> has been successfully generated.</p>  <p> <strong>Download PDF:</strong><br/> <a href=\"{{ $json.pdf_url }}\" target=\"_blank\"> View / Download Report </a> </p>  <p> <strong>File size:</strong> {{ Math.round($json.file_size_bytes / 1024) }} KB<br/> <strong>Link valid until:</strong> {{ $json.file_deletion_date }} </p>  <p> Regards,<br/> AI Equity Research Automation </p>",
        "options": {
          "appendAttribution": false
        },
        "subject": "AI Equity Research Report \u2013 Ready for Review"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "a295329e-3444-43d4-8e71-9d640d2724e1",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        -1072
      ],
      "parameters": {
        "width": 512,
        "height": 752,
        "content": "## Workflow Overview \n\n### How it works\n\nThis workflow automatically creates a professional equity research report for selected companies on a weekly basis. It begins by reading a list of companies from Google Sheets and checks which ones are enabled for analysis. Only enabled companies are processed, making it easy to control coverage without changing the workflow.\n\nFor each company, the workflow collects five years of financial data, including income statement, balance sheet, and cash flow information, from Financial Modeling Prep. At the same time, it pulls recent market-related news using NewsAPI. All raw data is cleaned and normalized so it follows a consistent and easy-to-analyze structure.\n\nOnce the data is prepared, key financial signals such as revenue growth, operating margins, free cash flow strength, and leverage ratios are calculated. These signals, along with recent news, are passed to AI models that generate a structured SWOT analysis, identify major risks, and provide a 12\u201324 month growth outlook. The AI is strictly guided to base its output only on the provided data.\n\nThe generated insights are compiled into a clean HTML equity research report, which is then converted into a PDF. If the PDF is created successfully, the workflow logs the report details in Google Sheets and sends an email containing the PDF download link.\n\n### Setup steps:\n\nAdd company tickers and an enabled column in Google Sheets\n\nConfigure Financial Modeling Prep, NewsAPI, and OpenAI API keys\n\nConnect Google Sheets and Gmail credentials"
      },
      "typeVersion": 1
    },
    {
      "id": "2c6bb56b-b7c6-4586-9361-553bed73afdd",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        -176
      ],
      "parameters": {
        "color": 7,
        "width": 896,
        "height": 416,
        "content": "### Company Selection and Looping\n\nThese nodes load companies from Google Sheets, filters only enabled entries, and loops through each company one at a time. It ensures controlled execution and allows users to manage company coverage directly from the sheet."
      },
      "typeVersion": 1
    },
    {
      "id": "57eaaf05-32fc-453e-90fb-2f041e9b482f",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        880,
        -400
      ],
      "parameters": {
        "color": 7,
        "width": 816,
        "height": 1024,
        "content": "### Financial and News Data Collection\n\nThese nodes fetch financial statements and recent market news from external APIs. Keeping data collection separate helps maintain clarity, simplifies troubleshooting, and ensures reliable inputs for later normalization and analysis steps."
      },
      "typeVersion": 1
    },
    {
      "id": "b3e5364a-f0db-4b26-a0d4-0b1e3dc7041e",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1728,
        -400
      ],
      "parameters": {
        "color": 7,
        "width": 1408,
        "height": 1024,
        "content": "### AI Analysis and Signal Generation\n\nThis group calculates financial signals and uses AI to generate SWOT insights, risks, and growth outlook. The AI relies only on computed metrics and recent news, avoiding assumptions or unsupported conclusions."
      },
      "typeVersion": 1
    },
    {
      "id": "47343c7f-5a6b-47fb-bdae-0dfaf6844ad6",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3200,
        -160
      ],
      "parameters": {
        "color": 7,
        "width": 1200,
        "height": 560,
        "content": "### Report Generation and Delivery \n\nThese nodes assemble the final report, convert it into a PDF, log key details in Google Sheets, and send the report link by email once generation is confirmed successful."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "cf197bd4-d253-4ffc-a8f7-827eed52ab7c",
  "connections": {
    "Fetch Cash Flow": {
      "main": [
        [
          {
            "node": "Normalize Cash Flow Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Market Data": {
      "main": [
        [
          {
            "node": "Normalize Market News Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Iterate Companies": {
      "main": [
        [],
        [
          {
            "node": "Fetch Income Statement",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Balance Sheet",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Cash Flow",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Market Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse SWOT Output": {
      "main": [
        [
          {
            "node": "Merge All AI Insights",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Company List": {
      "main": [
        [
          {
            "node": "Filter Enabled Companies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Balance Sheet": {
      "main": [
        [
          {
            "node": "Normalize Balance Sheet Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge All AI Insights": {
      "main": [
        [
          {
            "node": "Build Equity Research Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Income Statement": {
      "main": [
        [
          {
            "node": "Normalize Income Statement Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate SWOT Analysis": {
      "main": [
        [
          {
            "node": "Parse SWOT Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate PDF Generation": {
      "main": [
        [
          {
            "node": "Log Report Metadata",
            "type": "main",
            "index": 0
          },
          {
            "node": "Send Email Equity Research Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Enabled Companies": {
      "main": [
        [
          {
            "node": "Iterate Companies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Cash Flow Data": {
      "main": [
        [
          {
            "node": "Merge Financials and News",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Merge Financials and News": {
      "main": [
        [
          {
            "node": "Compute Financial and Market Signals",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Market News Data": {
      "main": [
        [
          {
            "node": "Merge Financials and News",
            "type": "main",
            "index": 3
          }
        ]
      ]
    },
    "LLM \u2013 SWOT Analysis Model": {
      "ai_languageModel": [
        [
          {
            "node": "Generate SWOT Analysis",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Build Equity Research Report": {
      "main": [
        [
          {
            "node": "Render Research Report to PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Balance Sheet Data": {
      "main": [
        [
          {
            "node": "Merge Financials and News",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "LLM \u2013 Risk and Growth Model": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Risks and Growth Outlook",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Parse Risks and Growth Output": {
      "main": [
        [
          {
            "node": "Merge All AI Insights",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Render Research Report to PDF": {
      "main": [
        [
          {
            "node": "Validate PDF Generation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Weekly Equity Research Trigger": {
      "main": [
        [
          {
            "node": "Fetch Company List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Income Statement Data": {
      "main": [
        [
          {
            "node": "Merge Financials and News",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Risks and Growth Outlook": {
      "main": [
        [
          {
            "node": "Parse Risks and Growth Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Email Equity Research Report": {
      "main": [
        [
          {
            "node": "Iterate Companies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Compute Financial and Market Signals": {
      "main": [
        [
          {
            "node": "Generate SWOT Analysis",
            "type": "main",
            "index": 0
          },
          {
            "node": "Generate Risks and Growth Outlook",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow automatically generates professional equity research reports for selected companies using financial data, market news, and AI analysis. It is designed for analysts, founders, and finance teams who want consistent, data-backed equity insights without manual…

Source: https://n8n.io/workflows/12949/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

This n8n automation workflow automates the creation, scripting, production, and posting of YouTube videos. It leverages AI (OpenAI), image generation (PIAPI), video rendering (Shotstack), and platform

Agent, OpenAI Chat, Airtable Tool +7
AI & RAG

Created by: Peyton Leveillee Last updated: October 2025

OpenAI Chat, Google Sheets, HTTP Request +5
AI & RAG

The Multi-Model Agency Content Engine is a high-performance editorial system designed for agencies. It solves the "blank page" problem by alternating between real-world social proof and strategic expe

Google Sheets, Gmail, Google Drive +6
AI & RAG

This workflow automates the creation, rendering, approval, and posting of TikTok-style POV (Point of View) videos to Instagram, with cross-posting to Facebook and YouTube. It eliminates manual video p

OpenAI Chat, Output Parser Item List, HTTP Request +10
AI & RAG

SEO Blog Article Generation Workflow. Uses outputParserStructured, httpRequest, agent, lmChatOpenAi. Scheduled trigger; 56 nodes.

Output Parser Structured, HTTP Request, Agent +4