feat: option lab

This commit is contained in:
OpenSquared
2026-07-28 11:14:31 +02:00
parent 568414ca0c
commit d2c393b8e5
11 changed files with 757 additions and 29 deletions

View File

@@ -81,7 +81,10 @@ def value_at(
r: float,
contract_size: float = DEFAULT_CONTRACT_SIZE,
) -> float:
"""Signed portfolio value (BS reprice for unexpired legs, intrinsic for expired ones)."""
"""Signed portfolio value (BS reprice for unexpired legs, intrinsic for expired ones).
check_bounded_risk calls this ~700 times per candidate it evaluates — second-order
Greeks are never read here, so they're skipped (include_second_order=False) rather than
computed and discarded on every one of those calls."""
total = 0.0
for leg in legs:
remaining = leg["days_to_expiry"] - eval_days_from_now
@@ -91,7 +94,7 @@ def value_at(
price = _intrinsic(S, leg["strike"], leg["option_type"])
else:
sigma = surface.iv_at(leg["strike"], remaining)
price = black_scholes(S, leg["strike"], remaining / 365, r, sigma, leg["option_type"])["price"]
price = black_scholes(S, leg["strike"], remaining / 365, r, sigma, leg["option_type"], include_second_order=False)["price"]
total += sign * price * qty * contract_size
return total