strategy · 四大库合体
流水线:
拉数据(datetime 定日期)→
pandas 管表 →
numpy 算信号(发动机算得快)→
scipy 做评估
策略:MA5 上穿 MA20(金叉)买入,MA5 下穿 MA20(死叉)卖出
本脚本为教学演示,不构成投资建议,今后只需要改策略就可以 —— 四大库合体就是一条完整的流水线。
导入与函数前置
from datetime import datetime
import numpy as np
import pandas as pd
from scipy import stats
from quant_data import get_kline
backtest_signals · 信号生成函数
核心逻辑:快线上穿慢线 → 1(持仓);快线下穿慢线 → 0(空仓);
shift(1) 防未来函数 —— 信号明天才生效。
def backtest_signals(df, fast=5, slow=20):
"""
在表格上算出金叉/死叉信号,返回加了信号列的表格。
fast 是快速均线天数(默认 5 天),slow 是慢速均线天数(默认 20 天)。
"""
close = df["close"]
df["MA" + str(fast)] = close.rolling(fast).mean()
df["MA" + str(slow)] = close.rolling(slow).mean()
df["signal"] = np.where(df["MA" + str(fast)] > df["MA" + str(slow)], 1, 0)
df["signal_change"] = np.diff(df["signal"], prepend=0)
df["position"] = df["signal"].shift(1).fillna(0)
return df
主流程 · 四大库依次登场
① datetime 定日期 + 拉数据
if __name__ == "__main__":
df = get_kline(start_date="20260101",
end_date=datetime.now().strftime("%Y%m%d"))
② pandas 管表
df["收益率"] = df["close"].pct_change()
③ numpy 算信号
df = backtest_signals(df)
④ scipy 评估
df["策略收益"] = df["position"] * df["收益率"]
sr = df["策略收益"].dropna()
sharpe = (sr.mean() * 252) / (sr.std() * np.sqrt(252)) if sr.std() else 0.0
t_stat, p_value = stats.ttest_1samp(sr, 0)
输出 · 买卖信号 & 策略评估
print("\n===== 最近 5 次买卖信号 =====")
trades = df[df["signal_change"] != 0]
if len(trades) > 0:
recent = trades.tail(5).copy()
action_list = []
for v in recent["signal_change"]:
if v == 1:
action_list.append("买入(金叉)")
elif v == -1:
action_list.append("卖出(死叉)")
else:
action_list.append("无")
recent["动作"] = action_list
print(recent[["动作", "close"]].to_string())
last = trades.iloc[-1]
if last["signal_change"] == 1:
last_action = "买入(金叉)"
else:
last_action = "卖出(死叉)"
print(f"\n最近一次信号:{last.name.date()} {last_action},当日收盘 {last['close']:.2f}")
else:
print("样本期内没有出现完整信号")
print("\n===== 策略评估 =====")
print(f"样本期策略平均日收益 : {sr.mean() * 100:.4f}%")
print(f"策略夏普比率 : {sharpe:.2f}")
print(f"t 检验 p 值 : {p_value:.4f} (<0.05 表示显著)")
print("\n⚠️ 金叉死叉只是最简单的教学思路,本脚本不构成投资建议")
核心要点速览
datetime:定日期
pandas:管表
numpy:算信号
scipy:做评估
金叉:MA5 上穿 MA20 → 买入
死叉:MA5 下穿 MA20 → 卖出
防未来函数:shift(1)
夏普比率:评估风险调整后收益
t 检验:判断策略是否显著
教学演示:不构成投资建议
金句:
datetime 定日期,
pandas 管表,
numpy 算信号,
scipy 做评估 ——
四大库合体,就是一条完整的流水线。
运行输出 · python .\1.py
PS> python .\1.py
[数据源] akshare 不可用(ProxyError),尝试 baostock...
login success!
logout success!
[数据源] baostock 获取成功,共 179 条
===== 最近 5 次买卖信号 =====
动作 close
date
2026-04-21 卖出(死叉) 1379.368565
2026-07-14 买入(金叉) 1214.880000
2026-08-19 卖出(死叉) 1307.880000
2026-09-08 买入(金叉) 1309.300000
2026-09-11 卖出(死叉) 1275.160000
最近一次信号:2026-09-11 卖出(死叉),当日收盘 1275.16
===== 策略评估 =====
样本期策略平均日收益 : -0.0290%
策略夏普比率 : -0.48
t 检验 p 值 : 0.6898 (<0.05 表示显著)
⚠️ 金叉死叉只是最简单的教学思路,本脚本不构成投资建议
关键结论:样本期内共出现 5 次买卖信号(3 次死叉 + 2 次金叉);
策略平均日收益 -0.0290%,夏普比率 -0.48;
t 检验 p = 0.6898 ≥ 0.05,策略收益不显著 —— 金叉死叉只是教学思路,实战需谨慎。