代码
# 克隆自聚宽文章: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