读取导出的日志
导出日志后,不建议从第一行开始硬读。TWS / IB Gateway 日志通常很长,而且不同版本的格式会有差异。更有效的方法是先确定问题时间,再按请求编号和订单编号把日志、程序输出、错误回调和界面状态对齐。
阅读日志的目标不是“看懂每一个字段”,而是回答几个关键问题:程序有没有发出请求,TWS / IB Gateway 有没有收到,请求参数是否合理,后续有没有返回数据、状态或错误。
先准备三份信息
Section titled “先准备三份信息”开始读日志前,先把这三份信息放在一起:
| 信息 | 用途 |
|---|---|
| 导出的 API 日志 | 查看 API 程序和 TWS / IB Gateway 之间的通信 |
| 程序控制台输出 | 查看你的代码收到哪些回调和异常 |
| 问题发生时间 | 在日志里缩小搜索范围 |
如果问题和订单有关,再准备订单状态信息;如果问题和行情有关,再准备合约信息、交易所、行情权限和请求参数。
从时间点开始找
Section titled “从时间点开始找”先不要搜索方法名,先定位时间:
- 找到问题发生的日期。
- 找到问题发生的大概时间,例如
10:25:30。 - 往前看 1 到 3 分钟,确认连接、请求和错误是否都在这一段。
- 往后看 1 到 3 分钟,确认有没有迟到的回调或后续错误。
很多 API 问题不是“没有返回”,而是返回比你预期慢、返回到了另一个 reqId、或者先返回了错误再返回结束信号。只看最后一行很容易误判。
API 日志通常会体现消息方向,但具体文字和符号会因版本而不同。阅读时只需要区分两类:
| 方向 | 含义 |
|---|---|
| 程序发往 TWS / IB Gateway | 你的代码调用了某个请求或下单方法 |
| TWS / IB Gateway 返回给程序 | 平台返回数据、状态、错误或结束信号 |
排查时先找“发出去的请求”,再找“对应的返回”。如果只有请求没有返回,问题可能在权限、参数、连接状态、pacing 限制或回调处理;如果连请求都看不到,先检查代码是否真的执行到了调用处。
不同接口要抓不同字段:
| 字段 | 常见位置 | 排查作用 |
|---|---|---|
clientId | 连接阶段、API 日志文件名或日志内容 | 区分哪个 API 客户端发出请求 |
reqId | 行情、历史数据、合约查询、scanner 等请求 | 把请求和返回数据对应起来 |
orderId | 下单、改单、撤单、订单状态 | 把订单操作和订单回调对应起来 |
conId | 合约详情、行情、订单 | 判断是否请求到了正确合约 |
errorCode | 错误回调或日志错误行 | 对照错误码章节判断原因 |
| 时间戳 | 每一段日志 | 判断先后顺序和是否延迟 |
新手最容易忽略的是 reqId 和 orderId。TWS API 是异步回调模型,不能只按代码调用顺序理解返回结果;你要用编号把每一组请求和回调串起来。
行情和历史数据日志怎么读
Section titled “行情和历史数据日志怎么读”行情、历史 K 线和合约查询通常都围绕 reqId 排查:
- 找到你程序发出的请求。
- 记录请求对应的
reqId。 - 搜索同一个
reqId后续返回。 - 看是否出现错误码、权限提示、pacing 提示或结束回调。
如果请求发出后没有数据,先不要马上判断接口不可用。常见原因包括合约定义不够明确、行情权限不足、市场未开盘、请求参数不符合限制、请求频率太高,或者程序没有正确处理回调。
订单日志怎么读
Section titled “订单日志怎么读”订单问题通常要同时看 orderId、错误码和订单状态:
- 找到
placeOrder()对应的发送记录。 - 记录
orderId。 - 查找同一个
orderId的openOrder()、orderStatus()、execDetails()或错误记录。 - 对照 TWS 界面的订单状态。
订单日志不要只看是否有错误码。很多订单会先返回 PreSubmitted、Submitted、Cancelled、Filled 等状态,再出现成交或撤单信息。还有一些风控、价格、权限、交易时段问题,会在 TWS 界面和错误回调里同时出现。
连接问题怎么读
Section titled “连接问题怎么读”连接类问题先看时间线:
| 现象 | 重点检查 |
|---|---|
| 连接不上 | 端口、同机连接限制、可信 IP、TWS 是否已登录 |
| 连接后马上断开 | clientId 冲突、API 设置、网络、TWS 重启 |
| 请求偶尔失败 | 是否断线重连、是否错过重新订阅、是否触发 pacing |
| 多程序互相影响 | 多个程序是否使用同一个 clientId |
如果日志里能看到连接成功,但程序里没有收到回调,要检查代码是否启动了 reader 线程、事件循环或消息处理逻辑。Python、Java、C#、C++ 在这部分写法不同,但核心都是要持续读取 TWS 返回消息。
和程序输出对照
Section titled “和程序输出对照”建议在代码里把关键回调也打印出来,然后和日志对照。最少要打印:
connected clientId=910request reqId=1001 type=historicalData symbol=AAPLerror reqId=1001 code=XXXX message=...historicalData reqId=1001 time=...historicalDataEnd reqId=1001上面是排查输出格式示例,不要求一模一样。重点是让日志中的 reqId、orderId、时间和你的程序输出能互相对应。
看到请求就以为一定会返回数据
Section titled “看到请求就以为一定会返回数据”请求发出只说明程序调用了 API,不代表请求合法、权限足够、合约明确或数据存在。还要继续看后续错误和结束信号。
没看到方法名就以为日志没用
Section titled “没看到方法名就以为日志没用”API 日志底层可能以协议消息、字段序列或平台字段名记录,不一定直接显示 Python 方法名。你要看请求编号、合约、订单编号、错误码和时间顺序。
只看一个日志文件
Section titled “只看一个日志文件”复杂问题可能需要同时看 API Logs 和 TWS / Gateway Logs。API 日志能看通信,平台日志能看登录、连接、数据农场和客户端状态。
只看中文界面提示
Section titled “只看中文界面提示”TWS 中文界面的提示有时会简化含义。排查时建议保留英文错误码、英文原文、日志片段和中文解释,不要只保存翻译后的界面文字。
推荐排查顺序
Section titled “推荐排查顺序”阅读导出日志时,按这个顺序最省时间:
- 确认日志日期正确。
- 找到问题发生时间。
- 找到连接记录和
clientId。 - 找到请求记录。
- 记录
reqId或orderId。 - 搜索同一编号的返回和错误。
- 对照程序输出。
- 对照 TWS / IB Gateway 界面状态。
- 把结论整理成最小复现说明。
这样读日志,不需要你一次性掌握全部 TWS API 协议细节,也能把大多数“为什么没返回”“为什么被拒单”“为什么和代码输出不一致”的问题缩小到具体原因。