前复权回测,策略为什么持仓占比会超过100%

策略分享
标签: #<Tag:0x00007fcf68e715a0>

(chidaye) #1
克隆策略

金叉死叉策略

当短期均线上穿长期均线,出现金叉,买入

当短期均线下穿长期均线,出现死叉,卖出

1. 主要参数

In [31]:
# 股票选择
instruments = ['000099.SHA','002197.SHA','600520.SHA','600312.SHA','600995.SHA','601998.SHA','000012.SZA','000625.SZA','000623.SHA','601088.SHA','601800.SHA','002673.SZA','002206.SZA','000559.SZA'] 
# 开始时间
start_date = '2017-01-29'  
# 结束时间
end_date = '2018-03-11'

2. 策略回测主体

In [32]:
# 策略主体
def initialize(context):
    context.short_period = 5
    context.long_period = 60
    
def handle_data(context, data):
    date = data.current_dt.strftime('%Y-%m-%d')  

    
    
    #----------------------------止赢模块START------------------------
    positions = {e.symbol: p.cost_basis  for e, p in context.portfolio.positions.items()}
    # 新建当日止赢股票列表是为了handle_data 策略逻辑部分不再对该股票进行判断
    current_stopwin_stock = [] 
    if len(positions) > 0:
        for i in positions.keys():
            stock_cost = positions[i] 
            stock_market_price = data.current(context.symbol(i), 'price') 
            # 赚10%就止赢
            if (stock_market_price - stock_cost ) / stock_cost>= 0.2:   
                context.order_target_percent(context.symbol(i),0)     
                current_stopwin_stock.append(i)
                print('日期:',date,'股票:',i,'出现止盈状况')
    #---------------------------止赢模块END---------------------------
             
    if context.trading_day_index <  context.long_period:
        return    

    for k in instruments:
        if k in current_stopwin_stock:
            continue
        sid = context.symbol(k)
        price = data.current(sid, 'price')  
        short_mavg = data.history(sid, 'price',context.short_period, '1d').mean()  
        long_mavg = data.history(sid, 'price',context.long_period, '1d').mean()     
        cash = context.portfolio.cash  / len(instruments)
        cur_position = context.portfolio.positions[sid].amount  
        
        if short_mavg > long_mavg and cur_position == 0  and data.can_trade(sid):  
            context.order_target_percent(sid, 0.2) 
        elif short_mavg < long_mavg  and cur_position > 0 and   data.can_trade(sid):  
            context.order_target_percent(sid, 0)
    
    
    
    
    

     

3.回测接口

In [33]:
m=M.trade.v3(
    instruments=instruments,
    start_date=start_date,
    end_date=end_date,
    initialize=initialize,
    handle_data=handle_data,
    order_price_field_buy='open', # 以开盘价买入
    order_price_field_sell='open', # 以开盘价卖出
    capital_base=1000000, # 本金
    price_type='forward_adjusted',
    
    )
[2018-03-22 15:53:25.044909] INFO: bigquant: backtest.v7 开始运行..
[2018-03-22 15:53:25.212047] INFO: algo: set price type:forward_adjusted
日期: 2017-09-01 股票: 601088.SHA 出现止盈状况
日期: 2017-09-28 股票: 000559.SZA 出现止盈状况
日期: 2017-10-24 股票: 002673.SZA 出现止盈状况
日期: 2017-12-15 股票: 600520.SHA 出现止盈状况
日期: 2018-02-01 股票: 601088.SHA 出现止盈状况
日期: 2018-02-05 股票: 601998.SHA 出现止盈状况
[2018-03-22 15:54:19.555699] INFO: Performance: Simulated 270 trading days out of 270.
[2018-03-22 15:54:19.557625] INFO: Performance: first open: 2017-02-03 01:30:00+00:00
[2018-03-22 15:54:19.559202] INFO: Performance: last close: 2018-03-09 07:00:00+00:00
  • 收益率-8.5%
  • 年化收益率-7.95%
  • 基准收益率21.28%
  • 阿尔法-0.18
  • 贝塔0.35
  • 夏普比率-1.41
  • 胜率0.3
  • 盈亏比1.421
  • 收益波动率8.81%
  • 信息比率-2.5
  • 最大回撤12.53%
[2018-03-22 15:54:21.212467] INFO: bigquant: backtest.v7 运行完成[56.167544s].

(小Q) #2

您好,原因是这样的,在2015年9月15日那天,止损会卖出该股票,同时后面的逻辑卖出部分也会卖出该股票,因此这里需要加入两行代码使得策略更加严谨。
添加的两行代码为:

if k in current_stoploss_stock or k in current_stopwin_stock:
    continue

添加位置是:

回测结果如下:


请教滚动训练情况下回测结果的几个问题