Enrich sim option positions with public index and mark prices.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+80
-15
@@ -552,20 +552,85 @@ class SimBroker:
|
|||||||
)
|
)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def option_positions_okx_rows(self) -> list[dict[str, Any]]:
|
def option_positions_okx_rows(self, exchange: Any = None) -> list[dict[str, Any]]:
|
||||||
"""对齐 OKX positions 行字段, 供 format_position_row 使用."""
|
"""对齐 OKX positions 行字段, 供 format_position_row 使用.
|
||||||
rows = []
|
|
||||||
|
模拟盘补充公开行情的 idxPx / markPx, 否则指数价与平掉回本均为空.
|
||||||
|
"""
|
||||||
|
from lib.exchange.okx_options_lib import (
|
||||||
|
expiry_ms_from_inst_id,
|
||||||
|
fetch_index_price,
|
||||||
|
inst_family_from_inst_id,
|
||||||
|
option_fields_from_inst_id,
|
||||||
|
quote_option_contract,
|
||||||
|
)
|
||||||
|
|
||||||
|
rows: list[dict[str, Any]] = []
|
||||||
|
idx_cache: dict[str, float | None] = {}
|
||||||
for p in self.list_option_positions():
|
for p in self.list_option_positions():
|
||||||
rows.append(
|
inst_id = str(p["inst_id"] or "")
|
||||||
{
|
sheets = float(p["sheets"])
|
||||||
"instId": p["inst_id"],
|
entry = float(p["entry_px"])
|
||||||
"pos": str(p["sheets"]),
|
ct_mult = float(p.get("ct_mult") or 0.01)
|
||||||
"avgPx": str(p["entry_px"]),
|
opt_type, strike = option_fields_from_inst_id(inst_id)
|
||||||
"markPx": str(p["entry_px"]),
|
mark = entry
|
||||||
"upl": "0",
|
idx = None
|
||||||
"uplRatio": "0",
|
exp_ms = expiry_ms_from_inst_id(inst_id)
|
||||||
"posSide": "long",
|
|
||||||
"mgnMode": "isolated",
|
if exchange is not None and inst_id:
|
||||||
}
|
try:
|
||||||
)
|
q = quote_option_contract(exchange, inst_id)
|
||||||
|
if q.get("ok"):
|
||||||
|
raw_mark = q.get("mark")
|
||||||
|
if raw_mark is None:
|
||||||
|
raw_mark = q.get("bid")
|
||||||
|
if raw_mark is not None and float(raw_mark) > 0:
|
||||||
|
mark = float(raw_mark)
|
||||||
|
if q.get("index_px") is not None:
|
||||||
|
idx = float(q["index_px"])
|
||||||
|
if q.get("opt_type"):
|
||||||
|
opt_type = str(q["opt_type"])
|
||||||
|
if q.get("strike") is not None:
|
||||||
|
strike = float(q["strike"])
|
||||||
|
if q.get("exp_time") is not None:
|
||||||
|
try:
|
||||||
|
exp_ms = int(float(q["exp_time"]))
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
pass
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
if idx is None:
|
||||||
|
family = inst_family_from_inst_id(inst_id) or ""
|
||||||
|
uly = family.replace("_UM", "") if family else ""
|
||||||
|
if uly and uly not in idx_cache:
|
||||||
|
try:
|
||||||
|
idx_cache[uly] = fetch_index_price(exchange, uly)
|
||||||
|
except Exception:
|
||||||
|
idx_cache[uly] = None
|
||||||
|
idx = idx_cache.get(uly)
|
||||||
|
|
||||||
|
eth = abs(sheets) * ct_mult
|
||||||
|
upl = (mark - entry) * eth
|
||||||
|
prem = float(p.get("premium_paid_usdc") or 0) or (entry * eth)
|
||||||
|
upl_ratio = (upl / prem) if prem > 1e-12 else 0.0
|
||||||
|
row: dict[str, Any] = {
|
||||||
|
"instId": inst_id,
|
||||||
|
"pos": str(sheets),
|
||||||
|
"availPos": str(sheets),
|
||||||
|
"avgPx": str(entry),
|
||||||
|
"markPx": str(mark),
|
||||||
|
"upl": str(round(upl, 4)),
|
||||||
|
"uplRatio": str(round(upl_ratio, 6)),
|
||||||
|
"posSide": "long",
|
||||||
|
"mgnMode": "isolated",
|
||||||
|
}
|
||||||
|
if idx is not None:
|
||||||
|
row["idxPx"] = str(idx)
|
||||||
|
if opt_type:
|
||||||
|
row["optType"] = opt_type
|
||||||
|
if strike is not None:
|
||||||
|
row["stk"] = str(strike)
|
||||||
|
if exp_ms:
|
||||||
|
row["expTime"] = str(exp_ms)
|
||||||
|
rows.append(row)
|
||||||
return rows
|
return rows
|
||||||
|
|||||||
+1
-1
@@ -340,7 +340,7 @@ def _patch_okx_options_lib(app_module: Any) -> None:
|
|||||||
def fetch_option_positions(ex):
|
def fetch_option_positions(ex):
|
||||||
try:
|
try:
|
||||||
if _GET_DB is not None and is_sim_mode(_GET_DB):
|
if _GET_DB is not None and is_sim_mode(_GET_DB):
|
||||||
return broker().option_positions_okx_rows()
|
return broker().option_positions_okx_rows(ex)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
return _orig_fetch_pos(ex)
|
return _orig_fetch_pos(ex)
|
||||||
|
|||||||
Reference in New Issue
Block a user