OpenBB-finance/OpenBB · error · OpenBBError
Error: Moneyness must be expressed as a percentage between 0
Error message
Error: Moneyness must be expressed as a percentage between 0 and 100
What it means
Raised in OptionsChainsData._get_nearest_otm_strikes (used for ITM/OTM strike boundaries). moneyness is a percentage: values in (0, 100) exclusive are divided by 100 to a fraction; a value > 100 or < 0 after that normalization raises this error. Note the edge: exactly 0 or exactly 100 are accepted as-is (0 stays 0), and passing 0.25 means 0.25% because 0<0.25<100 triggers /100.
Source
Thrown at openbb_platform/core/openbb_core/provider/utils/options_chains_properties.py:545
underlying_price: Optional[float]
Only supply this is if the underlying price is not a returned field.
Returns
-------
Dict[str, float]
Dictionary of the upper (call) and lower (put) strike prices.
"""
# pylint: disable=import-outside-toplevel
from pandas import Series
if moneyness is None:
moneyness = 0.25
if 0 < moneyness < 100:
moneyness = moneyness / 100
if moneyness > 100 or moneyness < 0:
raise OpenBBError(
"Error: Moneyness must be expressed as a percentage between 0 and 100"
)
df = self.dataframe
if underlying_price is None and not hasattr(df, "underlying_price"):
raise OpenBBError(
"Error: underlying_price must be provided if underlying_price is not available"
)
if date is not None:
date = self._get_nearest_expiration(date)
df = df[df.expiration.astype(str) == date]
strikes = Series(df.strike.unique().tolist())
last_price = (
underlying_price
if underlying_price is not NoneView on GitHub (pinned to 3e071fcc2c)
Solutions
- Pass the value as a percent in (0, 100): moneyness=25 for 25%
- Do not pass fractions — 0.25 is treated as 0.25%, not 25%
- Clamp/validate user input on your side to 0 < moneyness < 100 before the call
Example fix
# before strikes = res.filter_data(moneyness=0.25) # treated as 0.25%, not 25%; 250 would raise # after strikes = res.filter_data(moneyness=25) # 25 percent
Defensive patterns
Strategy: validation
Validate before calling
def normalize_moneyness(m) -> float:
if m is None:
return 25.0
if not 0 < m < 100 and m not in (0, 100):
raise ValueError("moneyness must be a percent in [0, 100]")
return m
moneyness = normalize_moneyness(user_moneyness) Type guard
def is_valid_moneyness(m) -> bool:
return isinstance(m, (int, float)) and 0 <= m <= 100 Try / catch
from openbb_core.app.model.abstract.error import OpenBBError
try:
strikes = res.filter_data(moneyness=moneyness)
except OpenBBError as e:
if "Moneyness must be expressed" in str(e):
strikes = res.filter_data(moneyness=25) # default 25 percent
else:
raise Prevention
- Always express moneyness in percent units (25 = 25%), never as a 0-1 fraction
- Validate/clamp user input to 0-100 at the form boundary
- Remember the default is 0.25 (i.e. 0.25%) when omitted — pass 25 explicitly for a quarter-window
When it happens
Trigger: Calling methods that take moneyness= (e.g. filter_data(moneyness=...)) with 250 (meaning 2.5x), -5, or a fraction intended as already-normalized like 0.25 (which gets re-interpreted as 0.25%). Values above 100 after no division, like moneyness=150, raise.
Common situations: Confusion between percent (25) and fraction (0.25) conventions; passing monetary strike offsets or multipliers instead of percentages.
Related errors
- Error: underlying_price must be provided if underlying_price
- Error: option_type must be either 'call' or 'put'
- 'underlying_price' was not returned in the provider data.
- Error: No validated data was found.
- Greeks are not available.
AI-assisted analysis of OpenBB-finance/OpenBB@3e071fcc2c (2026-08-14).
Data as JSON: /api/errors/aebfa8f1c5d49636.
Report an issue: GitHub.