"""03 | 双均线策略 + 回测 目标:写出人生第一个完整策略,并做归因。 策略:5日均线上穿20日均线买入,下穿卖出。 """ import pandas as pd, numpy as np import matplotlib; matplotlib.use("Agg") import matplotlib.pyplot as plt from lib_quant import get_daily, add_returns, net_value, stats FAST, SLOW = 5, 20 df = get_daily("600519", "20200101", "20241231") df = add_returns(df) df["ma_fast"] = df["收盘"].rolling(FAST).mean() df["ma_slow"] = df["收盘"].rolling(SLOW).mean() df["signal"] = (df["ma_fast"] > df["ma_slow"]).astype(int) # 1=持有 0=空仓 df["pos"] = df["signal"].shift(1).fillna(0) # 次日开盘才算,防未来函数 df["strat_ret"] = df["pos"] * df["ret"] nv_bh, nv_st = net_value(df["ret"]), net_value(df["strat_ret"]) print("== 买入持有 ==", stats(df["ret"])) print("== 双均线 ==", stats(df["strat_ret"])) plt.figure(figsize=(10, 4)) plt.plot(df["日期"], nv_bh, label="BuyHold") plt.plot(df["日期"], nv_st, label=f"MA{FAST}/{SLOW}") plt.legend(); plt.title("Strategy vs Buy&Hold"); plt.tight_layout() plt.savefig("../data/03_dual_ma.png", dpi=110) print("图已存 data/03_dual_ma.png") # 思考题: # 1) 为什么 pos 要 shift(1)?不 shift 会怎样?(把 shift(1) 去掉对比——这叫"未来函数") # 2) 改 FAST/SLOW 参数,结果稳吗?换 (10,60) 试试——这叫参数敏感性 # 3) 这策略赢过买入持有了吗?为什么?