"""v3 研究对比图:v2.1 vs F5 动态线 vs 组合候选(2013-2025,现金 0 口径)。 用法:python make_chart_v3.py """ import sys from pathlib import Path import matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt # noqa: E402 import engine as E # noqa: E402 from overlays import build_overlays # noqa: E402 matplotlib.rcParams["font.sans-serif"] = ["Microsoft YaHei", "SimHei", "DejaVu Sans"] matplotlib.rcParams["axes.unicode_minus"] = False HERE = Path(__file__).resolve().parent OV = build_overlays() CONFIGS = [("v2.1(12%,现行)", 12.0, None, "#c8912a"), ("F5 动态盈亏平衡线", 12.0, {"cb_line": OV["breakeven"]}, "#4569a0"), ("组合候选(8%+动量地板+闪断+动态线)", 8.0, {"cap_half": OV["mom12_1_cap"], "breaker": True, "cb_line": OV["breakeven"]}, "#7a4ea3")] fig, ax = plt.subplots(figsize=(11.5, 6), dpi=150) dates = None out_rows = [] for label, vol, ov, color in CONFIGS: _, _, data = E.run("2013-01-01", "2025-12-31", target_vol_ann=vol, overlay=ov, tag=None) curve = data["curve"] dates = [c["date"] for c in curve] V = [c["V"] for c in curve] B = [c["bh_V"] for c in curve] out_rows.append((label, dates, V)) ax.plot(dates, V, lw=1.5, color=color, label=label) ax.plot(dates, B, lw=1.0, color="#b8b8b8", label="买入持有") ax.set_yscale("log") 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("v3 研究:候选配置 vs v2.1(2013–2025,成本后,现金 0% 口径)", fontsize=12) ax.grid(alpha=0.25, which="both") ax.legend(loc="upper left", fontsize=9) fig.tight_layout() out = HERE / "results" / "v3" out.mkdir(parents=True, exist_ok=True) fig.savefig(out / "v3_equity.png") with open(out / "curves.csv", "w", encoding="utf-8") as f: f.write("date," + ",".join(l[0] for l in out_rows) + ",bh\n") for i, d in enumerate(dates): f.write(d + "," + ",".join(f"{r[2][i]:.4f}" for r in out_rows) + f",{B[i]:.4f}\n") print(f"已写 {out / 'v3_equity.png'} 与 curves.csv")