修复期权历史/复盘金额为0:模拟盘合成历史、币本位按ETH精度展示,复盘折算为U。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -271,28 +271,85 @@ def hide_review_trade(conn: sqlite3.Connection, trade_id: int) -> dict[str, Any]
|
||||
|
||||
|
||||
|
||||
def sync_options_from_local_trades(conn: sqlite3.Connection) -> dict[str, Any]:
|
||||
"""从本地 options_trades 已平仓记录导入复盘快照(不访问交易所)."""
|
||||
def sync_options_from_local_trades(
|
||||
conn: sqlite3.Connection,
|
||||
ex: Any | None = None,
|
||||
) -> dict[str, Any]:
|
||||
"""从本地 options_trades 已平仓记录导入复盘快照(不访问交易所).
|
||||
|
||||
币本位权利金/盈亏按指数折算成 USDT(U) 写入,复盘页统一按 U 展示.
|
||||
"""
|
||||
init_options_review_tables(conn)
|
||||
from lib.options.options_db import init_options_tables
|
||||
from lib.options.options_margin_mode_lib import margin_mode_from_inst_id, premium_ccy_for_mode
|
||||
|
||||
init_options_tables(conn)
|
||||
rows = conn.execute(
|
||||
"""
|
||||
SELECT id, inst_id, underlying, opt_type, strike, exp_time, sheets,
|
||||
open_quote, close_quote, premium_paid, realized_pnl,
|
||||
created_at, closed_at, signal_note, status
|
||||
open_quote, close_quote, premium_paid, premium_received, realized_pnl,
|
||||
premium_ccy, created_at, closed_at, signal_note, status
|
||||
FROM options_trades
|
||||
WHERE status = 'closed'
|
||||
ORDER BY id DESC
|
||||
LIMIT 500
|
||||
"""
|
||||
).fetchall()
|
||||
|
||||
def _index_px(underly: str) -> float | None:
|
||||
u = (underly or "ETH").strip().upper() or "ETH"
|
||||
pub = ex
|
||||
if pub is None:
|
||||
try:
|
||||
from lib.sim.hooks import _APP_MODULE
|
||||
|
||||
pub = getattr(_APP_MODULE, "exchange", None) if _APP_MODULE else None
|
||||
except Exception:
|
||||
pub = None
|
||||
if pub is None:
|
||||
return None
|
||||
try:
|
||||
t = pub.fetch_ticker(f"{u}/USDT") or {}
|
||||
last = t.get("last") or t.get("close")
|
||||
return float(last) if last is not None else None
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def _to_usdt(amount: float | None, *, ccy: str, idx: float | None) -> float | None:
|
||||
if amount is None:
|
||||
return None
|
||||
unit = (ccy or "USDC").strip().upper()
|
||||
if unit in ("ETH", "BTC"):
|
||||
if idx is None or idx <= 0:
|
||||
return None
|
||||
return round(float(amount) * float(idx), 4)
|
||||
return round(float(amount), 4)
|
||||
|
||||
inserted = updated = skipped = 0
|
||||
idx_cache: dict[str, float | None] = {}
|
||||
for r in rows:
|
||||
trade_id = int(r["id"])
|
||||
history_key = f"local_opt:{trade_id}"
|
||||
inst = str(r["inst_id"] or "")
|
||||
underly = str(r["underlying"] or (inst.split("-")[0] if inst else "ETH") or "ETH")
|
||||
ccy = str(r["premium_ccy"] or "").strip().upper()
|
||||
if not ccy:
|
||||
ccy = premium_ccy_for_mode(margin_mode_from_inst_id(inst), underly)
|
||||
if underly not in idx_cache:
|
||||
idx_cache[underly] = _index_px(underly)
|
||||
idx = idx_cache.get(underly)
|
||||
pnl = _safe_float(r["realized_pnl"])
|
||||
if pnl is None:
|
||||
paid0 = _safe_float(r["premium_paid"])
|
||||
recv0 = _safe_float(r["premium_received"])
|
||||
if paid0 is not None and recv0 is not None:
|
||||
pnl = recv0 - paid0
|
||||
prem = _safe_float(r["premium_paid"])
|
||||
pnl_u = _to_usdt(pnl, ccy=ccy, idx=idx)
|
||||
prem_u = _to_usdt(prem, ccy=ccy, idx=idx)
|
||||
if ccy in ("ETH", "BTC") and idx is None:
|
||||
pnl_u = pnl
|
||||
prem_u = prem
|
||||
opened_at = r["created_at"]
|
||||
closed_at = r["closed_at"]
|
||||
action = upsert_option_history_row(
|
||||
@@ -308,8 +365,8 @@ def sync_options_from_local_trades(conn: sqlite3.Connection) -> dict[str, Any]:
|
||||
"sheets": r["sheets"],
|
||||
"open_avg_px": r["open_quote"],
|
||||
"close_avg_px": r["close_quote"],
|
||||
"premium_paid": r["premium_paid"],
|
||||
"realized_pnl": pnl,
|
||||
"premium_paid": prem_u if prem_u is not None else prem,
|
||||
"realized_pnl": pnl_u if pnl_u is not None else pnl,
|
||||
"created_at": opened_at,
|
||||
"closed_at": closed_at,
|
||||
"status_label": "已平",
|
||||
@@ -552,7 +609,7 @@ def sync_all_review_sources(
|
||||
conn, ex, limit=options_limit, fetch_fn=fetch_fn, format_fn=format_fn
|
||||
)
|
||||
else:
|
||||
out["options"] = sync_options_from_local_trades(conn)
|
||||
out["options"] = sync_options_from_local_trades(conn, ex=ex)
|
||||
out["hedge"] = sync_hedge_plans_closed(conn)
|
||||
return out
|
||||
|
||||
@@ -579,7 +636,7 @@ def ensure_local_review_synced(
|
||||
backfill_hedge_option_legs_realized_pnl(conn, hist)
|
||||
except Exception:
|
||||
pass
|
||||
return sync_all_review_sources(conn, from_exchange=False)
|
||||
return sync_all_review_sources(conn, ex=ex, from_exchange=False)
|
||||
|
||||
|
||||
def _row_to_dict(row: Any) -> dict[str, Any]:
|
||||
|
||||
Reference in New Issue
Block a user