Download backtest/make_chart.py from lbb123/p05: direct link, hf CLI and curl.
- Browser
- Download file 2.24 kB
-
https://huggingface.co/spaces/lbb123/p05/resolve/main/backtest/make_chart.py
- Command line
-
hf download hf://spaces/lbb123/p05/backtest/make_chart.py
-
curl -L -o make_chart.py https://huggingface.co/spaces/lbb123/p05/resolve/main/backtest/make_chart.py
2.24 kB
| """净值曲线图:策略 vs 买入持有(对数轴),标注逻辑退出区间与 2026 OOS 分界。 | |
| 用法:python make_chart.py [tag] (默认 final,读 results/<tag>/{curve.csv,stats.json}) | |
| """ | |
| import csv | |
| import json | |
| import sys | |
| from pathlib import Path | |
| import matplotlib | |
| matplotlib.use("Agg") | |
| import matplotlib.pyplot as plt # noqa: E402 | |
| matplotlib.rcParams["font.sans-serif"] = ["Microsoft YaHei", "SimHei", "DejaVu Sans"] | |
| matplotlib.rcParams["axes.unicode_minus"] = False | |
| HERE = Path(__file__).resolve().parent | |
| tag = sys.argv[1] if len(sys.argv) > 1 else "final" | |
| res = HERE / "results" / tag | |
| rows = list(csv.DictReader(open(res / "curve.csv", encoding="utf-8"))) | |
| dates = [r["date"] for r in rows] | |
| V = [float(r["V"]) for r in rows] | |
| B = [float(r["bh_V"]) for r in rows] | |
| stats = json.loads((res / "stats.json").read_text(encoding="utf-8")) | |
| exit_spans = stats["exit_spans"] | |
| has_oos = "oos" in stats | |
| fig, ax = plt.subplots(figsize=(11.5, 6), dpi=150) | |
| ax.plot(dates, B, lw=1.2, color="#b8b8b8", label="买入持有 (LBMA PM)") | |
| ax.plot(dates, V, lw=1.6, color="#c8912a", label="金仓 v2.1 策略") | |
| ax.set_yscale("log") | |
| for lo, hi in exit_spans: | |
| ax.axvspan(lo, hi, color="#c0392b", alpha=0.13, lw=0) | |
| if has_oos: | |
| ax.axvline("2026-01-01", color="#4569a0", ls="--", lw=1.1) | |
| xmax = len(dates) - 1 | |
| ax.annotate("2026 样本外 →", xy=(0.865, 0.045), xycoords="axes fraction", | |
| fontsize=9, color="#4569a0") | |
| ax.annotate("红色底纹 = 逻辑退出区间\n(pace < 102 吨/季)", | |
| xy=(0.02, 0.74), xycoords="axes fraction", fontsize=9, color="#c0392b") | |
| tick_idx = [i for i, d in enumerate(dates) | |
| if d[5:7] == "01" and (i == 0 or dates[i - 1][5:7] != "01")] | |
| step = max(1, len(tick_idx) // 8) | |
| ax.set_xticks([dates[i] for i in tick_idx[::step]]) | |
| ax.set_xticklabels([dates[i][:4] for i in tick_idx[::step]], fontsize=9) | |
| ax.set_ylabel("净值(V0 = 10,000,对数轴)", fontsize=10) | |
| ax.set_title(f"金仓 v2.1 全历史回测 {dates[0]} → {dates[-1]}(USD,含 0.05% 单边成本)", fontsize=12) | |
| ax.grid(alpha=0.25, which="both") | |
| ax.legend(loc="upper left", fontsize=10) | |
| fig.tight_layout() | |
| out = res / "equity.png" | |
| fig.savefig(out) | |
| print(f"已写 {out}") | |