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

@@ -1,4 +1,4 @@
from fastapi import APIRouter, HTTPException
from fastapi import APIRouter, HTTPException, Query
import traceback as tb_mod
from pydantic import BaseModel
from typing import Optional, List, Dict, Any
@@ -179,6 +179,21 @@ def position_payoff(pos_id: str):
return compute_payoff(pos)
@router.get("/positions/{pos_id}/retrospective-optimal")
def position_retrospective_optimal(pos_id: str, as_of: str = Query(None)):
""""What would have been optimal, in hindsight?" — reprices the position's real legs
and runs the Strategy Builder optimizer against the REAL historical Saxo chain and the
REALIZED spot/IV move since entry (not a guessed scenario) — see
services.strategy_comparison.compute_retrospective_comparison. Expensive (runs the full
template-search optimizer), so this is on-demand from the Portfolio position detail, not
auto-computed for every open position."""
from services.strategy_comparison import compute_retrospective_comparison
pos = next((p for p in get_positions("open") + get_positions("closed") if p["id"] == pos_id), None)
if not pos:
raise HTTPException(status_code=404, detail=f"Position '{pos_id}' introuvable")
return compute_retrospective_comparison(pos, as_of=as_of)
@router.get("/scenario-exposure")
def scenario_exposure():
"""Reprices every open position under a handful of named macro scenarios (Risk-Off,

View File

@@ -248,3 +248,19 @@ def saxo_iv_snapshot(symbol: str):
def saxo_iv_history(symbol: str, days: int = Query(90, ge=1, le=730)):
from services.saxo_iv_engine import get_saxo_iv_history
return get_saxo_iv_history(symbol, days)
@router.get("/pricing-check")
def saxo_pricing_check(
ticker: str = Query(...),
date_a: str = Query(..., description="YYYY-MM-DD"),
date_b: str = Query(..., description="YYYY-MM-DD"),
target_dte: Optional[int] = Query(None, ge=1, le=365, description="Overrides the default (expiry closest to date_b)"),
):
"""Options Lab — was this option well priced between two dates? Picks the strike closest
to the underlying's actual outcome at date_b (hindsight), and by default the expiry
closest to date_b too (same hindsight principle, overridable via target_dte), reprices
it at both dates from real Saxo history, and decomposes the price move into
Delta/Theta/Vega contributions — see services.pricing_check.analyze_option_pricing."""
from services.pricing_check import analyze_option_pricing
return analyze_option_pricing(ticker, date_a, date_b, target_dte)