代码
# 克隆自聚宽文章:https://www.joinquant.com/post/20590 # 标题:ETF单均线跟踪轮动 # 作者:那時花開海布裡 ''' ================================================= 总体回测前设置参数和回测 ================================================= ''' def initialize(context): set_params() #1设置策参数 set_variables() #2设置中间变量 set_backtest() #3设置回测条件 #1 设置参数 def set_params(): # 设置基准收益 set_benchmark('000300.XSHG') g.lag = 13 g.hour = 14 g.minute = 25 g.hs = '000300.XSHG' #300指数 g.zz = '399006.XSHE'#创业板指数 g.sz = '000016.XSHG' #50指数 g.ETF300 = '000300.XSHG'#'300指数 g.ETF500 = '399006.XSHE'#'300指数 g.ETF50 = '000016.XSHG' #50指数 g.ETFrili = '511880.XSHG' #银华日利 #2 设置中间变量 def set_variables(): return #3 设置回测条件 def set_backtest(): set_option('use_real_price', True) #用真实价格交易 log.set_level('order', 'error') ''' ================================================= 每天开盘前 ================================================= ''' #每天开盘前要做的事情 def before_trading_start(context): set_slip_fee(context) #4 # 根据不同的时间段设置滑点与手续费 def set_slip_fee(context): # 将滑点设置为0 set_slippage(FixedSlippage(0)) # 根据不同的时间段设置手续费 dt=context.current_dt if dt>datetime.datetime(2013,1, 1): set_commission(PerTrade(buy_cost=0.0003, sell_cost=0.0013, min_cost=5)) elif dt>datetime.datetime(2011,1, 1): set_commission(PerTrade(buy_cost=0.001, sell_cost=0.002, min_cost=5)) elif dt>datetime.datetime(2009,1, 1): set_commission(PerTrade(buy_cost=0.002, sell_cost=0.003, min_cost=5)) else: set_commission(PerTrade(buy_cost=0.003, sell_cost=0.004, min_cost=5)) ''' ================================================= 每日交易时 ================================================= ''' def handle_data(context, data): # 获得当前时间 hour = context.current_dt.hour minute = context.current_dt.minute # 每天收盘时调整仓位 if hour == g.hour and minute == g.minute: signal = get_signal(context) if signal == 'sell_the_stocks': sell_the_stocks(context) print(context.portfolio.positions[g.ETFrili].total_amount) elif signal == 'ETF300' or signal == 'ETF500': buy_the_stocks(context,signal) elif signal == 's500b300': sell_the_stocks(context) buy_the_stocks(context,'ETF300') elif signal == 'sell_the_stocks': sell_the_stocks(context) buy_the_stocks(context,'ETF500') elif signal == 's500b50': sell_the_stocks(context) buy_the_stocks(context,'ETF50') elif signal == 's300b50': sell_the_stocks(context) buy_the_stocks(context,'ETF50') elif signal == 's50b300': sell_the_stocks(context) buy_the_stocks(context,'ETF300') elif signal == 's50b500': sell_the_stocks(context) buy_the_stocks(context,'ETF500') #5 #获取信号 def get_signal(context): #沪深300与创业板和上证50的当前股价 hs300,cp300,av300 = getStockPrice(g.hs, g.lag) zz500,cp500,av500 = getStockPrice(g.zz, g.lag) sz50,cp50,av50 = getStockPrice(g.sz, g.lag) #计算前13日变动 hs300increase = (cp300 - hs300) / hs300 zz500increase = (cp500 - zz500) / zz500 sz50increase = (cp50 - sz50) / sz50 hold300 = context.portfolio.positions[g.ETF300].total_amount hold500 = context.portfolio.positions[g.ETF500].total_amount hold50 = context.portfolio.positions[g.ETF50].total_amount if (hold300>0 and cp300<av300 and cp500<av500 and cp50<av50) or (hold500>0 and cp300<av300 and cp500<av500 and cp50<av50 ) or (hold50>0and cp300<av300 and cp500<av500 and cp50<av50): return 'sell_the_stocks' elif hs300increase>zz500increase and hs300increase>sz50increase and (hold300==0 and hold500==0 and hold50==0) and cp300>av300: return 'ETF300' elif zz500increase>hs300increase and zz500increase>sz50increase and (hold50==0 and hold300==0 and hold500==0) and cp500>av500: return 'ETF500' elif sz50increase>hs300increase and sz50increase>zz500increase and (hold50==0 and hold300==0 and hold500==0) and cp500>av500: return 'ETF50' elif hold500>0 and zz500increase<hs300increase and hs300increase>sz50increase and cp300>av300: return 's500b300' elif hold500>0 and zz500increase<sz50increase and hs300increase<sz50increase and cp50>av50: return 's500b50' elif hold300>0 and zz500increase>hs300increase and zz500increase>sz50increase and cp500>av500: return 's300b500' elif hold300>0 and sz50increase>hs300increase and sz50increase>zz500increase and cp50>av50: return 's300b50' elif hold50>0 and hs300increase>sz50increase and hs300increase>zz500increase and cp300>av300: return's50b300' elif hold50>0 and zz500increase>sz50increase and zz500increase>hs300increase and cp500>av500: return's50b500' #6 #取得股票某个区间内的所有收盘价(用于取前13日和当前价格) def getStockPrice(stock, interval): h = attribute_history(stock, interval*240, unit='1m', fields=('close'), skip_paused=True) return (h['close'].values[0],h['close'].values[-1],h['close'].mean()) def getCurrentPrice(stock): h= attribute_history(stock, 1, unit='1m', fields=('close'), skip_paused=True) return (h['close'].values[-1]) #7 #卖出股票 def sell_the_stocks(context): for stock in context.portfolio.positions.keys(): return (log.info("Selling %s" % stock), order_target_value(stock, 0),order_value('511880.XSHG', context.portfolio.cash)) #8 #买入股票 def buy_the_stocks(context,signal): holdrili = context.portfolio.positions[g.ETFrili].total_amount prili = getCurrentPrice(g.ETFrili) if holdrili ==0 : return (log.info("Buying %s"% signal ),order_value(eval('g.%s'% signal), context.portfolio.cash)) elif holdrili !=0: return (log.info("Buying %s"% signal ),order_target_value(g.ETFrili, 0),order_value(eval('g.%s'% signal), holdrili*prili)) ''' ================================================= 每日收盘后(本策略中不需要) ================================================= ''' def after_trading_end(context): return
代码, 清晰版
# 克隆自聚宽文章:https://www.joinquant.com/post/20590 # 标题:ETF单均线跟踪轮动 # 作者:那時花開海布裡 ''' ================================================= 总体回测前设置参数和回测 ================================================= ''' def initialize(context): set_params() #1设置策参数 set_variables() #2设置中间变量 set_backtest() #3设置回测条件 #1 设置参数 def set_params(): # 设置基准收益 set_benchmark('000300.XSHG') g.lag = 13 g.hour = 14 g.minute = 25 g.hs = '000300.XSHG' #300指数 g.zz = '399006.XSHE'#创业板指数 g.sz = '000016.XSHG' #50指数 g.ETF300 = '000300.XSHG'#'300指数 g.ETF500 = '399006.XSHE'#'300指数 g.ETF50 = '000016.XSHG' #50指数 g.ETFrili = '511880.XSHG' #银华日利 #2 设置中间变量 def set_variables(): return #3 设置回测条件 def set_backtest(): set_option('use_real_price', True) #用真实价格交易 log.set_level('order', 'error') ''' ================================================= 每天开盘前 ================================================= ''' #每天开盘前要做的事情 def before_trading_start(context): set_slip_fee(context) #4 # 根据不同的时间段设置滑点与手续费 def set_slip_fee(context): # 将滑点设置为0 set_slippage(FixedSlippage(0)) # 根据不同的时间段设置手续费 dt=context.current_dt if dt>datetime.datetime(2013,1, 1): set_commission(PerTrade(buy_cost=0.0003, sell_cost=0.0013, min_cost=5)) elif dt>datetime.datetime(2011,1, 1): set_commission(PerTrade(buy_cost=0.001, sell_cost=0.002, min_cost=5)) elif dt>datetime.datetime(2009,1, 1): set_commission(PerTrade(buy_cost=0.002, sell_cost=0.003, min_cost=5)) else: set_commission(PerTrade(buy_cost=0.003, sell_cost=0.004, min_cost=5)) ''' ================================================= 每日交易时 ================================================= ''' def handle_data(context, data): # 获得当前时间 hour = context.current_dt.hour minute = context.current_dt.minute # 每天收盘时调整仓位 if hour == g.hour and minute == g.minute: signal = get_signal(context) if signal == 'sell_the_stocks': sell_the_stocks(context) print(context.portfolio.positions[g.ETFrili].total_amount) elif signal == 'ETF300' or signal == 'ETF500': buy_the_stocks(context,signal) elif signal == 's500b300': sell_the_stocks(context) buy_the_stocks(context,'ETF300') elif signal == 'sell_the_stocks': sell_the_stocks(context) buy_the_stocks(context,'ETF500') elif signal == 's500b50': sell_the_stocks(context) buy_the_stocks(context,'ETF50') elif signal == 's300b50': sell_the_stocks(context) buy_the_stocks(context,'ETF50') elif signal == 's50b300': sell_the_stocks(context) buy_the_stocks(context,'ETF300') elif signal == 's50b500': sell_the_stocks(context) buy_the_stocks(context,'ETF500') #5 #获取信号 def get_signal(context): #沪深300与创业板和上证50的当前股价 hs300,cp300,av300 = getStockPrice(g.hs, g.lag) zz500,cp500,av500 = getStockPrice(g.zz, g.lag) sz50,cp50,av50 = getStockPrice(g.sz, g.lag) #计算前13日变动 hs300increase = (cp300 - hs300) / hs300 zz500increase = (cp500 - zz500) / zz500 sz50increase = (cp50 - sz50) / sz50 hold300 = context.portfolio.positions[g.ETF300].total_amount hold500 = context.portfolio.positions[g.ETF500].total_amount hold50 = context.portfolio.positions[g.ETF50].total_amount dpj = zz500increase<sz50increase and hs300increase<sz50increase and cp50>av50 zpj = zz500increase<hs300increase and hs300increase>sz50increase and cp300>av300 xpj = zz500increase>hs300increase and zz500increase>sz50increase and cp500>av500 pos_isEmpty = (hold300==0 and hold500==0 and hold50==0) all_isDown = (cp300<av300 and cp500<av500 and cp50<av50) #if (hold300>0 and all_isDown) or \ # (hold500>0 and all_isDown) or \ # (hold50>0 and all_isDown): if (not pos_isEmpty) and all_isDown: return 'sell_the_stocks' elif pos_isEmpty: if zpj: return 'ETF300' elif xpj: return 'ETF500' elif dpj: return 'ETF50' elif hold500>0 and zpj: return 's500b300' elif hold500>0 and dpj: return 's500b50' elif hold300>0 and xpj: return 's300b500' elif hold300>0 and dpj: return 's300b50' elif hold50>0 and zpj: return's50b300' elif hold50>0 and xpj: return's50b500' #6 #取得股票某个区间内的所有收盘价(用于取前13日和当前价格) def getStockPrice(stock, interval): h = attribute_history(stock, interval*240, unit='1m', fields=('close'), skip_paused=True) return (h['close'].values[0],h['close'].values[-1],h['close'].mean()) def getCurrentPrice(stock): h= attribute_history(stock, 1, unit='1m', fields=('close'), skip_paused=True) return (h['close'].values[-1]) #7 #卖出股票 def sell_the_stocks(context): for stock in context.portfolio.positions.keys(): return (log.info("Selling %s" % stock), order_target_value(stock, 0),order_value('511880.XSHG', context.portfolio.cash)) #8 #买入股票 def buy_the_stocks(context,signal): holdrili = context.portfolio.positions[g.ETFrili].total_amount prili = getCurrentPrice(g.ETFrili) if holdrili ==0 : return (log.info("Buying %s"% signal ),order_value(eval('g.%s'% signal), context.portfolio.cash)) elif holdrili !=0: return (log.info("Buying %s"% signal ),order_target_value(g.ETFrili, 0),order_value(eval('g.%s'% signal), holdrili*prili)) ''' ================================================= 每日收盘后(本策略中不需要) ================================================= ''' def after_trading_end(context): return
来源:https://www.cnblogs.com/duan-qs/p/11324889.html