{
  "$defs": {
    "ADXIndicatorValueRef": {
      "additionalProperties": false,
      "description": "ADX with access to +DI / -DI directional indicators.\n\nThe ADX indicator computes three series internally: the composite ADX\n(trend strength) plus the Plus Directional Indicator (+DI) and Minus\nDirectional Indicator (-DI). Use ``output`` to select which series:\n\n  - ``adx`` (default): composite Wilder ADX, 0-100 trend strength.\n  - ``plus_di``: +DI, upward directional movement strength.\n  - ``minus_di``: -DI, downward directional movement strength.\n\nAll outputs first exist after 2N bars seen (zero-based index 2N-1).\nPublic DI access intentionally waits for composite ADX readiness; TA-Lib\nPLUS_DI/MINUS_DI instead start at index N (DEC-018).\n\n``plus_di > minus_di`` indicates an up-trending directional bias;\n``plus_di < minus_di`` indicates a down-trending bias.",
      "properties": {
        "indicator": {
          "const": "adx_di",
          "default": "adx_di",
          "title": "Indicator",
          "type": "string"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "output": {
          "default": "adx",
          "enum": [
            "adx",
            "plus_di",
            "minus_di"
          ],
          "title": "Output",
          "type": "string"
        },
        "period": {
          "default": 14,
          "maximum": 500,
          "minimum": 2,
          "title": "Period",
          "type": "integer"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "title": "ADXIndicatorValueRef",
      "type": "object"
    },
    "AVWAPIndicatorValueRef": {
      "additionalProperties": false,
      "description": "Anchored VWAP \u2014 VWAP anchored to a specific session/week/month/custom point.\n\nMirrors the IR ``AnchoredVWAP`` model: ``anchor`` selects the canonical\nanchor boundary; ``anchor_datetime`` (ISO 8601 string) supplies the custom\nanchor instant when ``anchor=\"custom\"``.\n\nUse ``vwap`` for the simple session-anchored case; use ``avwap`` when you\nneed week/month/ytd/custom anchors or the ``std_dev`` band output.",
      "properties": {
        "anchor": {
          "default": "session",
          "enum": [
            "session",
            "session_open",
            "week",
            "week_open",
            "month",
            "month_open",
            "month_start",
            "ytd",
            "custom"
          ],
          "title": "Anchor",
          "type": "string"
        },
        "anchor_datetime": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Anchor Datetime"
        },
        "indicator": {
          "const": "avwap",
          "default": "avwap",
          "title": "Indicator",
          "type": "string"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "output": {
          "default": "value",
          "enum": [
            "value",
            "std_dev"
          ],
          "title": "Output",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "title": "AVWAPIndicatorValueRef",
      "type": "object"
    },
    "AdIndicatorValueRef": {
      "additionalProperties": false,
      "description": "Accumulation/Distribution line \u2014 running sum of close-location-value times volume.\n\nCumulative and unbounded from the first bar of loaded history (warmup bars\nincluded), so its absolute level is an artifact of where the data starts:\ncompare it against its own moving average or slope, never against a fixed\nnumber. A bar whose high equals its low contributes zero rather than\ndividing by zero.",
      "properties": {
        "indicator": {
          "const": "ad",
          "default": "ad",
          "title": "Indicator",
          "type": "string"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "title": "AdIndicatorValueRef",
      "type": "object"
    },
    "AnchorPeriod": {
      "enum": [
        "session",
        "week",
        "month"
      ],
      "type": "string"
    },
    "AnchorValueRef": {
      "additionalProperties": false,
      "description": "A field of a named anchor \u2014 a single bar captured earlier and then held.\n\nThe anchor is declared in the strategy's ``anchors`` (captured by\ntimestamp, bar index, or the first false-to-true flip of a condition);\nreferencing an ``anchor_id`` that is not declared fails at compile time.\nUntil the anchor actually fires the value is typed absence. A comparison\nover that absent operand is UNKNOWN; the action boundary takes no action.\n``mid`` and ``range`` are derived from the captured bar's high and low.\nDoes not accept ``resolution``.",
      "properties": {
        "anchor_field": {
          "enum": [
            "open",
            "high",
            "low",
            "close",
            "mid",
            "range"
          ],
          "title": "Anchor Field",
          "type": "string"
        },
        "anchor_id": {
          "title": "Anchor Id",
          "type": "string"
        },
        "kind": {
          "const": "anchor",
          "default": "anchor",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "anchor_id",
        "anchor_field"
      ],
      "title": "AnchorValueRef",
      "type": "object"
    },
    "AroonIndicatorValueRef": {
      "additionalProperties": false,
      "description": "Aroon \u2014 how recently the window's extreme printed, scaled 0-100 (`line` picks up/down).\n\nMeasured over ``period + 1`` bars including the current one: 100 means the\nhighest high (or lowest low) is the current bar, 0 means it is the oldest\nbar in the window. Ties resolve to the **oldest** matching bar, so a level\nthat has been revisited reads lower than 100 even when the current bar\nequals the extreme. This ref exposes only the up and down lines; there is\nno oscillator (up - down) output.",
      "properties": {
        "indicator": {
          "const": "aroon",
          "default": "aroon",
          "title": "Indicator",
          "type": "string"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "line": {
          "enum": [
            "up",
            "down"
          ],
          "title": "Line",
          "type": "string"
        },
        "period": {
          "maximum": 500,
          "minimum": 2,
          "title": "Period",
          "type": "integer"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "period",
        "line"
      ],
      "title": "AroonIndicatorValueRef",
      "type": "object"
    },
    "BandOutput": {
      "enum": [
        "upper",
        "middle",
        "lower"
      ],
      "type": "string"
    },
    "BinaryExprValueRef": {
      "additionalProperties": false,
      "description": "Binary expression over two ValueRef operands.\n\nProvided alongside UnaryExprValueRef so tests / flat-Condition authors can\nbuild composite expressions like ``abs(close - 100)``. Compiles to a binary\nIRExpression.",
      "properties": {
        "kind": {
          "const": "binary_expr",
          "default": "binary_expr",
          "title": "Kind",
          "type": "string"
        },
        "left": {
          "anyOf": [
            {
              "$ref": "#/$defs/ValueRef"
            },
            {
              "type": "number"
            }
          ]
        },
        "op": {
          "enum": [
            "+",
            "-",
            "*",
            "/",
            "max",
            "min"
          ],
          "title": "Op",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "right": {
          "anyOf": [
            {
              "$ref": "#/$defs/ValueRef"
            },
            {
              "type": "number"
            }
          ]
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "op",
        "left",
        "right"
      ],
      "title": "BinaryExprValueRef",
      "type": "object"
    },
    "BollingerValueRef": {
      "additionalProperties": false,
      "description": "Bollinger Bands \u2014 select band edge or derived property.\n\nOutputs:\n  - upper / middle / lower: price-level bands\n  - bandwidth: (upper - lower) / middle * 100\n  - stddev: population standard deviation over the window",
      "properties": {
        "indicator": {
          "const": "bollinger",
          "default": "bollinger",
          "title": "Indicator",
          "type": "string"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "multiplier": {
          "default": 2.0,
          "ge": 0.1,
          "le": 10.0,
          "title": "Multiplier",
          "type": "number"
        },
        "output": {
          "enum": [
            "upper",
            "middle",
            "lower",
            "bandwidth",
            "stddev"
          ],
          "title": "Output",
          "type": "string"
        },
        "period": {
          "default": 20,
          "maximum": 500,
          "minimum": 2,
          "title": "Period",
          "type": "integer"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "output"
      ],
      "title": "BollingerValueRef",
      "type": "object"
    },
    "CandlestickValueRef": {
      "additionalProperties": false,
      "description": "Candlestick pattern recognition as a numeric signal value (VIB-1316).\n\nEmits a per-bar value in ``{-1.0, 0.0, +1.0}`` indicating a bearish\npattern hit, no hit, or a bullish pattern hit respectively. Resolves the\npattern name to the same :class:`CandlePattern` class as\n``CandlePatternSpec`` and registers the same indicator, so the two paths\nare literally one value series, not two that agree.\n\nA name that reads as one side of a two-sided shape means that side only:\n``bearish_engulfing`` is ``-1`` on a bearish engulfing and ``0`` on a\nbullish one, never ``+1``.\n\nUse this ValueRef when you need the pattern value as an operand in a\n``compare`` or ``cross`` condition (e.g. ``candlestick(doji) == 1``).\nFor role-shaped entry/exit semantics with quality filters, prefer\n``CandlePatternSpec`` as the top-level ConditionSpec.",
      "properties": {
        "indicator": {
          "const": "candlestick",
          "default": "candlestick",
          "title": "Indicator",
          "type": "string"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "pattern": {
          "$ref": "#/$defs/PatternName"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "pattern"
      ],
      "title": "CandlestickValueRef",
      "type": "object"
    },
    "ConstantValueRef": {
      "additionalProperties": false,
      "description": "A fixed numeric literal, usable anywhere a value ref is accepted.\n\nThe one ref that is NOT a ``ValueRefBaseModel``: it has no ``symbol`` or\n``resolution`` qualifier. A bare int/float written into ``binary_expr``/\n``unary_expr`` operands or ``compare.right`` is coerced to this type\nautomatically, so writing it out explicitly is rarely necessary.",
      "properties": {
        "kind": {
          "const": "constant",
          "default": "constant",
          "title": "Kind",
          "type": "string"
        },
        "value": {
          "title": "Value",
          "type": "number"
        }
      },
      "required": [
        "value"
      ],
      "title": "ConstantValueRef",
      "type": "object"
    },
    "DispersionValueRef": {
      "additionalProperties": false,
      "description": "Spread of ``source`` across the WHOLE universe on the current bar.\n\nUnlike ``rank`` and ``xs_zscore`` it does not say where this symbol sits; every\nsymbol reads the same number, so it does not degrade while this symbol's own\nvalue is still warming up. ``stat`` chooses the standard deviation or the range.\n``source`` is evaluated once per symbol; it cannot carry a ``symbol`` and cannot\ncontain another cross-sectional operand. Requires a universe or portfolio strategy\nwith two or more symbols.\n\nExample, how widely 20-bar returns are spread across the universe:\n  {\"kind\": \"xs_dispersion\", \"stat\": \"stdev\",\n   \"source\": {\"kind\": \"indicator\", \"indicator\": \"roc\", \"period\": 20}}",
      "properties": {
        "kind": {
          "const": "xs_dispersion",
          "default": "xs_dispersion",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "source": {
          "anyOf": [
            {
              "$ref": "#/$defs/ValueRef"
            },
            {
              "type": "number"
            }
          ],
          "description": "Per-symbol value whose spread across the universe is measured on the current bar. It is evaluated for each symbol on its own data."
        },
        "stat": {
          "description": "'stdev' = sample standard deviation (ddof=1) of the symbols' values. 'range' = highest minus lowest.",
          "enum": [
            "stdev",
            "range"
          ],
          "title": "Stat",
          "type": "string"
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "source",
        "stat"
      ],
      "title": "DispersionValueRef",
      "type": "object"
    },
    "DonchianValueRef": {
      "additionalProperties": false,
      "description": "Donchian Channel \u2014 rolling max/min over `period` bars; **excludes the current bar** (differs from most charting platforms which include it).\n\nNote: this engine excludes the current bar so that a close-exceeds-upper\nbreakout signal is meaningful (the current bar cannot contaminate its own\nband). Most charting platforms plot Donchian bands *including* the current\nbar \u2014 strategies ported from those platforms will see the breakout-bar\nupper/lower differ by one bar of high/low data. See\n``docs/indicator-conventions.md``.",
      "properties": {
        "indicator": {
          "const": "donchian",
          "default": "donchian",
          "title": "Indicator",
          "type": "string"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "output": {
          "$ref": "#/$defs/BandOutput"
        },
        "period": {
          "default": 20,
          "maximum": 500,
          "minimum": 2,
          "title": "Period",
          "type": "integer"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "output"
      ],
      "title": "DonchianValueRef",
      "type": "object"
    },
    "EntryBarField": {
      "enum": [
        "open",
        "high",
        "low",
        "close",
        "range",
        "body_high",
        "body_low"
      ],
      "type": "string"
    },
    "EntryBarValueRef": {
      "additionalProperties": false,
      "description": "Reference to a field of the signal bar for the currently-open position.\n\nAuto-captured by the engine when a position opens. Returns NaN when no\nposition is open. Clears on position close. Use for ORB-style \"stop out\nbelow the signal-bar low\" without AnchorDefinition's silent-latching bug.\n\nFields:\n  - open / high / low / close: signal-bar OHLC\n  - range: high - low\n  - body_high: max(open, close)\n  - body_low: min(open, close)",
      "properties": {
        "entry_bar_field": {
          "$ref": "#/$defs/EntryBarField"
        },
        "kind": {
          "const": "entry_bar",
          "default": "entry_bar",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "entry_bar_field"
      ],
      "title": "EntryBarValueRef",
      "type": "object"
    },
    "EquityValueRef": {
      "additionalProperties": false,
      "description": "The strategy's running equity-curve value.\n\n``field`` selects: ``current`` (equity right now), ``peak`` (the running\nhigh-water mark), or ``drawdown_pct`` (percent below that peak \u2014 0 at a\nnew high, positive while underwater). Use ``drawdown_pct`` directly for a\ncircuit-breaker gate rather than deriving it from ``current``/``peak``.\n\nVIB-1370 / VIB-1319: the sub-metric selector is named ``field``\nacross every ValueRef-style type. The legacy name ``equity_metric`` was\nremoved.",
      "properties": {
        "field": {
          "enum": [
            "drawdown_pct",
            "current",
            "peak"
          ],
          "title": "Field",
          "type": "string"
        },
        "kind": {
          "const": "equity",
          "default": "equity",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "field"
      ],
      "title": "EquityValueRef",
      "type": "object"
    },
    "EventDistanceValueRef": {
      "additionalProperties": false,
      "description": "Distance from the current bar to an event type's next or previous occurrence.\n\n``direction=\"previous\"`` counts back to the latest occurrence at or before the\nbar: 0 on the bar the occurrence is assigned to. ``direction=\"next\"`` counts\nforward to the earliest occurrence strictly after the bar, so it is never 0\nin minutes. ``unit`` is wall-clock minutes or bars.\n\nWhen no such occurrence is known the value is infinity (present, not absent), so\n``distance <= N`` is false and ``not (distance <= N)`` is true: that is how a\n\"stay away from events\" gate is written.\n\nA ``next`` distance needs the event's date to be known in advance. Among system\nevents only those with a forward release calendar (macro.cpi,\nmacro.nonfarm_payrolls, macro.unemployment) qualify; any other system event is\nrefused with ``direction=\"next\"``, because the platform cannot anticipate it.\nCustom events are unrestricted. Use ``direction=\"previous\"`` to react after a\nsystem event.\n\nExample, within 5 bars after an event:\n  {\"kind\": \"event_distance\", \"event_type_id\": \"my-signal\", \"direction\": \"previous\",\n   \"unit\": \"bars\"}",
      "properties": {
        "direction": {
          "description": "'previous' = distance back to the latest occurrence at or before this bar. 'next' = distance forward to the earliest occurrence after this bar; needs a custom event or a system event with a forward release calendar.",
          "enum": [
            "next",
            "previous"
          ],
          "title": "Direction",
          "type": "string"
        },
        "event_type_id": {
          "description": "Event type ID from list_event_types().",
          "title": "Event Type Id",
          "type": "string"
        },
        "kind": {
          "const": "event_distance",
          "default": "event_distance",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        },
        "unit": {
          "anyOf": [
            {
              "enum": [
                "minutes",
                "bars"
              ],
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Measure the distance in wall-clock minutes or in bars; minutes when omitted.",
          "title": "Unit"
        }
      },
      "required": [
        "event_type_id",
        "direction"
      ],
      "title": "EventDistanceValueRef",
      "type": "object"
    },
    "EventFieldValueRef": {
      "additionalProperties": false,
      "description": "Field from latest event payload.\n\nAuthoring flow:\n  1. Call list_event_types().\n  2. Pick event_type_id from a returned event type.\n  3. Pick event_field from payload_schema.fields.\n\nExample:\n  {\"kind\": \"event_field\", \"event_type_id\": \"macro.cpi\",\n   \"event_field\": \"value\"}\n\nTo compare a release against a previous one, set occurrences_back on a\nsecond ref and subtract:\n  {\"kind\": \"binary_expr\", \"op\": \"-\",\n   \"left\":  {\"kind\": \"event_field\", \"event_type_id\": \"macro.cpi\",\n             \"event_field\": \"value\"},\n   \"right\": {\"kind\": \"event_field\", \"event_type_id\": \"macro.cpi\",\n             \"event_field\": \"value\", \"occurrences_back\": 1}}",
      "properties": {
        "event_field": {
          "description": "Payload field from payload_schema.fields. A field the event type's schema does not declare is refused, naming the declared fields.",
          "title": "Event Field",
          "type": "string"
        },
        "event_type_id": {
          "description": "Event type ID from list_event_types().",
          "title": "Event Type Id",
          "type": "string"
        },
        "fill": {
          "default": "previous",
          "description": "'previous' carries forward; 'none' resolves only on the event bar.",
          "enum": [
            "none",
            "previous"
          ],
          "title": "Fill",
          "type": "string"
        },
        "kind": {
          "const": "event_field",
          "default": "event_field",
          "title": "Kind",
          "type": "string"
        },
        "max_age_seconds": {
          "anyOf": [
            {
              "minimum": 0,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Staleness limit for carried-forward values, in seconds.",
          "title": "Max Age Seconds"
        },
        "occurrences_back": {
          "default": 0,
          "description": "0 = latest release; 1 = the release before it, and so on. Counted by distinct data period, so a later revision of an earlier period does not consume a step. Requires an event type whose payload declares a 'period' (the macro.*/treasury.*/market.*/energy.* release families) and fill='previous'. Resolves as missing when fewer than occurrences_back+1 releases are known.",
          "minimum": 0,
          "title": "Occurrences Back",
          "type": "integer"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "event_type_id",
        "event_field"
      ],
      "title": "EventFieldValueRef",
      "type": "object"
    },
    "GapIndicatorValueRef": {
      "additionalProperties": false,
      "description": "Session-open gap, in percent: (session open - prior session close) / prior session close * 100.\n\nThe value exists ONLY on the first bar of the chosen session, and only once the\nprior session's close is known; on every other bar it is absent, so a comparison\nover it is unknown. Compare it with a threshold to state a market fact: a gap up\nis ``gap > 0.5``, a gap down is ``gap < -0.5``. The operand names no trade side.\n\nThe source candles must preserve both session boundaries. US equity candles do so\nat every supported resolution; crypto candles (UTC-aligned) do so for all three\nsessions through 30m and for Asia at 1h. Other region and timeframe combinations\nare refused when the strategy is compiled. Unlike ``gap_pct`` (every bar, open\nagainst the previous close), this is session-aware.\n\nExample: {\"kind\": \"indicator\", \"indicator\": \"gap\", \"session\": \"us\"}",
      "properties": {
        "indicator": {
          "const": "gap",
          "default": "gap",
          "title": "Indicator",
          "type": "string"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "session": {
          "anyOf": [
            {
              "enum": [
                "us",
                "eu",
                "asia"
              ],
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Session whose opening gap is measured: 'us', 'eu' or 'asia'; 'us' when omitted. Requires candles aligned to that session's open and close (see the operand description).",
          "title": "Session"
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "title": "GapIndicatorValueRef",
      "type": "object"
    },
    "IndicatorValueRef": {
      "discriminator": {
        "mapping": {
          "ad": "#/$defs/AdIndicatorValueRef",
          "adx_di": "#/$defs/ADXIndicatorValueRef",
          "aroon": "#/$defs/AroonIndicatorValueRef",
          "atr": "#/$defs/PeriodIndicatorValueRef",
          "avwap": "#/$defs/AVWAPIndicatorValueRef",
          "bollinger": "#/$defs/BollingerValueRef",
          "candlestick": "#/$defs/CandlestickValueRef",
          "cci": "#/$defs/PeriodIndicatorValueRef",
          "cmf": "#/$defs/PeriodIndicatorValueRef",
          "donchian": "#/$defs/DonchianValueRef",
          "ema": "#/$defs/MovingAverageValueRef",
          "gap": "#/$defs/GapIndicatorValueRef",
          "keltner": "#/$defs/KeltnerValueRef",
          "macd": "#/$defs/MacdIndicatorValueRef",
          "macd_histogram": "#/$defs/MacdIndicatorValueRef",
          "macd_signal": "#/$defs/MacdIndicatorValueRef",
          "median": "#/$defs/PeriodIndicatorValueRef",
          "mfi": "#/$defs/PeriodIndicatorValueRef",
          "obv": "#/$defs/OBVIndicatorValueRef",
          "pivot_p": "#/$defs/PivotIndicatorValueRef",
          "pivot_r1": "#/$defs/PivotIndicatorValueRef",
          "pivot_r2": "#/$defs/PivotIndicatorValueRef",
          "pivot_r3": "#/$defs/PivotIndicatorValueRef",
          "pivot_s1": "#/$defs/PivotIndicatorValueRef",
          "pivot_s2": "#/$defs/PivotIndicatorValueRef",
          "pivot_s3": "#/$defs/PivotIndicatorValueRef",
          "roc": "#/$defs/PeriodIndicatorValueRef",
          "rsi": "#/$defs/PeriodIndicatorValueRef",
          "sma": "#/$defs/MovingAverageValueRef",
          "srsi_d": "#/$defs/SrsiIndicatorValueRef",
          "srsi_k": "#/$defs/SrsiIndicatorValueRef",
          "std": "#/$defs/PeriodIndicatorValueRef",
          "stochastic_d": "#/$defs/StochasticIndicatorValueRef",
          "stochastic_k": "#/$defs/StochasticIndicatorValueRef",
          "supertrend": "#/$defs/SupertrendIndicatorValueRef",
          "var": "#/$defs/PeriodIndicatorValueRef",
          "volume_sma": "#/$defs/PeriodIndicatorValueRef",
          "vwap": "#/$defs/VWAPIndicatorValueRef",
          "vwap_bands": "#/$defs/VWAPBandsValueRef",
          "vwma": "#/$defs/MovingAverageValueRef",
          "wma": "#/$defs/MovingAverageValueRef"
        },
        "propertyName": "indicator"
      },
      "oneOf": [
        {
          "$ref": "#/$defs/MovingAverageValueRef"
        },
        {
          "$ref": "#/$defs/PeriodIndicatorValueRef"
        },
        {
          "$ref": "#/$defs/MacdIndicatorValueRef"
        },
        {
          "$ref": "#/$defs/StochasticIndicatorValueRef"
        },
        {
          "$ref": "#/$defs/SrsiIndicatorValueRef"
        },
        {
          "$ref": "#/$defs/AdIndicatorValueRef"
        },
        {
          "$ref": "#/$defs/OBVIndicatorValueRef"
        },
        {
          "$ref": "#/$defs/AroonIndicatorValueRef"
        },
        {
          "$ref": "#/$defs/SupertrendIndicatorValueRef"
        },
        {
          "$ref": "#/$defs/BollingerValueRef"
        },
        {
          "$ref": "#/$defs/DonchianValueRef"
        },
        {
          "$ref": "#/$defs/KeltnerValueRef"
        },
        {
          "$ref": "#/$defs/VWAPBandsValueRef"
        },
        {
          "$ref": "#/$defs/VWAPIndicatorValueRef"
        },
        {
          "$ref": "#/$defs/AVWAPIndicatorValueRef"
        },
        {
          "$ref": "#/$defs/ADXIndicatorValueRef"
        },
        {
          "$ref": "#/$defs/PivotIndicatorValueRef"
        },
        {
          "$ref": "#/$defs/CandlestickValueRef"
        },
        {
          "$ref": "#/$defs/GapIndicatorValueRef"
        }
      ],
      "required": [
        "indicator"
      ]
    },
    "KeltnerValueRef": {
      "additionalProperties": false,
      "description": "Keltner Channel \u2014 EMA middle with ATR-based upper/lower bands.\n\nMirrors BollingerValueRef/DonchianValueRef. Exposes typed access to the\nthree KC band edges. ``period`` drives the EMA middle band. Set\n``atr_period`` to use a different lookback for the ATR that shapes the\nupper/lower bands (common practice is a shorter ATR than the EMA, e.g.\n``period=20, atr_period=10``). ``atr_period=None`` (default) reuses\n``period`` for ATR \u2014 historical behavior.",
      "properties": {
        "atr_period": {
          "anyOf": [
            {
              "maximum": 500,
              "minimum": 2,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Atr Period"
        },
        "indicator": {
          "const": "keltner",
          "default": "keltner",
          "title": "Indicator",
          "type": "string"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "multiplier": {
          "default": 2.0,
          "ge": 0.1,
          "le": 10.0,
          "title": "Multiplier",
          "type": "number"
        },
        "output": {
          "$ref": "#/$defs/BandOutput"
        },
        "period": {
          "default": 20,
          "maximum": 500,
          "minimum": 2,
          "title": "Period",
          "type": "integer"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "output"
      ],
      "title": "KeltnerValueRef",
      "type": "object"
    },
    "LivePositionValueRef": {
      "additionalProperties": false,
      "description": "A metric of the CURRENTLY OPEN position, read live every bar (not a\nfrozen snapshot from entry \u2014 contrast ``entry_bar``/``sequence_step``,\nwhich capture a value once and hold it).\n\n``field`` selects: ``entry_price``, ``bars_in_position``,\n``unrealized_pnl_pct`` / ``unrealized_pnl_usd``, or\n``max_excursion_pct`` / ``min_excursion_pct`` (the best/worst unrealized\nPnL% reached since entry \u2014 MAE/MFE). All are NaN while flat.\n\n``bars_in_position`` counts the bars the position has been open in,\nINCLUDING the bar it filled in: it is 1 at the close of the fill bar, not\n0. An exit on ``bars_in_position >= N`` therefore decides at the close of\nthe Nth held bar and fills at the next bar's open, so the trade's\n``exit_bar - entry_bar`` is exactly N.\n\nVIB-1398 / VIB-1370 / VIB-1319: the sub-metric selector is named\n``field`` across every ValueRef-style type. The legacy name\n``position_metric`` was removed (mirrors the IR-side\n``LivePositionRef.metric \u2192 field`` rename that VIB-1394 shipped).",
      "properties": {
        "field": {
          "enum": [
            "entry_price",
            "bars_in_position",
            "unrealized_pnl_pct",
            "unrealized_pnl_usd",
            "max_excursion_pct",
            "min_excursion_pct"
          ],
          "title": "Field",
          "type": "string"
        },
        "kind": {
          "const": "live_position",
          "default": "live_position",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "field"
      ],
      "title": "LivePositionValueRef",
      "type": "object"
    },
    "MacdIndicatorValueRef": {
      "additionalProperties": false,
      "description": "MACD \u2014 `indicator` selects the macd line, its signal line, or the histogram.\n\n``macd`` is ``EMA(fast) - EMA(slow)`` on close; ``macd_signal`` is an\nSMA-seeded EMA **of the MACD line**, not of price; ``macd_histogram`` is\n``macd - macd_signal``. The MACD line first exists after ``slow_period``\nbars have been seen, at zero-based index ``slow_period - 1``. The signal\nline and histogram first exist after ``slow_period + signal_period - 1``\nbars have been seen, at zero-based index ``slow_period + signal_period - 2``.\nEach line is NaN before its readiness point.",
      "properties": {
        "fast_period": {
          "maximum": 500,
          "minimum": 1,
          "title": "Fast Period",
          "type": "integer"
        },
        "indicator": {
          "enum": [
            "macd",
            "macd_signal",
            "macd_histogram"
          ],
          "title": "Indicator",
          "type": "string"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "signal_period": {
          "maximum": 500,
          "minimum": 1,
          "title": "Signal Period",
          "type": "integer"
        },
        "slow_period": {
          "maximum": 500,
          "minimum": 2,
          "title": "Slow Period",
          "type": "integer"
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "indicator",
        "fast_period",
        "slow_period",
        "signal_period"
      ],
      "title": "MacdIndicatorValueRef",
      "type": "object"
    },
    "MovingAverageValueRef": {
      "additionalProperties": false,
      "description": "Moving-average series use the same shape with the authored MA period range.",
      "properties": {
        "indicator": {
          "enum": [
            "ema",
            "sma",
            "wma",
            "vwma"
          ],
          "title": "Indicator",
          "type": "string"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "offset": {
          "default": 0,
          "maximum": 500,
          "minimum": 0,
          "title": "Offset",
          "type": "integer"
        },
        "period": {
          "maximum": 800,
          "minimum": 1,
          "title": "Period",
          "type": "integer"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "indicator",
        "period"
      ],
      "title": "MovingAverageValueRef",
      "type": "object"
    },
    "NamedZoneValueRef": {
      "additionalProperties": false,
      "description": "A boundary of a named strategy-level zone: its `upper`, `lower`, or derived `mid`.\n\n``mid`` is computed as ``(upper + lower) / 2`` at read time and is not a\nstored field. Zone boundaries may themselves be anchor refs, in which case\nthe whole zone reads NaN until that anchor fires. Referencing an undeclared\n``zone_id`` fails at compile time. Does not accept ``resolution``.",
      "properties": {
        "kind": {
          "const": "named_zone",
          "default": "named_zone",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        },
        "zone_field": {
          "$ref": "#/$defs/ZoneLevel"
        },
        "zone_id": {
          "title": "Zone Id",
          "type": "string"
        }
      },
      "required": [
        "zone_id",
        "zone_field"
      ],
      "title": "NamedZoneValueRef",
      "type": "object"
    },
    "OBVIndicatorValueRef": {
      "additionalProperties": false,
      "description": "On-balance volume \u2014 running sum of volume signed by the close-to-close direction.\n\nAn unchanged close contributes nothing (neither added nor subtracted). NaN\non the very first bar, since there is no prior close. Like ``ad`` this is\ncumulative from the start of loaded history, so its absolute level is\nmeaningless \u2014 compare it to its own average or slope, not to a constant.",
      "properties": {
        "indicator": {
          "const": "obv",
          "default": "obv",
          "title": "Indicator",
          "type": "string"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "title": "OBVIndicatorValueRef",
      "type": "object"
    },
    "PatternName": {
      "enum": [
        "hammer",
        "inverted_hammer",
        "shooting_star",
        "doji",
        "dragonfly_doji",
        "gravestone_doji",
        "spinning_top",
        "marubozu",
        "bullish_engulfing",
        "bearish_engulfing",
        "harami",
        "harami_cross",
        "inside_bar",
        "morning_star",
        "evening_star",
        "piercing_line",
        "dark_cloud_cover",
        "three_white_soldiers",
        "three_black_crows"
      ],
      "type": "string"
    },
    "PercentileValueRef": {
      "additionalProperties": false,
      "description": "Percentile RANK of the current bar's `field` (or of any `source` value) within the trailing `lookback_bars` window.\n\nReturns ``100 * (values strictly below the current one) / (lookback_bars - 1)``\nover a window that **includes the current bar**: a new window high reads\n100, a new window low reads 0. Ties are not counted, so a perfectly flat\nwindow reads 0.\n\n**This is the inverse of** ``rolling_stats(stat=\"percentile\")``, which\nreturns the *value* sitting at a given percentile level. Use this ref to\nask \"how extreme is price right now\", and ``rolling_stats`` to ask \"what\nprice is the 90th percentile\". NaN propagates: any missing value in the\nwindow returns NaN.\n\n``source`` ranks any value ref rather than a price field, so \"is the volume\nunusually high\" or \"is the band width unusually narrow\" is one operand:\n``lookback_bars`` (2 to 500) is the window the current value is ranked in.\nEvery bar in the window is evaluated, so a long window over a nested\nexpression costs more than a price field does.\n\nExample, the percentile of the Bollinger band width over 100 bars:\n  {\"kind\": \"percentile\", \"lookback_bars\": 100,\n   \"source\": {\"kind\": \"binary_expr\", \"op\": \"-\",\n              \"left\": {\"kind\": \"indicator\", \"indicator\": \"bollinger\", \"output\": \"upper\"},\n              \"right\": {\"kind\": \"indicator\", \"indicator\": \"bollinger\", \"output\": \"lower\"}}}",
      "properties": {
        "field": {
          "anyOf": [
            {
              "$ref": "#/$defs/PriceField"
            },
            {
              "type": "null"
            }
          ],
          "default": "close",
          "description": "Price field to rank (open, high, low or close). Mutually exclusive with `source`: when `source` is given there is no price field. Close when neither is given."
        },
        "kind": {
          "const": "percentile",
          "default": "percentile",
          "title": "Kind",
          "type": "string"
        },
        "lookback_bars": {
          "default": 100,
          "maximum": 500,
          "minimum": 2,
          "title": "Lookback Bars",
          "type": "integer"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "source": {
          "anyOf": [
            {
              "$ref": "#/$defs/ValueRef"
            },
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Any value ref to rank instead of a price field: an indicator, a volume, or an expression. Mutually exclusive with `field`. Its own resolution and symbol are honoured."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "title": "PercentileValueRef",
      "type": "object"
    },
    "PeriodIndicatorValueRef": {
      "additionalProperties": false,
      "description": "Entry point for the single-period indicator family (ema, sma, rsi, atr, roc, ...).\n\n``period`` means whatever that indicator's textbook definition means, and\nthat differs across the family: ``sma``/``std``/``median`` use a strict\nN-bar window, while ``ema``, ``rsi`` and ``atr`` are SMA-seeded\nand then smoothed exponentially (Wilder for rsi/atr), keeping a\nresponse to data older than N bars. SMA-seeded EMA first exists after N\nbars seen (zero-based index N-1); RSI and ATR at index N.\n\n``roc`` returns a **ratio, not a percentage** \u2014 a 5% move reads ``0.05``,\nso a threshold of ``5`` means 500%. ``offset`` reads the indicator's own\nvalue N bars back, which is how you express \"this indicator is rising\".",
      "properties": {
        "indicator": {
          "enum": [
            "rsi",
            "atr",
            "roc",
            "cci",
            "volume_sma",
            "mfi",
            "cmf",
            "std",
            "var",
            "median"
          ],
          "title": "Indicator",
          "type": "string"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "offset": {
          "default": 0,
          "maximum": 500,
          "minimum": 0,
          "title": "Offset",
          "type": "integer"
        },
        "period": {
          "maximum": 500,
          "minimum": 2,
          "title": "Period",
          "type": "integer"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "indicator",
        "period"
      ],
      "title": "PeriodIndicatorValueRef",
      "type": "object"
    },
    "PivotIndicatorValueRef": {
      "additionalProperties": false,
      "description": "Classic floor-trader pivot levels (P, S1-S3, R1-R3) from the PRIOR day's H/L/C.\n\nLevels are computed once per day and stay **constant for every bar of the\ncurrent day**, rolling forward only at the boundary \u2014 they are not\nrecomputed intraday. The boundary is the **UTC** calendar day, not the\nexchange session, which matters for crypto and for non-US venues. NaN until\none full prior day has completed.",
      "properties": {
        "indicator": {
          "enum": [
            "pivot_p",
            "pivot_s1",
            "pivot_s2",
            "pivot_s3",
            "pivot_r1",
            "pivot_r2",
            "pivot_r3"
          ],
          "title": "Indicator",
          "type": "string"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "indicator"
      ],
      "title": "PivotIndicatorValueRef",
      "type": "object"
    },
    "PriceField": {
      "description": "Price bar fields.",
      "enum": [
        "open",
        "high",
        "low",
        "close"
      ],
      "title": "PriceField",
      "type": "string"
    },
    "PriceValueRef": {
      "additionalProperties": false,
      "description": "A single OHLC field of the current bar, or of a bar `offset` bars back.\n\n``offset=0`` (the default) is the bar being evaluated. Reading past the\nstart of loaded history returns NaN rather than clamping to the first bar,\nand a NaN operand makes the enclosing compare false.",
      "properties": {
        "field": {
          "$ref": "#/$defs/PriceField",
          "default": "close"
        },
        "kind": {
          "const": "price",
          "default": "price",
          "title": "Kind",
          "type": "string"
        },
        "offset": {
          "default": 0,
          "maximum": 500,
          "minimum": 0,
          "title": "Offset",
          "type": "integer"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "title": "PriceValueRef",
      "type": "object"
    },
    "RankValueRef": {
      "additionalProperties": false,
      "description": "Cross-sectional rank of ``source`` among the universe's symbols on the current bar, 0 to 1.\n\nThe lowest symbol reads 0, the highest 1 (mid-rank for ties). With fewer than 2\nsymbols holding a value there is no rank: it is absent, so a comparison over it\nis unknown (not 0.5). ``source`` is evaluated once per symbol; it cannot carry a\n``symbol`` and cannot contain another cross-sectional operand. Requires a universe\nor portfolio strategy with two or more symbols.\n\nExample, the top tercile of the universe by 20-bar rate of change:\n  {\"kind\": \"rank\", \"source\": {\"kind\": \"indicator\", \"indicator\": \"roc\", \"period\": 20}}\ncompared with ``> 0.66``.",
      "properties": {
        "kind": {
          "const": "rank",
          "default": "rank",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "source": {
          "anyOf": [
            {
              "$ref": "#/$defs/ValueRef"
            },
            {
              "type": "number"
            }
          ],
          "description": "Per-symbol value to rank across the universe on the current bar, e.g. an indicator or a price. It is evaluated for each symbol on its own data."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "source"
      ],
      "title": "RankValueRef",
      "type": "object"
    },
    "RollingMaxValueRef": {
      "additionalProperties": false,
      "description": "Highest value of `source` over the prior `lookback_bars` \u2014 **excludes the current bar**.\n\n``source`` accepts ANY value ref, not just a price field: an indicator, a\nspread, or a nested expression. That is what makes normalisations\ncomposable \u2014 e.g. a stochastic of the MACD line is\n``(macd - rolling_min(macd)) / (rolling_max(macd) - rolling_min(macd))``\nbuilt with ``binary_expr``, with no dedicated indicator type.\n\nTwo behaviours to design around, both deliberate:\n\n- **The current bar is excluded** (same convention as ``donchian``), so a\n  close-exceeds-max breakout is meaningful \u2014 the current bar cannot\n  contaminate its own threshold. For a stochastic you want an INCLUSIVE\n  window, so rebuild one with ``binary_expr``:\n  ``{\"kind\": \"binary_expr\", \"op\": \"max\", \"left\": <source>,\n     \"right\": {\"kind\": \"rolling_max\", \"source\": <source>,\n               \"lookback_bars\": N - 1}}``\n- **NaN propagates**: one missing value anywhere in the window returns NaN\n  (no silent zero-substitution while `source` is still warming up), and a\n  NaN operand makes the enclosing compare false. Indicators with their own\n  NaN-compacting buffers \u2014 ``srsi_k``, ``stochastic_k`` \u2014 do NOT behave\n  this way, which is why they are not redundant with this ref.",
      "properties": {
        "field": {
          "anyOf": [
            {
              "$ref": "#/$defs/PriceField"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "kind": {
          "const": "rolling_max",
          "default": "rolling_max",
          "title": "Kind",
          "type": "string"
        },
        "lookback_bars": {
          "default": 20,
          "maximum": 500,
          "minimum": 2,
          "title": "Lookback Bars",
          "type": "integer"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "source": {
          "anyOf": [
            {
              "$ref": "#/$defs/ValueRef"
            },
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Any value ref (indicator, price, spread, or a nested binary_expr) as a raw dict \u2014 typed `dict` only to avoid a circular reference in the ref union, and validated against the full union at parse time."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "title": "RollingMaxValueRef",
      "type": "object"
    },
    "RollingMinValueRef": {
      "additionalProperties": false,
      "description": "Lowest value of `source` over the prior `lookback_bars` \u2014 **excludes the current bar**.\n\nThe mirror of ``rolling_max``; see that class for the composition pattern,\nthe inclusive-window workaround via ``binary_expr`` ``min``, and the\nNaN-propagation rule. ``source`` accepts any value ref, not just a price\nfield.",
      "properties": {
        "field": {
          "anyOf": [
            {
              "$ref": "#/$defs/PriceField"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "kind": {
          "const": "rolling_min",
          "default": "rolling_min",
          "title": "Kind",
          "type": "string"
        },
        "lookback_bars": {
          "default": 20,
          "maximum": 500,
          "minimum": 2,
          "title": "Lookback Bars",
          "type": "integer"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "source": {
          "anyOf": [
            {
              "$ref": "#/$defs/ValueRef"
            },
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Any value ref (indicator, price, spread, or a nested binary_expr) as a raw dict \u2014 typed `dict` only to avoid a circular reference in the ref union, and validated against the full union at parse time."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "title": "RollingMinValueRef",
      "type": "object"
    },
    "RollingStatsValueRef": {
      "additionalProperties": false,
      "description": "A rolling statistic of `source` over `lookback_bars` \u2014 mean, std, zscore, sum, count, rank, percentile or ema.\n\n``source`` accepts ANY value ref, including a nested ``binary_expr``, so\nthis is the general smoothing and normalisation primitive: an SMA of an\narbitrary expression is ``stat=\"mean\"``, and a rolling z-score of a spread\nis ``stat=\"zscore\"``. Combined with ``rolling_max``/``rolling_min`` it\nexpresses whole indicator families that have no dedicated type \u2014 the %K of\na stochastic over any series is a 3-bar ``\"mean\"`` of the normalised ratio.\n\n**NaN propagates**: one missing value in the window returns NaN, and a NaN\noperand makes the enclosing compare false. Purpose-built indicators that\ncompact their buffers to finite samples (``srsi_k``, ``stochastic_k``)\nsurvive undefined stretches that this ref does not, so they are not\nredundant with it.\n\n``percentile_level`` is required when ``stat=\"percentile\"`` and must be\nomitted otherwise.",
      "properties": {
        "kind": {
          "const": "rolling_stats",
          "default": "rolling_stats",
          "title": "Kind",
          "type": "string"
        },
        "lookback_bars": {
          "maximum": 1000,
          "minimum": 2,
          "title": "Lookback Bars",
          "type": "integer"
        },
        "percentile_level": {
          "anyOf": [
            {
              "ge": 0.0,
              "le": 100.0,
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Percentile Level"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "source": {
          "anyOf": [
            {
              "$ref": "#/$defs/ValueRef"
            },
            {
              "type": "number"
            }
          ],
          "description": "Value or expression to summarize."
        },
        "stat": {
          "enum": [
            "mean",
            "std",
            "zscore",
            "sum",
            "count",
            "rank",
            "percentile",
            "ema"
          ],
          "title": "Stat",
          "type": "string"
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "source",
        "lookback_bars",
        "stat"
      ],
      "title": "RollingStatsValueRef",
      "type": "object"
    },
    "SequenceStepValueRef": {
      "additionalProperties": false,
      "description": "Reference to a field of the bar that matched a named sequence step.\n\nAddress the bar that satisfied a specific step inside a specific\nSequenceCondition. Useful for \"stop at the retest bar's low\" in\nbreak-retest setups.\n\nLifecycle mirrors EntryBarValueRef: the snapshot is captured at step\nfire, preserved for the lifetime of the open position, cleared on\nposition close. NaN when no position is open or the step has not yet\nfired on the current match.\n\nFields:\n  - open / high / low / close: step-bar OHLC\n  - range: high - low\n  - body_high: max(open, close)\n  - body_low: min(open, close)",
      "properties": {
        "kind": {
          "const": "sequence_step",
          "default": "sequence_step",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "sequence_id": {
          "description": "Id of the target SequenceCondition.",
          "minLength": 1,
          "title": "Sequence Id",
          "type": "string"
        },
        "step_field": {
          "$ref": "#/$defs/EntryBarField"
        },
        "step_id": {
          "description": "Id of the step within the sequence.",
          "minLength": 1,
          "title": "Step Id",
          "type": "string"
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "sequence_id",
        "step_id",
        "step_field"
      ],
      "title": "SequenceStepValueRef",
      "type": "object"
    },
    "SessionValueRef": {
      "additionalProperties": false,
      "description": "Session-level value reference.\n\nDay-scoped mode (default): resolves against the full trading day in the\nsession timezone. field in {open, high, low, close, prior_close,\nbars_into_session, range, mid}.\n\nIntraday window mode: set ``window_start`` (HH:MM wall-clock in the\nsession timezone) and ``window_duration_minutes`` to aggregate OHLC\nacross a fixed intraday slot (e.g., Asian session 00:00+480, ORB\n09:30+30). Before the window opens each day: NaN. During the window:\nevolving aggregate. After close: frozen aggregate for the rest of the\nday; resets at the next day's window_start. Fields prior_close and\nbars_into_session are day-scope only (not valid with a window).",
      "properties": {
        "kind": {
          "const": "session",
          "default": "session",
          "title": "Kind",
          "type": "string"
        },
        "offset": {
          "anyOf": [
            {
              "maximum": 500,
              "minimum": 1,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Bars back. Absent is the session extreme through the current bar; k >= 1 is the extreme through bar i-k, with no value on a session's first k bars. Only the day-scoped 'high' and 'low' accept it. A level the current bar can still move needs offset 1 to be crossed.",
          "title": "Offset"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "session_field": {
          "enum": [
            "open",
            "high",
            "low",
            "close",
            "prior_close",
            "bars_into_session",
            "range",
            "mid",
            "in_session"
          ],
          "title": "Session Field",
          "type": "string"
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        },
        "window_duration_minutes": {
          "anyOf": [
            {
              "minimum": 1,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Window Duration Minutes"
        },
        "window_start": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Intraday window start as HH:MM wall-clock in the session timezone (e.g., '09:30'). Requires window_duration_minutes.",
          "title": "Window Start"
        }
      },
      "required": [
        "session_field"
      ],
      "title": "SessionValueRef",
      "type": "object"
    },
    "SharedSignalValueRef": {
      "additionalProperties": false,
      "description": "Reference to a portfolio-level shared signal by name (VIB-2102).\n\nResolves only inside a multi-member portfolio that declares a matching\n``shared_signals`` entry; bound to a member-local metric at portfolio\ncompile time. Illegal in a standalone strategy.",
      "properties": {
        "kind": {
          "const": "shared_signal",
          "default": "shared_signal",
          "title": "Kind",
          "type": "string"
        },
        "name": {
          "minLength": 1,
          "title": "Name",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "name"
      ],
      "title": "SharedSignalValueRef",
      "type": "object"
    },
    "SiblingValueRef": {
      "additionalProperties": false,
      "description": "The value of ``source`` on another symbol of the universe, on the current bar.\n\n``symbol`` must be a member of the strategy's universe; one outside it never has\na value, so such a strategy is refused when it is compiled. ``source`` is\nevaluated on that symbol's own data, not this one's; it cannot carry a ``symbol``\nand cannot contain another cross-sectional operand. Requires a universe or\nportfolio strategy with two or more symbols.\n\nExample, QQQ's close, to compare this symbol's close with:\n  {\"kind\": \"sibling\", \"symbol\": \"QQQ\", \"source\": {\"kind\": \"price\", \"field\": \"close\"}}",
      "properties": {
        "kind": {
          "const": "sibling",
          "default": "sibling",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "source": {
          "anyOf": [
            {
              "$ref": "#/$defs/ValueRef"
            },
            {
              "type": "number"
            }
          ],
          "description": "Value read on the sibling's own bars and indicators, independent of this symbol's data."
        },
        "symbol": {
          "description": "Symbol of the sibling in the strategy's universe whose value is read, e.g. 'QQQ' when the universe is ['SPY', 'QQQ', 'IWM'].",
          "minLength": 1,
          "title": "Symbol",
          "type": "string"
        }
      },
      "required": [
        "symbol",
        "source"
      ],
      "title": "SiblingValueRef",
      "type": "object"
    },
    "SrsiIndicatorValueRef": {
      "additionalProperties": false,
      "description": "Stochastic RSI \u2014 the stochastic formula applied to RSI values, not to price.\n\n``period`` is used twice: it is both the RSI period and the lookback of the\nstochastic applied over it. ``srsi_k`` is the raw %K smoothed by\n``k_period``; ``srsi_d`` smooths that again by ``d_period``.\n\n**Range is 0-100, not 0-1** \u2014 ``100 * (rsi - lowest_rsi) / rsi_range``,\nthe pandas-ta/TA-Lib convention and the same scale as this platform's own\n``rsi`` and ``stochastic_k``. So \"deeply oversold\" is ``<= 5``, NOT\n``<= 0.05``; a 0-1 threshold makes the condition silently almost-always or\nalmost-never true instead of erroring. Measured on SPY 1m Q1 2025:\n``>= 50`` fires 50.8% of bars, ``>= 95`` fires 10.2%, ``>= 0.95`` fires\n95.5%.\n\n**Not equivalent to the same shape built from `rolling_stats`/`rolling_max`\nover an `rsi` ref**, for two reasons. The scale is the big one: the generic\ncomposition returns 0-1, this returns 0-100, so identical thresholds mean\ndifferent things. Second, the lookback here is the last ``period``\n**finite** RSI samples \u2014 undefined RSI bars are skipped rather than\nadmitted to the window \u2014 so it survives flat stretches where the generic\ncomposition propagates NaN.",
      "properties": {
        "d_period": {
          "default": 3,
          "maximum": 100,
          "minimum": 1,
          "title": "D Period",
          "type": "integer"
        },
        "indicator": {
          "enum": [
            "srsi_k",
            "srsi_d"
          ],
          "title": "Indicator",
          "type": "string"
        },
        "k_period": {
          "default": 3,
          "maximum": 100,
          "minimum": 1,
          "title": "K Period",
          "type": "integer"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "period": {
          "maximum": 500,
          "minimum": 2,
          "title": "Period",
          "type": "integer"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "indicator",
        "period"
      ],
      "title": "SrsiIndicatorValueRef",
      "type": "object"
    },
    "StochasticIndicatorValueRef": {
      "additionalProperties": false,
      "description": "Stochastic oscillator \u2014 `stochastic_k` (smoothed %K) or `stochastic_d` (%D).\n\nRaw %K is ``100 * (close - lowest_low) / (highest_high - lowest_low)`` over\n``period`` bars **including the current bar** \u2014 the opposite convention to\n``rolling_max``/``rolling_min``, which exclude it. ``stochastic_k`` is\nalready SMA-smoothed over ``k_period`` (i.e. the slow %K, not raw %K), and\n``stochastic_d`` smooths that again over ``d_period``, so %D needs a\nfurther ``d_period`` bars before it is finite.\n\nA flat window (zero high-low range) yields ``0.0``, not NaN. This is a\npurpose-built indicator, not a shorthand for a ``rolling_max``/\n``rolling_min`` composition, which would use an exclusive window and\npropagate NaN instead.",
      "properties": {
        "d_period": {
          "default": 3,
          "maximum": 100,
          "minimum": 1,
          "title": "D Period",
          "type": "integer"
        },
        "indicator": {
          "enum": [
            "stochastic_k",
            "stochastic_d"
          ],
          "title": "Indicator",
          "type": "string"
        },
        "k_period": {
          "default": 3,
          "maximum": 100,
          "minimum": 1,
          "title": "K Period",
          "type": "integer"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "period": {
          "default": 14,
          "maximum": 500,
          "minimum": 2,
          "title": "Period",
          "type": "integer"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "indicator"
      ],
      "title": "StochasticIndicatorValueRef",
      "type": "object"
    },
    "SupertrendIndicatorValueRef": {
      "additionalProperties": false,
      "description": "SuperTrend \u2014 `output=\"value\"` gives the active band price, `\"direction\"` gives +1/-1.\n\n``value`` is whichever band is currently active (lower band in an uptrend,\nupper band in a downtrend), so it **jumps discontinuously across the price\nevery time the trend flips** \u2014 it is a trailing stop level, not a smooth\nline, and a price-vs-value comparison changes meaning on each flip. Use\n``direction`` when you want trend state. Both are NaN until ``period``\nbars have been seen (Wilder ATR, SMA-seeded).",
      "properties": {
        "indicator": {
          "const": "supertrend",
          "default": "supertrend",
          "title": "Indicator",
          "type": "string"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "multiplier": {
          "default": 3.0,
          "ge": 0.1,
          "le": 10.0,
          "title": "Multiplier",
          "type": "number"
        },
        "output": {
          "default": "value",
          "enum": [
            "value",
            "direction"
          ],
          "title": "Output",
          "type": "string"
        },
        "period": {
          "default": 10,
          "maximum": 500,
          "minimum": 2,
          "title": "Period",
          "type": "integer"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "title": "SupertrendIndicatorValueRef",
      "type": "object"
    },
    "SwingValueRef": {
      "additionalProperties": false,
      "description": "Price of a confirmed swing high/low \u2014 a bar whose extreme beats `strength` bars each side.\n\nConfirmation is **lagging by design**: a swing at bar N is not visible\nuntil bar ``N + strength``, because the bars to its right have to print\nfirst. That is what makes it lookahead-free, and it means the newest\nreadable swing is always at least ``strength`` bars old.\n\nThe comparison is strict, so a level matched exactly by a neighbouring bar\nnever forms a swing. ``offset`` counts back through confirmed swings\n(0 = most recent); typed absence if that many have not been confirmed yet.\nA comparison over that absent operand is UNKNOWN; the action boundary\ntakes no action.",
      "properties": {
        "kind": {
          "const": "swing",
          "default": "swing",
          "title": "Kind",
          "type": "string"
        },
        "offset": {
          "default": 0,
          "maximum": 20,
          "minimum": 0,
          "title": "Offset",
          "type": "integer"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "strength": {
          "default": 5,
          "maximum": 50,
          "minimum": 1,
          "title": "Strength",
          "type": "integer"
        },
        "swing_type": {
          "enum": [
            "high",
            "low"
          ],
          "title": "Swing Type",
          "type": "string"
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        },
        "value_at_swing": {
          "anyOf": [
            {
              "$ref": "#/$defs/ValueRef"
            },
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "The value to read at the swing bar. The swing itself is always found on PRICE (the bar high for a swing high, the bar low for a swing low); this chooses what is read there. Omitted means the swing's own price. Any value ref is accepted, and its own resolution and symbol are honoured."
        }
      },
      "required": [
        "swing_type"
      ],
      "title": "SwingValueRef",
      "type": "object"
    },
    "TimeValueRef": {
      "additionalProperties": false,
      "description": "Reference to the current bar's time field.\n\nVIB-1370 / VIB-1319: the sub-metric selector is named ``field`` across\nevery ValueRef-style type. The legacy name ``component`` was removed.\n\nCalendar/intraday fields: ``hour``, ``minute``, ``day_of_week`` (0=Mon),\n``day_of_month``, ``month`` (1=Jan), ``minutes_since_midnight``.\n\nSession-aware fields (use the strategy's session metadata):\n``minutes_to_close``, ``minutes_since_open``. Have no value for crypto (24h)\nand pre/post-market bars. A comparison over a missing value is unknown and\ntakes no action, negated or not: ``not(minutes_to_close <= 5)`` does not\nfire outside the session.",
      "properties": {
        "field": {
          "enum": [
            "hour",
            "minute",
            "day_of_week",
            "day_of_month",
            "month",
            "minutes_since_midnight",
            "minutes_to_close",
            "minutes_since_open"
          ],
          "title": "Field",
          "type": "string"
        },
        "kind": {
          "const": "time",
          "default": "time",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        },
        "timezone": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "IANA timezone (e.g. 'America/New_York'). None or 'UTC' = no conversion.",
          "title": "Timezone"
        }
      },
      "required": [
        "field"
      ],
      "title": "TimeValueRef",
      "type": "object"
    },
    "Timeframe": {
      "description": "Bar duration. These seven are the only granularities the data layer serves.",
      "enum": [
        "1m",
        "5m",
        "15m",
        "30m",
        "1h",
        "4h",
        "1d"
      ],
      "title": "Timeframe",
      "type": "string"
    },
    "TrackedValueRef": {
      "additionalProperties": false,
      "description": "Running highest or lowest value of ``source`` since the start of the run or since entry.\n\n``extreme`` chooses the maximum or the minimum and ``since`` the starting point.\nWith ``since: \"start\"`` (the default) it updates at the end of every bar, warm-up\nincluded, so a rule deciding at the close of bar t sees the extreme through bar t-1; a\nscheduled rule sees its frame bar included. With ``since: \"entry\"`` it is unset while\nflat, resets when a position opens from flat (not on a scale-in or a partial exit; a\nreversal opens from flat) and updates before decisions on each bar while invested, so a\nrule sees the extreme through the current bar. Absent values of ``source`` are skipped,\nand an unset value makes a comparison over it unknown. It keeps its state across a\npaper session's restarts. ``since: \"entry\"`` is refused in a signal scan, as every\noperation on the open position is.\n\nKnown gaps it inherits: a raw trailing ratchet built from it does not reset after it\nfires, ``since: \"entry\"`` folds in the whole bar of a mid-bar scheduled fill, and the\nreset runs only for the entry rule that filled. A ``since: \"entry\"`` value is refused\nanywhere inside a gate: a gate is evaluated while flat as well as invested, so a value\nthat resets at entry cannot be kept correct there. Use ``since: \"start\"``, or put the\ncondition on an exit. It returns the unit of ``source``.\n\nExample, the highest high since entry, to place a trailing exit under:\n  {\"kind\": \"tracked\", \"source\": {\"kind\": \"price\", \"field\": \"high\"}, \"extreme\": \"max\",\n   \"since\": \"entry\"}\ncompared with ``close`` using ``<``.",
      "properties": {
        "extreme": {
          "description": "'max' keeps the highest value of `source`, 'min' the lowest.",
          "enum": [
            "max",
            "min"
          ],
          "title": "Extreme",
          "type": "string"
        },
        "kind": {
          "const": "tracked",
          "default": "tracked",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "since": {
          "anyOf": [
            {
              "enum": [
                "start",
                "entry"
              ],
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Where the extreme starts. 'start' (also when omitted) runs from the first delivered bar of the run. 'entry' is unset while flat, resets when a position opens from flat and runs while invested; it is refused in a signal scan and inside a gate (a gate is evaluated while flat too).",
          "title": "Since"
        },
        "source": {
          "anyOf": [
            {
              "$ref": "#/$defs/ValueRef"
            },
            {
              "type": "number"
            }
          ],
          "description": "Any value ref whose running extreme is kept, e.g. a price field, an indicator or an expression. It is evaluated every bar with its own resolution and symbol."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "source",
        "extreme"
      ],
      "title": "TrackedValueRef",
      "type": "object"
    },
    "TradeHistoryValueRef": {
      "additionalProperties": false,
      "description": "A statistic computed from the strategy's own closed-trade history.\n\n``field`` selects the metric: ``trade_count`` (closed trades so far),\n``consecutive_wins`` / ``consecutive_losses`` (current streak length),\n``last_pnl`` / ``last_pnl_pct`` (the most recently closed trade's PnL),\n``rolling_win_rate`` / ``rolling_avg_pnl_pct`` (win rate / average PnL%\nover the last ``lookback_bars`` closed trades \u2014 ``lookback_bars`` is REQUIRED for these\ntwo and forbidden for every other field, since it counts TRADES, not\nbars), or ``bars_since_last_exit``.\n\nBefore the first trade closes: ``trade_count``, ``consecutive_wins`` and\n``consecutive_losses`` are all-time counters and read ``0``. The other\nfive have no value yet -- a typed absence (``no_position``), not a number\n-- so a condition reading one is UNKNOWN and takes no action (neither\ntrue nor false), and a ``formula`` sizing over one is refused at compile\nbecause it could never size the first entry.\n\nVIB-1367 phase 4 / VIB-1319: the sub-metric selector is named ``field``\nacross every ValueRef-style type. The legacy name ``trade_metric`` was\nremoved.",
      "properties": {
        "field": {
          "enum": [
            "trade_count",
            "consecutive_wins",
            "consecutive_losses",
            "last_pnl",
            "last_pnl_pct",
            "rolling_win_rate",
            "rolling_avg_pnl_pct",
            "bars_since_last_exit"
          ],
          "title": "Field",
          "type": "string"
        },
        "kind": {
          "const": "trade_history",
          "default": "trade_history",
          "title": "Kind",
          "type": "string"
        },
        "lookback_bars": {
          "anyOf": [
            {
              "minimum": 1,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Lookback Bars"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "field"
      ],
      "title": "TradeHistoryValueRef",
      "type": "object"
    },
    "TriggeringZoneValueRef": {
      "additionalProperties": false,
      "description": "Reference to the zone that fired the entry's ZoneCondition (VIB-591).\n\nResolves to a level of the *triggering* zone \u2014 the zone selected by the\nentry's ZoneCondition on the signal bar. An immutable snapshot is captured\ninto ``TradeContext`` so post-entry references (e.g. a standing stop-loss\nbound to the FVG's lower wick) keep resolving to the same zone for the\ntrade's lifetime. The id is retained for persisted-state compatibility.\n\nReturns NaN when no triggering zone is bound (no entry condition with a\nrequired ZoneCondition fired) and no compatibility lookup is available.",
      "properties": {
        "kind": {
          "const": "triggering_zone",
          "default": "triggering_zone",
          "title": "Kind",
          "type": "string"
        },
        "level": {
          "$ref": "#/$defs/ZoneLevel",
          "default": "mid"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "title": "TriggeringZoneValueRef",
      "type": "object"
    },
    "UnaryExprValueRef": {
      "additionalProperties": false,
      "description": "Unary expression over another ValueRef.\n\nWraps a single operand with an op from {abs, neg, log, log10, sqrt, pct_change}.\nCompiles to a unary IRExpression.",
      "properties": {
        "kind": {
          "const": "unary_expr",
          "default": "unary_expr",
          "title": "Kind",
          "type": "string"
        },
        "op": {
          "enum": [
            "abs",
            "neg",
            "log",
            "log10",
            "sqrt",
            "pct_change"
          ],
          "title": "Op",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "source": {
          "anyOf": [
            {
              "$ref": "#/$defs/ValueRef"
            },
            {
              "type": "number"
            }
          ]
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "op",
        "source"
      ],
      "title": "UnaryExprValueRef",
      "type": "object"
    },
    "VWAPBandOutput": {
      "enum": [
        "upper",
        "middle",
        "lower",
        "std_dev"
      ],
      "type": "string"
    },
    "VWAPBandsValueRef": {
      "additionalProperties": false,
      "description": "VWAP Bands \u2014 stddev envelopes around anchored VWAP.\n\nOutputs:\n  - upper  = VWAP + mult * sigma\n  - middle = VWAP\n  - lower  = VWAP - mult * sigma\n  - std_dev = sigma itself, NOT multiplied by ``multiplier``\n\nwhere sigma is the volume-weighted std dev of typical price vs VWAP,\naccumulated since the last anchor reset (session/week/month).\nA distance from the VWAP in standard deviations is\n``(close - middle) / std_dev``, written with ``binary_expr``.",
      "properties": {
        "anchor": {
          "$ref": "#/$defs/AnchorPeriod",
          "default": "session"
        },
        "indicator": {
          "const": "vwap_bands",
          "default": "vwap_bands",
          "title": "Indicator",
          "type": "string"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "multiplier": {
          "default": 2.0,
          "ge": 0.1,
          "le": 10.0,
          "title": "Multiplier",
          "type": "number"
        },
        "output": {
          "$ref": "#/$defs/VWAPBandOutput"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "output"
      ],
      "title": "VWAPBandsValueRef",
      "type": "object"
    },
    "VWAPIndicatorValueRef": {
      "additionalProperties": false,
      "description": "VWAP \u2014 anchored Volume-Weighted Average Price.\n\nResets at each anchor boundary (session/week/month). Use this ValueRef\nwhen you need the VWAP scalar as an operand in compare/cross conditions\n(e.g. ``close > vwap(session)``). For envelope/band semantics use\n``vwap_bands`` instead.\n\nMath: anchored cumulative volume-weighted typical price; zero-volume\nbars carry forward the prior VWAP value (no vol=1.0 substitution). See\n``docs/indicator-conventions.md``.",
      "properties": {
        "anchor": {
          "$ref": "#/$defs/AnchorPeriod",
          "default": "session"
        },
        "indicator": {
          "const": "vwap",
          "default": "vwap",
          "title": "Indicator",
          "type": "string"
        },
        "kind": {
          "const": "indicator",
          "default": "indicator",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "title": "VWAPIndicatorValueRef",
      "type": "object"
    },
    "ValueRef": {
      "discriminator": {
        "mapping": {
          "anchor": "#/$defs/AnchorValueRef",
          "binary_expr": "#/$defs/BinaryExprValueRef",
          "constant": "#/$defs/ConstantValueRef",
          "entry_bar": "#/$defs/EntryBarValueRef",
          "equity": "#/$defs/EquityValueRef",
          "event_distance": "#/$defs/EventDistanceValueRef",
          "event_field": "#/$defs/EventFieldValueRef",
          "indicator": "#/$defs/IndicatorValueRef",
          "live_position": "#/$defs/LivePositionValueRef",
          "named_zone": "#/$defs/NamedZoneValueRef",
          "percentile": "#/$defs/PercentileValueRef",
          "price": "#/$defs/PriceValueRef",
          "rank": "#/$defs/RankValueRef",
          "rolling_max": "#/$defs/RollingMaxValueRef",
          "rolling_min": "#/$defs/RollingMinValueRef",
          "rolling_stats": "#/$defs/RollingStatsValueRef",
          "sequence_step": "#/$defs/SequenceStepValueRef",
          "session": "#/$defs/SessionValueRef",
          "shared_signal": "#/$defs/SharedSignalValueRef",
          "sibling": "#/$defs/SiblingValueRef",
          "swing": "#/$defs/SwingValueRef",
          "time": "#/$defs/TimeValueRef",
          "tracked": "#/$defs/TrackedValueRef",
          "trade_history": "#/$defs/TradeHistoryValueRef",
          "triggering_zone": "#/$defs/TriggeringZoneValueRef",
          "unary_expr": "#/$defs/UnaryExprValueRef",
          "volume": "#/$defs/VolumeValueRef",
          "xs_dispersion": "#/$defs/DispersionValueRef",
          "xs_zscore": "#/$defs/ZScoreValueRef"
        },
        "propertyName": "kind"
      },
      "oneOf": [
        {
          "$ref": "#/$defs/PriceValueRef"
        },
        {
          "$ref": "#/$defs/IndicatorValueRef"
        },
        {
          "$ref": "#/$defs/ConstantValueRef"
        },
        {
          "$ref": "#/$defs/AnchorValueRef"
        },
        {
          "$ref": "#/$defs/NamedZoneValueRef"
        },
        {
          "$ref": "#/$defs/TriggeringZoneValueRef"
        },
        {
          "$ref": "#/$defs/SwingValueRef"
        },
        {
          "$ref": "#/$defs/PercentileValueRef"
        },
        {
          "$ref": "#/$defs/RollingMaxValueRef"
        },
        {
          "$ref": "#/$defs/RollingMinValueRef"
        },
        {
          "$ref": "#/$defs/VolumeValueRef"
        },
        {
          "$ref": "#/$defs/EventFieldValueRef"
        },
        {
          "$ref": "#/$defs/TradeHistoryValueRef"
        },
        {
          "$ref": "#/$defs/EquityValueRef"
        },
        {
          "$ref": "#/$defs/LivePositionValueRef"
        },
        {
          "$ref": "#/$defs/SessionValueRef"
        },
        {
          "$ref": "#/$defs/TimeValueRef"
        },
        {
          "$ref": "#/$defs/EntryBarValueRef"
        },
        {
          "$ref": "#/$defs/SequenceStepValueRef"
        },
        {
          "$ref": "#/$defs/RollingStatsValueRef"
        },
        {
          "$ref": "#/$defs/UnaryExprValueRef"
        },
        {
          "$ref": "#/$defs/BinaryExprValueRef"
        },
        {
          "$ref": "#/$defs/SharedSignalValueRef"
        },
        {
          "$ref": "#/$defs/EventDistanceValueRef"
        },
        {
          "$ref": "#/$defs/RankValueRef"
        },
        {
          "$ref": "#/$defs/ZScoreValueRef"
        },
        {
          "$ref": "#/$defs/DispersionValueRef"
        },
        {
          "$ref": "#/$defs/SiblingValueRef"
        },
        {
          "$ref": "#/$defs/TrackedValueRef"
        }
      ],
      "required": [
        "kind"
      ]
    },
    "VolumeValueRef": {
      "additionalProperties": false,
      "description": "Traded volume of the current bar, or of a bar `offset` bars back.\n\nVolume is in **base-asset units** (shares, or coins for crypto) unless the\nrun is configured for quote units, in which case it is multiplied by that\nbar's close. Reading past the start of loaded history returns NaN.",
      "properties": {
        "kind": {
          "const": "volume",
          "default": "volume",
          "title": "Kind",
          "type": "string"
        },
        "offset": {
          "default": 0,
          "maximum": 500,
          "minimum": 0,
          "title": "Offset",
          "type": "integer"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "title": "VolumeValueRef",
      "type": "object"
    },
    "ZScoreValueRef": {
      "additionalProperties": false,
      "description": "Cross-sectional z-score of ``source`` among the universe's symbols on the current bar.\n\nHow many sample standard deviations this symbol's value sits from the universe\nmean. With fewer than 2 values, or when every symbol sits on the mean, there is no\nz-score: it is absent (not 0). ``source`` is evaluated once per symbol; it cannot\ncarry a ``symbol`` and cannot contain another cross-sectional operand. Requires a\nuniverse or portfolio strategy with two or more symbols.\n\nExample, how far this symbol's RSI is from the universe average:\n  {\"kind\": \"xs_zscore\", \"source\": {\"kind\": \"indicator\", \"indicator\": \"rsi\", \"period\": 14}}",
      "properties": {
        "kind": {
          "const": "xs_zscore",
          "default": "xs_zscore",
          "title": "Kind",
          "type": "string"
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/Timeframe"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional higher-timeframe override for this value ref. Set it inside left/right refs such as {'kind': 'indicator', ..., 'resolution': '4h'} or {'kind': 'price', 'field': 'close', 'resolution': '4h'}. Do not put timeframe/source_timeframe on the parent condition. None = strategy timeframe."
        },
        "source": {
          "anyOf": [
            {
              "$ref": "#/$defs/ValueRef"
            },
            {
              "type": "number"
            }
          ],
          "description": "Per-symbol value to standardise against the universe on the current bar. It is evaluated for each symbol on its own data."
        },
        "symbol": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Optional reference symbol this value ref reads from (e.g. 'SPY'). None = the traded/primary symbol. Mutually exclusive with resolution.",
          "title": "Symbol"
        }
      },
      "required": [
        "source"
      ],
      "title": "ZScoreValueRef",
      "type": "object"
    },
    "ZoneLevel": {
      "enum": [
        "upper",
        "lower",
        "mid"
      ],
      "type": "string"
    }
  },
  "$ref": "#/$defs/RankValueRef"
}
