feat数据统计曲线改为累计已实现盈亏,划转提现不再影响。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -170,36 +170,106 @@ def _range_start_ms(range_key: str) -> tuple[str, int]:
|
||||
return "7d", now_ms - 7 * 86400 * 1000
|
||||
|
||||
|
||||
def query_cash_series_with_db(conn, *, range_key: str = "7d") -> dict[str, Any]:
|
||||
def _closed_at_to_ms(raw: Any) -> int | None:
|
||||
if raw is None or raw == "":
|
||||
return None
|
||||
try:
|
||||
from lib.options.options_stats_lib import _parse_ts
|
||||
|
||||
d = _parse_ts(raw)
|
||||
if d is None:
|
||||
return None
|
||||
return int(d.timestamp() * 1000)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def _trade_realized_usdt(row: Any) -> float | None:
|
||||
u = _safe_float(row["realized_pnl_usdt"] if hasattr(row, "keys") else None)
|
||||
if u is not None:
|
||||
return round(float(u), 4)
|
||||
# 兼容未冻结 U:币盈亏×平仓价
|
||||
try:
|
||||
coin = _safe_float(row["realized_pnl"])
|
||||
px = _safe_float(row["close_index_px"])
|
||||
except Exception:
|
||||
return None
|
||||
if coin is None or px is None or px <= 0:
|
||||
return None
|
||||
return round(float(coin) * float(px), 4)
|
||||
|
||||
|
||||
def query_realized_pnl_series_with_db(conn, *, range_key: str = "7d") -> dict[str, Any]:
|
||||
"""累计已实现盈亏曲线(只随平仓变化,划转/提现不影响)."""
|
||||
rk, start_ms = _range_start_ms(range_key)
|
||||
now_ms = int(time.time() * 1000)
|
||||
init_cash_sample_table(conn)
|
||||
try:
|
||||
from lib.options.options_db import init_options_tables
|
||||
|
||||
init_options_tables(conn)
|
||||
except Exception:
|
||||
pass
|
||||
rows = conn.execute(
|
||||
"""
|
||||
SELECT ts_ms, cash_usdt, equity_usdt
|
||||
FROM instance_cash_samples
|
||||
WHERE ts_ms >= ?
|
||||
ORDER BY ts_ms ASC
|
||||
""",
|
||||
(start_ms,),
|
||||
SELECT id, closed_at, created_at, realized_pnl_usdt, realized_pnl, close_index_px
|
||||
FROM options_trades
|
||||
WHERE status = 'closed'
|
||||
ORDER BY COALESCE(closed_at, created_at) ASC, id ASC
|
||||
"""
|
||||
).fetchall()
|
||||
points = []
|
||||
events: list[tuple[int, float]] = []
|
||||
for r in rows:
|
||||
cash = float(r["cash_usdt"])
|
||||
eq = r["equity_usdt"]
|
||||
v = float(eq) if eq is not None else cash
|
||||
points.append({"t": int(r["ts_ms"]), "v": v, "cash": cash})
|
||||
pnl_u = _trade_realized_usdt(r)
|
||||
if pnl_u is None:
|
||||
continue
|
||||
ts = _closed_at_to_ms(r["closed_at"]) or _closed_at_to_ms(r["created_at"])
|
||||
if ts is None:
|
||||
continue
|
||||
events.append((ts, float(pnl_u)))
|
||||
|
||||
cum = 0.0
|
||||
all_points: list[dict[str, Any]] = []
|
||||
for ts, pnl in events:
|
||||
cum = round(cum + pnl, 4)
|
||||
all_points.append({"t": int(ts), "v": cum})
|
||||
|
||||
baseline = 0.0
|
||||
series: list[dict[str, Any]] = []
|
||||
for p in all_points:
|
||||
if int(p["t"]) < start_ms:
|
||||
baseline = float(p["v"])
|
||||
continue
|
||||
if not series:
|
||||
series.append({"t": int(start_ms), "v": baseline})
|
||||
series.append({"t": int(p["t"]), "v": float(p["v"])})
|
||||
if not series:
|
||||
# 窗口内无新平仓:画水平线(历史累计或 0)
|
||||
series = [
|
||||
{"t": int(start_ms), "v": baseline},
|
||||
{"t": int(now_ms), "v": baseline},
|
||||
]
|
||||
else:
|
||||
last_v = float(series[-1]["v"])
|
||||
if int(series[-1]["t"]) < now_ms:
|
||||
series.append({"t": int(now_ms), "v": last_v})
|
||||
|
||||
return {
|
||||
"ok": True,
|
||||
"range": rk,
|
||||
"metric": "equity",
|
||||
"points": points,
|
||||
"metric": "realized_pnl",
|
||||
"points": series,
|
||||
"start_ms": start_ms,
|
||||
"end_ms": now_ms,
|
||||
"latest": points[-1]["v"] if points else None,
|
||||
"latest": series[-1]["v"] if series else None,
|
||||
"trade_count": len(events),
|
||||
}
|
||||
|
||||
|
||||
def query_cash_series_with_db(conn, *, range_key: str = "7d") -> dict[str, Any]:
|
||||
"""兼容旧名:数据统计曲线改为累计已实现盈亏."""
|
||||
return query_realized_pnl_series_with_db(conn, range_key=range_key)
|
||||
|
||||
|
||||
def sample_once(get_db: Callable, fetch_snapshot: Callable) -> bool:
|
||||
"""拉取快照并写入采样.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user