Skip to content

Payload Format — Future Indicator Design Guidelines

Current Approach: Natural Visual Encoding

Indicators encode state through natural visual elements: colors, line styles, text patterns, box positions, and table cell backgrounds. MCP reads these and the interpreter translates them into typed strategy state.

This works because: 1. MCP can read all Pine graphics (labels, lines, boxes, tables) 2. Visual encodings are deterministic 3. No indicator modifications required — read-only integration

Limitations

Limitation Impact
Color-dependent User customization can break parsing
Implicit structure Meaning inferred from color + style + position, not declared
No metadata No semantic tags on lines/boxes
No versioning Output changes are undetectable

Structured Payload Options

For indicators designed with MCP as a first-class consumer.

Option A: Delimiter-Based Label Text

Encode structured data as delimited strings in label text.

SIGNAL|KEY1:VALUE1|KEY2:VALUE2|KEY3:VALUE3

Example:

SIGNAL|V:2|BIAS:BULL|CONF:0.85|SESSION:NY_AM|TARGET:5892.50

Pine implementation:

payload = "SIGNAL|BIAS:BULL|CONF:" + str.tostring(confidence, "#.##") + "|SESSION:" + session_name
label.new(bar_index, close, payload, style=label.style_none, size=size.tiny, textcolor=color.new(color.white, 100))

Using label.style_none with transparent text makes it invisible to the trader but readable by MCP.

Option B: JSON in Table Cells

Encode structured data as JSON strings in hidden table cells.

{"bias": "bull", "confidence": 0.85, "session": "NY_AM", "target": 5892.50}

Pine implementation:

var t = table.new(position.bottom_left, 1, 5, bgcolor=color.new(color.white, 100), border_color=color.new(color.white, 100))
json_payload = '{"bias":"bull","confidence":' + str.tostring(confidence) + '}'
table.cell(t, 0, 0, json_payload, text_color=color.new(color.white, 100))

Comparison

Criterion Option A (Delimiter Labels) Option B (JSON Tables)
Parsing Low (string split) Medium (JSON parse)
Data richness Flat key-value Nested objects, arrays
Time-series One label per bar (natural) Single table (latest state only)
Historical access Labels persist at their bar Table shows current values only

Recommendation: - Option A for bar-specific signals (entry signals, pattern events) - Option B for current-state summaries (aggregated indicator state) - Both when an indicator needs event history and current state


Design Guidelines

  1. Separate human and machine channels — visible elements for the trader, hidden elements for MCP
  2. Include a version fieldV:2 or "version": 2
  3. Include a timestampTS:1713100800 for stale data detection
  4. Use consistent key names across all indicators (DIR, CONF, LVL, STATE, SESSION)
  5. Fail explicitly — emit STATE:NO_DATA|REASON:insufficient_bars rather than nothing
  6. One indicator, one table position — prevent collisions
  7. Keep payloads under 500 characters — Pine string ops are slow

When to Apply

This format is for future indicators built with MCP in mind. All 7 indicators in the current set are being built from scratch, so this format can be adopted from the start rather than retrofitted.