Home >  > VNPY源码(七)限价单与停止单

VNPY源码(七)限价单与停止单

0

这是VNPY中的一个难点,特别是停止单,相信很多人学了vnpy很久,还是没有搞懂。

一、什么是限价单?什么是停止单?
我们先来看看官方的回答吧:
问:请问backtesting里的cross_limit_order和cross_stop_order什么意思?是干什么用的?
答:撮合限价单委托,撮合本地停止单(条件单)委托。讲最新的行情K线或者TICK和策略之前下达的所有委托进行检查,如果能够撮合成交,则返回并记录数据。

请问你看得懂吗?反正我是看不懂。下面我试着来解释一下:

1.限价单
举个例子,在限价单下:

Long170:表示如果价格低于170,我们就买入。
如何判断下一个bar的是否低于170呢?我们只要看下一个bar的最低值是否低于170.

Long70:表示如果价格低于70,我们就买入。

2.停止单:
在停止单下:
Long170:表示如果价格高于170,我们就买入(突破买入)。
Long70:表示如果价格涨过了70,我们就买入。

3.Long 和Short
但是也要注意,并不是说Long就代表买入,

你持有空仓,平仓是Long, 你多头建仓,也是Long.
你持有多仓,平仓是short,你空头建仓,也是short。

举个例子:short170的意思,是我们打算在170的价格卖出。

二、cross_limit_order
通过判断限价与当前价,调用策略的on_order、on_trade函数,并更新仓位。

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)

        # Check whether limit orders can be filled.这里判断是否成交。
        long_cross = (
            order.direction == Direction.LONG 
            and order.price >= long_cross_price #目的是要低于限价买入,long_cross_price 等于bar的最低价,这行代码反过来看,就是bar的最低价小于我们设定的限价,所以要买入。
            and long_cross_price > 0
        )

        short_cross = (
            order.direction == Direction.SHORT 
            and order.price <= short_cross_price  #目的是高于限价卖出,反过来看,bar的最高价(short_cross_price)大于我们的限价了。
            and short_cross_price > 0
        )

        if not long_cross and not short_cross:
            continue

        # Push order udpate with status "all traded" (filled).
        order.traded = order.volume
        order.status = Status.ALLTRADED
        self.strategy.on_order(order)   #调用策略的on_order

        self.active_limit_orders.pop(order.vt_orderid)

        # Push trade update
        self.trade_count += 1

        if long_cross:
            trade_price = min(order.price, long_best_price)  #目的是要低于限价买入,如果开盘价比限价低,当然是按开盘价买入,如果开盘价比限价高,但是那个bar的最低价是小于我们的限价的,所以价格会走到我们的限价的价位,理论成交价格也是限价。
            pos_change = order.volume
        else:
            trade_price = max(order.price, short_best_price)
            pos_change = -order.volume

        trade = TradeData(
            symbol=order.symbol,
            exchange=order.exchange,
            orderid=order.orderid,
            tradeid=str(self.trade_count),
            direction=order.direction,
            offset=order.offset,
            price=trade_price,
            volume=order.volume,
            time=self.datetime.strftime("%H:%M:%S"),
            gateway_name=self.gateway_name,
        )
        trade.datetime = self.datetime

        self.strategy.pos += pos_change
        self.strategy.on_trade(trade)

        self.trades[trade.vt_tradeid] = trade

为了便于理解,我们只看Bar部分吧。

1.active_limit_orders
它的数据是在send_limit_order这个函数中生成的。

def send_limit_order(
    self, 
    direction: Direction,
    offset: Offset,
    price: float, 
    volume: float
):
    """"""
    self.limit_order_count += 1
    
    order = OrderData(
        symbol=self.symbol,
        exchange=self.exchange,
        orderid=str(self.limit_order_count),
        direction=direction,
        offset=offset,
        price=price,
        volume=volume,
        status=Status.SUBMITTING,
        gateway_name=self.gateway_name,
    )
    order.datetime = self.datetime

    self.active_limit_orders[order.vt_orderid] = order  #存入active_limit_orders这个字典
    self.limit_orders[order.vt_orderid] = order         #存入limit_orders这个字典

    return order.vt_orderid

三、cross_stop_order
通过判断限价与当前价,调用策略的on_stop_order、on_order、on_trade函数。

这里就和上面的不一样:

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

    for stop_order in list(self.active_stop_orders.values()):
        # Check whether stop order can be triggered.
        long_cross = (
            stop_order.direction == Direction.LONG 
            and stop_order.price <= long_cross_price    #目的是要高于限价买入,这里相当于bar的最高价(long_cross_price)大于我们的限价了
        )

        short_cross = (
            stop_order.direction == Direction.SHORT 
            and stop_order.price >= short_cross_price   #目的是要低于限价卖出(止损),这里相当于bar的最低价(short_cross_price)小于我们的限价了
        )

        if not long_cross and not short_cross:
            continue

        # Create order data.
        self.limit_order_count += 1

        order = OrderData(
            symbol=self.symbol,
            exchange=self.exchange,
            orderid=str(self.limit_order_count),
            direction=stop_order.direction,
            offset=stop_order.offset,
            price=stop_order.price,
            volume=stop_order.volume,
            status=Status.ALLTRADED,
            gateway_name=self.gateway_name,
        )
        order.datetime = self.datetime

        self.limit_orders[order.vt_orderid] = order     #将order存入了limit_orders字典


        # Create trade data.
       if long_cross:
            trade_price = max(stop_order.price, long_best_price)  #如果开盘价比限价高,当然是按开盘价买入,如果低,当然按限价买入。
            pos_change = order.volume
        else:
            trade_price = min(stop_order.price, short_best_price)
            pos_change = -order.volume

四、图形理解

本文暂无标签

发表评论

*

*