Skip to content

tradingview-strategy

ICT strategy interpretation layer. Reads four Pine indicators through tradingview-mcp, interprets graphics into structured signals, and produces StrategyFlags JSON. Serves a live dashboard at localhost:8000.


Pipeline Overview

graph LR
    subgraph Readers["Readers (parallel)"]
        R1["biasReader"]
        R2["sessionReader"]
        R3["obReader"]
        R4["smtReader"]
        R5["priceReader"]
    end

    subgraph Interpreters["Interpreters"]
        I1["biasInterpreter"]
        I2["sessionInterpreter"]
        I3["obInterpreter"]
        I4["smtInterpreter"]
        I5["priceInterpreter"]
    end

    subgraph Engine["Engine"]
        E1["No-trade filters"]
        E2["Confluence scoring"]
        E3["Setup detection"]
        E4["Flag builder"]
        E1 --> E2 --> E3 --> E4
    end

    R1 --> I1
    R2 --> I2
    R3 --> I3
    R4 --> I4
    R5 --> I5

    I1 & I2 & I3 & I4 & I5 --> E1

    E4 --> FLAGS["StrategyFlags JSON"]
    FLAGS --> DASH["Dashboard :8000"]

Readers

Each reader is responsible for a single indicator. It calls MCP tools with study_filter, normalizes the response, and returns raw data. Readers perform no interpretation.

Reader study_filter MCP Tools Used Output Shape
biasReader "Bias AI" getPineLabels, getPineTables { labels: [], tables: [] }
sessionReader "Session Hunt AI" getPineLabels, getPineLines { labels: [], lines: [] }
obReader "OB AI" getPineBoxes, getPineLabels { boxes: [], labels: [] }
smtReader "SMT Divergences" getPineLabels, getPineLines { labels: [], lines: [] }
priceReader N/A getOhlcv, quoteGet { bars: [], quote: {} }

Reader responsibilities:

  • Call MCP tools with study_filter to isolate indicator data
  • Handle empty responses (indicator not loaded, no visible data)
  • Normalize timestamps and coordinates
  • Return raw objects without interpretation

Every reader exports a single async function: async function read(options) -> { ... }


Interpreters

Each interpreter takes reader output and applies indicator-specific contract rules to produce a typed signal. This is where color mappings, label text parsing, and spatial logic live.

Interpreter Output Signal Key Fields
biasInterpreter BiasSignal dailyBias, weeklyBias, confidence, biasShift
sessionInterpreter SessionSignal activeSession, activeMacro, killzoneActive, liquiditySweep
obInterpreter OBSignal blocks[], nearestBlock, fvgFiltered, mitigated
smtInterpreter SMTSignal divergencePresent, direction, pair, strength
priceInterpreter PriceSignal currentPrice, atr, recentSwings, microStructure

Interpreters are synchronous and pure. No I/O, no side effects, no MCP calls.

Interpretation Examples

  • Bias AI: Green label = bullish, red = bearish. Tooltip regex Confidence: (\d+)% extracts confidence.
  • Session Hunt AI: Label text "NY AM | 0950-1010" parsed to session + macro. Dotted lines = liquidity levels.
  • OB AI: Box color = direction. Coordinates = zone boundaries. Nearby labels = FVG/mitigation status.
  • SMT AI: Label pairs on correlated instruments indicate divergence. Line slope = direction.

Engine

The engine receives all five signals and produces StrategyFlags.

No-Trade Filters

Hard filters checked first. If any triggers, tradeReady: false and confluence: 0:

  • No daily bias established
  • Outside all session killzones
  • No unmitigated order blocks visible
  • Bias shift detected (transitional state)

Confluence Scoring

Signal Component Weight Condition
Daily bias present 2 BiasSignal.dailyBias !== null
Weekly bias agrees with daily 1 Weekly matches daily
Active killzone 2 SessionSignal.killzoneActive
Active macro window 1 SessionSignal.activeMacro !== null
Unmitigated OB in bias direction 3 Direction matches bias, not mitigated
FVG-filtered OB 1 OBSignal.fvgFiltered
SMT divergence in bias direction 2 Direction matches bias

Raw score normalized to 0-100.

Setup Detection

When confluence exceeds threshold and no filters are active:

  • OB_FVG_BIAS -- order block + FVG filter + directional bias
  • SMT_OB_SESSION -- divergence-confirmed entry with session context
  • MACRO_OB_BIAS -- macro window entry

Flag Builder

Assembles the final StrategyFlags JSON:

{
  "timestamp": "2026-04-14T14:35: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 }],
  "smt": { "present": true, "direction": "bearish", "pair": "ES/NQ", "strength": 0.7 },
  "price": { "current": 5246.25, "atr": 12.5 },
  "confluence": 82,
  "tradeReady": true,
  "setup": "OB_FVG_BIAS",
  "noTradeReasons": []
}

Orchestration

scan.js -- Full Pipeline

scan.js executes one complete scan cycle:

  1. All five readers execute in parallel (independent indicators)
  2. Interpreters run sequentially (synchronous, fast)
  3. Engine runs once with all signals collected
  4. Returns StrategyFlags

Total wall-clock time is dominated by the slowest MCP read (~100-300ms).

poll.js -- Interval Scanning

Wraps scan.js in an interval loop with delta detection:

  • Configurable interval (default: 5 seconds)
  • Emits events only when flags change
  • Automatic retry on connection drops
  • Graceful shutdown support

Dashboard Integration

The dashboard/ directory inside tradingview-strategy contains a web server and UI.

server.js

Express-based server at localhost:8000 with three API endpoints:

Endpoint Method Returns
/api/data GET Current StrategyFlags JSON
/api/settings GET/POST Indicator configuration and thresholds
/api/screenshot GET Latest chart screenshot (PNG)

The dashboard HTML auto-refreshes by polling /api/data on an interval. It displays:

  • Current bias direction and confidence
  • Active session and macro window
  • Order block proximity and FVG status
  • SMT divergence state
  • Confluence score gauge
  • Trade readiness indicator
  • Live chart screenshot
  • Indicator settings popup for runtime configuration

Pipeline Integration

scan.js writes its output to a location that server.js reads on each API request. The dashboard is always showing the latest completed scan result. No WebSocket -- simple file-based hand-off with HTTP polling.


Contracts

The contracts/ directory holds source-of-truth definitions:

File Contents
schemas.js Zod schemas for all signal types and StrategyFlags
constants.js Session times, macro windows, confluence weights
colors.js Indicator-specific color-to-meaning mappings
indicators.js Indicator names (for study_filter) and expected graphics types

Contracts are the only shared dependency between readers and interpreters. When an indicator updates its output format, the contract file is the single point of change.