欢迎加入专注于财经数据与量化投研的【数据科学实战】知识星球!在这里,您将获取持续更新的《财经数据宝典》和《量化投研宝典》,这两部宝典相辅相成,为您在量化投研道路上提供明确指引。 《量化投研宝典》精选了业内持续维护且实用性强的开源工具(Backtrader、Qlib、VeighNa等),配合详细教程与代码示例,帮助您快速构建量化策略;《财经数据宝典》则汇集了多年财经数据维护经验,全面介绍从 AKShare、Tushare 到 Wind、iFind 等国内外数据源,并附有丰富的使用技巧。 无论您是量化投资新手还是经验丰富的研究者,星球社区都能帮您少走弯路,事半功倍,共同探索数据驱动的投资世界!
引言
在量化交易的世界里,如何构建一个既稳健又高效的交易系统一直是投资者追求的目标。今天,我将带你深入了解一个结合了 WAD(威廉姆斯累积/派发指标)和 CKS(Chande Kroll 止损)的混合交易系统。通过 Python 和 vectorbt 库,我们不仅能够实现策略的自动化,还能进行严格的回测和优化。
这个系统的独特之处在于它巧妙地融合了成交量分析和波动率管理两大核心要素,让我们一起来探索这个策略背后的秘密。
策略核心指标介绍
WAD 指标:洞察市场力量
WAD(Williams Accumulation/Distribution)是一个基于成交量的技术指标,通过比较当前收盘价与前一日收盘价,判断买方或卖方的控制力度。
def calculate_wad(df):
"""计算 WAD 指标"""
wad = [0]
for i in range(1, len(df)):
if df['Close'][i] > df['Close'][i - 1]:
# 上涨时,计算真实低点
trl = min(df['Low'][i], df['Close'][i - 1])
ad = df['Close'][i] - trl
elif df['Close'][i] < df['Close'][i - 1]:
# 下跌时,计算真实高点
trh = max(df['High'][i], df[
'Close'][i - 1])
ad = df['Close'][i] - trh
else:
ad = 0
wad.append(wad[-1] + ad)
return pd.Series(wad, index=df.index)
CKS 指标:动态止损保护
Chande Kroll Stop 是一个基于波动率的动态止损机制,它使用 ATR(平均真实波幅)和近期高低点来确定趋势突破的关键位置。
def calculate_chande_kroll(df, atr_period=10, stop_period=10, multiplier=1.5):
"""计算 Chande Kroll 止损位"""
# 计算真实波幅
tr = df['High'].combine(df['Low'], max) - df['Low'].combine(df['High'], min)
atr = tr.rolling(window=atr_period).mean()
# 计算止损位
high_stop = df['High'].rolling(window=stop_period).max() - multiplier * atr
low_stop = df['Low'].rolling(window=stop_period).min() + multiplier * atr
return high_stop, low_stop
交易信号生成逻辑
策略的交易信号基于以下条件:
- 入场信号:WAD 指标上升、CKS 高点大于低点、且 CKS 高点在当前价格之上
- 出场信号:WAD 指标下降、CKS 低点小于高点、且 CKS 低点在当前价格之下
def generate_signals_wad_cks(df):
"""生成交易信号"""
# 入场条件
entries = (df[
'CKS_High'] > df['CKS_Low']) & \
df['WAD_Rising'] & \
(df['CKS_High'] > df['Close'])
# 出场条件
exits = (df['CKS_High'] < df['CKS_Low']) & \
df['WAD_Falling'] & \
(df['CKS_Low'] < df['Close'])
return entries, exits
参数优化:Walk-Forward 方法
为了确保策略的稳健性,系统采用了 Walk-Forward 优化方法。这种方法模拟真实交易中的参数调整过程:
def walk_forward_optimization(df, start_year, end_year):
"""Walk-Forward 参数优化"""
results = []
param_combinations = generate_parameter_combinations()
for test_year in range(start_year + 4, end_year + 1):
# 设定训练期
train_start = test_year - 4
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:
atr_p, stop_p, mult, rise_shift, fall_shift = params
# 计算指标并生成信号
indicators = calculate_indicators(train_data, atr_p, stop_p,
mult, rise_shift, fall_shift)
entries, exits = generate_signals_wad_cks(indicators)
# 回测并评估性能
portfolio = vbt.Portfolio.from_signals(
close=train_data['Open'],
entries=entries.shift(1).fillna(False),
exits=exits.shift(1).fillna(False),
init_cash=100_000,
fees=0.001, # 0.1% 手续费
slippage=0.002, # 0.2% 滑点
freq='D'
)
performance = portfolio.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)
实战案例:KLAC 股票交易
让我们以 KLAC(科磊公司)股票为例,展示完整的策略实现过程:
import numpy as np
import pandas as pd
import yfinance as yf
import vectorbt as vbt
# 下载数据
symbol = 'KLAC'
start_date = '2015-01-01'
end_date = '2025-01-01'
df = yf.download(symbol, start=start_date, end=end_date)
# 运行优化
results = walk_forward_optimization(df, 2016, 2025)
# 基于每年最优参数生成综合信号
combined_entries = pd.Series(False, index=df.index)
combined_exits = pd.Series(False, index=df.index)
for _, row in results.iterrows():
year = row['Year']
atr_p, stop_p, mult, rise_shift, fall_shift = row['Best_Params']
# 计算该年度的信号
yearly_data = df[df.index.year == year]
yearly_data = calculate_indicators(yearly_data, atr_p, stop_p,
mult, rise_shift, fall_shift)
entries, exits = generate_signals_wad_cks(yearly_data)
# 合并信号
combined_entries.loc[entries.index] = entries
combined_exits.loc[exits.index] = exits
性能评估与风险分析
基础性能指标
策略在 2020-2025 年期间的表现:
深度分析:Alpha、Beta 和相关性
from scipy.stats import linregress
# 计算策略与基准的相对指标
portfolio_returns = portfolio.returns()
benchmark_returns = benchmark.returns()
# 线性回归计算 Alpha 和 Beta
slope, intercept, r_value, _, _ = linregress(benchmark_returns, portfolio_returns)
beta = slope # 0.6607
alpha = intercept # 0.0007(日度)
# 相关性
correlation = portfolio_returns.corr(benchmark_returns) # 0.8138
print(f"Alpha(日度): {alpha:.4f}")
print(f"Beta: {beta:.4f}")
print(f"相关性: {correlation:.4f}")
指标解读:
-
Alpha = 0.0007:策略每天产生约 0.07% 的超额收益,年化约 17.5%
- Beta = 0.66:策略波动性约为市场的 66%,风险较低
- 相关性 = 0.81:策略与市场方向基本一致,但波动更小
蒙特卡洛模拟验证
为了更全面地评估策略的稳健性,我们使用区块自助法(Block Bootstrap)进行 1000 次蒙特卡洛模拟:
# 蒙特卡洛模拟参数
n_simulations = 1000
block_size = 5 # 每个区块 5 个交易日
init_value = 100
# 模拟结果统计
# 平均最终收益:617.16%
# 中位数收益:452.16%
# 5% 分位数:64.64%
# 95% 分位数:1877.99%
# 平均最大回撤:38.27%
# 平均夏普比率:1.16
模拟结果显示,策略有约 65% 的概率在收益和回撤方面超越买入持有策略。
策略优化建议
- 止损优化
:加入更多止损条件,如固定止损或跟踪止损
总结
本文介绍的 WAD-CKS 混合交易系统展示了如何将成交量分析与波动率管理有效结合。通过 Python 和 vectorbt 的强大功能,我们不仅实现了策略的自动化,还通过 Walk-Forward 优化和蒙特卡洛模拟验证了其稳健性。
虽然策略在回测中表现出色,但投资者仍需谨记:历史表现不代表未来收益。在实际应用中,应该根据自己的风险承受能力和投资目标进行适当调整。
量化交易的魅力在于它将主观判断转化为客观规则,让投资决策更加科学和系统化。希望这个案例能为你的量化交易之路提供启发!
参考文章
加入专注于财经数据与量化投研的知识星球【数据科学实战】,获取完整研究解析、详细回测框架代码实现和完整策略逻辑实操指南。
财经数据与量化投研知识社区
核心权益如下:
- 赠送《财经数据宝典》完整文档,汇集多年财经数据维护经验
- 赠送《量化投研宝典》完整文档,汇集多年量化投研领域经验
- 赠送《PyBroker-入门及实战》视频课程,手把手学习量化策略开发
星球已有丰富内容积累,包括量化投研论文、财经高频数据、 PyBroker 视频教程、定期直播、数据分享和答疑解难。适合对量化投研和财经数据分析有兴趣的学习者及从业者。欢迎加入我们!