【新手求助】谁能帮我看看为什么这个回测这么慢,是不是哪不对?

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

(fireman) #1
克隆策略
In [ ]:
import numpy as np

start = '2017-01-01'
end = '2017-10-30'
df = D.history_data(D.instruments(),start_date=start, end_date=end, fields=['in_csi500']) 
instruments = list(set(df[df['in_csi500']==1]['instrument']))
capital_base = 100000
benchmark = '000300.SHA'                          # 策略参考标准
rebalance_period = 1
freq = 'd'
stock_num = 10


import talib

def initialize(context):
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5)) # 设置手续费
    context.hold_days = dict()  # 以便统计持仓天数
    context.max_hold = 10  # 该参数不能超过daily_buy_stock每天的数量
    

def handle_data(context, data):
    dt = data.current_dt.strftime('%Y-%m-%d') # 日期
    weight = 1 / context.max_hold # 个股权重
    
    stock_hold_now = [equity.symbol for equity in context.portfolio.positions]   # 目前持仓股票列表
    context.hold_num = len(stock_hold_now)  # 目前持仓股票数
    
    print('持仓:,',stock_hold_now,'持仓数目:',context.hold_num)
    
    stock_num_can_buy = context.max_hold - context.hold_num  # 还可以买入的股票数量
    count = 0 
    for st in context.instruments:
        if st in stock_hold_now:  # 如果股票已经持有
            continue 
            
        if count >= stock_num_can_buy:  # 如果股票数量已经达到max_hold
            break
        
        dealAmountYesterday = data.history(context.symbol(st),'volume',3,'1d')[-1]  # 当日成交量
        dealAmountYesterday_1 = data.history(context.symbol(st),'volume',3,'1d')[-2] # 前一日成交量
        dealAmountAverageofFive = data.history(context.symbol(st),'volume',5,'1d').mean() #前五天平均

        price = data.current(context.symbol(st),'price') # 最新一个交易日收盘价
        prices = data.history(context.symbol(st),'close',10,'1d').map(np.float)  # 转化成float格式
        
        ma1=data.history(context.symbol(st),'close',3,'1d')[-1]
        ma2=data.history(context.symbol(st),'close',3,'1d')[-2]
        ma5=data.history(context.symbol(st),'close',5,'1d').mean()
        ma20=data.history(context.symbol(st),'close',20,'1d').mean()    
       
        if data.can_trade(context.symbol(st)) and (ma1>1.05*ma2) and \
        (dealAmountYesterday>dealAmountYesterday_1) and (dealAmountYesterday>5*dealAmountAverageofFive):
            order_target_percent(context.symbol(st), weight) # 买入
            context.hold_days[st] = context.trading_day_index  #记录交易日期
            count += 1 # 当日买入股票数量增加1
            print(dt,'买入股票:',st)
        elif ma5<ma20 and st in stock_hold_now:
            order_target_percent(context.symbol(st), 0)  
            
m = M.trade.v2( 
    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=capital_base,
    benchmark=benchmark,
)   
[2017-12-03 21:04:18.217670] INFO: bigquant: backtest.v7 开始运行..
持仓:, [] 持仓数目: 0
持仓:, [] 持仓数目: 0
持仓:, [] 持仓数目: 0
持仓:, [] 持仓数目: 0
持仓:, [] 持仓数目: 0
持仓:, [] 持仓数目: 0
持仓:, [] 持仓数目: 0

(iQuant) #2

您好,主要是代码逻辑有问题。你之前的代码如下:

 if data.can_trade(context.symbol(st)) and (ma1>1.05*ma2) and \
        (dealAmountYesterday>dealAmountYesterday_1) and (dealAmountYesterday>5*dealAmountAverageofFive):

由于5dealAmountAverageofFive 表明的是5日成交量之和,因此dealAmountYesterday>5dealAmountAverageofFive 这个条件语句永远为False,导致开仓条件不满足。

你可以将其修改为:

dealAmountYesterday>dealAmountAverageofFive

这样的话,你的策略就能正常运行了。