跨品種套利策略:
本策略根據計算滾動的.過去的30個bar的均值正負0.5個標準差得到布林線
并在最新價差上穿上軌來做空價差,下穿下軌來做多價差
并在回歸至上下軌水平內的時候平倉
?
獲取數據:
# 獲取兩個品種的收盤價時間序列closes=ContextInfo.get_market_data(['close'], stock_code=ContextInfo.trade_pair, period = ContextInfo.period, count=31)if closes.empty:return
制作指標:
up_closes = closes[ContextInfo.trade_pair[0]]['close']
down_closes = closes[ContextInfo.trade_pair[1]]['close']
# 計算價差
spread = up_closes[:-1] - down_closes[:-1]
#spread=0
# 計算布林帶上下軌
up = np.mean(spread) + 0.5 * np.std(spread)
down = np.mean(spread) - 0.5 * np.std(spread)
# 計算價差
if (up_closes[-1] is None) or (down_closes[-1] is None):spread_now=0
else:spread_now = up_closes[-1] - down_closes[-1]
策略代碼:
#coding:gbk
'''
回測模型示例(非實盤交易策略)本策略根據計算滾動的.過去的30個bar的均值正負0.5個標準差得到布林線
并在最新價差上穿上軌來做空價差,下穿下軌來做多價差
并在回歸至上下軌水平內的時候平倉
'''import numpy as npdef init(ContextInfo):ContextInfo.trade_pair=['rb00.SF','hc00.SF']ContextInfo.position_tag = {'long':False,'short':False} #初始化持倉狀態ContextInfo.set_universe(ContextInfo.trade_pair) # 設置標的期貨合約對應股票池ContextInfo.accid = '103427'def handlebar(ContextInfo):index = ContextInfo.barposbartimetag = ContextInfo.get_bar_timetag(index)print(timetag_to_datetime(bartimetag,'%Y-%m-%d %H:%M%S'))# 獲取兩個品種的收盤價時間序列closes=ContextInfo.get_market_data(['close'], stock_code=ContextInfo.trade_pair, period = ContextInfo.period, count=31)if closes.empty:returnup_closes = closes[ContextInfo.trade_pair[0]]['close']down_closes = closes[ContextInfo.trade_pair[1]]['close']# 計算價差spread = up_closes[:-1] - down_closes[:-1]#spread=0# 計算布林帶上下軌up = np.mean(spread) + 0.5 * np.std(spread)down = np.mean(spread) - 0.5 * np.std(spread)# 計算價差if (up_closes[-1] is None) or (down_closes[-1] is None):spread_now=0else:spread_now = up_closes[-1] - down_closes[-1]#無交易時若價差上(下)穿布林帶上(下)軌則做空(多)價差position_up_long = ContextInfo.position_tag['long']position_up_short = ContextInfo.position_tag['short']if not position_up_long and not position_up_short:if spread_now > up:#開空code1,開多code2sell_open(ContextInfo.trade_pair[0],1,ContextInfo,ContextInfo.accid)buy_open(ContextInfo.trade_pair[1],1,ContextInfo,ContextInfo.accid)ContextInfo.position_tag['short'] = Trueif spread_now < down:#開多code1,開空code2buy_open(ContextInfo.trade_pair[0],1,ContextInfo,ContextInfo.accid)sell_open(ContextInfo.trade_pair[1],1,ContextInfo,ContextInfo.accid)ContextInfo.position_tag['long'] = True# 價差回歸時平倉elif position_up_short:if spread_now <= up:#平空code1,平多code2buy_close_tdayfirst(ContextInfo.trade_pair[0],1,ContextInfo,ContextInfo.accid)sell_close_tdayfirst(ContextInfo.trade_pair[1],1,ContextInfo,ContextInfo.accid)ContextInfo.position_tag['short'] = False# 跌破下軌反向開倉if spread_now < down:#開多code1,開空code2buy_open(ContextInfo.trade_pair[0],1,ContextInfo,ContextInfo.accid)sell_open(ContextInfo.trade_pair[1],1,ContextInfo,ContextInfo.accid)ContextInfo.position_tag['long'] = Trueelif position_up_long:if spread_now >= down:#平多code1,平空code2sell_close_tdayfirst(ContextInfo.trade_pair[0],1,ContextInfo,ContextInfo.accid)buy_close_tdayfirst(ContextInfo.trade_pair[1],1,ContextInfo,ContextInfo.accid)ContextInfo.position_tag['long'] = Falseif spread_now > up:#開空code1,開多code2sell_open(ContextInfo.trade_pair[0],1,ContextInfo,ContextInfo.accid)buy_open(ContextInfo.trade_pair[1],1,ContextInfo,ContextInfo.accid)ContextInfo.position_tag['short'] = TrueContextInfo.paint('short_spread',int(spread_now > up),-1,0,'noaxis')ContextInfo.paint('long_spread',int(spread_now < down),-1,0,'noaxis')