跳转到内容

读取导出的日志

导出日志后,不建议从第一行开始硬读。TWS / IB Gateway 日志通常很长,而且不同版本的格式会有差异。更有效的方法是先确定问题时间,再按请求编号和订单编号把日志、程序输出、错误回调和界面状态对齐。

阅读日志的目标不是“看懂每一个字段”,而是回答几个关键问题:程序有没有发出请求,TWS / IB Gateway 有没有收到,请求参数是否合理,后续有没有返回数据、状态或错误。

开始读日志前,先把这三份信息放在一起:

信息用途
导出的 API 日志查看 API 程序和 TWS / IB Gateway 之间的通信
程序控制台输出查看你的代码收到哪些回调和异常
问题发生时间在日志里缩小搜索范围

如果问题和订单有关,再准备订单状态信息;如果问题和行情有关,再准备合约信息、交易所、行情权限和请求参数。

先不要搜索方法名,先定位时间:

  1. 找到问题发生的日期。
  2. 找到问题发生的大概时间,例如 10:25:30
  3. 往前看 1 到 3 分钟,确认连接、请求和错误是否都在这一段。
  4. 往后看 1 到 3 分钟,确认有没有迟到的回调或后续错误。

很多 API 问题不是“没有返回”,而是返回比你预期慢、返回到了另一个 reqId、或者先返回了错误再返回结束信号。只看最后一行很容易误判。

API 日志通常会体现消息方向,但具体文字和符号会因版本而不同。阅读时只需要区分两类:

方向含义
程序发往 TWS / IB Gateway你的代码调用了某个请求或下单方法
TWS / IB Gateway 返回给程序平台返回数据、状态、错误或结束信号

排查时先找“发出去的请求”,再找“对应的返回”。如果只有请求没有返回,问题可能在权限、参数、连接状态、pacing 限制或回调处理;如果连请求都看不到,先检查代码是否真的执行到了调用处。

不同接口要抓不同字段:

字段常见位置排查作用
clientId连接阶段、API 日志文件名或日志内容区分哪个 API 客户端发出请求
reqId行情、历史数据、合约查询、scanner 等请求把请求和返回数据对应起来
orderId下单、改单、撤单、订单状态把订单操作和订单回调对应起来
conId合约详情、行情、订单判断是否请求到了正确合约
errorCode错误回调或日志错误行对照错误码章节判断原因
时间戳每一段日志判断先后顺序和是否延迟

新手最容易忽略的是 reqIdorderId。TWS API 是异步回调模型,不能只按代码调用顺序理解返回结果;你要用编号把每一组请求和回调串起来。

行情、历史 K 线和合约查询通常都围绕 reqId 排查:

  1. 找到你程序发出的请求。
  2. 记录请求对应的 reqId
  3. 搜索同一个 reqId 后续返回。
  4. 看是否出现错误码、权限提示、pacing 提示或结束回调。

如果请求发出后没有数据,先不要马上判断接口不可用。常见原因包括合约定义不够明确、行情权限不足、市场未开盘、请求参数不符合限制、请求频率太高,或者程序没有正确处理回调。

订单问题通常要同时看 orderId、错误码和订单状态:

  1. 找到 placeOrder() 对应的发送记录。
  2. 记录 orderId
  3. 查找同一个 orderIdopenOrder()orderStatus()execDetails() 或错误记录。
  4. 对照 TWS 界面的订单状态。

订单日志不要只看是否有错误码。很多订单会先返回 PreSubmittedSubmittedCancelledFilled 等状态,再出现成交或撤单信息。还有一些风控、价格、权限、交易时段问题,会在 TWS 界面和错误回调里同时出现。

连接类问题先看时间线:

现象重点检查
连接不上端口、同机连接限制、可信 IP、TWS 是否已登录
连接后马上断开clientId 冲突、API 设置、网络、TWS 重启
请求偶尔失败是否断线重连、是否错过重新订阅、是否触发 pacing
多程序互相影响多个程序是否使用同一个 clientId

如果日志里能看到连接成功,但程序里没有收到回调,要检查代码是否启动了 reader 线程、事件循环或消息处理逻辑。Python、Java、C#、C++ 在这部分写法不同,但核心都是要持续读取 TWS 返回消息。

建议在代码里把关键回调也打印出来,然后和日志对照。最少要打印:

connected clientId=910
request reqId=1001 type=historicalData symbol=AAPL
error reqId=1001 code=XXXX message=...
historicalData reqId=1001 time=...
historicalDataEnd reqId=1001

上面是排查输出格式示例,不要求一模一样。重点是让日志中的 reqIdorderId、时间和你的程序输出能互相对应。

看到请求就以为一定会返回数据

Section titled “看到请求就以为一定会返回数据”

请求发出只说明程序调用了 API,不代表请求合法、权限足够、合约明确或数据存在。还要继续看后续错误和结束信号。

API 日志底层可能以协议消息、字段序列或平台字段名记录,不一定直接显示 Python 方法名。你要看请求编号、合约、订单编号、错误码和时间顺序。

复杂问题可能需要同时看 API Logs 和 TWS / Gateway Logs。API 日志能看通信,平台日志能看登录、连接、数据农场和客户端状态。

TWS 中文界面的提示有时会简化含义。排查时建议保留英文错误码、英文原文、日志片段和中文解释,不要只保存翻译后的界面文字。

阅读导出日志时,按这个顺序最省时间:

  1. 确认日志日期正确。
  2. 找到问题发生时间。
  3. 找到连接记录和 clientId
  4. 找到请求记录。
  5. 记录 reqIdorderId
  6. 搜索同一编号的返回和错误。
  7. 对照程序输出。
  8. 对照 TWS / IB Gateway 界面状态。
  9. 把结论整理成最小复现说明。

这样读日志,不需要你一次性掌握全部 TWS API 协议细节,也能把大多数“为什么没返回”“为什么被拒单”“为什么和代码输出不一致”的问题缩小到具体原因。