{
  "price_for_a_real_run_usdc": 2,
  "grammar": {
    "note": "Rules are data, not code. Nothing you send is executed — it is interpreted against a fixed whitelist.",
    "expression": {
      "logic": [
        "{op:'and', terms:[expr,...]}",
        "{op:'or', terms:[expr,...]}",
        "{op:'not', term:expr}"
      ],
      "compare": [
        "{op:'gt'|'lt'|'gte'|'lte', left:term, right:term}"
      ],
      "cross": [
        "{op:'cross_above'|'cross_below', left:term, right:term}"
      ]
    },
    "term": {
      "constant": "{const: 30}",
      "indicators": {
        "price": "close of the bar",
        "sma": "simple moving average, {ind:\"sma\", n:50}",
        "ema": "exponential moving average",
        "rsi": "Wilder RSI, default n=14",
        "atr": "average true range",
        "atr_pct": "ATR as a percent of price — for volatility filters",
        "high": "highest high of the last n bars (Donchian upper)",
        "low": "lowest low of the last n bars (Donchian lower)",
        "return": "percent change over the last n bars"
      },
      "limits": {
        "n": "2..1000 bars",
        "nodes": 40,
        "depth": 6
      }
    },
    "guarantees": [
      "Every indicator is strictly causal: bar i uses bars 0..i only.",
      "The finished signal is lagged one bar and executed at the NEXT bar open. You cannot switch this off.",
      "Long-only, no leverage, no shorting — it must be simulatable with spot USDC.",
      "Costs are charged on every position change: your feeBps per side plus your flat gas cost."
    ]
  },
  "example": {
    "asset": "BTCUSDT",
    "timeframe": "1d",
    "folds": 6,
    "costs": {
      "feeBps": 25,
      "gasUsd": 0.02,
      "startUsd": 1000
    },
    "long_when": {
      "op": "gt",
      "left": {
        "ind": "sma",
        "n": 50
      },
      "right": {
        "ind": "sma",
        "n": 200
      }
    }
  }
}
