{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://secedgarterminal.com/schemas/market-signals-v1.schema.json",
  "title": "EDGAR Terminal Market Signals v1",
  "description": "Machine-readable contract for EDGAR Factor Lab regression diagnostics and filing-derived descriptive measures. The response contains derived statistics, not bulk vendor price histories, forecasts, investment advice, or validated expected-return factors.",
  "type": "object",
  "required": [
    "schema_version",
    "methodology_version",
    "universe_version",
    "snapshot_id",
    "status",
    "cache_status",
    "generated_at",
    "data_through",
    "request",
    "issuer",
    "sample",
    "estimates",
    "edgar_snapshot",
    "filing_event",
    "evidence_gap",
    "quality",
    "interpretation",
    "provenance",
    "equations",
    "warnings",
    "limitations",
    "links",
    "cite_as"
  ],
  "properties": {
    "schema_version": {
      "const": "edgar.market-signals.v1",
      "description": "Version of this response contract."
    },
    "methodology_version": {
      "type": "string",
      "const": "market-signals-1.0.0"
    },
    "universe_version": {
      "type": "string",
      "description": "Version of the curated Market company universe and SEC metric engine."
    },
    "snapshot_id": {
      "type": "string",
      "minLength": 1,
      "description": "Identifier for the SEC snapshot, normalized request, inputs, and calculation time used for this result."
    },
    "status": {
      "type": "string",
      "enum": ["ready", "partial", "withheld", "stale"],
      "description": "ready means all headline and Evidence Gap requirements were met; partial means regression diagnostics are usable but filing-derived evidence is incomplete; withheld means headline regressions failed an input or sample-quality gate; stale means a retained prior result or a calculation whose SEC input snapshot is stale."
    },
    "cache_status": {
      "type": "string",
      "enum": ["computed", "warm", "stale"],
      "description": "Delivery state, kept separate from the underlying data provider."
    },
    "generated_at": { "$ref": "#/$defs/dateTime" },
    "data_through": {
      "$ref": "#/$defs/nullableDate",
      "description": "Latest common date covered by the asset, SPY, and sector-proxy inputs."
    },
    "request": { "$ref": "#/$defs/request" },
    "issuer": { "$ref": "#/$defs/issuer" },
    "sample": {
      "type": ["object", "null"],
      "description": "Exactly aligned daily log-return sample. Null when diagnostics are withheld before model estimation.",
      "properties": {
        "requested_start": { "$ref": "#/$defs/nullableDate" },
        "effective_start": { "$ref": "#/$defs/nullableDate" },
        "effective_end": { "$ref": "#/$defs/nullableDate" },
        "observations": { "type": "integer", "minimum": 0 },
        "eligible_benchmark_intervals": { "type": "integer", "minimum": 0 },
        "overlap_coverage": { "type": ["number", "null"], "minimum": 0, "maximum": 1 },
        "excluded": {
          "type": "object",
          "properties": {
            "asset_prices": { "type": "integer", "minimum": 0 },
            "market_prices": { "type": "integer", "minimum": 0 },
            "sector_prices": { "type": "integer", "minimum": 0 },
            "unmatched_benchmark_intervals": { "type": "integer", "minimum": 0 }
          },
          "additionalProperties": true
        }
      },
      "additionalProperties": true
    },
    "estimates": {
      "type": ["object", "null"],
      "description": "OLS regression diagnostics on daily log returns. Null when adjusted, aligned input requirements are not met.",
      "properties": {
        "market_model": { "$ref": "#/$defs/regression" },
        "conditional_beta": { "$ref": "#/$defs/conditionalBeta" },
        "independent_sector_sensitivity": { "$ref": "#/$defs/sectorModel" },
        "rolling_beta": { "$ref": "#/$defs/rollingBeta" }
      },
      "additionalProperties": true
    },
    "edgar_snapshot": {
      "type": ["object", "null"],
      "description": "Current peer-normalized filing-change diagnostic. This is a descriptive snapshot, not a historical factor return or expected-return signal.",
      "required": ["available", "diagnostic_only", "filing_change_z", "reason", "cohort_id", "direction", "coverage", "components", "claim_limits"],
      "properties": {
        "schema_version": { "type": "string", "const": "edgar-market-signals-v1" },
        "available": { "type": "boolean" },
        "diagnostic_only": { "type": "boolean" },
        "ticker": { "type": ["string", "null"] },
        "cik": { "type": ["string", "null"] },
        "basis": { "type": "string", "enum": ["ttm", "annual"] },
        "filing_change_z": { "$ref": "#/$defs/nullableNumber" },
        "reason": { "type": ["string", "null"] },
        "cohort_id": { "type": ["string", "null"] },
        "template": { "$ref": "#/$defs/nullableLabel" },
        "direction": { "$ref": "#/$defs/nullableLabel" },
        "coverage": { "$ref": "#/$defs/filingCoverage" },
        "components": {
          "type": "array",
          "items": { "$ref": "#/$defs/filingComponent" }
        },
        "methodology": { "type": "object", "additionalProperties": true },
        "claim_limits": { "$ref": "#/$defs/stringArray" }
      },
      "additionalProperties": true
    },
    "filing_event": {
      "type": ["object", "null"],
      "description": "Model-adjusted return response following the latest comparable filing. A pre-open SEC acceptance may use that session; intraday, post-close, non-trading-day, and date-only filings begin on the next benchmark session. Every reported horizon requires uninterrupted exact asset, SPY, and sector-proxy intervals.",
      "properties": {
        "event_date": { "$ref": "#/$defs/nullableDate" },
        "acceptance_timestamp": { "$ref": "#/$defs/nullableDateTime" },
        "event_start": { "$ref": "#/$defs/nullableDate" },
        "event_interval_end": { "$ref": "#/$defs/nullableDate" },
        "timing_quality": {
          "type": "string",
          "enum": [
            "filing_date_next_session_proxy",
            "acceptance_timestamp_nontrading_date",
            "acceptance_timestamp_before_market_open",
            "acceptance_timestamp_during_or_after_session"
          ]
        },
        "estimation": {
          "type": "object",
          "properties": {
            "start": { "$ref": "#/$defs/nullableDate" },
            "end": { "$ref": "#/$defs/nullableDate" },
            "observations": { "type": "integer", "minimum": 0 },
            "gap_sessions": { "type": "integer", "minimum": 0 }
          },
          "additionalProperties": true
        },
        "windows": {
          "type": "object",
          "properties": {
            "1": { "$ref": "#/$defs/eventWindow" },
            "5": { "$ref": "#/$defs/eventWindow" },
            "20": { "$ref": "#/$defs/eventWindow" }
          },
          "additionalProperties": true
        }
      },
      "additionalProperties": true
    },
    "evidence_gap": {
      "type": ["object", "null"],
      "description": "Descriptive disagreement between the clipped filing-change z-score and clipped price-response z-score. It is not a forecast, valuation, recommendation, or trade signal.",
      "required": ["available", "diagnostic_only", "evidence_gap", "inputs", "classification", "gap_interpretation", "formula", "reason", "input_clip", "neutral_band", "range", "claim_limits"],
      "properties": {
        "schema_version": { "type": "string", "const": "edgar-market-signals-v1" },
        "available": { "type": "boolean" },
        "diagnostic_only": { "type": "boolean" },
        "evidence_gap": { "$ref": "#/$defs/nullableNumber" },
        "inputs": { "$ref": "#/$defs/evidenceGapInputs" },
        "classification": { "$ref": "#/$defs/nullableClassification" },
        "gap_interpretation": { "type": ["string", "null"] },
        "formula": { "type": "string" },
        "reason": { "type": ["string", "null"] },
        "input_clip": { "type": "number", "exclusiveMinimum": 0 },
        "neutral_band": { "type": "number", "minimum": 0 },
        "range": {
          "type": "object",
          "required": ["min", "max"],
          "properties": {
            "min": { "type": "number" },
            "max": { "type": "number" }
          },
          "additionalProperties": false
        },
        "claim_limits": { "$ref": "#/$defs/stringArray" }
      },
      "additionalProperties": true
    },
    "quality": { "$ref": "#/$defs/quality" },
    "interpretation": {
      "type": "string",
      "description": "Deterministic plain-language summary of the dated result, not generated investment advice."
    },
    "provenance": { "$ref": "#/$defs/provenance" },
    "equations": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["id", "expression", "inference"],
        "properties": {
          "id": { "type": "string" },
          "expression": { "type": "string" },
          "inference": { "type": "string" }
        },
        "additionalProperties": true
      }
    },
    "warnings": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["code", "severity", "message"],
        "properties": {
          "code": { "type": "string", "pattern": "^[A-Z][A-Z0-9_]*$" },
          "severity": { "type": "string", "enum": ["info", "warning", "error"] },
          "message": { "type": "string" }
        },
        "additionalProperties": true
      }
    },
    "limitations": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Interpretation boundaries that apply even when status is ready."
    },
    "links": {
      "type": "object",
      "required": ["methodology", "api", "schema", "company_analysis", "sec_companyfacts"],
      "properties": {
        "methodology": { "type": "string", "format": "uri" },
        "api": { "type": "string", "format": "uri" },
        "schema": { "type": "string", "format": "uri" },
        "company_analysis": { "type": "string", "format": "uri" },
        "sec_companyfacts": { "type": "string", "format": "uri" }
      },
      "additionalProperties": true
    },
    "cite_as": { "type": "string", "minLength": 1 }
  },
  "additionalProperties": true,
  "$defs": {
    "nullableNumber": { "type": ["number", "null"] },
    "dateTime": { "type": "string", "format": "date-time" },
    "nullableDateTime": { "type": ["string", "null"], "format": "date-time" },
    "nullableDate": { "type": ["string", "null"], "format": "date" },
    "stringArray": {
      "type": "array",
      "items": { "type": "string" }
    },
    "nullableLabel": {
      "type": ["object", "null"],
      "required": ["id", "label"],
      "properties": {
        "id": { "type": "string" },
        "label": { "type": "string" }
      },
      "additionalProperties": false
    },
    "nullableClassification": {
      "type": ["object", "null"],
      "required": ["id", "label", "interpretation"],
      "properties": {
        "id": { "type": "string" },
        "label": { "type": "string" },
        "interpretation": { "type": "string" }
      },
      "additionalProperties": false
    },
    "filingCoverage": {
      "type": "object",
      "required": ["required_components", "available_components", "ratio", "eligible_peer_issuers", "minimum_peers_per_component", "peer_filing_clock"],
      "properties": {
        "required_components": { "type": "integer", "minimum": 0 },
        "available_components": { "type": "integer", "minimum": 0 },
        "ratio": { "type": "number", "minimum": 0, "maximum": 1 },
        "eligible_peer_issuers": { "type": "integer", "minimum": 0 },
        "minimum_peers_per_component": { "type": "integer", "minimum": 2 },
        "peer_filing_clock": { "$ref": "#/$defs/peerFilingClock" }
      },
      "additionalProperties": false
    },
    "peerFilingClock": {
      "type": ["object", "null"],
      "required": ["focus", "earliest_peer", "latest_peer", "observed_peers", "missing_peers", "peers_after_focus"],
      "properties": {
        "focus": { "type": ["string", "null"] },
        "earliest_peer": { "type": ["string", "null"] },
        "latest_peer": { "type": ["string", "null"] },
        "observed_peers": { "type": "integer", "minimum": 0 },
        "missing_peers": { "type": "integer", "minimum": 0 },
        "peers_after_focus": { "type": ["integer", "null"], "minimum": 0 }
      },
      "additionalProperties": false
    },
    "peerDistribution": {
      "type": "object",
      "required": ["count", "median", "mad", "q1", "q3", "standard_deviation", "scale", "scale_method", "min", "max"],
      "properties": {
        "count": { "type": "integer", "minimum": 0 },
        "median": { "$ref": "#/$defs/nullableNumber" },
        "mad": { "$ref": "#/$defs/nullableNumber" },
        "q1": { "$ref": "#/$defs/nullableNumber" },
        "q3": { "$ref": "#/$defs/nullableNumber" },
        "standard_deviation": { "$ref": "#/$defs/nullableNumber" },
        "scale": { "$ref": "#/$defs/nullableNumber" },
        "scale_method": { "type": ["string", "null"], "enum": ["median_absolute_deviation", "interquartile_range", "sample_standard_deviation", null] },
        "min": { "$ref": "#/$defs/nullableNumber" },
        "max": { "$ref": "#/$defs/nullableNumber" }
      },
      "additionalProperties": false
    },
    "filingComponent": {
      "type": "object",
      "required": ["key", "label", "unit", "weight", "required", "available", "current", "prior", "change", "z", "weighted_z", "peer_percentile", "peer_count", "peer_candidates", "peer_distribution", "reason"],
      "properties": {
        "key": { "type": "string" },
        "label": { "type": "string" },
        "unit": { "const": "percentage_points" },
        "weight": { "type": "number", "exclusiveMinimum": 0, "maximum": 1 },
        "required": { "type": "boolean" },
        "available": { "type": "boolean" },
        "current": { "$ref": "#/$defs/nullableNumber" },
        "prior": { "$ref": "#/$defs/nullableNumber" },
        "change": { "$ref": "#/$defs/nullableNumber" },
        "supplied_change": { "$ref": "#/$defs/nullableNumber" },
        "supplied_change_consistent": { "type": ["boolean", "null"] },
        "change_source": { "type": ["string", "null"] },
        "z": { "$ref": "#/$defs/nullableNumber" },
        "raw_z": { "$ref": "#/$defs/nullableNumber" },
        "clipped": { "type": "boolean" },
        "weighted_z": { "$ref": "#/$defs/nullableNumber" },
        "peer_percentile": { "$ref": "#/$defs/nullableNumber" },
        "peer_count": { "type": "integer", "minimum": 0 },
        "peer_candidates": { "type": "integer", "minimum": 0 },
        "peer_distribution": { "$ref": "#/$defs/peerDistribution" },
        "reason": { "type": ["string", "null"] }
      },
      "additionalProperties": false
    },
    "evidenceGapInputs": {
      "type": "object",
      "required": ["filing_change_z", "price_response_z", "clipped_filing_change_z", "clipped_price_response_z"],
      "properties": {
        "filing_change_z": { "$ref": "#/$defs/nullableNumber" },
        "price_response_z": { "$ref": "#/$defs/nullableNumber" },
        "clipped_filing_change_z": { "$ref": "#/$defs/nullableNumber" },
        "clipped_price_response_z": { "$ref": "#/$defs/nullableNumber" }
      },
      "additionalProperties": false
    },
    "request": {
      "type": "object",
      "required": ["ticker", "window", "basis", "cohort", "sector_proxy", "market_benchmark", "frequency"],
      "properties": {
        "ticker": { "type": "string", "pattern": "^[A-Z0-9][A-Z0-9.-]{0,9}$" },
        "window": { "type": "string", "enum": ["1y", "3y", "5y"] },
        "basis": { "type": "string", "enum": ["ttm", "annual"] },
        "cohort": { "type": "string" },
        "sector_proxy": { "type": "string", "enum": ["XLF", "XLRE", "XHB", "XLE", "XLY", "XLK", "XLI", "XLV", "XLU"] },
        "market_benchmark": { "const": "SPY" },
        "frequency": { "const": "daily" }
      },
      "additionalProperties": true
    },
    "issuer": {
      "type": "object",
      "required": ["ticker", "name", "cik", "sic", "cohorts"],
      "properties": {
        "ticker": { "type": "string" },
        "name": { "type": "string" },
        "cik": { "type": "string", "pattern": "^[0-9]{10}$" },
        "sic": { "type": "string" },
        "cohorts": { "type": "array", "items": { "type": "string" }, "uniqueItems": true }
      },
      "additionalProperties": true
    },
    "regression": {
      "type": ["object", "null"],
      "description": "OLS with an intercept. Inference uses Newey-West HAC standard errors. Return and volatility fields are decimal log-return units, so 0.20 represents 20% annualized volatility.",
      "properties": {
        "observations": { "type": "integer", "minimum": 0 },
        "intercept_daily": { "$ref": "#/$defs/nullableNumber", "description": "Regression intercept on daily log returns; not Jensen alpha." },
        "intercept_annualized": { "$ref": "#/$defs/nullableNumber", "description": "Daily regression intercept multiplied by 252; not compounded and not Jensen alpha." },
        "intercept_standard_error": { "$ref": "#/$defs/nullableNumber" },
        "beta": { "$ref": "#/$defs/nullableNumber" },
        "beta_standard_error": { "$ref": "#/$defs/nullableNumber" },
        "beta_confidence_interval95": {
          "type": ["array", "null"],
          "items": { "type": "number" },
          "minItems": 2,
          "maxItems": 2
        },
        "beta_t_statistic": { "$ref": "#/$defs/nullableNumber" },
        "r_squared": { "type": ["number", "null"], "minimum": 0, "maximum": 1 },
        "adjusted_r_squared": { "$ref": "#/$defs/nullableNumber" },
        "correlation": { "type": ["number", "null"], "minimum": -1, "maximum": 1 },
        "asset_volatility_annualized": { "$ref": "#/$defs/nullableNumber" },
        "benchmark_volatility_annualized": { "$ref": "#/$defs/nullableNumber" },
        "residual_volatility_annualized": { "$ref": "#/$defs/nullableNumber" },
        "hac_lag": { "type": ["integer", "null"], "minimum": 0 },
        "durbin_watson": { "$ref": "#/$defs/nullableNumber" },
        "influential_dates": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "date": { "$ref": "#/$defs/nullableDate" },
              "distance": { "$ref": "#/$defs/nullableNumber" }
            },
            "additionalProperties": true
          }
        }
      },
      "additionalProperties": true
    },
    "conditionalBeta": {
      "type": ["object", "null"],
      "properties": {
        "upside": { "$ref": "#/$defs/regression" },
        "downside": { "$ref": "#/$defs/regression" },
        "observations": {
          "type": "object",
          "properties": {
            "upside": { "type": "integer", "minimum": 0 },
            "downside": { "type": "integer", "minimum": 0 },
            "zero": { "type": "integer", "minimum": 0 }
          },
          "additionalProperties": true
        },
        "asymmetry": { "$ref": "#/$defs/nullableNumber", "description": "Downside beta minus upside beta." },
        "inference": { "type": "string", "description": "Lag-0 HAC/HC1 is used because sign-filtered observations are not consecutive trading sessions." }
      },
      "additionalProperties": true
    },
    "sectorModel": {
      "type": ["object", "null"],
      "description": "Sector sensitivity after orthogonalizing the selected sector proxy against SPY using Frisch-Waugh-Lovell residualization.",
      "properties": {
        "observations": { "type": "integer", "minimum": 0 },
        "intercept_daily": { "$ref": "#/$defs/nullableNumber" },
        "market_beta": { "$ref": "#/$defs/nullableNumber" },
        "independent_sector_beta": { "$ref": "#/$defs/nullableNumber" },
        "joint_intercept_daily": { "$ref": "#/$defs/nullableNumber" },
        "joint_market_beta": { "$ref": "#/$defs/nullableNumber" },
        "sector_market_beta": { "$ref": "#/$defs/nullableNumber" },
        "sector_market_intercept_daily": { "$ref": "#/$defs/nullableNumber" },
        "r_squared": { "type": ["number", "null"], "minimum": 0, "maximum": 1 },
        "residual_volatility_annualized": { "$ref": "#/$defs/nullableNumber" }
      },
      "additionalProperties": true
    },
    "rollingBeta": {
      "type": ["object", "null"],
      "properties": {
        "window": { "type": "integer", "minimum": 2, "description": "Trading-return observations per rolling regression." },
        "points": {
          "type": "array",
          "items": {
            "type": "object",
            "required": ["date", "beta"],
            "properties": {
              "date": { "type": "string", "format": "date" },
              "beta": { "type": "number" }
            },
            "additionalProperties": true
          }
        },
        "current": { "$ref": "#/$defs/nullableNumber" },
        "median": { "$ref": "#/$defs/nullableNumber" },
        "minimum": { "$ref": "#/$defs/nullableNumber" },
        "maximum": { "$ref": "#/$defs/nullableNumber" },
        "range": { "$ref": "#/$defs/nullableNumber" }
      },
      "additionalProperties": true
    },
    "eventWindow": {
      "type": ["object", "null"],
      "properties": {
        "sessions": { "type": "integer", "minimum": 1 },
        "through": { "$ref": "#/$defs/nullableDate" },
        "cumulative_abnormal_return": { "$ref": "#/$defs/nullableNumber" },
        "standardized_response": { "$ref": "#/$defs/nullableNumber" }
      },
      "additionalProperties": true
    },
    "quality": {
      "type": "object",
      "required": ["grade", "headline_eligible", "evidence_gap_eligible", "observations", "peer_count", "eligible_peer_issuers", "filing_components", "required_filing_components", "filing_score_complete", "peer_filings_after_focus", "filing_event_complete", "sec_snapshot_status"],
      "properties": {
        "grade": { "type": "string", "enum": ["A", "B", "C", "D"] },
        "headline_eligible": { "type": "boolean" },
        "evidence_gap_eligible": { "type": "boolean" },
        "observations": { "type": "integer", "minimum": 0 },
        "peer_count": { "type": "integer", "minimum": 0 },
        "eligible_peer_issuers": { "type": "integer", "minimum": 0 },
        "filing_components": { "type": "integer", "minimum": 0 },
        "required_filing_components": { "type": "integer", "minimum": 0 },
        "filing_score_complete": { "type": "boolean" },
        "peer_filings_after_focus": { "type": ["integer", "null"], "minimum": 0 },
        "filing_event_complete": { "type": "boolean" },
        "sec_snapshot_status": { "type": "string" }
      },
      "additionalProperties": true
    },
    "provenance": {
      "type": "object",
      "required": ["sec", "prices"],
      "properties": {
        "sec": {
          "type": "object",
          "required": ["source", "snapshot_generated_at", "reporting_basis", "point_in_time", "cutoff", "current_filing", "prior_filing"],
          "properties": {
            "source": { "type": "string", "format": "uri" },
            "snapshot_generated_at": { "$ref": "#/$defs/dateTime" },
            "reporting_basis": { "type": "string", "enum": ["ttm", "annual"] },
            "point_in_time": { "type": "boolean" },
            "cutoff": { "type": ["object", "null"], "additionalProperties": true },
            "current_filing": { "type": ["object", "null"], "additionalProperties": true },
            "prior_filing": { "type": ["object", "null"], "additionalProperties": true }
          },
          "additionalProperties": true
        },
        "prices": {
          "type": "object",
          "required": ["asset", "market", "sector_proxy"],
          "properties": {
            "asset": { "$ref": "#/$defs/priceSeries" },
            "market": { "$ref": "#/$defs/priceSeries" },
            "sector_proxy": { "$ref": "#/$defs/priceSeries" }
          },
          "additionalProperties": true
        }
      },
      "additionalProperties": true
    },
    "priceSeries": {
      "type": "object",
      "required": ["ticker", "provider", "cache_status", "price_basis", "adjustment_coverage", "retrieved_at", "first_observation", "last_observation", "observations", "attempts"],
      "properties": {
        "ticker": { "type": "string" },
        "provider": { "type": "string", "enum": ["yahoo_finance", "stooq"] },
        "cache_status": { "type": "string" },
        "price_basis": { "type": "string" },
        "adjustment_coverage": { "type": ["number", "null"], "minimum": 0, "maximum": 1 },
        "retrieved_at": { "$ref": "#/$defs/nullableDateTime" },
        "first_observation": { "$ref": "#/$defs/nullableDate" },
        "last_observation": { "$ref": "#/$defs/nullableDate" },
        "observations": { "type": "integer", "minimum": 0 },
        "attempts": { "type": "array", "items": { "type": "object", "additionalProperties": true } }
      },
      "additionalProperties": true
    }
  }
}
