Data Flow¶
End-to-end walkthrough of how a TradingView chart becomes structured trading signals displayed on a live dashboard. Uses a concrete example: an ES 5-minute chart during the New York AM session.
Full Platform Flow¶
graph TB
TV["TradingView Desktop<br/>ES 5min chart, 4 indicators"]
TV -- "CDP WebSocket<br/>localhost:9222" --> MCP["tradingview-mcp<br/>data_get_pine_labels/lines/boxes/tables"]
MCP -- "study_filter per indicator" --> READ["Readers<br/>5 parallel reads"]
READ -- "normalized raw objects" --> INTERP["Interpreters<br/>contract rules applied"]
INTERP -- "5 typed signals" --> ENG["Engine<br/>confluence + filters"]
ENG -- "StrategyFlags JSON" --> SERVER["server.js<br/>localhost:8000"]
SERVER -- "/api/data" --> BROWSER["Browser<br/>dashboard UI"]
SERVER -- "nginx proxy" --> DOMAIN["ictedgefund.com"]
Scenario¶
- Symbol: ES (E-mini S&P 500 futures)
- Timeframe: 5 minutes
- Time: 2026-04-14 09:55 ET (NY AM killzone, 0950-1010 macro active)
- Chart state: Daily bias bearish, active macro window, bearish OB with FVG filter, SMT divergence between ES/NQ
Stage 1: TradingView Renders Pine Graphics¶
Four indicators run inside TradingView and render their output as Pine graphics objects. These exist in the DOM as structured data, not just pixels:
| Indicator | Renders |
|---|---|
| Bias AI | Labels (bias direction) + tables (weekly bias, confidence) |
| Session Hunt AI | Labels (session/macro IDs) + lines (liquidity levels) |
| OB AI | Boxes (order block zones) + labels (FVG/mitigation status) |
| SMT AI | Labels (divergence type) + lines (divergence connections) |
Stage 2: MCP Reads via CDP¶
Each reader calls tradingview-mcp with study_filter to isolate its indicator. All five reads execute in parallel.
Bias AI labels (data_get_pine_labels({ study_filter: "Bias AI" })):
[
{ "time": 1744617600, "price": 5248.75, "text": "Bearish", "color": "#FF5252",
"style": "label_down", "tooltip": "Daily Bias: Bearish | Confidence: 85%" },
{ "time": 1744185600, "price": 5260.00, "text": "Bearish", "color": "#FF5252",
"style": "label_down", "tooltip": "Weekly Bias: Bearish" }
]
OB AI boxes (data_get_pine_boxes({ study_filter: "OB AI" })):
[
{ "left": 1744625400, "top": 5245.50, "right": 1744632600, "bottom": 5243.00,
"backgroundColor": "rgba(255, 82, 82, 0.2)", "borderColor": "#FF5252",
"text": "OB" }
]
Session Hunt AI labels + lines, SMT AI labels -- similar structured objects with timestamps, coordinates, colors, and text.
Stage 3: Readers Normalize¶
Each reader converts raw MCP responses into consistent shapes:
- Unix timestamps to ISO strings
- Coordinates into
{ time, price }objects - Related objects grouped (box + nearby label)
- Out-of-range graphics filtered
No interpretation. The reader does not know what a red box means.
Bias reader output:
{
"labels": [
{ "time": "2026-04-14T08:00:00Z", "price": 5248.75, "text": "Bearish",
"color": "#FF5252", "tooltip": "Daily Bias: Bearish | Confidence: 85%" }
],
"tables": []
}
Stage 4: Interpreters Extract Signals¶
Each interpreter applies its indicator contract to produce a typed signal.
{
"type": "BiasSignal",
"dailyBias": "bearish",
"weeklyBias": "bearish",
"confidence": 0.85,
"biasShift": false
}
#FF5252 = bearish. Tooltip regex Confidence: (\d+)% extracts 0.85.
{
"type": "OBSignal",
"blocks": [{ "direction": "bearish", "high": 5245.50, "low": 5243.00,
"fvgFiltered": true, "mitigated": false }],
"nearestBlock": { "direction": "bearish", "distanceFromPrice": 0.75 }
}
#FF5252 border = bearish. Nearby "OB" label = active (not mitigated).
Stage 5: Engine Scores and Builds Flags¶
No-Trade Filter Check¶
| Filter | Result |
|---|---|
| Daily bias established | Pass (bearish) |
| Inside killzone | Pass (NY AM) |
| Unmitigated OB visible | Pass (bearish OB) |
| No bias shift | Pass |
All filters pass.
Confluence Scoring¶
| Component | Present | Weight | Score |
|---|---|---|---|
| Daily bias | Yes | 2 | 2 |
| Weekly agrees | Yes | 1 | 1 |
| Active killzone | Yes | 2 | 2 |
| Active macro | Yes | 1 | 1 |
| Unmitigated OB in bias dir | Yes | 3 | 3 |
| FVG-filtered OB | Yes | 1 | 1 |
| SMT in bias dir | Yes | 2 | 2 |
| Total | 12/12 | 100 |
Stage 6: StrategyFlags Output¶
{
"timestamp": "2026-04-14T13:55:00Z",
"symbol": "ES",
"timeframe": "5",
"bias": { "daily": "bearish", "weekly": "bearish", "shift": false, "confidence": 0.85 },
"session": { "name": "NY_AM", "macro": "0950-1010", "killzone": true },
"orderBlocks": [{ "direction": "bearish", "high": 5245.50, "low": 5243.00,
"fvg": true, "mitigated": false, "distanceFromPrice": 0.75 }],
"smt": { "present": true, "direction": "bearish", "pair": "ES/NQ", "strength": 0.7 },
"price": { "current": 5246.25, "atr": 12.5, "microStructure": "lower_highs" },
"confluence": 100,
"tradeReady": true,
"setup": "SMT_OB_SESSION",
"noTradeReasons": []
}
Stage 7: Dashboard Display¶
server.js serves this JSON at /api/data. The browser polls and renders:
- Confluence gauge at 100 (green)
- "TRADE READY" indicator lit
- Setup type: SMT_OB_SESSION
- Bearish bias badge with 85% confidence
- NY AM session active, 0950-1010 macro highlighted
- Order block zone drawn on chart screenshot
- SMT divergence indicator for ES/NQ
nginx proxies localhost:8000 to ictedgefund.com with SSL termination via certbot.
Transformation Summary¶
Pine graphics (DOM objects)
↓ CDP Runtime.evaluate()
Raw JSON arrays (labels, lines, boxes, tables)
↓ study_filter isolation
Per-indicator raw data
↓ timestamp normalization, coordinate extraction
Normalized reader output
↓ color mapping, text parsing, spatial logic
Typed signals (BiasSignal, SessionSignal, OBSignal, SMTSignal, PriceSignal)
↓ no-trade filters, weighted scoring, setup detection
StrategyFlags JSON
↓ HTTP /api/data
Dashboard UI
↓ nginx reverse proxy + SSL
ictedgefund.com
Each transformation is a pure function of its inputs. No hidden state, no side effects, no feedback loops.