高频回测模块报错
由junglewolfz创建,最终由junglewolfz 被浏览 43 用户
代码
代码:在高频回测模块的k线处理函数定义如下:
# 回测引擎:每日数据处理函数,每天执行一次
def bigquant_run(context, data):
    
    # 相隔几天(hold_days)进行一下换仓
    if context.trading_day_index % context.hold_days != 0:
        return 
    
    # 按日期过滤得到今日的预测数据
    ranker_prediction = context.ranker_prediction[
        context.ranker_prediction.date == data.current_dt.strftime('%Y-%m-%d')]
    # 目前持仓
    positions = {e.symbol: p.amount * p.last_sale_price for e, p in context.portfolio.positions.items()}
    # 权重
    buy_cash_weights = context.stock_weights
    # 今日买入股票列表
    stock_to_buy = list(ranker_prediction.instrument[:len(buy_cash_weights)])
    # 持仓上限
    max_cash_per_instrument = context.portfolio.portfolio_value * context.max_cash_per_instrument
    # 通过positions对象,使用列表生成式的方法获取目前持仓的股票列表
    stock_hold_now = [equity.symbol for equity in context.portfolio.positions ]
    # 继续持有的股票:调仓时,如果买入的股票已经存在于目前的持仓里,那么应继续持有
    no_need_to_sell = [i for i in stock_hold_now if i in stock_to_buy]
    # 需要卖出的股票
    stock_to_sell = [i for i in stock_hold_now if i not in no_need_to_sell]
  
    # 卖出
    for stock in stock_to_sell:
        # 如果该股票停牌,则没法成交。因此需要用can_trade方法检查下该股票的状态
        # 如果返回真值,则可以正常下单,否则会出错
        # 因为stock是字符串格式,我们用symbol方法将其转化成平台可以接受的形式:Equity格式
        if data.can_trade(context.symbol(stock)):
            # order_target_percent是平台的一个下单接口,表明下单使得该股票的权重为0,
            #   即卖出全部股票,可参考回测文档
            context.order_target_percent(context.symbol(stock), 0)
    
    # 如果当天没有买入的股票,就返回
    if len(stock_to_buy) == 0:
        return
    
    # 买入
    for i, instrument in enumerate(stock_to_buy):
        cash = context.portfolio.portfolio_value * buy_cash_weights[i]
        if cash > max_cash_per_instrument - positions.get(instrument, 0):
            # 确保股票持仓量不会超过每次股票最大的占用资金量
            cash = max_cash_per_instrument - positions.get(instrument, 0)
        if cash > 0:
            context.order_value(context.symbol(instrument), cash)
报错:
AttributeError                            Traceback (most recent call last)
<ipython-input-4-2f2051da032e> in <module>
    287 )
    288 
--> 289 m21 = M.hftrade.v2(
    290     instruments=m12.instrument_list,
    291     options_data=m8.predictions,
<ipython-input-4-2f2051da032e> in m21_handle_data_bigquant_run(context, data)
     95         context.ranker_prediction.date == data.current_dt.strftime('%Y-%m-%d')]
     96     # 目前持仓
---> 97     positions = {e.symbol: p.amount * p.last_sale_price for e, p in context.portfolio.positions.items()}
     98     # 权重
     99     buy_cash_weights = context.stock_weights
<ipython-input-4-2f2051da032e> in <dictcomp>(.0)
     95         context.ranker_prediction.date == data.current_dt.strftime('%Y-%m-%d')]
     96     # 目前持仓
---> 97     positions = {e.symbol: p.amount * p.last_sale_price for e, p in context.portfolio.positions.items()}
     98     # 权重
     99     buy_cash_weights = context.stock_weights
AttributeError: 'str' object has no attribute 'symbol'
解答
直接从trade模块拷贝过来的话确实会有问题,很多trade模块的接口和HFTrade模块的接口确实会有些不同。
for e, p in context.portfolio.positions.items():
    print(e) # e即为symbol,不需要原来的e.symbol
    print(j) # j是一个对象,标的为股票的话对象名为StockPosition,期货的话为FuturePosition / 具体对象名能有哪些attribute, 可以参考文档https://bigquant.com/wiki/doc/-uUmJMOnqYu
文档中这个地方即为上述的对象名下面可获取的attribute列表
\