feat: option
This commit is contained in:
@@ -41,6 +41,32 @@ def _rows_from_df(df) -> List[Dict[str, Any]]:
|
||||
|
||||
|
||||
def get_chain_slice(symbol: str, target_days: int = 8, n_expiries: int = 3) -> Dict[str, Any]:
|
||||
"""
|
||||
Fetch the real option chain for `symbol` — yfinance by default, with an automatic
|
||||
Saxo fallback for instruments yfinance can't handle (FX/futures options).
|
||||
|
||||
Dispatch: a Saxo-formatted symbol (exchange suffix, e.g. "OG:xcme") goes straight to
|
||||
Saxo; otherwise yfinance is tried first (unchanged, proven path for stocks/ETFs), and
|
||||
only falls back to Saxo if yfinance fails AND a Saxo connection is available.
|
||||
"""
|
||||
if ":" in symbol:
|
||||
from services.saxo_client import get_chain_slice_saxo
|
||||
return get_chain_slice_saxo(symbol, target_days, n_expiries)
|
||||
|
||||
try:
|
||||
return _get_chain_slice_yfinance(symbol, target_days, n_expiries)
|
||||
except ValueError:
|
||||
from services import saxo_auth
|
||||
from services.saxo_client import get_chain_slice_saxo
|
||||
if saxo_auth.get_status().get("connected"):
|
||||
try:
|
||||
return get_chain_slice_saxo(symbol, target_days, n_expiries)
|
||||
except Exception as e:
|
||||
logger.debug(f"[OptionChain] Saxo fallback failed for {symbol}: {e}")
|
||||
raise
|
||||
|
||||
|
||||
def _get_chain_slice_yfinance(symbol: str, target_days: int = 8, n_expiries: int = 3) -> Dict[str, Any]:
|
||||
"""
|
||||
Fetch the real option chain for `symbol` around a target horizon (days).
|
||||
Returns the `n_expiries` expirations closest to target_days, each with
|
||||
|
||||
Reference in New Issue
Block a user