fix(portfolio): 周报双修——回测基准认 equity 列(生产四文件全被 balance-only 拒)+daily_returns 同日多行取末次(多写者防覆写) [vps]
CI/CD / test (push) Successful in 22s
CI/CD / nas-deploy (push) Successful in 12s
CI/CD / nas-verify (push) Successful in 8s

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-25 14:49:10 +08:00
parent 3fcf58728b
commit a2fb7b4dbb
2 changed files with 36 additions and 7 deletions
+12 -7
View File
@@ -31,13 +31,16 @@ def _week_start(d: date) -> date:
def daily_returns(series: list[tuple[str, float]]) -> dict[str, float]:
"""[(date, equity)] → {date: 当日收益率};首日无前值跳过,前值 0 防除零.
平盘日(收益 0.0)照记不剔除——剔除会低估 TE(M5 终审裁定).
"""[(date, equity)] → {date: 当日收益率};同日多行取末次写入(多写者日末终值),
首日无前值跳过,前值 0 防除零.平盘日(收益 0.0)照记不剔除——剔除会低估 TE(M5 终审裁定).
"""
last: dict[str, float] = {}
for d, eq in series:
last[d] = eq
out: dict[str, float] = {}
prev: float | None = None
for d, eq in sorted(series):
for d in sorted(last):
eq = last[d]
if prev is not None and prev != 0:
out[d] = eq / prev - 1.0
prev = eq
@@ -57,7 +60,7 @@ def load_actual_daily_returns(db_path: str, account_id: int,
def load_backtest_daily_returns(db_path: str,
task_id: str) -> dict[str, float] | None:
"""回测基准:backtest_stats 最新行 → equity_path JSON(date/balance,orient=records)."""
"""回测基准:backtest_stats 最新行 → equity_path JSON(date/balance|equity,orient=records)."""
with sqlite3.connect(db_path) as conn:
row = conn.execute(
"SELECT equity_path FROM backtest_stats WHERE task_id=? "
@@ -67,11 +70,13 @@ def load_backtest_daily_returns(db_path: str,
try:
import pandas as pd
ec = pd.read_json(row[0], orient="records")
if "balance" not in ec.columns:
col = "balance" if "balance" in ec.columns else (
"equity" if "equity" in ec.columns else None)
if col is None:
return None
dates = pd.to_datetime(ec["date"]).dt.strftime("%Y-%m-%d")
series = list(zip(dates.tolist(),
pd.to_numeric(ec["balance"], errors="coerce").tolist()))
pd.to_numeric(ec[col], errors="coerce").tolist()))
series = [(d, float(v)) for d, v in series if v == v] # NaN 剔除
return daily_returns(series) if series else None
except Exception as exc: