Load options review from local records with compact journal UI.
Drop exchange sync for the review page, auto-import closed local options and hedge plans, and match contract-style multi-timeframe upload styling with smaller fonts. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -133,6 +133,69 @@ def upsert_option_history_row(conn: sqlite3.Connection, row: dict[str, Any]) ->
|
||||
return "inserted"
|
||||
|
||||
|
||||
def sync_options_from_local_trades(conn: sqlite3.Connection) -> dict[str, Any]:
|
||||
"""从本地 options_trades 已平仓记录导入复盘快照(不访问交易所)."""
|
||||
init_options_review_tables(conn)
|
||||
from lib.options.options_db import init_options_tables
|
||||
|
||||
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
|
||||
FROM options_trades
|
||||
WHERE status = 'closed'
|
||||
ORDER BY id DESC
|
||||
LIMIT 500
|
||||
"""
|
||||
).fetchall()
|
||||
inserted = updated = skipped = 0
|
||||
for r in rows:
|
||||
trade_id = int(r["id"])
|
||||
history_key = f"local_opt:{trade_id}"
|
||||
pnl = _safe_float(r["realized_pnl"])
|
||||
opened_at = r["created_at"]
|
||||
closed_at = r["closed_at"]
|
||||
action = upsert_option_history_row(
|
||||
conn,
|
||||
{
|
||||
"history_key": history_key,
|
||||
"pos_id": f"local:{trade_id}",
|
||||
"inst_id": r["inst_id"],
|
||||
"underlying": r["underlying"],
|
||||
"opt_type": r["opt_type"],
|
||||
"strike": r["strike"],
|
||||
"exp_time": r["exp_time"],
|
||||
"sheets": r["sheets"],
|
||||
"open_avg_px": r["open_quote"],
|
||||
"close_avg_px": r["close_quote"],
|
||||
"premium_paid": r["premium_paid"],
|
||||
"realized_pnl": pnl,
|
||||
"created_at": opened_at,
|
||||
"closed_at": closed_at,
|
||||
"status_label": "已平",
|
||||
},
|
||||
)
|
||||
if action == "inserted":
|
||||
inserted += 1
|
||||
elif action == "updated":
|
||||
updated += 1
|
||||
else:
|
||||
skipped += 1
|
||||
set_sync_state(conn, "options_last_sync_at", _now_str())
|
||||
set_sync_state(conn, "options_last_count", str(len(rows)))
|
||||
set_sync_state(conn, "options_sync_source", "local")
|
||||
return {
|
||||
"ok": True,
|
||||
"source": "local",
|
||||
"fetched": len(rows),
|
||||
"inserted": inserted,
|
||||
"updated": updated,
|
||||
"skipped": skipped,
|
||||
}
|
||||
|
||||
|
||||
def sync_options_from_exchange(
|
||||
conn: sqlite3.Connection,
|
||||
ex: Any,
|
||||
@@ -141,7 +204,7 @@ def sync_options_from_exchange(
|
||||
fetch_fn: Optional[Callable[..., list[dict[str, Any]]]] = None,
|
||||
format_fn: Optional[Callable[..., dict[str, Any]]] = None,
|
||||
) -> dict[str, Any]:
|
||||
"""从 OKX positions-history 导入已全平期权仓位."""
|
||||
"""从 OKX positions-history 导入已全平期权仓位(可选,默认不用)."""
|
||||
init_options_review_tables(conn)
|
||||
from lib.exchange.okx_options_lib import (
|
||||
fetch_all_option_positions_history,
|
||||
@@ -171,8 +234,10 @@ def sync_options_from_exchange(
|
||||
skipped += 1
|
||||
set_sync_state(conn, "options_last_sync_at", _now_str())
|
||||
set_sync_state(conn, "options_last_count", str(len(raw_rows)))
|
||||
set_sync_state(conn, "options_sync_source", "exchange")
|
||||
return {
|
||||
"ok": True,
|
||||
"source": "exchange",
|
||||
"fetched": len(raw_rows),
|
||||
"inserted": inserted,
|
||||
"updated": updated,
|
||||
@@ -326,24 +391,31 @@ def sync_hedge_plans_closed(conn: sqlite3.Connection) -> dict[str, Any]:
|
||||
|
||||
def sync_all_review_sources(
|
||||
conn: sqlite3.Connection,
|
||||
ex: Any | None,
|
||||
ex: Any | None = None,
|
||||
*,
|
||||
options_limit: int = 500,
|
||||
from_exchange: bool = False,
|
||||
fetch_fn: Optional[Callable[..., list[dict[str, Any]]]] = None,
|
||||
format_fn: Optional[Callable[..., dict[str, Any]]] = None,
|
||||
) -> dict[str, Any]:
|
||||
"""默认只读本地 options_trades + 已结束对冲计划;不访问交易所."""
|
||||
init_options_review_tables(conn)
|
||||
out: dict[str, Any] = {"ok": True, "options": None, "hedge": None}
|
||||
if ex is not None:
|
||||
if from_exchange and ex is not None:
|
||||
out["options"] = sync_options_from_exchange(
|
||||
conn, ex, limit=options_limit, fetch_fn=fetch_fn, format_fn=format_fn
|
||||
)
|
||||
else:
|
||||
out["options"] = {"ok": False, "msg": "期权 exchange 未就绪"}
|
||||
out["options"] = sync_options_from_local_trades(conn)
|
||||
out["hedge"] = sync_hedge_plans_closed(conn)
|
||||
return out
|
||||
|
||||
|
||||
def ensure_local_review_synced(conn: sqlite3.Connection) -> dict[str, Any]:
|
||||
"""列表/统计前轻量刷新本地源."""
|
||||
return sync_all_review_sources(conn, from_exchange=False)
|
||||
|
||||
|
||||
def _row_to_dict(row: Any) -> dict[str, Any]:
|
||||
return dict(row) if row is not None else {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user