首页 > 编程知识 正文

跨期套利(期货)

时间:2023-05-06 12:15:39 阅读:210343 作者:2277

# coding=utf-8from __future__ import print_function, absolute_import, unicode_literalsimport numpy as npfrom gm.api import *try: import statsmodels.tsa.stattools as tsexcept: print('请安装statsmodels库')'''本策略根据EG两步法(1.序列同阶单整2.OLS残差平稳)判断序列具有协整关系之后(若无协整关系则全平仓位不进行操作)通过计算两个真实价格序列回归残差的0.9个标准差上下轨,并在价差突破上轨的时候做空价差,价差突破下轨的时候做多价差并在回归至标准差水平内的时候平仓回测数据为:SHFE.rb1801和SHFE.rb1805的1min数据回测时间为:2017-09-25 08:00:00到2017-10-01 15:00:00'''# 协整检验的函数def cointegration_test(series01, series02): urt_rb1801 = ts.adfuller(np.array(series01), 1)[1] urt_rb1805 = ts.adfuller(np.array(series01), 1)[1] # 同时平稳或不平稳则差分再次检验 if (urt_rb1801 > 0.1 and urt_rb1805 > 0.1) or (urt_rb1801 < 0.1 and urt_rb1805 < 0.1): urt_diff_rb1801 = ts.adfuller(np.diff(np.array(series01)), 1)[1] urt_diff_rb1805 = ts.adfuller(np.diff(np.array(series01), 1))[1] # 同时差分平稳进行OLS回归的残差平稳检验 if urt_diff_rb1801 < 0.1 and urt_diff_rb1805 < 0.1: matrix = np.vstack([series02, np.ones(len(series02))]).T beta, c = np.linalg.lstsq(matrix, series01)[0] resid = series01 - beta * series02 - c if ts.adfuller(np.array(resid), 1)[1] > 0.1: result = 0.0 else: result = 1.0 return beta, c, resid, result else: result = 0.0 return 0.0, 0.0, 0.0, result else: result = 0.0 return 0.0, 0.0, 0.0, resultdef init(context): context.goods = ['SHFE.rb1801', 'SHFE.rb1805'] # 订阅品种 subscribe(symbols=context.goods, frequency='60s', count=801, wait_group=True)def on_bar(context, bars): # 获取过去800个60s的收盘价数据 close_01 = context.data(symbol=context.goods[0], frequency='60s', count=801, fields='close')['close'].values close_02 = context.data(symbol=context.goods[1], frequency='60s', count=801, fields='close')['close'].values # 展示两个价格序列的协整检验的结果 beta, c, resid, result = cointegration_test(close_01, close_02) # 如果返回协整检验不通过的结果则全平仓位等待 if not result: print('协整检验不通过,全平所有仓位') order_close_all() return # 计算残差的标准差上下轨 mean = np.mean(resid) up = mean + 0.9 * np.std(resid) down = mean - 0.9 * np.std(resid) # 计算新残差 resid_new = close_01[-1] - beta * close_02[-1] - c # 获取rb1801的多空仓位 position_01_long = context.account().position(symbol=context.goods[0], side=PositionSide_Long) position_01_short = context.account().position(symbol=context.goods[0], side=PositionSide_Short) if not position_01_long and not position_01_short: # 上穿上轨时做空新残差 if resid_new > up: order_target_volume(symbol=context.goods[0], volume=1, order_type=OrderType_Market, position_side=PositionSide_Short) print(context.goods[0] + '以市价单开空仓1手') order_target_volume(symbol=context.goods[1], volume=1, order_type=OrderType_Market, position_side=PositionSide_Long) print(context.goods[1] + '以市价单开多仓1手') # 下穿下轨时做多新残差 if resid_new < down: order_target_volume(symbol=context.goods[0], volume=1, order_type=OrderType_Market, position_side=PositionSide_Long) print(context.goods[0], '以市价单开多仓1手') order_target_volume(symbol=context.goods[1], volume=1, order_type=OrderType_Market, position_side=PositionSide_Short) print(context.goods[1], '以市价单开空仓1手') # 新残差回归时平仓 elif position_01_short: if resid_new <= up: order_close_all() print('价格回归,平掉所有仓位') # 突破下轨反向开仓 if resid_new < down: order_target_volume(symbol=context.goods[0], volume=1, order_type=OrderType_Market, position_side=PositionSide_Long) print(context.goods[0], '以市价单开多仓1手') order_target_volume(symbol=context.goods[1], volume=1, order_type=OrderType_Market, position_side=PositionSide_Short) print(context.goods[1], '以市价单开空仓1手') elif position_01_long: if resid_new >= down: order_close_all() print('价格回归,平所有仓位') # 突破上轨反向开仓 if resid_new > up: order_target_volume(symbol=context.goods[0], volume=1, order_type=OrderType_Market, position_side=PositionSide_Short) print(context.goods[0], '以市价单开空仓1手') order_target_volume(symbol=context.goods[1], volume=1, order_type=OrderType_Market, position_side=PositionSide_Long) print(context.goods[1], '以市价单开多仓1手')if __name__ == '__main__': ''' strategy_id策略ID,由系统生成 filename文件名,请与本文件名保持一致 mode实时模式:MODE_LIVE回测模式:MODE_BACKTEST token绑定计算机的ID,可在系统设置-密钥管理中生成 backtest_start_time回测开始时间 backtest_end_time回测结束时间 backtest_adjust股票复权方式不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST backtest_initial_cash回测初始资金 backtest_commission_ratio回测佣金比例 backtest_slippage_ratio回测滑点比例 ''' run(strategy_id='strategy_id', filename='main.py', mode=MODE_BACKTEST, token='token_id', backtest_start_time='2017-09-25 08:00:00', backtest_end_time='2017-10-01 16:00:00', backtest_adjust=ADJUST_PREV, backtest_initial_cash=500000, backtest_commission_ratio=0.0001, backtest_slippage_ratio=0.0001)

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。