一句话回答: 布林带有两种相反玩法:跌破下轨买入是均值回归(赌回中轨),突破上轨买入是趋势追涨(赌延续)。本文回测突破策略——用 AlphaFeed 取前复权日线算布林带,收盘上穿上轨做多、回落到中轨离场,次日开盘成交避免未来函数,扣手续费,并与均值回归、买入持有对比,看趋势追涨在该品种上是否有效。
很多人只知道「布林带跌破下轨买、涨破上轨卖」的均值回归用法,但在强趋势品种上,突破上轨往往意味着行情启动、追涨反而更赚。到底用哪种?不能拍脑袋,要回测。坑同样是:前复权价、次日开盘成交避免未来函数、扣手续费,还要和均值回归版、买入持有放一起比较。
from alphafeed import AlphaFeed
import pandas as pd
af = AlphaFeed() # 读取 ALPHAFEED_API_KEY
df = af.klines.get("600519.SH", period="1d", count=500,
adjust="forward", to_dataframe=True)
df = df.sort_values("trade_date").reset_index(drop=True)
N, K = 20, 2
df["mid"] = df["close"].rolling(N).mean()
df["std"] = df["close"].rolling(N).std(ddof=0)
df["upper"] = df["mid"] + K * df["std"]
df["lower"] = df["mid"] - K * df["std"]参数 | 含义 | 取值 |
|---|---|---|
| 中轨均线周期 | 20 |
| 标准差倍数(带宽) | 2 |
入场 | 收盘上穿上轨 | 趋势追涨 |
离场 | 收盘回落中轨下方 | 落袋/止损 |
# 收盘上穿上轨=进场信号;收盘跌回中轨下方=离场信号
df["cross_up"] = (df["close"] > df["upper"]) & (df["close"].shift() <= df["upper"].shift())
df["exit_sig"] = df["close"] < df["mid"]
pos = 0; signal = []
for i in range(len(df)):
if pos == 0 and df["cross_up"].iloc[i]:
pos = 1
elif pos == 1 and df["exit_sig"].iloc[i]:
pos = 0
signal.append(pos)
df["signal"] = signal
df["position"] = pd.Series(signal).shift(1).fillna(0) # 次日开盘才持仓FEE = 0.0013
df["open_ret"] = df["open"].pct_change().shift(-1) # t 持仓吃 t→t+1 开盘收益
df["trade"] = df["position"].diff().abs().fillna(0)
df["strat_ret"] = df["position"] * df["open_ret"].fillna(0) - df["trade"] * FEE
df["equity"] = (1 + df["strat_ret"]).cumprod()
df["bench"] = (1 + df["close"].pct_change().fillna(0)).cumprod()# 均值回归版:跌破下轨买、回到中轨卖
posr = 0; sr = []
for i in range(len(df)):
below = df["close"].iloc[i] < df["lower"].iloc[i]
back = df["close"].iloc[i] >= df["mid"].iloc[i]
if posr == 0 and below: posr = 1
elif posr == 1 and back: posr = 0
sr.append(posr)
df["pos_rev"] = pd.Series(sr).shift(1).fillna(0)
df["rev_ret"] = df["pos_rev"] * df["open_ret"].fillna(0) - df["pos_rev"].diff().abs().fillna(0) * FEE
rev_eq = (1 + df["rev_ret"]).cumprod()
def cagr(eq): return eq.iloc[-1] ** (252/len(eq)) - 1
print(f"突破 收益{df['equity'].iloc[-1]-1:.2%} 年化{cagr(df['equity']):.2%} "
f"回撤{(df['equity']/df['equity'].cummax()-1).min():.2%} 交易{int(df['trade'].sum()//2)}次")
print(f"回归 收益{rev_eq.iloc[-1]-1:.2%}")
print(f"买入持有 收益{df['bench'].iloc[-1]-1:.2%}")position.shift(1) 次日开盘成交。ddof=0),改口径数值会变。Q:布林带突破和均值回归到底用哪个?
A:没有绝对答案。趋势强的品种/阶段突破追涨更好,震荡市均值回归更好。本文把两者与买入持有并列回测,就是让你用数据判断。
Q:为什么离场用「回到中轨」?
A:中轨是均线,跌回中轨下方常意味着突破动能衰竭,是相对稳健的离场点。也可用跌破上轨或 ATR 止损。
Q:K 值调大调小有什么影响?
A:K 越大带越宽、突破越少但更可靠;K 越小突破更频繁、假信号更多。常用 2。
Q:需要付费吗?
A:单只历史日线有免费额度;多标的批量回测(klines.batch + universes)需 Starter 及以上。详见定价页。
布林带突破策略是「趋势追涨」,与「跌破下轨买入」的均值回归相反。用 AlphaFeed 取前复权日线算布林带,收盘上穿上轨做多、回中轨离场,次日开盘成交避免未来函数、扣手续费,再和均值回归、买入持有对比,就能客观判断该品种适合追突破还是做回归。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。