OpenBB-finance/OpenBB · error · OpenBBError

Error: '{stat}' could not be generated because the underlyin

Error message

Error: '{stat}' could not be generated because the underlying price was not returned by the provider. Set manually with 'underlying_price' property.

What it means

Raised inside OptionsChainsData.filter_data when stat is 'dex' or 'gex' (uppercased to DEX/GEX), that computed column is absent from the cached dataframe, greeks ARE present, but the underlying price is missing — the DEX/GEX formula multiplies by underlying_price, so it cannot be derived. Setting last_price (or the underlying_price property) injects the price and lets the columns be computed.

Source

Thrown at openbb_platform/core/openbb_core/provider/utils/options_chains_properties.py:340

        """
        # pylint: disable=import-outside-toplevel
        from numpy import nan
        from pandas import DataFrame, concat

        stats = ["open_interest", "volume", "dex", "gex"]
        _stat = stat.upper() if stat in ["dex", "gex"] else stat
        by = "strike" if date is not None else by
        if stat is not None:
            if stat not in stats:
                raise OpenBBError(f"Error: stat must be one of {stats}")
            if stat in ["volume", "open_interest"]:
                return DataFrame(self._get_stat(stat, moneyness=moneyness, date=date)[by]).replace({nan: None})  # type: ignore
            if (
                _stat not in self.dataframe.columns
                and self.has_greeks
                and "underlying_price" not in self.dataframe.columns
            ):
                raise OpenBBError(
                    f"Error: '{stat}' could not be generated because"
                    + " the underlying price was not returned by the provider."
                    + " Set manually with 'underlying_price' property."
                )
            df = DataFrame(self._get_stat(_stat, moneyness=moneyness, date=date)[by])  # type: ignore
            return df.replace({nan: None})

        df = self.dataframe

        if moneyness is not None:
            df_calls = DataFrame(
                df[df.strike >= df.underlying_price].query("option_type == 'call'")
            )
            df_puts = DataFrame(
                df[df.strike <= df.underlying_price].query("option_type == 'put'")
            )
            df = concat([df_calls, df_puts])

View on GitHub (pinned to 3e071fcc2c)

Solutions

  1. Set the override before filtering: result.last_price = 585.20; then result.filter_data(stat='gex')
  2. Or request the chains from a provider that returns underlying_price alongside greeks
  3. If exposure stats are optional, wrap the call in a has_greeks + underlying-price check and degrade gracefully

Example fix

# before
df = res.filter_data(stat="dex")  # OpenBBError: 'dex' could not be generated...

# after
res.last_price = 185.50
df = res.filter_data(stat="dex")
Defensive patterns

Strategy: validation

Validate before calling

def prep_for_exposure(res, spot: float):
    if spot is not None and res.last_price is None:
        res.last_price = spot
    return res

# call before filter_data(stat="dex"/"gex") whenever the provider omits the spot

Type guard

def can_filter_exposure(res) -> bool:
    return res.has_greeks and ("underlying_price" in res.dataframe.columns or res.last_price is not None)

Try / catch

from openbb_core.app.model.abstract.error import OpenBBError

try:
    df = res.filter_data(stat="gex")
except OpenBBError as e:
    if "underlying price was not returned" in str(e):
        res.last_price = get_spot(symbol)
        df = res.filter_data(stat="gex")
    else:
        raise

Prevention

When it happens

Trigger: result.filter_data(stat='gex') on a chains response whose provider returned greeks but no underlying_price, and where result.last_price was never set. The enriched dataframe therefore lacks the DEX/GEX columns this branch requires.

Common situations: Greeks-rich providers without spot quotes (some derivatives-only endpoints); users who fetched with one provider and then set a spot from another source but forgot the last_price override.

Related errors


AI-assisted analysis of OpenBB-finance/OpenBB@3e071fcc2c (2026-08-14). Data as JSON: /api/errors/e3d3ca27978fae3c. Report an issue: GitHub.