joinquant戦略

コード

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


おすすめ

転載: www.cnblogs.com/duan-qs/p/11324889.html