diff --git a/backend/routers/strategy_builder.py b/backend/routers/strategy_builder.py index 568bcfc..17aaabc 100644 --- a/backend/routers/strategy_builder.py +++ b/backend/routers/strategy_builder.py @@ -320,6 +320,11 @@ def price(req: PriceRequest): "max_gain": result.get("max_gain"), "max_loss": result.get("max_loss"), "bounded_risk": bounded_risk, }, + # Exact per-leg quote (exec_price/mid) actually used to build entry_cost — lets + # entry_cost be reconciled by hand against THIS number, instead of whatever the + # leg dropdown's own (independently-fetched, possibly a few seconds older/newer) + # chain snapshot happens to show at the moment of reading the screen. + "leg_prices": result.get("leg_prices"), "risk_debug": result.get("risk_debug"), }, ) diff --git a/backend/services/strategy_engine.py b/backend/services/strategy_engine.py index 530e62a..304c59e 100644 --- a/backend/services/strategy_engine.py +++ b/backend/services/strategy_engine.py @@ -173,12 +173,19 @@ def price_combo( entry_ref = 0.0 entry_ref_mid = 0.0 + leg_prices = [] # exact per-leg quote actually used — for reconciling entry_cost by hand for leg in legs: ep = entry_price(leg, chain_slice, surface_now, r) sign = _sign(leg) qty = leg.get("quantity", 1) entry_ref += sign * ep["exec_price"] * qty * contract_size entry_ref_mid += sign * ep["mid"] * qty * contract_size + leg_prices.append({ + "expiry_date": leg.get("expiry_date"), "strike": leg.get("strike"), + "option_type": leg.get("option_type"), "position": leg.get("position"), "quantity": qty, + "exec_price": round(ep["exec_price"], 6), "mid": round(ep["mid"], 6), + "contribution": round(sign * ep["exec_price"] * qty * contract_size, 2), + }) # Scenario exit: apply each leg's own bid/ask spread (est. from entry quote) to the # theoretical scenario value, since we don't have a live quote for the future date. @@ -225,6 +232,7 @@ def price_combo( "max_loss": bounded["max_loss"], "bounded_risk": bounded["bounded"], "risk_debug": bounded.get("risk_debug"), + "leg_prices": leg_prices, "greeks_now": greeks_at(legs, spot_now, 0, surface_now, r), "greeks_scenario": greeks_at(legs, spot_scenario, horizon_days, surface_scenario, r), "net_delta_now": delta_now,