feat: option lab
This commit is contained in:
@@ -6645,8 +6645,21 @@ def get_snapshot_rows_asof(symbol: Optional[str] = None, as_of: Optional[str] =
|
|||||||
"""One row per (symbol, expiry_date, strike, option_type) — the freshest capture at or
|
"""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
|
before `as_of` (an ISO datetime string), or simply the freshest capture overall when
|
||||||
as_of is omitted. Powers the Saxo History page's default 'current chain' view and its
|
as_of is omitted. Powers the Saxo History page's default 'current chain' view and its
|
||||||
'replay a past moment' filter — the full granular history stays in the table underneath
|
'replay a past moment' filter, and services.option_chain.get_chain_slice's `as_of`
|
||||||
for later backtest use, this just picks one row per contract."""
|
historical reconstruction (Portfolio retrospective comparison, Options Lab pricing
|
||||||
|
check) — the full granular history stays in the table underneath for later backtest
|
||||||
|
use, this just picks one row per contract.
|
||||||
|
|
||||||
|
A bare date (no time component, e.g. "2026-07-21") is treated as the END of that day,
|
||||||
|
not the start. `created_at` is always a real capture timestamp like
|
||||||
|
"2026-07-21 13:59:43" — comparing that against the bare string "2026-07-21" with SQL's
|
||||||
|
`<=` is a plain string comparison, and a 19-char timestamp always sorts AFTER its own
|
||||||
|
10-char date prefix, so every row captured that day would be silently excluded and a
|
||||||
|
date that genuinely has data would look like it has none (this was a real bug: querying
|
||||||
|
`as_of="2026-07-21"` against a symbol with rows *starting* on 2026-07-21 returned empty).
|
||||||
|
"""
|
||||||
|
if as_of and len(as_of) <= 10:
|
||||||
|
as_of = as_of + "T23:59:59"
|
||||||
conn = get_conn()
|
conn = get_conn()
|
||||||
where_symbol = "AND symbol = ?" if symbol else ""
|
where_symbol = "AND symbol = ?" if symbol else ""
|
||||||
where_asof = "AND created_at <= ?" if as_of else ""
|
where_asof = "AND created_at <= ?" if as_of else ""
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ def get_chain_slice(
|
|||||||
really was on a position's entry_date, not today's. Every days-to-expiry figure is
|
really was on a position's entry_date, not today's. Every days-to-expiry figure is
|
||||||
computed relative to `as_of` in that case, not date.today() — using today's date to
|
computed relative to `as_of` in that case, not date.today() — using today's date to
|
||||||
size a historical chain would silently misdate every contract in it.
|
size a historical chain would silently misdate every contract in it.
|
||||||
|
|
||||||
|
A bare date (no time component) in `as_of` is handled by get_snapshot_rows_asof itself
|
||||||
|
(treated as end-of-day, not start — see its docstring for why that matters).
|
||||||
"""
|
"""
|
||||||
from services.database import get_latest_saxo_snapshot_rows, get_snapshot_rows_asof
|
from services.database import get_latest_saxo_snapshot_rows, get_snapshot_rows_asof
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user