Files
OpenFin/backend/routers/options.py
OpenSquared d256b65d30 Initial commit — GeoOptions Intelligence Cockpit v2.0
Stack: FastAPI + React/TypeScript + SQLite + GPT-4o
Features: Radar géopolitique, Marchés, Régime Macro, Journal de Bord MTM,
Rapport IA, Super Contexte (base de raisonnement évolutive), Boucle feedback IA.
Deploy: Docker + docker-compose + nginx pour openfin.open-squared.tech

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 20:29:59 +02:00

112 lines
3.3 KiB
Python

from fastapi import APIRouter, Query
from typing import Optional
from services.options_pricer import (
black_scholes, compute_pnl_curve, bull_call_spread,
bear_put_spread, long_straddle, implied_vol_surface
)
from services.data_fetcher import get_quote, compute_historical_iv
router = APIRouter(prefix="/api/options", tags=["options"])
@router.get("/price")
def price_option(
symbol: str = Query(...),
strike: float = Query(...),
expiry_days: int = Query(90),
option_type: str = Query("call"),
rate: float = Query(0.05),
):
q = get_quote(symbol)
S = q["price"] if q and "price" in q else strike
sigma = compute_historical_iv(symbol)
T = expiry_days / 365
result = black_scholes(S, strike, T, rate, sigma, option_type)
result["underlying_price"] = S
result["sigma"] = sigma
return result
@router.get("/pnl-curve")
def pnl_curve(
symbol: str = Query(...),
strike: float = Query(...),
expiry_days: int = Query(90),
option_type: str = Query("call"),
quantity: int = Query(1),
premium_paid: float = Query(...),
rate: float = Query(0.05),
):
q = get_quote(symbol)
S = q["price"] if q and "price" in q else strike
sigma = compute_historical_iv(symbol)
T = expiry_days / 365
return compute_pnl_curve(S, strike, T, rate, sigma, option_type, quantity, premium_paid)
@router.get("/strategy/bull-call-spread")
def bull_spread(
symbol: str = Query(...),
strike_low: float = Query(...),
strike_high: float = Query(...),
expiry_days: int = Query(90),
rate: float = Query(0.05),
):
q = get_quote(symbol)
S = q["price"] if q and "price" in q else strike_low
sigma = compute_historical_iv(symbol)
T = expiry_days / 365
result = bull_call_spread(S, strike_low, strike_high, T, rate, sigma)
result["underlying_price"] = S
result["sigma"] = sigma
return result
@router.get("/strategy/bear-put-spread")
def bear_spread(
symbol: str = Query(...),
strike_high: float = Query(...),
strike_low: float = Query(...),
expiry_days: int = Query(90),
rate: float = Query(0.05),
):
q = get_quote(symbol)
S = q["price"] if q and "price" in q else strike_high
sigma = compute_historical_iv(symbol)
T = expiry_days / 365
result = bear_put_spread(S, strike_high, strike_low, T, rate, sigma)
result["underlying_price"] = S
result["sigma"] = sigma
return result
@router.get("/strategy/straddle")
def straddle(
symbol: str = Query(...),
strike: float = Query(...),
expiry_days: int = Query(90),
rate: float = Query(0.05),
):
q = get_quote(symbol)
S = q["price"] if q and "price" in q else strike
sigma = compute_historical_iv(symbol)
T = expiry_days / 365
result = long_straddle(S, strike, T, rate, sigma)
result["underlying_price"] = S
result["sigma"] = sigma
return result
@router.get("/iv-surface")
def iv_surface(
symbol: str = Query(...),
rate: float = Query(0.05),
):
q = get_quote(symbol)
S = q["price"] if q and "price" in q else 100.0
sigma = compute_historical_iv(symbol)
strikes_pct = [0.80, 0.85, 0.90, 0.95, 1.00, 1.05, 1.10, 1.15, 1.20]
expiries = [7, 14, 30, 60, 90, 180]
surface = implied_vol_surface(S, strikes_pct, expiries, rate, sigma)
return {"symbol": symbol, "spot": S, "surface": surface}