VeighNa量化社区
你的开源社区量化交易平台
Member
avatar
加入于:
帖子: 141
声望: 57

0.修改OrderData如下:

@dataclass
class OrderData(BaseData):
    """
    Order data contains information for tracking lastest status 
    of a specific order.
    """

    symbol: str
    exchange: Exchange
    orderid: str

    type: OrderType = OrderType.LIMIT
    direction: Direction = Direction.NET
    offset: Offset = Offset.NONE
    price: float = 0
    volume: float = 0
    traded: float = 0
    status: Status = Status.SUBMITTING
    datetime: datetime = None

    cancel_time: str = ""
    def __post_init__(self):
        """"""
        self.vt_symbol = f"{self.symbol}_{self.exchange.value}/{self.gateway_name}"
        self.vt_orderid = f"{self.gateway_name}_{self.orderid}"
        #未成交量
        self.untrade = self.volume - self.traded

1.策略init初始化参数

        #状态控制初始化
        self.chase_long_trigger = False
        self.chase_sell_trigger = False
        self.chase_short_trigger = False
        self.chase_cover_trigger = False  
        self.cancel_status = False
        self.last_vt_orderid = ""
        self.long_trade_volume = 0
        self.short_trade_volume = 0
        self.sell_trade_volume = 0
        self.cover_trade_volume = 0 
        self.chase_interval   =    10    #拆单间隔:秒

get_position_detail参考这个帖子 https://www.vnpy.com/forum/topic/2167-cha-xun-cang-wei-chi-cang-jun-jie-wei-cheng-jiao-wei-tuo-dan-yi-ge-han-shu-gao-ding

2.on_tick里面的代码如下

from vnpy.trader.object import TickData, BarData, TradeData, OrderData,Status
    def __init__(self, strategy_engine: StrategyEngine, strategy_name: str,vt_symbols: List[str], setting: dict):
        """
        """
        super().__init__(strategy_engine, strategy_name, vt_symbols, setting)
        #撤单条件选择,默认使用超时撤单,为False使用突破价格范围撤单
        self.cancel_timer_trigger = True
    def on_tick(self, tick: TickData):
        active_orders = self.get_position_detail(chase_vt_symbol).active_orders
        vt_orderid = ""
        if active_orders:
            #委托完成状态
            order_finished = False
            self.last_vt_orderid = list(active_orders.items())[0][0]         #委托单vt_orderid
            active_order:OrderData = list(active_orders.items())[0][1]      #委托单类 
            if self.cancel_timer_trigger:
                #撤单触发条件,超时撤单
                trigger_status = (raw_tick.datetime - active_order.datetime).total_seconds() > self.chase_interval
            else:
                price_tick = self.get_contract_detail(chase_vt_symbol).price_tick
                #突破价格范围撤单
                trigger_status = not active_order.price - price_tick * self.cancel_trigger_payup <= raw_tick.last_price <= active_order.price + price_tick * self.cancel_trigger_payup
            #开平仓追单,部分交易没有平仓指令(Offset.NONE)
            if active_order.offset in (Offset.NONE,Offset.OPEN):
                if active_order.direction == Direction.LONG:
                    self.long_trade_volume = active_order.untrade
                    if trigger_status and self.long_trade_volume > 0 and (not self.chase_long_trigger) and self.last_vt_orderid:
                        #撤销之前发出的未成交订单
                        self.cancel_order(self.last_vt_orderid)
                        self.chase_long_trigger = True
                elif active_order.direction == Direction.SHORT:
                    self.short_trade_volume = active_order.untrade    
                    if trigger_status and self.short_trade_volume > 0 and (not self.chase_short_trigger) and self.last_vt_orderid:  
                        self.cancel_order(self.last_vt_orderid)
                        self.chase_short_trigger = True
            #平仓追单
            elif active_order.offset in (Offset.CLOSE,Offset.CLOSETODAY,Offset.CLOSEYESTERDAY):
                if active_order.direction == Direction.SHORT: 
                    self.sell_trade_volume = active_order.untrade
                    if trigger_status and self.sell_trade_volume > 0 and (not self.chase_sell_trigger) and self.last_vt_orderid: 
                        self.cancel_order(self.last_vt_orderid)
                        self.chase_sell_trigger = True                                                    
                if active_order.direction == Direction.LONG:
                    self.cover_trade_volume = active_order.untrade
                    if trigger_status and self.cover_trade_volume > 0 and (not self.chase_cover_trigger) and self.last_vt_orderid:                                                       
                        self.cancel_order(self.last_vt_orderid)
                        self.chase_cover_trigger = True   
        else:
            order_finished = True
            self.cancel_status = False
        #追单的委托单状态是正常的撤销状态则发出追单指令
        if self.get_order(self.last_vt_orderid) and self.get_order(self.last_vt_orderid).status == Status.CANCELLED:
            if self.chase_long_trigger:
                if order_finished:
                    self.buy(chase_vt_symbol,raw_tick.ask_price_1,self.long_trade_volume)
                    self.long_trade_volume = 0
                    self.chase_long_trigger = False  
                else:
                    self.cancel_surplus_order(list(active_orders))
            elif self.chase_short_trigger:
                if  order_finished:
                    self.short(chase_vt_symbol,raw_tick.bid_price_1,self.short_trade_volume)
                    self.short_trade_volume = 0
                    self.chase_short_trigger = False 
                else:
                    self.cancel_surplus_order(list(active_orders))
            elif self.chase_sell_trigger:
                if order_finished:
                    self.sell(chase_vt_symbol,raw_tick.bid_price_1,self.sell_trade_volume)
                    self.sell_trade_volume = 0
                    self.chase_sell_trigger = False                      
                else:
                    self.cancel_surplus_order(list(active_orders))
            elif self.chase_cover_trigger:
                if order_finished:
                    self.cover(chase_vt_symbol,raw_tick.ask_price_1,self.cover_trade_volume)
                    self.cover_trade_volume = 0
                    self.chase_cover_trigger = False
                else:
                    self.cancel_surplus_order(list(active_orders))
    #------------------------------------------------------------------------------------
    def cancel_surplus_order(self,orderids:list):
        """
        撤销剩余活动委托单
        """
        if not self.cancel_status:
            for vt_orderid in  orderids:
                self.cancel_order(vt_orderid)
            self.cancel_status = True
