QuantConnect/Lean · error · AssertionError

Expected greeks to be calculated for {contract.symbol.value}

Error message

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

What it means

The complement of 178: raised in the except ArgumentException handler when the style IS supported but accessing contract.greeks threw ArgumentException anyway. It proves a supported style/model combination must succeed. CAVEAT: option_style_str is assigned inside the try (line 64) AFTER the throwing statement (line 61); if contract.greeks throws, option_style_str is undefined and this raise line itself raises NameError before the intended AssertionError message. The root cause it targets: a price model incorrectly rejecting a style it should support.

Source

Thrown at Algorithm.Python/OptionPriceModelForOptionStylesBaseRegressionAlgorithm.py:70

        if not self._check_greeks or len(contracts) == 0 or not self._option:
            return

        self._check_greeks = False
        self._tried_greeks_calculation = True

        for contract in contracts:
            greeks = None
            try:
                greeks = contract.greeks

                # 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 price model's SupportFor/style guard; ensure it does not throw for styles it supports.
  2. Confirm the regression subclass declared option_style_is_supported consistently with the model's actual support matrix.
  3. Fix the latent bug: move option_style_str assignment before the try (or outside it) so the error message is constructible when contract.greeks throws early.
  4. Verify the option's OptionStyle matches what the model is expected to price.

Example fix

# before: option_style_str only defined inside try, undefined if greeks throws
try:
    greeks = contract.greeks
    option_style_str = 'American' if ... else 'European'
    ...
except ArgumentException:
    raise AssertionError(f'... {option_style_str} ...')  # NameError risk
# after: compute the label before the try so the message is always valid
option_style_str = 'American' if self._option.style == OptionStyle.AMERICAN else 'European'
try:
    greeks = contract.greeks
except ArgumentException:
    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')
Defensive patterns

Strategy: try-catch

Validate before calling

# preflight: a supported style must compute greeks without throwing
if self._option_style_is_supported:
    try:
        contract.greeks
    except ArgumentException as e:
        self.debug(f"supported style unexpectedly rejected: {e}")

Type guard

def style_is_supported(price_model, style) -> bool:
    return price_model.supported_styles(style)

Try / catch

# compute the label OUTSIDE the try so the error message is always buildable
option_style_str = 'American' if self._option.style == OptionStyle.AMERICAN else 'European'
try:
    greeks = contract.greeks
except ArgumentException:
    if self._option_style_is_supported:
        raise AssertionError(f'Expected greeks for {contract.symbol.value} ({option_style_str}, {type(self._option.price_model).__name__}), but they were not')

Prevention

When it happens

Trigger: self._option_style_is_supported is True, but contract.greeks threw ArgumentException. Execution enters the except block and the supported-style branch raises (or, due to the scoping bug, raises NameError on option_style_str).

Common situations: The price model's style-support check became too strict (rejecting a supported style); the option was created with the wrong style for the model; a refactor inverted the Supports() result.

Related errors


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