AlphaFeed Blog

如何用 Python 回测周线双均线金叉策略?用更高周期降噪(附未来函数防范)

策略与回测 · 代码验证于 2026-10-15

如何用 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

关键坑与注意事项

常见问题(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%),提醒:降噪减少交易却不保证盈利,一切以回测为准、不可外推。

相关链接:


免责声明:本文仅为技术与数据接口使用示例,代码与策略仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。