Logic

1
选定基础股票池为hs300成分股中sh和sz市场各自流通市值最大的前3只股票。 获取股票22日历史收盘价,计算布林带的中轨、上轨和下轨。 如果持有该股票并且收盘价向下突破布林带下轨,则卖出该股票。 如果收盘价向上突破布林带上轨,则买入该股票。 如果可用资金不够买10000股时,用目标价值下单函数下单。

Code

1
#encoding:gbk ''' 中轨=20日K线的移动平均 上轨=中轨+两倍标准差 下轨=中轨-两倍标准差 ''' import pandas as pd import numpy as np import talib def init(ContextInfo): #hs300成分股中sh和sz市场各自流通市值最大的前3只股票 ContextInfo.trade_code_list=['601398.SH','601857.SH','601288.SH','000333.SZ','002415.SZ','000002.SZ'] #设定基础股票池 ContextInfo.set_universe(ContextInfo.trade_code_list) #设置交易账户 ContextInfo.accID = '110000009218' #获取账户持仓信息 #positioninfo= get_trade_detail_data(ContextInfo.accID,'stock','Position') def handlebar(ContextInfo): #获取股票22日历史收盘价 h=ContextInfo.get_history_data(22,'1d','close',3) #获取持仓信息 holdings=get_holdings(ContextInfo.accID,'STOCK') #保存两日的布林带轨道线情况 boll_med=dict.fromkeys(ContextInfo.trade_code_list,[0,0]) boll_up=dict.fromkeys(ContextInfo.trade_code_list,[0,0]) boll_down=dict.fromkeys(ContextInfo.trade_code_list,[0,0]) for k in ContextInfo.trade_code_list: pc=h[k][-1] #前一日收盘价 pc_pre=h[k][-2] #前一日的布林带,今日的布林带 boll_med[k]=[np.mean(h[k][:21]),np.mean(h[k][1:])] boll_up[k]=[boll_med[k][0]+2*np.std(h[k][:21]),boll_med[k][1]+2*np.std(h[k][1:])] boll_down[k]=[boll_med[k][0]-2*np.std(h[k][:21]),boll_med[k][1]-2*np.std(h[k][1:])] #print(boll_med[k],boll_up[k],boll_down[k]) #日K线中轨以下运行 #if pc<boll_med[k][1]: #收盘价向下突破布林带下轨则平仓 if pc_pre>boll_down[k][0] and pc<boll_down[k][1] and k in holdings.keys(): order_shares(k,-holdings[k]*100,ContextInfo,ContextInfo.accID) #日K线中轨以上运行 #if pc>boll_med[k][1]: #收盘价向上突破布林带上轨则买入 elif pc_pre<boll_up[k][0] and pc>boll_up[k][1]: #order_shares(k,10000,ContextInfo,ContextInfo.accID) accoundinfo= get_trade_detail_data(ContextInfo.accID,'stock','account') for i in accoundinfo: RC = i.m_dAvailable #print(RC) if pc*10000<RC: order_shares(k,10000,ContextInfo,ContextInfo.accID) #可用资金不够买10000股时,用目标价值下单函数下单 elif pc*10000>RC: order_target_value(k,0.8*RC,ContextInfo,ContextInfo.accID) #获取持仓信息{code.market:手数}m_nVolume def get_holdings(accountid,datatype): holdinglist={} resultlist=get_trade_detail_data(accountid,datatype,"POSITION") for obj in resultlist: holdinglist[obj.m_strInstrumentID+"."+obj.m_strExchangeID]=obj.m_nVolume/100 #返回{code.market:持仓手数} #print(obj.m_strInstrumentID,obj.m_nVolume,obj.m_strInstrumentName) return holdinglist

注:该策略未加入止盈止损。

Back Test

回测设置:

初始资金:100w

时间: 2022/01/03——2023/07/27

佣金:万一免五

回测结果:

夏普比率:0.835

下方差: 0.031

索提诺比率:5.690

跟踪误差:0.OO1

信息比率: 0.003

最大回撤率:0.129