回测仓位有问题

新手专区
标签: #<Tag:0x00007fb3d539d038>

(shenhaiyangthu) #1
# 回测引擎:每日数据处理函数,每天执行一次
def m19_handle_data_bigquant_run(context, data):
    # 按日期过滤得到今日的预测数据
    ranker_prediction = context.ranker_prediction[
        context.ranker_prediction.date == data.current_dt.strftime('%Y-%m-%d')]
    print('%s'%data.current_dt.strftime('%Y-%m-%d'))

    # 1. 资金分配
    positions = {e.symbol: p.amount * p.last_sale_price
                 for e, p in context.perf_tracker.position_tracker.positions.items()}

    # 2. 生成卖出订单:对持仓的股票,按机器学习算法预测的排序末位淘汰
    equities = {e.symbol: e for e, p in context.perf_tracker.position_tracker.positions.items()}
    #print('ranker_prediction%s'%ranker_prediction.instrument[:10])
    print('equities%s'%equities)
    for e, p in context.perf_tracker.position_tracker.positions.items():
        print('%s'%e)
        print('%s'%p)
    instruments = list(reversed(list(ranker_prediction.instrument[ranker_prediction.instrument.apply(
            lambda x: x in equities and not context.has_unfinished_sell_order(equities[x]))])))
    print('rank order for sell %s' % instruments)
    for instrument in instruments:
        context.order_target(context.symbol(instrument), 0)
        context.stocks_to_sell += 1
    print('stocks_to_sell %d' % context.stocks_to_sell)

    # 3. 生成买入订单:按机器学习算法预测的排序,买入前面的stock_count只股票
    cash_for_buy = context.portfolio.cash
    buy_instruments = []
    if context.is_init == 0 and context.stocks_to_sell > 0:
        buy_instruments = list(ranker_prediction.instrument[:context.stocks_to_sell])
        print('hello2')
        cash = cash_for_buy / context.stocks_to_sell
        print('rank order for buy %s' % buy_instruments)
    if context.is_init == 1 and context.run_times == 20:
        buy_instruments = list(ranker_prediction.instrument[:context.stock_count])
        context.is_init = 0
        print('is_init: %d'%context.is_init)
        cash = cash_for_buy / context.stock_count
        print('rank order for buy %s' % buy_instruments)

    max_cash_per_instrument = context.portfolio.portfolio_value * context.max_cash_per_instrument
    context.run_times += 1
    for i, instrument in enumerate(buy_instruments):
        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)
            print('buy %s'% context.symbol(instrument))
            context.stocks_to_sell = 0
            print('buy %d'% context.stocks_to_sell)


# 回测引擎:准备数据,只执行一次
def m19_prepare_bigquant_run(context):
    pass

# 回测引擎:初始化函数,只执行一次
def m19_initialize_bigquant_run(context):
    # 加载预测数据
    context.ranker_prediction = context.options['data'].read_df()

    # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
    # 预测数据,通过options传入进来,使用 read_df 函数,加载到内存 (DataFrame)
    # 设置买入的股票数量,这里买入预测股票列表排名靠前的5只
    context.stock_count = 5
    # 每只的股票的权重,如下的权重分配会使得靠前的股票分配多一点的资金,[0.339160, 0.213986, 0.169580, ..]
    #context.stock_weights = T.norm([1 / math.log(i + 2) for i in range(0, stock_count)])
    context.stock_weights = [0.2,0.2,0.2,0.2,0.2]
    # 设置每只股票占用的最大资金比例
    context.max_cash_per_instrument = 1
    context.options['hold_days'] = 5
    context.is_init = 1
    context.run_times = 0
    context.stocks_to_sell = 0
    print('init')

在买入和卖出各一次之后,再次买入 第二天看到的股票仓位还是空的


(iQuant) #2

您好,收到您的提问,已提交给策略工程师,会尽快给您答复。


(达达) #3

在第一次卖出的当日并没有触发买入,因此卖出后当日收盘时的持仓股票为空


(shenhaiyangthu) #4

我有打印一些日志,卖出之后第二天有买入的,但这些买入的没有记录在持仓里面,导致后面卖出失败


(iQuant) #5

请检查一下是否买入成功,有时候停牌或者是涨停是无法买入的