> ## Documentation Index
> Fetch the complete documentation index at: https://noxstock.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Why we refuse

> Why specific metrics are deliberately absent, and which served fields to use instead.

StockContext is intentionally conservative. A value we cannot prove from a filing is a typed refusal: schema 1 uses `{ "available": false, "reason": "..." }`, and schema 2 uses `{ "unavailable": "..." }`. Do not turn either form into `null`, `0`, or a hidden chart gap.

This page documents the main deliberate absences. They are not backlog promises. When there is a truthful alternative, use the served fields or the `recovery` object. When the API cannot prove the metric, the correct answer is the refusal.

## Negative P/E

**Refused:** `price_to_earnings` refuses with `ratio_undefined_nonpositive_denominator` when EPS or net income is not positive.

The multiple is non-monotonic across zero. A $30 stock losing $0.01/share shows P/E ≈ -3,000, while a $20 stock losing $20/share shows P/E ≈ -1. Sorting, screening, or comparing those negative multiples silently inverts the loss severity exactly where mistakes are most expensive. The industry is split: some vendors serve the negative value; Compustat-class systems and consumer sites typically blank it.

A vendor serving a negative P/E is following an honest convention on real inputs. That is not fabrication, and we do not claim it is. Fabrication is asserting a filing fact the filing does not contain, such as `0.0` for a never-reported line or revenue for a statement shape with no revenue line. StockContext refuses the negative multiple for machine-safety, not because the vendor convention is fake. The response says which is which.

**Use instead:** `earnings_yield_pct` serves signed for loss years. It is well-defined, sorts correctly through zero, and is basis-stamped `net_income_over_market_cap`. The served negative `eps_diluted` sits on the same response as proof that the P/E refusal is arithmetic, not missing data. The refusal envelope points there with `recovery.action: "use_alternative_field"` and `field: "earnings_yield_pct"`.

```json theme={null}
{
  "data": {
    "snapshot": {
      "market_cap": { "v": 1000000000, "d": "≈$1B" },
      "net_income": { "v": "-5000000", "d": "≈-$5M" },
      "eps_diluted": { "v": "-0.05" }
    },
    "valuation": {
      "price_to_earnings": {
        "unavailable": "ratio_undefined_nonpositive_denominator",
        "recovery": { "action": "use_alternative_field", "field": "earnings_yield_pct" }
      },
      "earnings_yield_pct": { "value": -0.5, "basis": "net_income_over_market_cap" }
    }
  }
}
```

## PEG ratio

**Refused:** `peg` / PEG ratio is not a served field.

Forward PEG needs analyst consensus earnings estimates, and fundamentals here are SEC-only. Trailing PEG can look mechanical, but it silently changes meaning or breaks when earnings or EPS growth crosses zero. Serving one canonical PEG would make the API choose a caveat for the caller.

**Use instead:** `stock_overview` serves `valuation.price_to_earnings` plus per-field growth where available, including `growth.eps_diluted.yoy_pct` in schema 2 summaries. Multi-year `cagr_2y_pct` also serves per-field when the API can compute it; read the field's own growth object instead of assuming every growth field has the same keys. An agent that explicitly accepts trailing-PEG caveats can compose its own value after checking that the growth denominator and latest EPS are positive.

```json theme={null}
{
  "valuation": { "price_to_earnings": 39.46 },
  "growth": { "eps_diluted": { "yoy_pct": 22.7 } }
}
```

Do not call the computed result StockContext-served PEG; it is your derived metric.

## EBITDA without filed D\&A

**Refused:** `ebitda` and dependent multiples such as `ev_to_ebitda` refuse when the filing does not provide a depreciation-and-amortization operand on the statement face.

EBITDA is only an exact derivation when every operand is a filed value. If D\&A is not on the statement face, synthesizing it from notes, roll-forwards, or vendor conventions would fabricate an operand and make the derived multiple look more certain than it is.

**Use instead:** when D\&A is filed, `ebitda` serves as `derived` and full provenance shows `operating_income + depreciation_amortization`; `ev_to_ebitda` then serves from `enterprise_value / ebitda`. When it refuses, use the filed operating and cash-flow fields that did serve, such as `operating_income` or `operating_cash_flow`.

