VeighNa量化社区
你的开源社区量化交易平台 | vn.py | vnpy
Member
avatar
加入于:
帖子: 1
声望: 0

请教一下,

在TargetPosTemplate中,函数trade的定义如下:

def trade(self) -> None:
""""""
if not self.check_order_finished():
self.cancel_old_order()
else:
self.send_new_order()

请问在实盘(是实盘,和回测无关)中,假如我们是在bar的尺度上调用trade函数,能否在cancel_old_order之后再加上send_new_order?以达到撤单后立刻重新挂单的效果?如果可以,那么之前函数没有这么写的原因是什么?是怕陷入一些挂撤单的死循环吗?

感谢!

Super Moderator
avatar
加入于:
帖子: 77
声望: 8

TargetPosTemplate 中,trade 函数的设计是为了确保在调整目标仓位时,先撤销未完成的旧订单,然后再发送新订单。你提到的在 cancel_old_order 之后立刻调用 send_new_order 的想法是可行的,但需要谨慎处理,以避免潜在的问题。


1. 能否在 cancel_old_order 之后立刻调用 send_new_order

是的,可以在 cancel_old_order 之后立刻调用 send_new_order,以达到撤单后立刻重新挂单的效果。例如:

def trade(self) -> None:
    """执行交易逻辑"""
    if not self.check_order_finished():
        self.cancel_old_order()
        self.send_new_order()  # 撤单后立刻重新挂单
    else:
        self.send_new_order()

2. 为什么原函数没有这么写?

原函数没有在 cancel_old_order 之后立刻调用 send_new_order,主要是为了避免以下潜在问题:

1) 撤单和挂单的异步性

在实盘中,撤单和挂单是异步操作。撤单请求发出后,交易所可能需要一定时间才能处理完成。如果在撤单未完成时立刻挂单,可能会导致以下问题:

  • 撤单未完成,新订单可能无法成功挂出。
  • 如果撤单和新订单同时存在,可能会导致仓位管理混乱。

2) 死循环风险

如果在 cancel_old_order 之后立刻调用 send_new_order,而新订单又因为某些原因(如价格波动)无法立即成交,可能会导致策略不断撤单和挂单,陷入死循环。这种情况会显著增加交易成本和系统负载。

3) 交易所限制

某些交易所对撤单和挂单的频率有限制。频繁的撤单和挂单可能会触发交易所的风控机制,导致账户被限制交易。


3. 如何安全地实现撤单后立刻挂单?

如果你确实需要在撤单后立刻挂单,可以通过以下方式实现:

1) 等待撤单完成

cancel_old_order 之后,等待撤单完成后再调用 send_new_order。可以通过 on_order 回调函数监听撤单状态:

def on_order(self, order: OrderData) -> None:
    """委托单更新回调"""
    if order.status == Status.ALLTRADED or order.status == Status.CANCELLED:
        self.send_new_order()  # 撤单完成后重新挂单

2) 增加延迟

cancel_old_order 之后,增加一个短暂的延迟(如 1 秒),再调用 send_new_order,以避免撤单和挂单的冲突:

import time

def trade(self) -> None:
    """执行交易逻辑"""
    if not self.check_order_finished():
        self.cancel_old_order()
        time.sleep(1)  # 增加延迟
        self.send_new_order()
    else:
        self.send_new_order()

3) 限制撤单和挂单频率

通过计数器或时间戳限制撤单和挂单的频率,避免频繁操作:

def trade(self) -> None:
    """执行交易逻辑"""
    if not self.check_order_finished():
        self.cancel_old_order()
        if self.can_send_new_order():  # 检查是否满足挂单条件
            self.send_new_order()
    else:
        self.send_new_order()

4. 总结

  • cancel_old_order 之后立刻调用 send_new_order 是可行的,但需要谨慎处理异步性和死循环风险。
  • 原函数没有这么写,主要是为了避免撤单和挂单的冲突、死循环风险以及交易所限制。
  • 如果需要实现撤单后立刻挂单,可以通过等待撤单完成、增加延迟或限制频率等方式来确保安全。

希望以上解答对你有帮助!如果还有其他问题,欢迎继续讨论。

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

沪公网安备 31011502017034号

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