IB paper手册

IB Paper Trading 手册 + 延迟测试脚本

背景:IB 无官方订单延迟 benchmark,需自测 order-to-ack 基线。本文含 Paper 账户开通/使用手册 + 完整测试脚本。


📘 IB Paper Trading 手册

1. 为什么需要账号(无公开测试端点)

你的脚本 → 本地 TWS/IB Gateway(必须登录账号)→ IBKR 服务器

API 没有独立公开端点,连接必须经过本地运行的 TWS/Gateway,且 Gateway 必须用账号登录。

2. Paper 账户开通流程

  1. 官网 interactivebrokers.com 注册 Individual 账户
  2. 登录 Account Management → 开启 Paper Trading(无需真实入金)
  3. 模拟资金:100 万美元
  4. 本地安装 TWS 或 IB Gateway,登录时选择 Paper 环境

3. 端口与连接参数

环境端口说明
Paper Trading7496模拟环境,可随意测试
Live 实盘7497真实账户(/ 4001 加密)
# Gateway 启动参数
ibgateway  # 登录时选 Paper 环境;API 设置勾选 Enable ActiveX and Socket Clients
# 连接 clientId 任意(0-31),脚本断开后注意释放

4. 各指标在 Paper 的可信度

指标Paper 可信度原因
order-to-ack✅ 高提交→IBKR 确认的处理路径与真实账户几乎一致,延迟量级可信
order-to-fill⚠️ 低Paper 成交由模拟引擎撮合(近似盘口),成交速度参考意义弱于真实市场

正确用法:Paper 测 order-to-ack 拿延迟基线(p50/p95);order-to-fill 和滑点用真实小仓位测(实盘策略日志直接可用)。


🧪 order-to-ack 延迟测试脚本

方案 A:ib_insync(推荐,简洁)

from ib_insync import IB, Stock, LimitOrder
import time, statistics, asyncio

times = []  # (submitted, ack) 秒

ib = IB()
ib.connect('127.0.0.1', 7496, clientId=1, timeout=10)

contract = Stock('AAPL', 'SMART', 'USD')
order = LimitOrder('BUY', 100, 100.0)  # 远离市价的限价单,不会成交

for i in range(50):
    t_submit = time.perf_counter()
    trade = ib.placeOrder(contract, order)
    # 等待 orderStatus 回调到达 Submitted
    ib.sleep(0.5)
    t_ack = time.perf_counter()
    times.append((t_ack - t_submit) * 1000)  # ms
    ib.cancelOrder(order)
    ib.sleep(0.2)

ib.disconnect()

p50 = statistics.median(times)
p95 = sorted(times)[int(len(times) * 0.95) - 1]
print(f"order-to-ack: p50={p50:.1f}ms  p95={p95:.1f}ms  n={len(times)}")

方案 B:原生 ibapi(无第三方依赖)

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
from ibapi.order import Order
import time, threading, statistics

class LatencyTest(EWrapper, EClient):
    def __init__(self):
        EClient.__init__(self, self)
        self.times = []
        self.t_submit = 0
        self.pending = 0

    def orderStatus(self, orderId, status, filled, remaining,
                    avgFillPrice, permId, parentId, lastFillPrice,
                    clientId, whyHeld, mktCapPrice):
        if status == 'Submitted':
            self.times.append((time.perf_counter() - self.t_submit) * 1000)
            self.pending -= 1
            if self.pending <= 0:
                self.disconnect()

test = LatencyTest()
test.connect('127.0.0.1', 7496, clientId=2)
threading.Thread(target=test.run, daemon=True).start()

contract = Contract()
contract.symbol = 'AAPL'
contract.secType = 'STK'
contract.exchange = 'SMART'
contract.currency = 'USD'

order = Order()
order.action = 'BUY'
order.orderType = 'LMT'
order.totalQuantity = 100
order.lmtPrice = 100.0  # 远离市价,不会成交

test.pending = 50
for i in range(50):
    test.t_submit = time.perf_counter()
    test.placeOrder(1000 + i, contract, order)
    time.sleep(0.1)

import time as t
while test.isConnected():
    t.sleep(0.1)

times = test.times
print(f"order-to-ack: p50={statistics.median(times):.1f}ms  "
      f"p95={sorted(times)[int(len(times)*0.95)-1]:.1f}ms  n={len(times)}")

测试要点

  1. 挂远离市价的限价单(如 AAPL 挂 100.0)——确保不成交,只测 ack 路径
  2. 50 次以上取 p50/p95,单次测量无意义
  3. 每次测完 cancelOrder 释放
  4. 用 paper(7496)测,不碰实盘
  5. 如果测 order-to-fill:用真实小仓位,从策略日志的 placeOrder 时间戳 vs execDetails 时间戳

📈 结果解读

p50 order-to-ack含义
< 10 ms网络+IBKR 处理良好,接近本地最优
10-50 ms正常量级(跨区域网络为主)
100 ms+跨国网络 RTT 主导,延迟敏感策略需考虑服务器就近部署(AWS/VPS 就近 IBKR 接入点)

📎 来源:本文基于 IBKR 官方文档(TWS API Guide:连接端口 7496/7497;Paper Trading 说明)与社区延迟测量实践整理(2026-08-06)。IB 官方未发布延迟 benchmark,数值需自测确认。