Files

34 lines
1.4 KiB
Python

"""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) 这策略赢过买入持有了吗?为什么?