回测的过程中,偶尔会遇到开仓价不在范围内。
具体看代码,backtesting.py, class BacktestingEngine, def cross_limit_order(self):

        # Check whether limit orders can be filled.
        long_cross = (
            order.direction == Direction.LONG
            and order.price >= long_cross_price
            and long_cross_price > 0
        )

        short_cross = (
            order.direction == Direction.SHORT
            and order.price <= short_cross_price
            and short_cross_price > 0
        )

        if not long_cross and not short_cross:
            continue

在回测的过程中,有时候会遇到order.price < long_cross_priceorder.price > short_cross_price的情况, order.status有可能一直是未成交Status.NOTTRADED的状态,可能导致之后的交易都无法完成。

现优化思路如下,让开仓价在当前new_bar的范围内:

def cross_limit_order(self):
    """
    Cross limit order with last bar/tick data.
    """
    if self.mode == BacktestingMode.BAR:
        long_cross_price = self.bar.low_price
        short_cross_price = self.bar.high_price
        long_best_price = self.bar.open_price
        short_best_price = self.bar.open_price
    else:
        long_cross_price = self.tick.ask_price_1
        short_cross_price = self.tick.bid_price_1
        long_best_price = long_cross_price
        short_best_price = short_cross_price

    for order in list(self.active_limit_orders.values()):
        # Push order update with status "not traded" (pending).

        if order.status == Status.SUBMITTING:
            order.status = Status.NOTTRADED
            self.strategy.on_order(order)

        '''
        增加逻辑,回测的时候,如果在下一个bar中无法成交,则改报价。 
        让开仓价在当前new_bar的范围内 
        start
        '''
        # 如果报价比long_cross_price小,那么改报价
        if order.direction == Direction.LONG and order.price < long_cross_price:
            order.price = long_cross_price

        # 如果报价比long_cross_price小,那么改报价
        if order.direction == Direction.SHORT and order.price > short_cross_price:
            order.price = short_cross_price
        '''
        end
        '''

        # Check whether limit orders can be filled.
        long_cross = (
            order.direction == Direction.LONG
            and order.price >= long_cross_price
            and long_cross_price > 0
        )

        short_cross = (
            order.direction == Direction.SHORT
            and order.price <= short_cross_price
            and short_cross_price > 0
        )

        if not long_cross and not short_cross:
            continue

...
...
...