前言
《WonderTrader架构详解》系列文章已经写了四篇了,对于笔者这样的懒人来说,实在是一个大工程。这次先暂时不介绍架构了,本文将给大家介绍一下如何在WonderTrader上编写一个跨品种套利策略,旨在给大家演示一下WonderTrader下多标的策略的一般写法,同时也介绍一下笔者在wtpy最新版本v0.6.3
中最新发布的绩效分析模块。
WonderTrader架构文章列表:
- WonderTrader架构详解之一——整体架构
- WonderTrader架构详解之二——从数据说起
- WonderTrader架构详解之三——信号与执行
- WonderTrader架构详解之四——浅谈平台对策略的支持
套利策略简介
相信每一个做量化的人,都研究过套利策略。套利策略以其逻辑的相对简单、收益的相对稳定而得到多数人的青睐。同时,套利策略和趋势策略有较强的互补性,这就意味着,如果配合得当,对平滑收益曲线,降低绩效的波动,提高夏普有极大的促进作用。
套利策略的分类就非常多了,笔者曾在《WonderTrader架构详解之四——浅谈平台对策略的支持》文中引用了丁鹏博士的《量化投资——策略与技术》对于策略的分类,里面提到的套利的模式就有很多种,例如:期现套、跨期套、跨品种套、配对交易等等。
笔者为了开发该策略,查阅资料的时候,看到一个观点,深以为然:不管套利策略分类多么繁复,套利策略的本质是在不同合约之间的价差波动中寻找交易机会。
套利策略实现
策略设计
鉴于笔者的量化策略的技能树,还没点亮,所以本文中的策略示例,是从互联网上学习到的,笔者在此由衷地感谢此策略的分享者。该策略基本设计如下:
- 合约对选择螺纹钢主力连续合约
SHFE.rb.HOT
和铁矿石主力连续合约DCE.i.HOT
- 回测数据为主力连续数据,进行了复权处理,防止主力合约换月不同步的时候引起的价差变化
- 基于1分钟数据,对过去
N
分钟两组收盘价序列进行线性回归,得到一个系数beta
、一个常量c
和一个残差序列 - 对残差序列进行ADF检验,如果残差序列是一个平稳序列,则进入信号计算逻辑
- 根据得到的系数
beta
和常量c
,以及最新的价格计算新的残差 - 当新的残差超出一个阈值,就触发入场信号,当价差再回归到阈值以内,就触发出场信号
策略实现
参数设计
根据上文的介绍,策略核心的参数如下:code1
:套利合约1,本例设置为SHFE.rb.HOT
code2
:套利合约2,本例设置为DCE.i.HOT
period
:数据周期,本例设置为m1
,即一分钟线threshold
:阈值,本例设置为0.9
N
:统计的K线条数,本例设置为360
,即一个交易日的一分钟线bar_cnt
:策略读取的K线条数,大于N
,主要考虑预留滚动计算的空间
def __init__(self, name:str, code1:str, code2:str, bar_cnt:int, period:str, N:int, threshold:float=1): BaseCtaStrategy.__init__(self, name) self.__n__ = N self.__threshold__ = threshold self.__period__ = period self.__bar_cnt__ = bar_cnt self.__code_1__ = code1 self.__code_2__ = code2
协整检验
策略核心的逻辑在于协整检验,只有协整检验通过了,才能进行信号触发。# 协整检验函数 def cointegration_check(series01, series02): # 对两个序列分别进行ADF检验 urt_1 = ts.adfuller(np.array(series01), 1)[1] urt_2 = ts.adfuller(np.array(series02), 1)[1] # 同时平稳或不平稳则差分再次检验 if (urt_1 > 0.1 and urt_2 > 0.1) or (urt_1 < 0.1 and urt_2 < 0.1): urt_diff_1 = ts.adfuller(np.diff(np.array(series01)), 1)[1] urt_diff_2 = ts.adfuller(np.diff(np.array(series02), 1))[1] # 同时差分平稳进行OLS回归的残差平稳检验 if urt_diff_1 < 0.1 and urt_diff_2 < 0.1: matrix = np.vstack([series02, np.ones(len(series02))]).T beta, c = np.linalg.lstsq(matrix, series01, rcond=None)[0] resid = series01 - beta * series02 - c # 最后对残差序列再进行ADF检验 if ts.adfuller(np.array(resid), 1)[1] > 0.1: result = False else: result = True return beta, c, resid, result else: result = False return 0.0, 0.0, 0.0, result else: result = False return 0.0, 0.0, 0.0, result
信号发出
当残差超出上边界,说明残差正向扩大,根据残差均值回归的特性,这时就需要做空价差;相反的,当残差超出下边界,说明残差反向扩大,这时就需要做多价差;当参加在上下边界范围之内,则清掉已有的头寸,等待下一次机会。# 计算新残差 resid_new = close_ay1[-1] - self.beta * close_ay2[-1] - self.c if resid_new > self.up and curPos1 != 1: context.stra_log_text("[%d.%04d]残差正向扩大,做空价差" % (curDate, curTime)) context.stra_enter_short(self.__code_1__, 1, 'OpenSA') context.stra_enter_long(self.__code_2__, 1, 'OpenLB') elif resid_new < self.down and curPos1 != -1: context.stra_log_text("[%d.%04d]残差反向扩大,做多价差" % (curDate, curTime)) context.stra_enter_long(self.__code_1__, 1, 'OpenLA') context.stra_enter_short(self.__code_2__, 1, 'OpenSB') elif curPos1 != 0 and self.down <= resid_new and resid_new <= self.up: context.stra_log_text("[%d.%04d]残差回归,清掉头寸" % (curDate, curTime)) context.stra_set_position(self.__code_1__, 0, 'CutA') context.stra_set_position(self.__code_2__, 0, 'CutB')
策略回测
绩效分析
本例中采用的wtpy在v0.6.3
版本中发布的增强版绩效分析工具进行分析,调用方法和老版本基本一样,但是分析的入口有所变化。
analyst = WtBtAnalyst()
analyst.add_strategy("t1_rb_i", folder="./outputs_bt/t1_rb_i/", init_capital=350000, rf=0.02, annual_trading_days=240)
# 绩效分析的入口,老版本run的仍然可用
analyst.run_new()
绩效分析截图
策略绩效概要
详细交易列表
总体交易分析
连续交易分析
收益分布
日度绩效分析
其他周期绩效
逐日绩效概览
从前面可以看出,新版本的绩效分析模块提供了更多维度的分析功能。新版本的绩效分析模块,主要参考了MultiCharts
的绩效分析报告,所以从分析结果的全面性和实用性来说,应该是有保障的。
回到策略本身,从前面的绩效报告可以看出,该策略显然是不大成功的。如何优化该策略呢?笔者考虑是否可以通过加入止盈止损逻辑来进行优化,或者通过调整阈值进行优化。不过这些已经超出本文的宗旨了,如果有朋友感兴趣,可以自行研究。
策略获取
本文中的示例策略已经分享到github上wtpy项目中的/demos/cta_arbitrage_bt下,有兴趣的朋友可以自行去下载。点此跳转
结束语
本文对利用WonderTrader编写套利策略的介绍就到此结束了。笔者今日一边写文章,一边感到忐忑不安。笔者虽然一直在优秀的量化团队里跟大家一起合作,但是由于笔者是从事技术方面的工作,所以对策略的了解毕竟还是停留在表面,因此生怕今天分享的策略出现了低级错误。好在笔者最后还是决定从网络上寻找现成的策略,这样才稍稍缓解了笔者的不安。即便是这样,本文及本文演示的策略也难免有错漏之处,也希望各位看客能够包涵指正。所幸本文的终极目标是通过笔者今日抛出的“砖头”引起大家找到更多的“美玉”,如果能够对大家有所裨益,那就再好不过了。
最后再安利一下WonderTrader
WonderTrader旨在给各位量化从业人员提供更好的轮子,将技术相关的东西都封装在平台中,打造更高效的底层框架,力求给策略研发带来更好的策略开发和交易体验。
WonderTrader的github
地址:https://github.com/wondertrad...
WonderTrader官网地址:https://wondertrader.github.io
wtpy的github
地址:https://github.com/wondertrad...
市场有风险,投资需谨慎。以上陈述仅作为对于历史事件的回顾,不代表对未来的观点,同时不作为任何投资建议。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。