重置订单 ID 序列
订单 ID 序列由 TWS 维护。一般开发不需要重置它,只要程序正确保存 nextValidId() 返回值,并在每次下单后递增即可。
重置订单 ID 序列只适合少数场景,例如本地模拟账户长期测试后订单编号变得很大,且你确认没有任何活动 API 订单需要继续管理。
什么时候不要重置
Section titled “什么时候不要重置”| 场景 | 原因 |
|---|---|
| 有未完成 API 订单 | 重置后容易造成编号混乱。 |
| 多个 API 客户端正在连接 | 不同客户端可能仍在使用旧序列。 |
| 程序依赖历史订单 ID | 重置会破坏你的本地映射。 |
| 实盘账户 | 没有充分理由不要动。 |
订单编号变大本身不是问题。orderId=100001 和 orderId=1 对 API 来说没有高低优劣,只要它可用且不冲突即可。
一般处理方式
Section titled “一般处理方式”正常程序应该这样管理订单 ID:
def nextValidId(self, orderId: int) -> None: self.next_order_id = orderId
def submit_order(self, contract, order) -> None: order_id = self.next_order_id self.placeOrder(order_id, contract, order) self.next_order_id += 1只要这样做,订单 ID 是 1 还是 100001 通常都不重要。
在模拟账户里确实要重置前,先确认:
| 检查项 | 说明 |
|---|---|
| 没有未完成订单 | TWS 订单监控里没有 API 提交后仍活跃的订单。 |
| 程序已断开连接 | 关闭所有 API 客户端。 |
| 本地状态已清理 | 不再使用旧的订单 ID 映射。 |
| 明确是模拟环境 | 实盘环境不要为了“数字好看”重置。 |
如果只是担心订单 ID 太大,不需要重置。让 TWS 继续维护序列,程序按 nextValidId() 返回值使用即可。
重置后要做什么
Section titled “重置后要做什么”重置后重新连接 TWS,再等待新的 nextValidId():
app.connect("127.0.0.1", 7497, clientId=98200)# 等待 nextValidId(orderId),不要沿用旧变量。不要把重置前保存的 next_order_id 继续拿来下单。
文档示例不自动重置订单序列。重置会改变后续订单示例的编号环境,适合在 TWS 设置界面确认没有活动 API 订单后再操作。
reqIds(-1) 能正常返回下一个有效 ID;如果需要确认重置是否生效,重置后再次运行同样脚本即可。
CONNECTED=TrueINITIAL_NEXT_VALID_ID=1REQ_IDS_SENT=TrueREQUESTED_NEXT_VALID_ID_RECEIVED=TrueREQUESTED_NEXT_VALID_ID=1ALL_IDS=1,1NON_INFO_ERROR_COUNT=0如果重置后仍然返回较大的编号,通常说明 TWS 仍然认为有历史或活动 API 订单需要保持序列安全。此时不要强行依赖某个固定数字,继续按返回值使用即可。