乐趣区

关于量化:如何用WonderTrader开发商品套利策略

前言

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')

策略回测

绩效剖析

本例中采纳的 wtpyv0.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 旨在给各位量化从业人员提供更好的轮子,将技术相干的货色都封装在平台中,打造更高效的底层框架,力求给策略研发带来更好的策略开发和交易体验。

WonderTradergithub 地址:https://github.com/wondertrad…

WonderTrader官网地址:https://wondertrader.github.io

wtpygithub 地址:https://github.com/wondertrad…


市场有危险,投资需谨慎。以上陈说仅作为对于历史事件的回顾,不代表对将来的观点,同时不作为任何投资倡议。

退出移动版