欢迎访问369期货网 369会员登录 注册

当前位置: 主页 > 期货量化

量化交易小技巧 -01- 量化下单的时候如何避免重复信号导致重复下单

时间:2025-10-14 16:07|来源:369期货网|作者:369期货网|点击:
之前有个朋友问信号重复出现怎么解决,这个问题,还真的是把我困扰到了,我以为这是个基础的问题来着。

毕竟我之前写的代码就有避免这个问题的细节展示。
图片
看过我之前写的代码的朋友应该有注意到,我的买卖都是有单独的列表去展示读取,这样就能保证唯一性,不会重复下单。


一、事前:订单去重键(Order Key)

为每一条下单指令生成全局唯一标识,下单前先看这个 Key 是否已经存在推荐做法:

策略ID、交易标的、买卖方向、下单价格、时间戳这 5 个信息先拼成一个字符串,再对这个字符串做一次哈希(如 MD5、SHA256 等),得到一个固定长度、几乎不会重复的“指纹”。
这个指纹就是所谓的 订单去重键(order_key),用来唯一标识这一次下单请求

如:

    import hashlib, timedef make_order_key(strategy, symbol, side, price):    raw = f"{strategy}_{symbol}_{side}_{price}_{int(time.time()*1000)}"    return hashlib.md5(raw.encode()).hexdigest()

    存储:

    把已成功的 order_key写进Redis Set(过期时间>交易所撮合延迟),下单前用SISMEMBER判断:

      if redis_client.sismember("order_keys", order_key):    return None        # 已存在,跳过


      二、事中:本地订单簿同步(Order Book Sync)

      即使 Key 不重复,网络重传或交易所 Session 复用也可能造成重单。因此要把“已报“状态保存在本地,并在任何下单动作前强制刷新。

      典型流程:

      1.下单前通过 REST 轮询或 WebSocket 订阅把订单簿拉到本地内存/数据库。

      2.用(symbol, client_order_id)做唯一索引,若已存在且状态为 NEW/PARTIALLY_FILLED ,则拦截。

      3.下单后立即把这条记录写进本地表,并标记状态PENDING等收到回报再更新。

        def submit_order(symbol, price, qty, client_oid):    if local_order_repo.exists(symbol, client_oid):        return "DUPLICATE"    order_id = exchange_api.place_order(symbol, price, qty, client_oid)    local_order_repo.insert(order_id, symbol, client_oid, "PENDING")


        三、事后:幂等重试 +超时回滚

        即便本地已判重,仍可能因 下单后未收到回报 而误判为失败并重试。需要幂等重试策略:

        图片
          def safe_place_order(params):    oid = params["client_oid"]    if order_repo.get_status(oid) in ["NEW", "PENDING"]:        return order_repo.get_exchange_oid(oid)    try:        eoid = exchange.place_order(**params)        order_repo.record(oid, eoid, "PENDING")        return eoid    except NetworkError:        # 网络抖动,先查        return exchange.query_order(oid)


          四、附加手段

          数据库唯一索引:在 MySQL里给 client_order_id 建唯一索引,兜底防重。

          滑点保护:连续 N 秒内只允许同方向同价位一单,减少重复信号

          日志审计:所有下单、回报、查询写入 Kafka,实时消费做幂等校验。

          有其他问题的可以评论区留言,这边看到就会解答,如果问题简单就会直接答复,问的多的会举例说明。



          编辑推荐

          Copyright © 2024-2025 成都宁时科技有限公司 版权所有

          蜀ICP备2022023994号