File size: 2,242 Bytes
0580e8e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
"""净值曲线图:策略 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}")