feat数据统计曲线改为权益采样,现金加现货币权利金与浮盈。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
"""实例数据统计:复盘 KPI + 资金曲线 API,以及后台现金采样."""
|
||||
"""实例数据统计:复盘 KPI + 权益曲线 API,以及后台权益采样."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Callable
|
||||
@@ -10,13 +10,72 @@ def install_instance_data_stats(app: Flask, app_module: Any) -> None:
|
||||
get_db: Callable = app_module.get_db
|
||||
login_required = app_module.login_required
|
||||
|
||||
def _fetch_balances() -> dict[str, Any]:
|
||||
ex = getattr(app_module, "exchange_options", None)
|
||||
if ex is None:
|
||||
return {}
|
||||
from lib.exchange.okx_options_lib import fetch_options_balances
|
||||
def _fetch_equity_snapshot() -> dict[str, Any]:
|
||||
from lib.instance.instance_cash_sample_lib import (
|
||||
cash_usdt_from_balances,
|
||||
equity_usdt_from_snapshot,
|
||||
)
|
||||
|
||||
return fetch_options_balances(ex, force=False) or {}
|
||||
ex = getattr(app_module, "exchange_options", None)
|
||||
bal: dict[str, Any] = {}
|
||||
if ex is not None:
|
||||
try:
|
||||
from lib.exchange.okx_options_lib import fetch_options_balances
|
||||
|
||||
bal = fetch_options_balances(ex, force=False) or {}
|
||||
except Exception:
|
||||
bal = {}
|
||||
cash = cash_usdt_from_balances(bal if isinstance(bal, dict) else None)
|
||||
|
||||
positions: list[dict[str, Any]] = []
|
||||
cfg = None
|
||||
try:
|
||||
cfg = app.extensions.get("options_cfg")
|
||||
except Exception:
|
||||
cfg = None
|
||||
if isinstance(cfg, dict) and cfg.get("enabled"):
|
||||
try:
|
||||
from lib.options.options_dashboard_lib import (
|
||||
fetch_light_option_positions_for_dashboard,
|
||||
)
|
||||
|
||||
positions = fetch_light_option_positions_for_dashboard(cfg) or []
|
||||
except Exception:
|
||||
positions = []
|
||||
|
||||
btc_px = eth_px = None
|
||||
if ex is not None:
|
||||
try:
|
||||
from lib.options.options_stats_lib import _underlying_index_usdt
|
||||
|
||||
btc_px = _underlying_index_usdt(ex, "BTC")
|
||||
eth_px = _underlying_index_usdt(ex, "ETH")
|
||||
except Exception:
|
||||
btc_px = eth_px = None
|
||||
if (btc_px is None or eth_px is None) and positions:
|
||||
for p in positions:
|
||||
if not isinstance(p, dict):
|
||||
continue
|
||||
under = str(p.get("underlying") or "").upper()
|
||||
idx = None
|
||||
try:
|
||||
idx = float(p.get("idx_px") or p.get("index_px") or 0)
|
||||
except (TypeError, ValueError):
|
||||
idx = None
|
||||
if idx is None or idx <= 0:
|
||||
continue
|
||||
if under == "BTC" and btc_px is None:
|
||||
btc_px = idx
|
||||
elif under == "ETH" and eth_px is None:
|
||||
eth_px = idx
|
||||
|
||||
equity = equity_usdt_from_snapshot(
|
||||
bal if isinstance(bal, dict) else None,
|
||||
positions,
|
||||
btc_px=btc_px,
|
||||
eth_px=eth_px,
|
||||
)
|
||||
return {"cash_usdt": cash, "equity_usdt": equity}
|
||||
|
||||
@app.route("/api/instance/cash_curve")
|
||||
@login_required
|
||||
@@ -26,9 +85,8 @@ def install_instance_data_stats(app: Flask, app_module: Any) -> None:
|
||||
sample_once,
|
||||
)
|
||||
|
||||
# 打开页面时尽量补一笔最新点(失败忽略)
|
||||
try:
|
||||
sample_once(get_db, _fetch_balances)
|
||||
sample_once(get_db, _fetch_equity_snapshot)
|
||||
except Exception:
|
||||
pass
|
||||
range_key = (request.args.get("range") or "7d").strip()
|
||||
@@ -40,10 +98,9 @@ def install_instance_data_stats(app: Flask, app_module: Any) -> None:
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
# 后台采样(daemon);无密钥时会空转跳过
|
||||
try:
|
||||
from lib.instance.instance_cash_sample_lib import start_cash_sample_loop
|
||||
|
||||
start_cash_sample_loop(get_db, _fetch_balances)
|
||||
start_cash_sample_loop(get_db, _fetch_equity_snapshot)
|
||||
except Exception as e:
|
||||
print(f"[instance_cash_sample] start skipped: {e}", flush=True)
|
||||
|
||||
Reference in New Issue
Block a user