Add live expiry countdown for options positions on instance page and trading hub.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -227,6 +227,35 @@ def option_fields_from_inst_id(inst_id: str) -> tuple[str | None, float | None]:
|
||||
return opt_type, strike
|
||||
|
||||
|
||||
def expiry_ms_from_inst_id(inst_id: str) -> int | None:
|
||||
"""从 instId 日期段解析到期时刻(OKX 期权默认 08:00 UTC)。"""
|
||||
parts = (inst_id or "").strip().split("-")
|
||||
if len(parts) < 3:
|
||||
return None
|
||||
date_part = parts[-3]
|
||||
if not re.fullmatch(r"\d{6}", date_part):
|
||||
return None
|
||||
try:
|
||||
from datetime import datetime, timezone
|
||||
|
||||
yy, mm, dd = int(date_part[0:2]), int(date_part[2:4]), int(date_part[4:6])
|
||||
dt = datetime(2000 + yy, mm, dd, 8, 0, 0, tzinfo=timezone.utc)
|
||||
return int(dt.timestamp() * 1000)
|
||||
except (ValueError, OSError):
|
||||
return None
|
||||
|
||||
|
||||
def normalize_option_exp_ms(exp_time: Any, inst_id: str = "") -> int | None:
|
||||
"""统一期权到期毫秒时间戳(优先 API expTime,否则从 instId 推算)。"""
|
||||
raw = _safe_float(exp_time)
|
||||
if raw is not None and raw > 0:
|
||||
ms = int(raw)
|
||||
if ms < 10_000_000_000:
|
||||
ms *= 1000
|
||||
return ms
|
||||
return expiry_ms_from_inst_id(inst_id)
|
||||
|
||||
|
||||
def fetch_option_instrument_meta(ex: ccxt.okx, inst_id: str) -> dict[str, Any] | None:
|
||||
family = inst_family_from_inst_id(inst_id)
|
||||
if not family:
|
||||
@@ -839,6 +868,7 @@ def format_position_row(pos: dict[str, Any], ct_mult: float = 0.01) -> dict[str,
|
||||
pos=sheets,
|
||||
ct_mult=ct_mult,
|
||||
)
|
||||
exp_time_ms = normalize_option_exp_ms(pos.get("expTime"), inst_id)
|
||||
return {
|
||||
"inst_id": inst_id or pos.get("instId"),
|
||||
"pos": sheets,
|
||||
@@ -849,7 +879,8 @@ def format_position_row(pos: dict[str, Any], ct_mult: float = 0.01) -> dict[str,
|
||||
"premium_paid": premium_paid,
|
||||
"upl": upl,
|
||||
"upl_ratio_pct": round(upl_ratio * 100, 2) if upl_ratio is not None else None,
|
||||
"exp_time": pos.get("expTime"),
|
||||
"exp_time": exp_time_ms,
|
||||
"exp_time_ms": exp_time_ms,
|
||||
"opt_type": opt_type,
|
||||
"strike": strike,
|
||||
"avail_pos": _safe_float(pos.get("availPos")),
|
||||
|
||||
Reference in New Issue
Block a user