```json theme={null}
{
  "valuation": {
    "ebitda": { "v": "144748000000", "d": "≈$144.7B" },
    "ev_to_ebitda": 30.48,
    "computed": ["ebitda", "enterprise_value"]
  }
}
```

## Financial-shape margins and inventory

**Refused:** generic COGS, gross-margin, operating-margin, and inventory-derived metrics are `not_applicable_for_shape` when the filer shape does not have those lines.

Banks, brokers, BDCs, and investment companies do not use an industrial "sales minus COGS equals gross profit" statement shape. Mapping bank interest expense or BDC investment income into COGS/inventory fields would produce familiar-looking numbers, but they would not be filing-proven economic lines.

**Use instead:** follow `recovery.field` and the fields catalog. Banks and brokers expose shape-native lines such as `net_interest_income`; bank overview exposes `efficiency_ratio_pct`; BDCs expose `total_investment_income`, and BDC overview can serve `price_to_nav` when both operands are available. Other specialty shapes serve their own native analysis fields instead of generic COGS/inventory fields. Never infer any of these from COGS.

```json theme={null}
{
  "unavailable": "not_applicable_for_shape",
  "recovery": { "action": "use_alternative_field", "field": "net_interest_income" }
}
```

## REIT FFO

**Refused:** `ffo` / `affo` refuse when the NAREIT adjustment lines are not tagged in XBRL.

Net income plus D\&A is not FFO. REIT FFO can require gains, impairments, unconsolidated JV adjustments, noncontrolling-interest adjustments, and other bridge lines that are often not tagged on the XBRL statement face. Serving a shortcut would be worse than refusing because it would look like a filed NAREIT bridge.

**Use instead:** REIT overview keeps the earnings-based `payout_ratio` labeled with its basis and additionally serves `dividends_to_ocf` when dividends and operating cash flow are provable. If you need management's FFO bridge, use the full filing; do not reconstruct it from net income and D\&A.

```json theme={null}
{
  "payout_ratio": { "value": 1.1312, "basis": "dividends_to_net_income" },
  "dividends_to_ocf": {
    "value": 0.7517,
    "note": "earnings-based payout overstates REIT payout due to real-estate depreciation; FFO not tagged in XBRL"
  }
}
```

## Back-derived share counts

**Refused:** weighted-average share counts are never back-derived from net income divided by EPS.

That arithmetic can disagree with the filed share count because EPS is rounded, share classes differ, and basic/diluted definitions are not interchangeable. A derived share count that disagrees with the filed one poisons every per-share ratio built on top of it.

**Use instead:** use `weighted_avg_shares_basic` and `weighted_avg_shares_diluted` only when they are filed and served. For point-in-time valuation, use `shares_outstanding` when served. If the share operand refuses, downstream per-share metrics refuse too.

## Missing is not zero

**Refused:** an absent filing line is never emitted as `0.0`.

Some data feeds collapse absence into zero, which makes "not tagged" indistinguishable from "the company reported exactly zero." That is a silent wrong-number path, especially for dividends, buybacks, inventory, and shape-specific lines.

**Use instead:** keep the refusal object and branch on it. A genuinely tagged zero serves as a real zero; an unprovable value serves as a closed-vocabulary refusal reason.

```json theme={null}
{ "unavailable": "not_reported" }
```

## Recovery and the zero-wrong gate

**Refused:** a value that is unverified, contradicted by the SEC oracle, or outside the extraction scope refuses instead of serving.

The product gate is mechanical: `known_wrong_served == 0`. Coverage can be incomplete; a served wrong value cannot be accepted. That is why refusal reasons are closed-vocabulary tokens and why recovery instructions are part of the value envelope.

**Use instead:** read `recovery` before deciding what to do next. It may tell an agent to retry, use another tool, use the full document, use an alternative field, or take no action. Resolve the machine catalog with `stock_reference`:

```json theme={null}
{ "schema": 2, "catalog": "refusal_reasons" }
```

See [Schema 2 refusals and provenance](/schema-2/refusals-and-provenance) for the schema-2 grammar and [Schema 2 reference catalogs](/schema-2/reference-catalogs) for the fields and refusal catalogs.
