This is a submission for the AI Agents Challenge powered by n8n and Bright Data
What I Built
GridSense is a real-time AI trading assistant that ingests live stock/ETF/index snapshots and fresh headlines via Bright Data, then recommends grid trading actions (buy/hold/sell) with clear price bands, position sizing, and risk limits.
It’s designed for liquid tickers (e.g., QQQ, ^NDX, NKY, 510880) and supports:
- Auto-grid construction (center = last price; step = ATR- or %-based; levels up/down configurable).
- Dynamic re-centering when volatility/price regimes shift.
- Capital allocation & max-exposure guardrails (per-level budget, cumulative cap, soft stop).
- Explainable outputs: the agent shows why it recommends a level (snapshot + recent news shocks + volatility filter).
Demo
Public Chat: https://your-public-chat.example.com
Video Walkthrough (alt): https://your-demo-video.example.com
Usage hints in chat:
- “analyze TSLA with 1% grid, 10 levels”
- “recenter grid on QQQ if 30m ATR > yesterday ATR”
- “pause buys if negative news surprise > medium”
n8n Workflow
Workflow JSON (Gist): https://gist.github.com/your-handle/gridsense-workflow.json
High-level flow
- Chat Trigger / Example Chat Window →
- AI Agent (OpenAI) with tools →
- Bright Data Verified Node (snapshot/news) →
- Function/Code (normalize quotes, compute ATR/step) →
- Decision Block (grid build/recenter) →
- Formatter (human output + CSV/JSON) →
- (Optional) Webhook to downstream execution simulator
Technical Implementation
System Instructions (excerpt used in AI Agent node)
You are a quantitative trading assistant. Always:
1) First call the Bright Data tool to fetch the latest price snapshot (and, if available, recent headlines) for the user’s tickers.
2) If data is sparse or delayed, state assumptions and proceed.
3) Build a symmetric grid around last price:
- step: percentage or ATR-based (select the tighter of user-provided step or ATR-derived step)
- levels: N up and N down
- capital: allocate per-level, enforce max exposure cap
4) Output:
a) Buy levels (price, qty, rationale)
b) Sell levels (price, qty, rationale)
c) Recenter/disable rules if volatility regime changes
d) Clear final verdict: BUY / HOLD / TRIM with confidence.
Never provide financial advice; provide educational, model-based signals only.
Model Choice
- LLM: OpenAI GPT-4o-mini (cost-efficient, strong tool-use).
- Latency controls: short context + compact JSON schema for tool outputs.
- Determinism: temperature=0.2 for decisions, 0.5 for explanations.
Memory
- Session memory for user preferences (default step %, number of levels, max exposure, favored tickers).
- Stateless option for compliance: memory can be disabled per session.
Tools Used
-
Bright Data Verified Node — primary real-time data source for:
- Quotes snapshot from public finance pages.
- Recent headlines to de-risk buys during adverse news.
-
Function/Code node — grid math:
- Step size =
max(user_step%, min_cap, ATR_k * 100%))
with guards. - Position sizing = geometric or equal-weight per grid line.
- Recenter rule = trigger if price drifts > X steps or ATR regime switches.
- Step size =
IF / Merge / Switch — route when snapshot is stale, retry or fall back.
Bright Data Verified Node
How it’s wired
- Operation: “Scrape / Collect by URL (snapshot)” for designated quote/news URLs.
-
Inputs:
ticker
,market
,urls[]
, optionaldataset
tag for run labeling. - Flow:
- Trigger collection (snapshot).
- Poll status until ready.
- Download structured payload (price, change, ts, headline items).
- Error/Anti-bot handling: rely on Bright Data’s infra for CAPTCHAs/rate limits; implement exponential backoff + max retry 2 in n8n.
-
Normalization: Map fields →
{symbol, last, ts, prev_close, day_chg, day_chg_pct, headlines[]}
; validate timestamps and drop outliers.
Why Bright Data helps the grid
- Freshness: grid levels use current last price and volatility proxy; stale quotes would misplace bands.
- Context: headlines act as binary filters (e.g., “negative surprise” → reduce buys / widen step).
Journey
Problem & approach. Retail-friendly grid strategies often fail in live use because step sizes and centers are static and blind to regime shifts. I used Bright Data to ground the agent in fresh quotes and contextual headlines, and n8n to orchestrate a robust, inspectable pipeline.
What was hard.
- Snapshot timing: aligning tool polling with LLM tool-use; solved with a status-poll sub-flow and strict timeouts.
- Volatility-aware grids: ATR from short windows can be noisy; I capped min/max steps and required consensus across 15m/60m lookbacks.
- Explainability: traders want why; I structured outputs into level tables with per-level rationales.
What I learned.
- Real-time web data unlocks actionable agent behavior if you normalize and guard for staleness.
- n8n’s AI Agent + Verified Node combo keeps the system low-code but still auditable.
- Good defaults matter: conservative exposure caps and recenter rules prevent most “marching losses.”
Compliance & disclaimer.
This project analyzes public information for educational purposes only. It does not provide financial advice or execute trades. Respect each site’s terms of use and local regulations when collecting data.
Cover Image idea: A minimal grid-ladder chart overlaying live price ticks.
Tags: devchallenge, n8nbrightdatachallenge, ai, webdev
JSON:
{
"name": "My workflow 5",
"nodes": [
{
"parameters": {
"public": true,
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"typeVersion": 1.3,
"position": [
0,
0
],
"id": "3f07d769-5fda-421d-b76d-5fe2ef632494",
"name": "When chat message received",
"webhookId": "061b4b74-7f0a-4ac1-a1e6-31463db28c2f"
},
{
"parameters": {
"promptType": "define",
"text": "=# 角色与目标\n你是一名严谨的金融经济专家与量化策略顾问。核心目标:基于“实时快照数据 + 新闻”,从**网格交易**视角,对目标标的给出**单一且明确**的结论(买入|观望|减仓/止盈),并配套可执行的网格参数建议。\n\n# 工具使用(必须遵守)\n1) **必须先调用**「Download the snapshot content in BrightData」工具,围绕用户输入自动抓取相关标的的:\n - 最新价格/走势(近N个数据点、成交量/波动信息若可得)\n - 近期重要新闻/事件(财报、政策、行业要闻、突发)\n2) 若快照含多来源,优先官方/权威;记录数据时间戳与来源。\n3) **数据可能不完全充足也没关系**:你仍需据**已得数据**给出判断;不得编造数据或来源。无法量化处以保守口径阐明假设,再做结论(必要时默认“观望”更稳妥)。\n4) 不要向用户索取更多信息;用户只负责**触发分析**。分析什么、如何分析,由工具返回的数据决定。\n\n# 选标的与范围(自动决策)\n- 从 {{ $json.chatInput }} 与快照内容中**自动识别**标的(股票/指数/ETF)。若出现多个,优先与输入最相关且数据最完整者;其余可简述但不喧宾夺主。\n\n# 分析方法(网格交易视角)\n- 区间刻画(尽量用20~60个数据点;不足时用可得最长区间):\n - 中枢价:中位数或(若可得)成交量加权均值\n - 波动带:标准差/ATR 或分位区间(P25~P75、P20~P80)\n - 上/下沿:中枢±1σ(或P25/P75;数据稀少时说明近似处理)\n- 新闻因子打分:正/中/负(基于近7~14日要闻的性质、权威度、时效性)\n- 判定规则(结合现价区间位置 + 新闻因子):\n - **买入(分批)**:现价≤中枢-1σ(或≤P25),且新闻因子非明显负向\n - **观望**:现价≈中枢±0.5σ(或P40~P60),或数据不足/新闻不明朗\n - **减仓/止盈**:现价≥中枢+1σ(或≥P75),且新闻不支持继续上行或有兑现压力\n- 网格建议(当适合做网格时):\n - 基准价:当前价或中枢价(注明依据)\n - 网格间距:参考ATR或分位带宽度的20%~40%(1.0%~2.5%示例)\n - 层数:5~9层(视风险偏好与资金规模),给出单格资金占比\n - 触发逻辑:每下行一格买入、上行一格卖出;极端行情的暂停/宽格策略\n\n# 输出格式(严格执行)\n**结论**:<买入|观望|减仓/止盈>(仅且必须一项)\n\n**关键依据(来自Bright Data快照)**:\n- 数据时间范围/来源:<时间戳/来源/快照条目ID>\n- 现价 vs 区间:现价=<X>;中枢≈<M>;下沿≈<L>;上沿≈<U>\n- 新闻因子:<正/中/负>;要点1~3条(标注快照条目ID)\n\n**网格方案(若适合做网格)**:\n- 基准价:<数值与选择依据>\n- 间距:<百分比或绝对值>;层数:<N>\n- 单格资金占比:<%>;预计持仓上限:<%或手数>\n- 风险控制:<触发/暂停条件与极端行情处理>\n\n**不确定性与假设(如有)**:\n- <数据缺口、近似方法、事件未落地等;说明对结论的影响方向>\n\n# 数据不足时的处理\n- 仍需给出**明确结论**;若价格数据缺口较大但新闻指向不一,默认“观望”更稳健,并列出最少所需增量数据(如:再补充近30~60个收盘价与近7日权威要闻)以提升把握度。严禁杜撰。\n\n# 合规口径\n- 保持专业、可审计;不承诺收益。所有结论可回溯至快照字段/条目ID。\n\n# 用户输入\n{{ $json.chatInput }}\n",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 2.2,
"position": [
208,
0
],
"id": "d33f9f12-30d2-4e90-bf59-bbd07c9963aa",
"name": "AI Agent"
},
{
"parameters": {
"model": {
"__rl": true,
"value": "gpt-5",
"mode": "list",
"cachedResultName": "gpt-5"
},
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1.2,
"position": [
-80,
176
],
"id": "b38ddf62-6bdb-4eb3-9fa8-13a2e3a73f9e",
"name": "OpenAI Chat Model",
"credentials": {
"openAiApi": {
"id": "cHt3W6zrE1MZhapR",
"name": "OpenAi account 3"
}
}
},
{
"parameters": {},
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"typeVersion": 1.3,
"position": [
224,
208
],
"id": "4abade06-8605-4d3a-9e96-3cda20da81ab",
"name": "Simple Memory"
},
{
"parameters": {
"endpointUrl": "https://mcp.brightdata.com/mcp",
"serverTransport": "httpStreamable",
"authentication": "bearerAuth"
},
"type": "@n8n/n8n-nodes-langchain.mcpClientTool",
"typeVersion": 1.1,
"position": [
512,
208
],
"id": "1bde776a-9e7d-40ba-81eb-0809fe8d99d8",
"name": "MCP Client",
"credentials": {
"httpBearerAuth": {
"id": "jTc0l6p5ezvgKuTV",
"name": "Bearer Auth account"
}
}
},
{
"parameters": {
"method": "POST",
"url": "https://api.brightdata.com/datasets/v3/trigger",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "dataset_id",
"value": "gd_lmrpz3vxmz972ghd7"
},
{
"name": "include_errors",
"value": "true"
}
]
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer 0d326b72b67cb50fdd486842b4e6764e87fd045b0d484f331c4cb8b6d801b8db"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "[\n {\n \"url\": \"https://finance.yahoo.com/quote/MSFT?p=MSFT&.tsrc=fin-srch\"\n },\n {\n \"url\": \"https://finance.yahoo.com/quote/WIX?p=WIX&.tsrc=fin-srch\"\n },\n {\n \"url\": \"https://finance.yahoo.com/quote/NVDA?ncid=yahooproperties_peoplealso_km0o32z3jzm\"\n }\n]",
"options": {}
},
"type": "n8n-nodes-base.httpRequestTool",
"typeVersion": 4.2,
"position": [
672,
208
],
"id": "abb48a85-2d33-4bd5-b2cd-7e218900e7e1",
"name": "HTTP Request"
},
{
"parameters": {
"resource": "webScrapper",
"operation": "downloadSnapshot",
"snapshot_id": "s_mez3q8uqmlqaevyxe",
"requestOptions": {}
},
"type": "@brightdata/n8n-nodes-brightdata.brightDataTool",
"typeVersion": 1,
"position": [
368,
208
],
"id": "a41a1e58-b572-4e85-8097-ab876c2d90a7",
"name": "Download the snapshot content in BrightData",
"credentials": {
"brightdataApi": {
"id": "XQB52as52ayl6Y4F",
"name": "BrightData account"
}
}
},
{
"parameters": {
"modelName": "=models/gemini-2.5-pro",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"typeVersion": 1,
"position": [
80,
208
],
"id": "c8d256fd-d337-48c7-abf0-13a242f1b1ce",
"name": "Google Gemini Chat Model",
"credentials": {
"googlePalmApi": {
"id": "3j30ClZg3Q4SCt6v",
"name": "Google Gemini(PaLM) Api account"
}
}
}
],
"pinData": {},
"connections": {
"When chat message received": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "AI Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"MCP Client": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"HTTP Request": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[]
]
},
"Download the snapshot content in BrightData": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "c4fc2805-fc98-4b8c-b7e0-39eb8ab79826",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "061a623fbcc7557c2a8cf9adeff88a4f0361991b2064e18da2d2ec55546c5ea8"
},
"id": "XliULf3PU7mN4zfc",
"tags": []
}
Top comments (0)