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