• QQ空间
  • 回复
  • 收藏

【宽客策略源码】跨期套利策略

geek168 数据策略 2019-8-11 15:54 91358人围观


本策略根据EG两步法(1.序列同阶单整2.OLS残差平稳)判断序列具有协整关系之后(若无协整关系则全平仓位不进行操作),通过计算两个真实价格序列回归残差的0.9个标准差上下轨,并在价差突破上轨的时候做空价差,价差突破下轨的时候做多价差,并在回归至标准差水平内的时候平仓

回测数据为:SHFE.rb1801和SHFE.rb1805的1min数据
回测时间为:2017-09-25 08:00:00到2017-10-01 15:00:00


  1. # coding=utf-8
  2. from __future__ import print_function, absolute_import, unicode_literals
  3. import numpy as np
  4. from gm.api import *
  5. try:
  6.     import statsmodels.tsa.stattools as ts
  7. except:
  8.     print('请安装statsmodels库')

  9. # 协整检验的函数
  10. def cointegration_test(series01, series02):
  11.     urt_rb1801 = ts.adfuller(np.array(series01), 1)[1]
  12.     urt_rb1805 = ts.adfuller(np.array(series01), 1)[1]
  13.     # 同时平稳或不平稳则差分再次检验
  14.     if (urt_rb1801 > 0.1 and urt_rb1805 > 0.1) or (urt_rb1801 < 0.1 and urt_rb1805 < 0.1):
  15.         urt_diff_rb1801 = ts.adfuller(np.diff(np.array(series01)), 1)[1]
  16.         urt_diff_rb1805 = ts.adfuller(np.diff(np.array(series01), 1))[1]
  17.         # 同时差分平稳进行OLS回归的残差平稳检验
  18.         if urt_diff_rb1801 < 0.1 and urt_diff_rb1805 < 0.1:
  19.             matrix = np.vstack([series02, np.ones(len(series02))]).T
  20.             beta, c = np.linalg.lstsq(matrix, series01)[0]
  21.             resid = series01 - beta * series02 - c
  22.             if ts.adfuller(np.array(resid), 1)[1] > 0.1:
  23.                 result = 0.0
  24.             else:
  25.                 result = 1.0
  26.             return beta, c, resid, result
  27.         else:
  28.             result = 0.0
  29.             return 0.0, 0.0, 0.0, result
  30.     else:
  31.         result = 0.0
  32.         return 0.0, 0.0, 0.0, result
  33. def init(context):
  34.     context.goods = ['SHFE.rb1801', 'SHFE.rb1805']
  35.     # 订阅品种
  36.     subscribe(symbols=context.goods, frequency='60s', count=801, wait_group=True)
  37. def on_bar(context, bars):
  38.     # 获取过去800个60s的收盘价数据
  39.     close_01 = context.data(symbol=context.goods[0], frequency='60s', count=801, fields='close')['close'].values
  40.     close_02 = context.data(symbol=context.goods[1], frequency='60s', count=801, fields='close')['close'].values
  41.     # 展示两个价格序列的协整检验的结果
  42.     beta, c, resid, result = cointegration_test(close_01, close_02)
  43.     # 如果返回协整检验不通过的结果则全平仓位等待
  44.     if not result:
  45.         print('协整检验不通过,全平所有仓位')
  46.         order_close_all()
  47.         return
  48.     # 计算残差的标准差上下轨
  49.     mean = np.mean(resid)
  50.     up = mean + 0.9 * np.std(resid)
  51.     down = mean - 0.9 * np.std(resid)
  52.     # 计算新残差
  53.     resid_new = close_01[-1] - beta * close_02[-1] - c
  54.     # 获取rb1801的多空仓位
  55.     position_01_long = context.account().position(symbol=context.goods[0], side=PositionSide_Long)
  56.     position_01_short = context.account().position(symbol=context.goods[0], side=PositionSide_Short)
  57.     if not position_01_long and not position_01_short:
  58.         # 上穿上轨时做空新残差
  59.         if resid_new > up:
  60.             order_target_volume(symbol=context.goods[0], volume=1, order_type=OrderType_Market,
  61.                                 position_side=PositionSide_Short)
  62.             print(context.goods[0] + '以市价单开空仓1手')
  63.             order_target_volume(symbol=context.goods[1], volume=1, order_type=OrderType_Market,
  64.                                 position_side=PositionSide_Long)
  65.             print(context.goods[1] + '以市价单开多仓1手')
  66.         # 下穿下轨时做多新残差
  67.         if resid_new < down:
  68.             order_target_volume(symbol=context.goods[0], volume=1, order_type=OrderType_Market,
  69.                                 position_side=PositionSide_Long)
  70.             print(context.goods[0], '以市价单开多仓1手')
  71.             order_target_volume(symbol=context.goods[1], volume=1, order_type=OrderType_Market,
  72.                                 position_side=PositionSide_Short)
  73.             print(context.goods[1], '以市价单开空仓1手')
  74.     # 新残差回归时平仓
  75.     elif position_01_short:
  76.         if resid_new <= up:
  77.             order_close_all()
  78.             print('价格回归,平掉所有仓位')
  79.         # 突破下轨反向开仓
  80.         if resid_new < down:
  81.             order_target_volume(symbol=context.goods[0], volume=1, order_type=OrderType_Market,
  82.                                 position_side=PositionSide_Long)
  83.             print(context.goods[0], '以市价单开多仓1手')
  84.             order_target_volume(symbol=context.goods[1], volume=1, order_type=OrderType_Market,
  85.                                 position_side=PositionSide_Short)
  86.             print(context.goods[1], '以市价单开空仓1手')
  87.     elif position_01_long:
  88.         if resid_new >= down:
  89.             order_close_all()
  90.             print('价格回归,平所有仓位')
  91.         # 突破上轨反向开仓
  92.         if resid_new > up:
  93.             order_target_volume(symbol=context.goods[0], volume=1, order_type=OrderType_Market,
  94.                                 position_side=PositionSide_Short)
  95.             print(context.goods[0], '以市价单开空仓1手')
  96.             order_target_volume(symbol=context.goods[1], volume=1, order_type=OrderType_Market,
  97.                                 position_side=PositionSide_Long)
  98.             print(context.goods[1], '以市价单开多仓1手')
  99. if __name__ == '__main__':
  100.     '''
  101.     strategy_id策略ID,由系统生成
  102.     filename文件名,请与本文件名保持一致
  103.     mode实时模式:MODE_LIVE回测模式:MODE_BACKTEST
  104.     token绑定计算机的ID,可在系统设置-密钥管理中生成
  105.     backtest_start_time回测开始时间
  106.     backtest_end_time回测结束时间
  107.     backtest_adjust股票复权方式不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
  108.     backtest_initial_cash回测初始资金
  109.     backtest_commission_ratio回测佣金比例
  110.     backtest_slippage_ratio回测滑点比例
  111.     '''
  112.     run(strategy_id='strategy_id',
  113.         filename='main.py',
  114.         mode=MODE_BACKTEST,
  115.         token='token_id',
  116.         backtest_start_time='2017-09-25 08:00:00',
  117.         backtest_end_time='2017-10-01 16:00:00',
  118.         backtest_adjust=ADJUST_PREV,
  119.         backtest_initial_cash=500000,
  120.         backtest_commission_ratio=0.0001,
  121.         backtest_slippage_ratio=0.0001)
复制代码


跨期套利.png


路过

雷人

握手

鲜花

鸡蛋
原作者: abctrader
关注微信