跳转到内容

成交详情

成交详情是订单管理里最适合用来记录交易流水的接口。订单状态告诉你订单处于什么状态,成交详情告诉你实际发生了哪些成交、成交价格是多少、成交数量是多少,以及这笔成交后面应该如何和佣金费用对应起来。

TWS API 使用 reqExecutions() 查询成交,并通过 execDetails() 返回每一条成交,最后用 execDetailsEnd() 表示本次返回结束。若这笔成交有佣金与费用信息,TWS 还会通过 commissionAndFeesReport() 返回同一个 execId 对应的费用数据。

官方参考:TWS API Documentation

你要解决的问题应该看哪个回调
订单有没有被 TWS 接收openOrder()orderStatus()
订单现在是什么状态orderStatus()
订单实际成交了几笔execDetails()
每笔成交的价格、数量、方向Execution 对象
每笔成交的佣金、费用、已实现盈亏commissionAndFeesReport()
查询结果是否已经返回完execDetailsEnd()

订单状态和成交详情不要混成一张表。一个订单可能经历 Submitted、Cancelled、Filled 等多个状态;成交详情则是一条条实际成交记录。交易系统里通常会把订单表、成交表、费用表分开保存,再用 orderIdpermIdexecId 做关联。

from ibapi.execution import ExecutionFilter
# 1. 构造成交过滤条件。空过滤器表示查询 TWS 可见范围内的成交。
exec_filter = ExecutionFilter()
# 2. 发送成交详情请求。reqId 由程序自己分配,用来识别这次请求。
app.reqExecutions(98301, exec_filter)
# 3. 每返回一笔成交,TWS 会调用一次 execDetails。
def execDetails(self, reqId, contract, execution):
print(
reqId,
execution.execId,
contract.symbol,
execution.side,
execution.shares,
execution.price,
)
# 4. 成交对应的佣金与费用会通过这个回调返回。
def commissionAndFeesReport(self, commissionReport):
print(
commissionReport.execId,
commissionReport.commissionAndFees,
commissionReport.currency,
commissionReport.realizedPNL,
)
# 5. 这一批成交详情返回完毕。
def execDetailsEnd(self, reqId):
print("成交详情返回结束", reqId)
EXEC_DETAILS_END=True
EXEC_ROWS=0
COMMISSION_ROWS=0
COMPLETED_ORDER_ROWS=4
COMPLETED_ORDER=symbol=AAPL;secType=STK;action=BUY;orderType=LMT;totalQuantity=1;status=Cancelled;permId=1466795661

这个结果说明接口链路正常,但 TWS 可见范围内没有真实成交。已取消的订单有时可以出现在 completed orders 里,但只要没有成交,就不会有 execDetails(),也不会有 commissionAndFeesReport()

reqExecutions() 默认查询账户当天可见的成交。官方文档提到,如果希望查询最近最多 7 天的成交,需要在 TWS 交易日志设置里调整 “Show trades for” 范围;IB Gateway 通常无法通过界面调整这个交易日志范围,因此更常见的是只拿到当天成交。

这也是很多新手第一次调用时看到空结果的原因:接口没有报错,只是当天没有成交,或者 TWS 可见范围没有覆盖到想查的成交。

建议字段说明
订单表orderIdpermIdclientIdaccountstatustotalQuantity保存订单生命周期。
成交表execIdorderIdpermIdclientIdtimesymbolsidesharesprice保存真实成交流水。
费用表execIdcommissionAndFeescurrencyrealizedPNLyield_yieldRedemptionDate保存佣金、费用和成交盈亏。
  • orderStatus.filled > 0 不等于已经拿到了完整成交流水。交易系统仍应读取 execDetails()
  • COMPLETED_ORDER_ROWS > 0 不等于有成交。Cancelled、ApiCancelled 等订单可能没有任何成交。
  • execDetailsEnd() 只是说明本次查询结束,不代表一定查到了成交。
  • commissionAndFeesReport() 可能比 execDetails() 晚到,程序要允许先保存成交,再用同一个 execId 补齐费用。