Hub funds and dashboard: include OKX options balances in USDT totals.

Merge options USDC/USDT at 1:1 into fund overview snapshots, dashboard aggregation, and monitor board totals while keeping a separate options breakdown in the UI.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-07 13:06:01 +08:00
parent 6cc3382526
commit 3163912266
9 changed files with 362 additions and 21 deletions
+40 -12
View File
@@ -8,6 +8,7 @@ from pathlib import Path
from typing import Any, Optional
from lib.hub.hub_trades_lib import current_trading_day
from lib.hub.hub_options_funds_lib import merge_board_row_balances
from lib.paths import manual_trading_hub_dir
@@ -160,13 +161,20 @@ def record_fund_snapshot(
total = account_total_usdt(fu, tu)
if total is None:
continue
row_accounts[key] = {
entry: dict[str, Any] = {
"name": ac.get("name"),
"funding_usdt": fu,
"trading_usdt": tu,
"total_usdt": total,
"recorded_at": _now_str(),
}
ofu = _safe_float(ac.get("options_funding_usdt"))
otu = _safe_float(ac.get("options_trading_usdt"))
if ofu is not None:
entry["options_funding_usdt"] = ofu
if otu is not None:
entry["options_trading_usdt"] = otu
row_accounts[key] = entry
if row_accounts:
days[day] = {"accounts": row_accounts, "updated_at": _now_str()}
days = _prune_days(
@@ -188,14 +196,23 @@ def record_fund_snapshot_from_board(
for row in rows or []:
if not isinstance(row, dict):
continue
if not row.get("account_ok"):
if not row.get("account_ok") and not (
"options" in (row.get("capabilities") or [])
and isinstance(row.get("options"), dict)
and row.get("options", {}).get("ok")
):
continue
merged = merge_board_row_balances(row)
if not merged.get("data_ok"):
continue
accounts.append(
{
"key": row.get("key") or row.get("id"),
"name": row.get("name"),
"funding_usdt": row.get("funding_usdt"),
"trading_usdt": row.get("trading_usdt"),
"funding_usdt": merged.get("funding_usdt"),
"trading_usdt": merged.get("trading_usdt"),
"options_funding_usdt": merged.get("options_funding_usdt"),
"options_trading_usdt": merged.get("options_trading_usdt"),
"monitored": True,
}
)
@@ -297,14 +314,21 @@ def build_fund_overview(
monitored = True
row = _live_row_for_exchange(ex, rows_by_key)
fu = tu = total = None
pf = pt = ofu = otu = None
data_ok = False
if row and row.get("account_ok"):
fu = _safe_float(row.get("funding_usdt"))
tu = _safe_float(row.get("trading_usdt"))
total = account_total_usdt(fu, tu)
data_ok = total is not None
if data_ok:
live_total += total
caps = ex.get("capabilities") or []
if row:
merged = merge_board_row_balances({**row, "capabilities": caps})
if merged.get("data_ok"):
fu = merged.get("funding_usdt")
tu = merged.get("trading_usdt")
total = merged.get("total_usdt")
pf = merged.get("perpetual_funding_usdt")
pt = merged.get("perpetual_trading_usdt")
ofu = merged.get("options_funding_usdt")
otu = merged.get("options_trading_usdt")
data_ok = True
live_total += float(total)
live_known += 1
series = _account_series(history, key) if key else []
@@ -329,6 +353,10 @@ def build_fund_overview(
"data_ok": data_ok,
"funding_usdt": fu,
"trading_usdt": tu,
"perpetual_funding_usdt": pf,
"perpetual_trading_usdt": pt,
"options_funding_usdt": ofu,
"options_trading_usdt": otu,
"total_usdt": total,
"series": series,
"drawdown": dd,
@@ -387,7 +415,7 @@ def format_fund_history_text(
if not history:
return "(暂无资金历史快照)"
names = account_names or {}
lines = ["【资金快照(资金账户 + 交易账户 USDT)】"]
lines = ["【资金快照(资金账户 + 交易账户 USDT,含期权 USDC≈USDT)】"]
for day in sorted(history.keys()):
block = history.get(day) or {}
ac_map = block.get("accounts") or {}