Unequal-wing iron condor maintenance uses the put width when the call wing is wider
An isolated, zero-order Cloud probe on LEAN 2.5.0.0.18057 returns maintenance margin based only on the put wing for an unequal-wing credit iron condor. The native resolver recognizes the position as one Iron Condor. When the call wing is wider, the returned maintenance is below the gross expiration loss of the four-leg position.
Observed results
All contracts are European SPXW options expiring June 8, 2026. Every position group has quantity 2, with contract multipliers of 100. The probe creates position objects for the resolver; it never changes holdings or submits orders.
| Case |
Long put |
Short put |
Short call |
Long call |
Put/call widths |
Native maintenance |
Gross expiration loss |
| Equal wings |
7090 |
7185 |
7510 |
7605 |
95 / 95 |
$19,000 |
$19,000 |
| Call wing wider |
7135 |
7185 |
7500 |
7660 |
50 / 160 |
$10,000 |
$32,000 |
| Put wing wider |
7090 |
7235 |
7510 |
7605 |
145 / 95 |
$29,000 |
$29,000 |
Gross expiration loss is computed independently from the piecewise four-leg payoff at every strike and both tails. It excludes entry premium and fees. These figures measure LEAN native maintenance, not actual brokerage margin.
Expected behavior and source
For this recognized credit condor, the width-based maintenance calculation should account for the wider loss-bearing wing. Both call and put spread helpers already exist in the buying-power model. The condor maintenance branch at the tested LEAN commit calls only GetShortPutLongPutStrikeDifferenceMargin.
Using the maximum of the existing call and put helper results appears to address this credit-condor case while retaining their quantity, contract-unit and currency handling. Reverse/debit strategies, butterflies and other regressions still require native validation before adopting that change.
The initial-margin branch uses the same put helper, but this report directly tests maintenance only. Process-dependent grouping is separately tracked in issue 9648; this calculation issue reproduces with a single recognized group and does not rely on choosing between multiple groupings.
Reproducer
This Python algorithm compiled without warnings and completed the one-session probe with zero orders. Its cash balance is an arbitrary test configuration; no margin is consumed by actual holdings.
from AlgorithmImports import *
from datetime import datetime
import json
from QuantConnect.Securities.Positions import (
IPosition,
Position,
PositionCollection,
OptionStrategyPositionGroupResolver,
PositionGroupMaintenanceMarginParameters,
)
CASES = (
("equal", (7090, 7185, 7510, 7605)),
("call_wider", (7135, 7185, 7500, 7660)),
("put_wider", (7090, 7235, 7510, 7605)),
)
QUANTITY = 2
class UnequalWingMarginProbe(QCAlgorithm):
def initialize(self):
if self.live_mode:
raise RuntimeError("Unequal-wing probe supports backtests only")
self.set_start_date(2026, 6, 8)
self.set_end_date(2026, 6, 8)
self.set_cash(200000)
self.set_brokerage_model(BrokerageName.INTERACTIVE_BROKERS_BROKERAGE, AccountType.MARGIN)
spy = self.add_equity("SPY", Resolution.DAILY).symbol
self.set_benchmark(spy)
underlying = self.add_index("SPX", Resolution.MINUTE).symbol
self._probe_cases = []
subscribed = set()
resolver = OptionStrategyPositionGroupResolver(self.securities)
for name, strikes in CASES:
native_positions: list[IPosition] = []
symbols = []
for index, strike in enumerate(strikes):
right = OptionRight.PUT if index < 2 else OptionRight.CALL
sign = 1 if index in (0, 3) else -1
symbol = Symbol.create_option(underlying, "SPXW", Market.USA,
OptionStyle.EUROPEAN, right, strike, datetime(2026, 6, 8))
if symbol not in subscribed:
self.add_index_option_contract(symbol, Resolution.MINUTE)
subscribed.add(symbol)
native_positions.append(Position(symbol, sign * QUANTITY, 1))
symbols.append(symbol)
groups = list(resolver.resolve(PositionCollection(native_positions)))
if len(groups) != 1 or str(groups[0].buying_power_model) != "Iron Condor":
raise RuntimeError(f"Expected exactly one native Iron Condor for {name}")
group = groups[0]
if float(group.quantity) != QUANTITY:
raise RuntimeError("Native resolver changed the group quantity")
margin = group.buying_power_model.get_maintenance_margin(
PositionGroupMaintenanceMarginParameters(self.portfolio, group))
multipliers = [float(self.securities[symbol].symbol_properties.contract_multiplier)
for symbol in symbols]
if multipliers != [100.0] * 4:
raise RuntimeError(f"Unexpected multipliers: {multipliers}")
call_width = strikes[3] - strikes[2]
put_width = strikes[1] - strikes[0]
payoff = []
for spot in (0, *strikes, strikes[3] + 1000):
value = (max(strikes[0] - spot, 0) - max(strikes[1] - spot, 0)
- max(spot - strikes[2], 0) + max(spot - strikes[3], 0))
payoff.append(value * QUANTITY * 100)
gross_loss = -min(payoff)
if gross_loss != max(call_width, put_width) * QUANTITY * 100:
raise RuntimeError("Piecewise payoff and width formula disagree")
self._probe_cases.append(dict(case=name, strikes=strikes, quantity=QUANTITY,
call_width=call_width, put_width=put_width,
native_maintenance_margin=float(margin.value), gross_expiry_loss=gross_loss,
multipliers=multipliers))
def on_end_of_algorithm(self):
self.set_summary_statistic("Wing probe", json.dumps(self._probe_cases, separators=(",", ":")))
self.set_summary_statistic("Wing probe status", "completed_no_orders")
Can the team confirm the intended unequal-wing maintenance treatment and provide a supported Cloud correction? I can repeat the three fixed cases and the separate grouping reproducer against an updated engine.
Unequal-wing iron condor maintenance uses the put width when the call wing is wider
An isolated, zero-order Cloud probe on LEAN 2.5.0.0.18057 returns maintenance margin based only on the put wing for an unequal-wing credit iron condor. The native resolver recognizes the position as one Iron Condor. When the call wing is wider, the returned maintenance is below the gross expiration loss of the four-leg position.
Observed results
All contracts are European SPXW options expiring June 8, 2026. Every position group has quantity 2, with contract multipliers of 100. The probe creates position objects for the resolver; it never changes holdings or submits orders.
Gross expiration loss is computed independently from the piecewise four-leg payoff at every strike and both tails. It excludes entry premium and fees. These figures measure LEAN native maintenance, not actual brokerage margin.
Expected behavior and source
For this recognized credit condor, the width-based maintenance calculation should account for the wider loss-bearing wing. Both call and put spread helpers already exist in the buying-power model. The condor maintenance branch at the tested LEAN commit calls only
GetShortPutLongPutStrikeDifferenceMargin.Using the maximum of the existing call and put helper results appears to address this credit-condor case while retaining their quantity, contract-unit and currency handling. Reverse/debit strategies, butterflies and other regressions still require native validation before adopting that change.
The initial-margin branch uses the same put helper, but this report directly tests maintenance only. Process-dependent grouping is separately tracked in issue 9648; this calculation issue reproduces with a single recognized group and does not rely on choosing between multiple groupings.
Reproducer
This Python algorithm compiled without warnings and completed the one-session probe with zero orders. Its cash balance is an arbitrary test configuration; no margin is consumed by actual holdings.
Can the team confirm the intended unequal-wing maintenance treatment and provide a supported Cloud correction? I can repeat the three fixed cases and the separate grouping reproducer against an updated engine.