feat: cockpit
This commit is contained in:
@@ -6239,6 +6239,32 @@ def get_latest_saxo_snapshot_rows(symbol: str) -> List[Dict[str, Any]]:
|
||||
return [dict(r) for r in rows]
|
||||
|
||||
|
||||
def get_saxo_daily_snapshot_rows(symbol: str, days: int = 365) -> List[Dict[str, Any]]:
|
||||
"""One row per (snapshot_date, expiry_date, strike, option_type) — the day's last
|
||||
capture per contract, for every day in the last `days` that has any snapshot. Unlike
|
||||
get_latest_saxo_snapshot_rows (overall-latest only), this gives an end-of-day
|
||||
cross-section per day, used to build a Saxo-only ATM IV history (services.saxo_iv_engine)
|
||||
for IV Rank/Percentile computed purely from our own accumulated Saxo captures — never
|
||||
blended with the yfinance-based iv_history table."""
|
||||
conn = get_conn()
|
||||
rows = conn.execute("""
|
||||
SELECT s.* FROM saxo_option_snapshots s
|
||||
JOIN (
|
||||
SELECT snapshot_date, expiry_date, strike, option_type, MAX(created_at) AS max_created
|
||||
FROM saxo_option_snapshots
|
||||
WHERE symbol = ? AND snapshot_date >= date('now', ?)
|
||||
GROUP BY snapshot_date, expiry_date, strike, option_type
|
||||
) latest
|
||||
ON s.snapshot_date = latest.snapshot_date AND s.expiry_date = latest.expiry_date
|
||||
AND s.strike = latest.strike AND s.option_type = latest.option_type
|
||||
AND s.created_at = latest.max_created
|
||||
WHERE s.symbol = ?
|
||||
ORDER BY s.snapshot_date, s.expiry_date, s.strike
|
||||
""", (symbol, f"-{days} days", symbol)).fetchall()
|
||||
conn.close()
|
||||
return [dict(r) for r in rows]
|
||||
|
||||
|
||||
def get_snapshot_rows_asof(symbol: Optional[str] = None, as_of: Optional[str] = None) -> List[Dict[str, Any]]:
|
||||
"""One row per (symbol, expiry_date, strike, option_type) — the freshest capture at or
|
||||
before `as_of` (an ISO datetime string), or simply the freshest capture overall when
|
||||
|
||||
Reference in New Issue
Block a user