fix: fund overview history starts from 2026-06-09

Add HUB_FUND_HISTORY_START_DAY so curves and drawdown exclude snapshots before the baseline trading day.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-10 16:58:57 +08:00
parent 77c7bbbb13
commit ba629ea0ee
7 changed files with 71 additions and 9 deletions
+24 -3
View File
@@ -18,6 +18,12 @@ try:
except ValueError:
FUND_HISTORY_DAYS = 180
FUND_HISTORY_START_DAY = (os.getenv("HUB_FUND_HISTORY_START_DAY") or "2026-06-09").strip()[:10]
def fund_history_start_day() -> str:
return FUND_HISTORY_START_DAY or "2026-06-09"
def _now_str() -> str:
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
@@ -72,12 +78,20 @@ def _atomic_write(path: Path, data: dict) -> None:
os.replace(tmp, path)
def _prune_days(days: dict, *, keep_days: int, anchor_day: str) -> dict:
def _prune_days(
days: dict,
*,
keep_days: int,
anchor_day: str,
start_day: Optional[str] = None,
) -> dict:
try:
anchor = datetime.strptime(anchor_day[:10], "%Y-%m-%d")
except ValueError:
anchor = datetime.now()
cutoff = (anchor - timedelta(days=max(1, keep_days) - 1)).strftime("%Y-%m-%d")
rolling_cutoff = (anchor - timedelta(days=max(1, keep_days) - 1)).strftime("%Y-%m-%d")
start = (start_day or fund_history_start_day()).strip()[:10]
cutoff = max(rolling_cutoff, start) if start else rolling_cutoff
return {k: v for k, v in (days or {}).items() if str(k) >= cutoff}
@@ -127,6 +141,9 @@ def record_fund_snapshot(
) -> dict[str, Any]:
"""写入当日各户资金账户/交易账户余额,并裁剪历史。"""
day = (trading_day or "").strip()[:10] or current_trading_day(reset_hour=reset_hour)
start = fund_history_start_day()
if start and day < start:
return _load_store().get("days") or {}
store = _load_store()
days = dict(store.get("days") or {})
row_accounts: dict[str, dict] = {}
@@ -150,7 +167,9 @@ def record_fund_snapshot(
}
if row_accounts:
days[day] = {"accounts": row_accounts, "updated_at": _now_str()}
days = _prune_days(days, keep_days=keep_days, anchor_day=day)
days = _prune_days(
days, keep_days=keep_days, anchor_day=day, start_day=fund_history_start_day()
)
_atomic_write(FUND_HISTORY_PATH, {"version": 1, "days": days})
return days
@@ -187,6 +206,7 @@ def get_fund_history(*, anchor_day: str, keep_days: int = FUND_HISTORY_DAYS) ->
dict(store.get("days") or {}),
keep_days=keep_days,
anchor_day=anchor_day,
start_day=fund_history_start_day(),
)
@@ -341,6 +361,7 @@ def build_fund_overview(
"trading_day": day,
"reset_hour": reset_hour,
"keep_days": keep_days,
"history_start_day": fund_history_start_day(),
"updated_at": updated_at,
"totals": {
"monitored_count": len(monitored_keys),
+2
View File
@@ -99,3 +99,5 @@ AI_MODEL=huihui_ai/deepseek-r1-abliterated:latest
TRADING_DAY_RESET_HOUR=8
# 资金概况 / AI 上下文:分户资金快照保留交易日数(默认 180)
# HUB_FUND_HISTORY_DAYS=180
# 资金曲线与回撤统计起始交易日(默认 2026-06-09,该日之前不记、不展示)
# HUB_FUND_HISTORY_START_DAY=2026-06-09
+2 -1
View File
@@ -215,7 +215,8 @@
const parts = [
"交易日 " + (data.trading_day || "—"),
"切日 " + (data.reset_hour != null ? data.reset_hour : 8) + ":00 北京",
"历史 " + (data.keep_days || 180) + " ",
" " + (data.history_start_day || "2026-06-09") + " ",
"最多 " + (data.keep_days || 180) + " 交易日",
];
if (data.updated_at) parts.push("刷新 " + data.updated_at);
if (totals.live_known_count != null) {
+2 -2
View File
@@ -334,7 +334,7 @@
<div id="page-funds" class="page hidden">
<div class="page-head">
<h1><span class="head-tag">FND</span> 资金概况</h1>
<p class="page-desc">总资金 = 各监控户(资金账户 + 交易账户);按北京时间交易日切日快照,保留 180 天</p>
<p class="page-desc">总资金 = 各监控户(资金账户 + 交易账户);自 2026-06-09 起按北京时间交易日切日快照,最多保留 180 天</p>
</div>
<div class="funds-toolbar toolbar">
<button type="button" id="funds-btn-refresh" class="primary">刷新</button>
@@ -456,7 +456,7 @@
<script src="/assets/chart_draw.js?v=20260609-market-day-split"></script>
<script src="/assets/chart.js?v=20260609-market-day-split"></script>
<script src="/assets/archive.js?v=20260608-hub-archive-history"></script>
<script src="/assets/funds.js?v=20260609-hub-funds"></script>
<script src="/assets/funds.js?v=20260609-hub-funds-start"></script>
<script src="/assets/ai_review_render.js?v=2"></script>
<script src="/assets/app.js?v=20260609-hub-funds"></script>
</body>
+1 -1
View File
@@ -200,7 +200,7 @@ Chrome **桌面快捷方式**图标来自站点 `favicon` / `manifest`(已配
| 功能 | 说明 |
|------|------|
| **总资金** | 已监控账户的 **资金户 + 交易户** 合计(不含浮盈) |
| **总曲线** | 按北京时间交易日(默认 8:00 切日)每日一点,保留 **180** 天 |
| **总曲线** | **2026-06-09** 起、按北京时间交易日(默认 8:00 切日)每日一点,最多 **180** 天 |
| **最大回撤** | 基于总资金余额曲线(非平仓盈亏回撤) |
| **分户** | 每户资金/交易拆分、迷你曲线、分户回撤;**未监控** 不参与合计 |
| **快照** | 监控板聚合成功时写入 `hub_fund_history.json` |
+4 -2
View File
@@ -14,7 +14,8 @@
| **缺数据** | 资金户、交易户任一侧缺失 → 该户当日快照 **跳过**(不估、不补 0 |
| **交易日** | 北京时间 `TRADING_DAY_RESET_HOUR`(默认 **8:00**)切日,与四所统计一致 |
| **曲线粒度** | 每个交易日 **1 个点** |
| **历史保留** | 默认 **180** 个交易日`HUB_FUND_HISTORY_DAYS` |
| **统计起点** | 默认 **2026-06-09**`HUB_FUND_HISTORY_START_DAY`;此前不记、不展示 |
| **历史保留** | 自起点起最多 **180** 个交易日(`HUB_FUND_HISTORY_DAYS` |
| **最大回撤** | 基于 **总资金曲线**(分户同理),峰值到谷底的最大跌幅(U 与 %) |
> 与实例统计页「最大回撤」不同:实例统计来自 **平仓盈亏累计**;资金概况来自 **账户余额曲线**。
@@ -63,7 +64,8 @@
| 变量 | 默认 | 说明 |
|------|------|------|
| `HUB_FUND_HISTORY_DAYS` | `180` | 资金快照保留交易日数 |
| `HUB_FUND_HISTORY_DAYS` | `180` | 资金快照保留交易日数(与起点取较晚边界) |
| `HUB_FUND_HISTORY_START_DAY` | `2026-06-09` | 曲线/回撤统计起始交易日 |
| `TRADING_DAY_RESET_HOUR` | `8` | 切日整点(北京),与四所 `.env` 建议一致 |
| `HUB_BOARD_POLL_INTERVAL` | `5` | 监控聚合间隔(秒),影响快照刷新频率 |
+36
View File
@@ -5,6 +5,7 @@ from hub_fund_history_lib import (
account_total_usdt,
build_fund_overview,
compute_drawdown,
get_fund_history,
record_fund_snapshot,
)
@@ -77,3 +78,38 @@ def test_build_fund_overview_skips_unmonitored(tmp_path, monkeypatch):
assert off["monitored"] is False
assert off["total_usdt"] is None
assert out["totals"]["drawdown"]["max_drawdown_u"] == 0.0
def test_history_start_day_filters_older(tmp_path, monkeypatch):
hist_path = tmp_path / "hub_fund_history.json"
monkeypatch.setattr("hub_fund_history_lib.FUND_HISTORY_PATH", hist_path)
monkeypatch.setattr("hub_fund_history_lib.FUND_HISTORY_START_DAY", "2026-06-09")
record_fund_snapshot(
"2026-06-01",
[
{
"key": "binance",
"name": "Binance",
"funding_usdt": 1,
"trading_usdt": 1,
"monitored": True,
}
],
keep_days=180,
)
record_fund_snapshot(
"2026-06-09",
[
{
"key": "binance",
"name": "Binance",
"funding_usdt": 10,
"trading_usdt": 20,
"monitored": True,
}
],
keep_days=180,
)
hist = get_fund_history(anchor_day="2026-06-10", keep_days=180)
assert "2026-06-01" not in hist
assert "2026-06-09" in hist