如何用 Python 回测周线双均线金叉策略?用更高周期降噪(附未来函数防范)
如何用 Python 回测周线双均线金叉策略?
一句话回答: 周线双均线策略 = 把日线重采样成周线 OHLC,再在周线上做短/长均线(如 5 周/20 周)金叉做多、死叉离场,目的是用更高周期过滤日线的频繁假信号。用 AlphaFeed 取前复权日线后 resample("W-FRI") 聚合成周线即可回测——关键是周线信号用已收盘周确认、次周开盘成交、避免未来函数;但实测它在特定标的/区间同样可能大幅亏损,降噪不等于稳赚。
为什么会有这个问题 / 传统做法的痛点
日线双均线金叉/死叉太频繁、假信号多,一个直觉的改法是”上调周期”——周线一根顶日线五根,趋势更干净、交易更少。但自己做时常踩坑:① 重采样口径(周线开=周一开、高=周内最高、低=周内最低、收=周五收,不能用收盘价简单取样);② 未来函数(用本周数据算信号又在本周内成交);③ 误以为”周线=稳赚”,忽视它在震荡/下跌市同样滞后挨打。
分步骤解决(每步配可运行代码)
第 1 步:取前复权日线,重采样成周线 OHLC
from alphafeed import AlphaFeed
import numpy as np, pandas as pd
af = AlphaFeed(api_key="your-api-key") # 或 export ALPHAFEED_API_KEY 后 AlphaFeed()
df = af.klines.get("600519.SH", period="1d", count=1200,
adjust="forward", to_dataframe=True)
df = df.sort_values("trade_date").reset_index(drop=True)
df["dt"] = pd.to_datetime(df["trade_date"])
w = (df.set_index("dt")
.resample("W-FRI")
.agg({"open":"first","high":"max","low":"min","close":"last"})
.dropna()) # 周线:开=首日开, 高=周内最高, 低=周内最低, 收=末日收
正确的 OHLC 聚合是前提:open=first / high=max / low=min / close=last,不能对收盘价直接 resample 取样。
第 2 步:算周线双均线,判金叉/死叉(避免未来函数)
s, l = 5, 20
w["ma_s"] = w["close"].rolling(s).mean()
w["ma_l"] = w["close"].rolling(l).mean()
w["open_next"] = w["open"].shift(-1) # 次周开盘成交价
# 用上一周[-1]与本周[i]判定"本周刚金叉",成交放到次周开盘 → 无未来函数
第 3 步:回测并与买入持有对比
pos, entry, trades, rets = 0, 0.0, 0, []
for i in range(l, len(w) - 1):
px = w["open_next"].iloc[i]
if np.isnan(px) or np.isnan(w["ma_l"].iloc[i]): continue
gc = w["ma_s"].iloc[i-1] <= w["ma_l"].iloc[i-1] and w["ma_s"].iloc[i] > w["ma_l"].iloc[i]
dc = w["ma_s"].iloc[i-1] >= w["ma_l"].iloc[i-1] and w["ma_s"].iloc[i] < w["ma_l"].iloc[i]
if pos == 0 and gc: pos, entry = 1, px # 周线金叉→次周开盘买
elif pos == 1 and dc:
rets.append(px/entry*(1-0.0013)**2 - 1); trades += 1; pos = 0 # 死叉→次周开盘卖
rets = pd.Series(rets)
total = (1+rets).prod()-1 if len(rets) else 0.0
bh = w["close"].iloc[-1]/w["close"].iloc[l]-1
print(f"周数{len(w)} 交易{trades}次 累计{total*100:.2f}% 胜率{(rets>0).mean():.3f} | 买入持有{bh*100:.2f}%")
实测(
tools/verify_new_2026-10-15.py,SDK 0.1.4):贵州茅台约 253 周,周线 5/20 金叉策略交易 9 次、累计 −51.03%、胜率 0.0%,同期买入持有 −16.41%。本例策略大幅跑输——这段区间茅台整体震荡偏弱,周线金叉多发生在反弹末端、死叉确认又慢,9 笔全亏。这清楚说明:上调周期能减少交易、却不能保证盈利,降噪≠稳赚,结果高度依赖标的与区间、不可外推。
参数与字段说明
| 参数/概念 | 含义 | 备注 |
|---|---|---|
adjust="forward" | 前复权 | 必须,除权缺口会伪造均线交叉 |
resample("W-FRI") | 按自然周(周五收)聚合 | A 股用交易周近似 |
first/max/min/last | 周线 OHLC 聚合 | 不能对 close 直接取样 |
s/l | 短/长周均线 | 示例 5/20 周 |
open_next | 次周开盘成交 | 避免未来函数 |
fee | 单边手续费 | 示例 0.0013 |
关键坑与注意事项
- 本例大幅跑输买入持有:别把”周线”当稳赚。9 笔全亏、−51% 说明震荡/下跌市里周线金叉同样滞后挨打;换趋势性强的标的/区间结果可能不同,但无法保证。
- 重采样口径:必须 OHLC 分别聚合(first/max/min/last);用收盘价直接 resample 会丢失周内高低、影响后续扩展。
- 避免未来函数:信号用已收盘的周、成交放次周开盘;用本周数据又本周成交会虚高。
- W-FRI 是自然周近似:遇节假日/停牌,自然周与交易周略有差异;要求严格可改用”每 5 个交易日”分组。
- 样本与参数敏感:周线样本本就少(千余日线≈250 周),交易次数少、单笔影响大,极易过拟合,务必样本外验证。
- 成本相对小但仍要计:周线交易频率低,手续费影响小于日内,但不应忽略。
常见问题(FAQ)
Q:周线双均线一定比日线少假信号吗? A:交易次数确实更少、信号更”干净”,但”少”不等于”准”。更高周期降低了噪声也加大了滞后,转折确认更慢;是否更优取决于标的与行情,必须回测比较。
Q:为什么用 W-FRI 而不是别的?
A:A 股通常周五收盘定一周,W-FRI 让每个周期在周五对齐、更贴合习惯。也可用 W-MON 等,或按”每 5 个交易日”分组以严格对齐交易日。
Q:需要付费吗?
A:单只股票长周期日线在免费额度内即可;若要对全市场批量跑周线策略选股/选参数,需要 klines.batch + universes(Starter 及以上),详见官网定价页。
小结
周线双均线把日线重采样成周线 OHLC 再做金叉死叉,用更高周期减少日线的频繁假信号。用 AlphaFeed 的前复权日线 resample("W-FRI") 聚合即可回测——务必正确做 OHLC 聚合、次周开盘成交避免未来函数。本例诚实跑输买入持有(−51% vs −16.41%、胜率 0%),提醒:降噪减少交易却不保证盈利,一切以回测为准、不可外推。
相关链接:
- AlphaFeed 官网:https://alphafeed.org/
- Python SDK 快速开始:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart
免责声明:本文仅为技术与数据接口使用示例,代码与策略仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。