# template.py里面增加
    #------------------------------------------------------------------
    def get_order(self,vt_orderid:str) -> Union[OrderData,None]:
        """
        通过vt_orderid获取委托单
        """
        return self.cta_engine.get_order(vt_orderid) 
# cta_strategy\engine.py里面增加
    #------------------------------------------------------------------------------------
    def get_order(self,vt_orderid:str) -> Union[OrderData,None]:
        """
        通过vt_orderid获取委托单
        """
        self.main_engine.get_order(vt_orderid)
Administrator
avatar
加入于:
帖子: 4500
声望: 320

必须加精

Member
avatar
加入于:
帖子: 141
声望: 57

不要修改撤单和追单的判断条件哦,都是一个坑一个坑填起来的
description

Member
avatar
加入于:
帖子: 62
声望: 3

需要tick数据才能回测了。。。

Member
avatar
加入于:
帖子: 7
声望: 0

请问楼主大神,在on_tick里面,get_contract_tick(),这个方法在什么地方定义的?chase_vt_symbol这个变量也没有找到

Member
avatar
加入于:
帖子: 141
声望: 57

@信徒 改好了 你再看下

Member
avatar
加入于:
帖子: 59
声望: 4

on_tick函数内撤单追单详解,实盘在用的代码
mark

Member
avatar
加入于:
帖子: 59
声望: 4

最大的缺点就是:注释太少了
月总,能多加些注释么?

Member
avatar
加入于:
帖子: 7
声望: 0

@上弦之月
请问下月总,这个追单逻辑是有没有考虑带有停止单的情况?我的策略里有停止单,测试的时候每分钟都触发了一个停止单。

Member
avatar
加入于:
帖子: 2
声望: 1

赞一个

Member
avatar
加入于:
帖子: 141
声望: 57

信徒 wrote:

@上弦之月
请问下月总,这个追单逻辑是有没有考虑带有停止单的情况?我的策略里有停止单,测试的时候每分钟都触发了一个停止单。
追单都是直接发出去的,不用停止单多此一举

Member
avatar
加入于:
帖子: 4
声望: 1

想请教一下@上弦之月
查询仓位代码中:
def update_trade(self, trade: TradeData):
的最后两行为什么要注释掉?

    #self.long_pos = self.long_td + self.long_yd
    #self.short_pos = self.short_td + self.short_yd
Member
avatar
加入于:
帖子: 4
声望: 1

另外,查询仓位代码中:
update_order_request
的分离gateway_name和orderid
代码:
gateway_name, *split_orderid = vtorderid.split("")
这行为什么要改成这样?,原来是:gateway_name, orderid = vt_orderid.split(".")

Member
avatar
加入于:
帖子: 141
声望: 57

@lqx #self.long_pos = self.long_td + self.long_yd这里搞错了,update_orderrequest里面这样处理orderid是为了以后拼接多个""连接的orderid,现在看来没什么,我也懒的改了

Member
avatar
加入于:
帖子: 4
声望: 1

想再请教一下楼主@上弦之月,撤单与重新下单之间怎么保证原子操作,即,撤单失败,但是又重新下单了

Member
avatar
加入于:
帖子: 141
声望: 57

lqx wrote:

想再请教一下楼主@上弦之月,撤单与重新下单之间怎么保证原子操作,即,撤单失败,但是又重新下单了
撤单失败了,order_finished为False不会追单,运行self.cancel_surplus_order(list(working_order_dict))里面的代码再撤单一次。总之单子没撤完不会追单

Member
avatar
加入于:
帖子: 14
声望: 0

特别棒~!!支持月总~!

Member
avatar
加入于:
帖子: 25
声望: 0

太棒了。不过请教@上弦之月,为什么要把update_order函数活动委托定义中的【submitting】剔除?如果下单后时间间隔超过设置的10秒还没成交,那即使submitting的委托不也应该需要撤单吗?谢谢月总!

Member
avatar
加入于:
帖子: 141
声望: 57

@qk submitting是vnpy里面定义的委托状态,只需要处理交易所的未成交和部分成交状态委托单

Member
avatar
加入于:
帖子: 25
声望: 0

谢谢您亲自回复!

© 2015-2022 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号

沪公网安备 31011502017034号

【用户协议】
【隐私政策】
【免责条款】