Files
qihuo/trade_log_lib.py
T
dekun 9f48f22d16 Gate order cancel to trading hours and sync trade logs from CTP.
Disable cancel UI outside sessions, query exchange fills for records, and label local vs counterparty rows.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-26 00:35:51 +08:00

70 lines
2.1 KiB
Python

"""交易记录:字段补全、资金曲线数据。"""
from __future__ import annotations
from typing import Any
TRADE_LOG_EXTRA_COLUMNS = (
"ALTER TABLE trade_logs ADD COLUMN margin_pct REAL",
"ALTER TABLE trade_logs ADD COLUMN equity_after REAL",
"ALTER TABLE trade_logs ADD COLUMN source TEXT DEFAULT 'local'",
"ALTER TABLE trade_logs ADD COLUMN ctp_trade_key TEXT",
)
def ensure_trade_log_columns(conn) -> None:
for sql in TRADE_LOG_EXTRA_COLUMNS:
try:
conn.execute(sql)
except Exception:
pass
def calc_equity_after(capital: float, pnl_net: float) -> float | None:
cap = float(capital or 0)
if cap <= 0:
return None
return round(cap + float(pnl_net or 0), 2)
def enrich_trades_for_records(
trades: list[dict[str, Any]],
*,
initial_capital: float = 0.0,
) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]:
"""表格仍按 id 降序;资金曲线按平仓时间升序用最新资金绘制。"""
rows = [dict(t) for t in trades]
chrono = sorted(
rows,
key=lambda t: ((t.get("close_time") or ""), int(t.get("id") or 0)),
)
running = float(initial_capital or 0)
curve: list[dict[str, Any]] = []
for t in chrono:
pnl_net = float(t.get("pnl_net") or 0)
eq = t.get("equity_after")
if eq is None:
if running > 0:
eq = round(running + pnl_net, 2)
else:
eq = None
t["equity_after"] = eq
if eq is not None:
running = float(eq)
if t.get("margin_pct") is None:
margin = float(t.get("margin") or 0)
cap_before = float(eq or 0) - pnl_net if eq is not None else 0.0
if margin > 0 and cap_before > 0:
t["margin_pct"] = round(margin / cap_before * 100, 2)
if eq is not None:
curve.append({
"time": (t.get("close_time") or "")[:19],
"value": float(eq),
"id": int(t.get("id") or 0),
})
return rows, curve