{ "name": "Olostep Investment Research HTML Email - Weekday Market Open", "nodes": [ { "parameters": { "rule": { "interval": [ { "field": "cronExpression", "expression": "30 9 * * 1-5" } ] } }, "type": "n8n-nodes-base.scheduleTrigger", "typeVersion": 1.2, "position": [ 4640, 1120 ], "name": "Weekday Market Open Trigger" }, { "parameters": {}, "type": "n8n-nodes-base.manualTrigger", "typeVersion": 1, "position": [ 4640, 1312 ], "name": "Manual Test Trigger" }, { "parameters": { "assignments": { "assignments": [ { "name": "tickers", "type": "string", "value": "MSFT,NVDA" }, { "name": "email_to", "type": "string", "value": "recipient@example.com" }, { "name": "email_from", "type": "string", "value": "sender@example.com" }, { "name": "email_subject_prefix", "type": "string", "value": "Daily Investment Research Report" } ] }, "options": {} }, "type": "n8n-nodes-base.set", "typeVersion": 3.4, "position": [ 4864, 1216 ], "name": "Investment Watchlist" }, { "parameters": { "jsCode": "const data = $input.first().json;\nconst tickers = data.tickers.split(',').map(function(t) { return t.trim(); }).filter(Boolean);\n\nreturn tickers.map(function(ticker) {\n return {\n json: {\n ticker: ticker,\n investment_query: ticker + ' latest investor relations SEC filings earnings call transcript financial news risk factors catalysts',\n email_to: data.email_to,\n email_from: data.email_from,\n email_subject_prefix: data.email_subject_prefix\n }\n };\n});" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 5088, 1216 ], "name": "Split Tickers" }, { "parameters": { "operation": "search", "query": "={{ $json.investment_query }}" }, "type": "n8n-nodes-olostep.olostepScrape", "typeVersion": 1, "position": [ 5312, 1216 ], "name": "Olostep Search - Investment Sources" }, { "parameters": { "jsCode": "const items = $input.all();\n\nconst watchlist = items.map(function(item) {\n return {\n ticker: item.json.ticker || 'Unknown',\n sources: item.json.organic || item.json.results || item.json.data || []\n };\n});\n\nconst first = items.length > 0 ? items[0].json : {};\n\nreturn [\n {\n json: {\n report_date: new Date().toISOString().split('T')[0],\n watchlist: watchlist,\n email_to: first.email_to || 'recipient@example.com',\n email_from: first.email_from || 'sender@example.com',\n email_subject_prefix: first.email_subject_prefix || 'Daily Investment Research Report'\n }\n }\n];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 5536, 1216 ], "name": "Combine Ticker Research" }, { "parameters": { "modelId": { "__rl": true, "value": "gpt-5.4-mini", "mode": "list", "cachedResultName": "GPT-5.4-MINI" }, "responses": { "values": [ { "content": "=You are an investment research assistant.\n\nYou will receive search and scraped web results for multiple stock tickers. Your job is to turn the results into one clean Markdown email report for the full watchlist.\n\nImportant rules:\n- Create only one complete report for the full watchlist.\n- Do not repeat the title, generated date, executive summary, or disclaimer for each ticker.\n- Do not give direct buy, sell, or hold advice.\n- Do not say \"invest in this\" or \"sell this\".\n- Do not predict stock prices.\n- Do not invent numbers or facts.\n- Use only the information provided in the input.\n- If information is missing, write \"Not found in provided sources.\"\n- Keep the report concise but useful.\n- Group the report by ticker/company.\n- Include source links under each company.\n- For each company, include a neutral \"Signal Summary\" with: Opportunity Signals, Risk / Exit Watch Signals, and Research Priority.\n- Research Priority may be High / Medium / Low, but it must not be framed as financial advice.\n\nReport date:\n{{ $json.report_date }}\n\nInput data:\n{{ JSON.stringify($json.watchlist) }}\n\nCreate the Markdown report using this structure:\n\n# Daily Investment Research Report\n\nGenerated on: {{ $json.report_date }}\n\n## Executive Summary\n\nWrite 5-7 bullets summarizing the most important findings across all tickers.\n\n## Watchlist Signal Table\n\nCreate a simple Markdown table with these columns:\n| Ticker | Opportunity Signals | Risk / Exit Watch Signals | Research Priority |\n\nImportant: The table must not include Buy, Sell, or Hold recommendations.\n\n## Ticker-by-Ticker Analysis\n\nFor each ticker or company found in the input, create this section:\n\n### [Company Name] ([Ticker if available])\n\n#### Key Sources Reviewed\n- [Source title](Source URL)\n- [Source title](Source URL)\n\n#### Recent Updates\nSummarize the most important recent updates from the sources.\n\n#### Opportunity Signals\n- Bullet 1\n- Bullet 2\n- Bullet 3\n\n#### Risk / Exit Watch Signals\n- Bullet 1\n- Bullet 2\n- Bullet 3\n\n#### Financial / Earnings Signals\nSummarize any revenue, earnings, margin, guidance, or filing-related information found.\n\n#### Competitive Position\nSummarize any information about competitors, market position, product demand, or sector trends.\n\n#### Investor Questions to Investigate Next\n- Question 1\n- Question 2\n- Question 3\n\n#### Research Confidence\nChoose one: High / Medium / Low\n\nExplain the confidence rating in one short sentence.\n\n---\n\n## Cross-Watchlist Themes\n\nSummarize patterns across all companies, such as AI demand, data center growth, margin pressure, regulatory risk, leadership changes, earnings momentum, and competitive pressure.\n\n## Red Flags to Monitor\n\nList the most important risks found across the full watchlist.\n\n## Follow-Up Research Checklist\n\n- Review latest 10-K or 10-Q filings\n- Compare latest earnings call transcripts\n- Check revenue guidance\n- Review analyst downgrades or upgrades\n- Look for lawsuits, investigations, layoffs, or executive changes\n\n## Disclaimer\n\nThis report is generated from public web research and is for research automation only. It is not financial advice. It does not provide buy, sell, or hold recommendations.\n" } ] }, "builtInTools": {}, "options": {} }, "type": "@n8n/n8n-nodes-langchain.openAi", "typeVersion": 2.2, "position": [ 5760, 1216 ], "name": "OpenAI - Create Full Watchlist Email Report" }, { "parameters": { "jsCode": "const output = $json.output && $json.output[0] && $json.output[0].content && $json.output[0].content[0] && $json.output[0].content[0].text;\nconst markdown = output || $json.text || '';\n\nfunction escapeHtml(str) {\n return String(str)\n .replace(/&/g, '&')\n .replace(//g, '>');\n}\n\nlet html = escapeHtml(markdown);\n\nhtml = html\n .replace(/\\*\\*(.*?)\\*\\*/gim, '$1')\n .replace(/\\[(.*?)\\]\\((.*?)\\)/gim, '$1');\n\nhtml = html\n .replace(/^#### (.*$)/gim, '
/g, '
')\n .replace(/
| /g, ' | ')\n .replace(/ | /g, ' | ');\n\nreturn [\n {\n json: {\n email_to: $('Split Tickers').first().json.email_to,\n email_from: $('Split Tickers').first().json.email_from,\n email_subject: subjectPrefix + ' - ' + reportDate,\n email_html: styledHtml\n }\n }\n];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 6112, 1216 ], "name": "Build HTML Email Body" }, { "parameters": { "sendTo": "={{ $json.email_to }}", "subject": "={{ $json.email_subject }}", "message": "={{ $json.email_html }}", "options": { "senderName": "Investment Research Bot" } }, "type": "n8n-nodes-base.gmail", "typeVersion": 2.1, "position": [ 6336, 1216 ], "name": "Send HTML Email via Gmail" }, { "parameters": { "content": "## Daily investment research email\n\n### How it works\nThis workflow researches a stock watchlist with Olostep, summarizes the findings with OpenAI GPT-5.4-mini, and sends one styled Gmail report.\n\n### Setup steps\n- [ ] Add Olostep, OpenAI, and Gmail credentials.\n- [ ] Update the `Investment Watchlist` node with tickers and email fields.\n- [ ] Run `Manual Test Trigger` and review the email before activating.\n\n### Customization\nChange the ticker list, schedule, prompt, subject, or HTML styling to match your research workflow.", "height": 320, "width": 624 }, "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [ 5104, 688 ], "name": "Sticky Note4" }, { "parameters": { "content": "### How can we improve this workflow?\n### Share feedback on the n8n template page or repository.", "height": 96, "width": 624, "color": 4 }, "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [ 5104, 1024 ], "name": "Sticky Note5" } ], "pinData": {}, "connections": { "Weekday Market Open Trigger": { "main": [ [ { "node": "Investment Watchlist", "type": "main", "index": 0 } ] ] }, "Manual Test Trigger": { "main": [ [ { "node": "Investment Watchlist", "type": "main", "index": 0 } ] ] }, "Investment Watchlist": { "main": [ [ { "node": "Split Tickers", "type": "main", "index": 0 } ] ] }, "Split Tickers": { "main": [ [ { "node": "Olostep Search - Investment Sources", "type": "main", "index": 0 } ] ] }, "Olostep Search - Investment Sources": { "main": [ [ { "node": "Combine Ticker Research", "type": "main", "index": 0 } ] ] }, "Combine Ticker Research": { "main": [ [ { "node": "OpenAI - Create Full Watchlist Email Report", "type": "main", "index": 0 } ] ] }, "OpenAI - Create Full Watchlist Email Report": { "main": [ [ { "node": "Build HTML Email Body", "type": "main", "index": 0 } ] ] }, "Build HTML Email Body": { "main": [ [ { "node": "Send HTML Email via Gmail", "type": "main", "index": 0 } ] ] } }, "active": false, "settings": { "executionOrder": "v1", "binaryMode": "separate" }, "tags": [ "AI", "Finance", "Email", "Research", "Automation" ] } |
|---|