欢迎加入专注于财经数据与量化投研的【数据科学实战】知识星球!在这里,您将获取持续更新的《财经数据宝典》和《量化投研宝典》,这两部宝典相辅相成,为您在量化投研道路上提供明确指引。 《量化投研宝典》精选了业内持续维护且实用性强的开源工具(Backtrader、Qlib、VeighNa等),配合详细教程与代码示例,帮助您快速构建量化策略;《财经数据宝典》则汇集了多年财经数据维护经验,全面介绍从 AKShare、Tushare 到 Wind、iFind 等国内外数据源,并附有丰富的使用技巧。 无论您是量化投资新手还是经验丰富的研究者,星球社区都能帮您少走弯路,事半功倍,共同探索数据驱动的投资世界!
引言
在量化交易领域,如何设计一个既能适应市场变化又能稳定盈利的策略是每个交易者的追求。今天,我们将深入探讨一个基于 Fisher Transform 和 KST(Know Sure Thing)指标的自适应动量交易策略。通过对 VeriSign(VRSN)股票的实战回测,我们将看到这个策略如何在真实市场条件下表现,以及如何用 Python 实现整个交易系统。
什么是自适应动量策略?
自适应动量策略是一种能够根据市场条件动态调整参数的交易系统。与传统的固定参数策略不同,它通过走步优化(Walk-Forward Optimization)技术,定期更新最优参数,从而更好地适应市场变化。
核心指标介绍
1. Fisher Transform 指标
Fisher Transform 是一种将价格数据转换为接近正态分布的技术指标,能够更清晰地识别价格转折点。
def calculate_fisher_transform(df, period=10):
"""
计算 Fisher Transform 指标
参数:
df: 包含 OHLC 数据的 DataFrame
period: 计算周期,默认 10
"""
# 计算滚动最高价和最低价
high_rolling = df['High'].rolling(window=period).max()
low_rolling = df['Low'].rolling(window=period).min()
# 计算归一化价格,限制在 -0.999 到 0.999 之间
X = 2 * ((df['Close'] - low_rolling) / (high_rolling - low_rolling) - 0.5).clip(-0.999, 0.999)
# Fisher 变换公式
fisher = 0.5 * np.log((1 + X) / (1 - X))
# 计算信号线(9 期 EMA)
fisher_signal = fisher.ewm(span=9).mean()
return fisher, fisher_signal
2. KST(Know Sure Thing)指标
KST 是一种动量振荡指标,通过组合不同周期的变化率(ROC)来识别市场趋势。
def calculate_kst(df, roc1=10, roc2=15, roc3=20, roc4=30):
"""
计算 KST 指标
参数:
df: 包含价格数据的 DataFrame
roc1-roc4: 不同的变化率周期
"""
# 计算四个不同周期的变化率移动平均
r1 = df['Close'].pct_change(roc1).rolling(10).mean()
r2 = df['Close'].pct_change(roc2).rolling(10).mean()
r3 = df['Close'].pct_change(roc3).rolling(10).mean()
r4 = df['Close'].pct_change(roc4).rolling(15).mean()
# KST 公式:加权组合
kst = r1 + 2 * r2 + 3 * r3 + 4 * r4
# 信号线(9 期移动平均)
kst_signal = kst.rolling(9).mean()
# 计算柱状图
kst_hist = kst - kst_signal
return kst, kst_signal, kst_hist
交易信号生成逻辑
策略的交易信号基于两个指标的综合判断:
def generate_signals_fisher_kst(df):
"""
生成交易信号
买入条件:Fisher > 0 且 Fisher_Signal > 0 且 KST_Hist > 0
卖出条件:Fisher < 0 且 Fisher_Signal > 0 且 KST_Hist < 0
"""
entry = (df['Fisher'] > 0) & (df['Fisher_Signal'] > 0
) & (df['KST_Hist'] > 0)
exit = (df['Fisher'] 0) & (df['Fisher_Signal'] > 0) & (df['KST_Hist'] 0)
return entry, exit
走步优化:让策略自适应市场
走步优化是量化交易中的重要技术,它通过滚动窗口的方式,使用历史数据训练模型,然后在未来数据上测试。
def walk_forward_optimization(df, start_year, end_year):
"""
走步优化实现
使用 3 年训练数据,1 年测试数据
"""
results = []
param_combinations = generate_parameter_combinations()
for test_year in range(start_year + 3, end_year + 1):
# 定义训练期:前 3 年
train_start = test_year - 3
train_end = test_year - 1
train_data = df[(df.index.year >= train_start) & (df.index.year <= train_end)]
best_params = None
best_performance = -np.inf
# 遍历所有参数组合
for params in param_combinations:
fisher_p, r1, r2, r3, r4 = params
data = train_data.copy()
# 计算指标
data['Fisher'], data['Fisher_Signal'] = calculate_fisher_transform(data, period=fisher_p)
data['KST'], data['KST_Signal'], data['KST_Hist'] = calculate_kst(data, r1, r2, r3, r4)
# 生成信号并回测
entries, exits = generate_signals_fisher_kst(data)
# 使用 vectorbt 进行回测
pf = vbt.Portfolio.from_signals(
close=data['Open'],
entries=entries.shift(1), # 信号延迟一天执行
exits=exits.shift(1),
init_cash=100_000,
fees=0.001, # 0.1% 手续费
slippage=0.002, # 0.2% 滑点
freq='D'
)
performance = pf.total_return()
if performance > best_performance:
best_performance = performance
best_params = params
results.append({
'Year': test_year,
'Best_Params': best_params
})
return pd.DataFrame(results)
实战案例:VRSN 股票回测结果
1. 最优参数演化
通过走步优化,我们得到了 2020-2025 年每年的最优参数:
- 2020 年:Fisher 周期 12,KST 参数(15,10,30,30)
- 2021 年:Fisher 周期 17,KST 参数(15,15,15,30)
- 2022 年:Fisher 周期 13,KST 参数(10,25,30,30)
- 2023 年:Fisher 周期 16,KST 参数(10,25,25,35)
- 2024 年:Fisher 周期 16,KST 参数(10,25,25,35)
- 2025 年:Fisher 周期 19,KST 参数(5,15,30,35)
2. 性能指标对比
策略表现:
买入持有表现:
3. 风险调整后的表现
策略相对于基准的表现:
- 相关性:0.8128(与市场高度相关但保持独立性)
Monte Carlo 模拟:评估策略稳健性
为了评估策略的稳健性,我们使用了区块自助法(Block Bootstrap)进行 Monte Carlo 模拟:
# Monte Carlo 模拟核心代码
n_simulations = 1000
block_size = 5 # 每个区块 5 天,保持时间序列特性
for _ in range(n_simulations):
# 随机抽取区块
block_indices = np.random.randint(0, len(returns) - block_size + 1, size=n_blocks)
sampled_returns = np.concatenate([returns[i:i+block_size] for i in block_indices])[:n_days]
# 计算模拟路径
equity = init_value * np.cumprod(1 + sampled_returns)
# 计算性能指标
max_dd = np.max(1 - equity / np.maximum.accumulate(equity))
total_return = (equity[-1] / init_value) - 1
模拟结果显示:
实践建议
参数优化频率:建议每季度或每半年重新优化一次参数,以适应市场变化。
风险管理:虽然策略表现优于买入持有,但仍有相当概率表现不佳,建议:
总结
本文详细介绍了一个基于 Fisher Transform 和 KST 指标的自适应动量交易策略。通过 VRSN 股票的实战回测,我们看到了策略的优势和局限性。虽然策略在收益率、夏普比率等指标上优于买入持有,但 Monte Carlo 模拟揭示了其潜在风险。
成功的量化交易不仅需要好的策略,更需要严格的风险管理和持续的优化。希望本文能为你的量化交易之路提供有价值的参考。记住,历史回测结果不代表未来表现,实盘交易前请充分评估风险。
参考文章
加入专注于财经数据与量化投研的知识星球【数据科学实战】,获取完整研究解析、详细回测框架代码实现和完整策略逻辑实操指南。财经数据与量化投研知识社区
核心权益如下:
- 赠送《财经数据宝典》完整文档,汇集多年财经数据维护经验
- 赠送《量化投研宝典》完整文档,汇集多年量化投研领域经验
- 赠送《PyBroker-入门及实战》视频课程,手把手学习量化策略开发
星球已有丰富内容积累,包括量化投研论文、财经高频数据、 PyBroker 视频教程、定期直播、数据分享和答疑解难。适合对量化投研和财经数据分析有兴趣的学习者及从业者。欢迎加入我们!