求救 股票买卖问题

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

(h2476) #1

股票每天买两种,但是如果有一只达到最大限额就只会交易另一只股票,怎么改才能交易排序的第三只股票?


(Daviddddddd) #2

我记得trade模块没有对某一支股票总价值的限制吧,只是在每一次交易的时候,每支股票只能使用不超过当天可交易金额的20%(可以自己手动设置)。也就是说,同一只股票,可以今天买,明天也买呀。或者您可以把您的策略发一下,我来帮你看看你的困惑是什么。


(h2476) #3
def m1_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只
    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.max_cash_per_instrument = 0.2
    context.hold_days = 5

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

    # 1. 资金分配
    # 平均持仓时间是hold_days,每日都将买入股票,每日预期使用 1/hold_days 的资金
    # 实际操作中,会存在一定的买入误差,所以在前hold_days天,等量使用资金;之后,尽量使用剩余资金(这里设置最多用等量的1.5倍)
    is_staging = context.trading_day_index < context.hold_days # 是否在建仓期间(前 hold_days 天)
    cash_avg = context.portfolio.portfolio_value / context.hold_days
    cash_for_buy = min(context.portfolio.cash, (1 if is_staging else 1.5) * cash_avg)
    cash_for_sell = cash_avg - (context.portfolio.cash - cash_for_buy)
    positions = {e.symbol: p.amount * p.last_sale_price
                 for e, p in context.perf_tracker.position_tracker.positions.items()}

    # 2. 生成卖出订单:hold_days天之后才开始卖出;对持仓的股票,按StockRanker预测的排序末位淘汰
    if not is_staging and cash_for_sell > 0:
        equities = {e.symbol: e for e, p in context.perf_tracker.position_tracker.positions.items()}
        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)
            cash_for_sell -= positions[instrument]
            if cash_for_sell <= 0:
                break

    # 3. 生成买入订单:按StockRanker预测的排序,买入前面的stock_count只股票
    buy_cash_weights = context.stock_weights
    buy_instruments = list(ranker_prediction.instrument[:len(buy_cash_weights)])
    max_cash_per_instrument = context.portfolio.portfolio_value * context.max_cash_per_instrument
    for i, instrument in enumerate(buy_instruments):
        cash = cash_for_buy * 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)

就随便加入一个回测模块,主函数里的**#3**:max_cash_per_instrument=账户总价值*占用最大资金权重,然后计算这一支股票的当日可交易的cash,cash>0才继续交易,否则就交易其他股票,buy_instruments里已固定了5只,也就是说只会交易四只,这时候本来要用的资金就闲置下来了,所以这时候我想获取一下buy_instruments外排序的下一只,该怎么改?


(h2476) #4

有没有什么api可以直接获取的?


(Daviddddddd) #5

明白了!要获得buy_instruments排序外的其他股票,最简单的就是
remain_instruments = list(ranker_prediction.instrument[len(buy_cash_weights):])
在这个基础上,就可以根据你希望的交易规则,如权重,数量等,交易这些股票啦


(Daviddddddd) #6

事实上,整个排好序的股票,是存储在ranker_prediction.instrument里面的。
示例中我们使用了排名靠前的几只股票来交易:
buy_instruments = list(ranker_prediction.instrument[:len(buy_cash_weights)])
我们当然也可以根据自己的需要来设定想要的交易方式,比如股票个数等。