QuantConnect/Lean · error · AssertionError

Expected greeks to have valid values. Greeks were: Delta: {g

Error message

Expected greeks to have valid values. Greeks were: Delta: {greeks.delta}, Rho: {greeks.rho}, Theta: {greeks.theta}, Vega: {greeks.vega}, Gamma: {greeks.gamma}

What it means

This assertion fires inside a QuantConnect Lean regression test that validates an option price model (e.g. BlackScholes, BjerksundStensland) actually produced mathematically sane Greeks for a contract whose option style the model claims to support. Lean exposes Greeks via contract.greeks; for supported styles the engine must return a populated Greek object whose values fall within theoretically valid ranges. The check enforces CALL delta in [0,1] with rho>=0, PUT delta in [-1,0] with rho<=0, theta!=0, vega>=0, gamma>=0, because a supported model returning out-of-range Greeks signals a pricing or data-feeding bug rather than a legitimate edge case.

Source

Thrown at Algorithm.Python/OptionPriceModelForOptionStylesBaseRegressionAlgorithm.py:80

                # Greeks should have not been successfully accessed if the option style is not supported
                option_style_str = 'American' if self._option.style == OptionStyle.AMERICAN else 'European'
                if not self._option_style_is_supported:
                    raise AssertionError(f'Expected greeks not to be calculated for {contract.symbol.value}, an {option_style_str} style option, using {type(self._option.price_model).__name__}, which does not support them, but they were')
            except ArgumentException:
                # ArgumentException is only expected if the option style is not supported
                if self._option_style_is_supported:
                    raise AssertionError(f'Expected greeks to be calculated for {contract.symbol.value}, an {option_style_str} style option, using {type(self._option.price_model).__name__}, which supports them, but they were not')

            # Greeks should be valid if they were successfuly accessed for supported option style
            # Delta can be {-1, 0, 1} if the price is too wild, rho can be 0 if risk free rate is 0
            # Vega can be 0 if the price is very off from theoretical price, Gamma = 0 if Delta belongs to {-1, 1}
            if (self._option_style_is_supported
                and (not greeks
                    or ((contract.right == OptionRight.CALL and (greeks.delta < 0.0 or greeks.delta > 1.0 or greeks.rho < 0.0))
                        or (contract.right == OptionRight.PUT and (greeks.delta < -1.0 or greeks.delta > 0.0 or greeks.rho > 0.0))
                        or greeks.theta == 0.0 or greeks.vega < 0.0 or greeks.gamma < 0.0))):
                raise AssertionError(f'Expected greeks to have valid values. Greeks were: Delta: {greeks.delta}, Rho: {greeks.rho}, Theta: {greeks.theta}, Vega: {greeks.vega}, Gamma: {greeks.gamma}')



View on GitHub (pinned to d2c3659f87)

Solutions

  1. Inspect the printed Greek values to identify which bound was violated (delta sign/range, rho sign, theta==0, vega<0, gamma<0) and correlate it with the contract.right.
  2. Verify the option price model set via option.set_price_model(...) actually supports the contract's OptionStyle (American vs European); an unsupported style should raise ArgumentException earlier, not yield bad Greeks.
  3. Check the underlying price and implied volatility feeds for the regression date; stale/NaN IV or a bad spot causes the model to return degenerate Greeks.
  4. If you are editing the pricing model in Lean C#, diff the Greek calculation against the known-good prior output and re-run the regression after the fix.

Example fix

// before: model returns CALL delta = -0.15
// after (correct pricing-model fix in C#): ensure delta sign convention matches contract.right
// In the test, narrow only what you intentionally assert:
if self._option_style_is_supported and (not greeks or greeks.delta is None):
    raise AssertionError('Greeks not populated for supported style')
Defensive patterns

Strategy: validation

Validate before calling

# Before trusting greeks, validate the price model supports the style and bounds-check each Greek
def safe_greeks(contract, option):
    if not option.price_model.supports_style(option.style):
        return None
    g = contract.greeks
    if g is None or any(v is None for v in (g.delta, g.rho, g.theta, g.vega, g.gamma)):
        return None
    lo, hi = (0.0, 1.0) if contract.right == OptionRight.CALL else (-1.0, 0.0)
    if not (lo <= g.delta <= hi):
        return None
    return g

Type guard

from QuantConnect.Data.Market import Greeks

def greeks_are_valid(greeks, right) -> bool:
    if greeks is None:
        return False
    if right == OptionRight.CALL:
        if not (0.0 <= greeks.delta <= 1.0) or greeks.rho < 0.0:
            return False
    else:
        if not (-1.0 <= greeks.delta <= 0.0) or greeks.rho > 0.0:
            return False
    return greeks.theta != 0.0 and greeks.vega >= 0.0 and greeks.gamma >= 0.0

Prevention

When it happens

Trigger: Accessing contract.greeks for a contract whose option style is marked supported (self._option_style_is_supported == True) when at least one Greek violates the bounds: e.g. a CALL whose delta < 0 or > 1, a CALL with rho < 0, a PUT with delta < -1 or > 0, a PUT with rho > 0, theta exactly 0.0, vega < 0, or gamma < 0. The value `greeks` being None/falsy also triggers it.

Common situations: A Lean engine change to the price model math that miscalculates a Greek; switching the risk-free rate feed so rho crosses zero unexpectedly; feeding stale or missing implied-volatility data so the model extrapolates; or running the regression against a data package whose underlying prices are wildly off from theoretical, causing delta to clip to +/-1 plus sign errors.

Related errors


AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13). Data as JSON: /api/errors/febdfcbd9eb11a93. Report an issue: GitHub.