{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://optionincometools.com/research/schemas/screen-yield-vs-realized.json",
  "title": "Screen yield vs realized return — observation",
  "description": "One observation = one option contract entered at screen time, tracked to its exit (expiry, close, or assignment), with realized P&L recorded. Used to measure the gap between annualized screen yield and realized return across many cycles. See https://optionincometools.com/research/screen-yield-vs-realized/ for the full methodology.",
  "type": "object",
  "required": [
    "observationId",
    "screenTimestamp",
    "underlying",
    "strategy",
    "expiration",
    "dte",
    "strike",
    "delta",
    "bid",
    "ask",
    "midpoint",
    "spreadPctMid",
    "volume",
    "openInterest",
    "impliedVolatility",
    "screenYield",
    "methodologyVersion"
  ],
  "properties": {
    "observationId": { "type": "string", "description": "UUID for this observation." },
    "screenTimestamp": { "type": "string", "format": "date-time", "description": "When the option was selected by the screener." },
    "underlying": { "type": "string", "description": "Ticker symbol." },
    "strategy": { "type": "string", "enum": ["covered-call", "cash-secured-put", "wheel", "iron-condor", "iron-butterfly"] },
    "expiration": { "type": "string", "format": "date", "description": "Option expiration date." },
    "dte": { "type": "integer", "minimum": 0, "description": "Days to expiration at screen time." },
    "strike": { "type": "number", "description": "Strike price." },
    "delta": { "type": "number", "description": "Delta at screen time (absolute value for puts)." },
    "bid": { "type": "number", "minimum": 0 },
    "ask": { "type": "number", "minimum": 0 },
    "midpoint": { "type": "number", "minimum": 0 },
    "spreadPctMid": { "type": "number", "minimum": 0, "description": "(ask - bid) / midpoint." },
    "volume": { "type": "integer", "minimum": 0 },
    "openInterest": { "type": "integer", "minimum": 0 },
    "impliedVolatility": { "type": "number", "minimum": 0 },
    "screenYield": {
      "type": "object",
      "properties": {
        "cycleYield": { "type": "number" },
        "annualizedScreenYield": { "type": "number" },
        "formula": { "type": "string", "default": "(premium / capital at risk) * (365 / DTE)" }
      },
      "required": ["cycleYield", "annualizedScreenYield"]
    },
    "exitTimestamp": { "type": ["string", "null"], "format": "date-time", "description": "When the position was exited. Null if still open." },
    "exitReason": {
      "type": ["string", "null"],
      "enum": [null, "expired-worthless", "expired-itm", "closed-early", "assigned", "early-exercised", "rolled"]
    },
    "assignment": { "type": "boolean", "default": false },
    "earlyExercise": { "type": "boolean", "default": false },
    "slippageAssumption": { "type": "number", "default": 0.25, "description": "Fraction of bid-ask spread assumed as fill slippage. Default 25%." },
    "commissionPerLeg": { "type": "number", "default": 0.65, "description": "USD per contract per leg." },
    "realizedPremiumPerContract": { "type": ["number", "null"], "description": "Actual premium captured after slippage + commission." },
    "realizedReturnOnCapital": { "type": ["number", "null"], "description": "Realized P&L divided by capital at risk." },
    "underlyingPriceAtScreen": { "type": "number" },
    "underlyingPriceAtExit": { "type": ["number", "null"] },
    "volatilityRegime": {
      "type": ["string", "null"],
      "enum": [null, "low-vix", "normal-vix", "high-vix"],
      "description": "Bucketed VIX level at screen time. Low <15, Normal 15-25, High >25."
    },
    "liquidityBucket": {
      "type": ["string", "null"],
      "enum": [null, "thin", "moderate", "deep"],
      "description": "Bucketed liquidity score at screen time."
    },
    "methodologyVersion": { "type": "string", "description": "Semver of the methodology that generated this observation, e.g. 1.0.0." },
    "dataProvider": { "type": "string", "default": "polygon.io" },
    "notes": { "type": ["string", "null"] }
  },
  "additionalProperties": false
}
