总览
市场指标不是普通股票,也不是账户统计字段。在 TWS API 中,NYSE 涨跌家数、NYSE 成交量指数、TRIN 和 TICK 这类数据通常按指数合约请求,接口仍然使用一档行情的 reqMktData()。
这组页面只讲官方文档列出的 NYSE 市场指标。它们适合做市场宽度、短线情绪和盘中监控,不适合直接当作交易信号单独使用。
| 步骤 | 接口 / 回调 | 说明 |
|---|---|---|
| 1 | Contract() | 构造市场指标合约,secType 使用 IND。 |
| 2 | reqMktData() | 请求实时一档行情。 |
| 3 | tickPrice() / tickSize() | 接收指标数值或相关数量更新。 |
| 4 | cancelMktData() | 不再需要时取消订阅。 |
| 5 | error() | 接收权限、合约、订阅状态等错误。 |
| 字段 | 示例 | 中文说明 |
|---|---|---|
symbol | AD-NYSE | 指标代码。不同指标使用不同 symbol。 |
secType | IND | 表示指数或指标类合约。 |
exchange | NYSE | 指标所属交易所。 |
currency | USD | 美元计价。 |
本组页面使用的四个指标如下:
| 指标 | symbol | 用途 |
|---|---|---|
| NYSE 涨跌家数 | AD-NYSE | 观察上涨股票数量和下跌股票数量的差异。 |
| NYSE 成交量指数 | VOL-NYSE | 观察上涨成交量和下跌成交量的关系。 |
| NYSE TRIN 指标 | TRIN-NYSE | 结合涨跌家数与涨跌成交量衡量市场结构强弱。 |
| NYSE TICK 指标 | TICK-NYSE | 观察短时间内上涨跳动和下跌跳动的差异。 |
Python 示例
Section titled “Python 示例”from ibapi.contract import Contract
def nyse_indicator(symbol: str) -> Contract: """构造 NYSE 市场指标合约。""" contract = Contract() contract.symbol = symbol contract.secType = "IND" contract.exchange = "NYSE" contract.currency = "USD" return contract
# 请求 NYSE TICK 指标。app.reqMktData( 97504, nyse_indicator("TICK-NYSE"), "", False, False, [],)reqMktData() 的参数含义和普通股票一致:
| 参数 | 示例 | 中文说明 |
|---|---|---|
tickerId | 97504 | 本次行情请求编号,用来匹配回调。 |
contract | nyse_indicator("TICK-NYSE") | 指标合约。 |
genericTickList | "" | 本组指标不需要额外 generic tick。 |
snapshot | False | False 表示订阅流式更新。 |
regulatorySnapshot | False | 不请求监管快照。 |
mktDataOptions | [] | 通常留空。 |
参考边界样例
Section titled “参考边界样例”TWS API 可以连接,并且 TWS 能识别这四个指标合约,但账户没有对应市场数据订阅时,不会返回价格或数量回调:
CONNECTED=TrueREQUESTED=97501:AD-NYSE,97502:VOL-NYSE,97503:TRIN-NYSE,97504:TICK-NYSEPRICE_ROWS=0SIZE_ROWS=0CANCELLED=97501,97502,97503,97504TWS 返回的主要错误是 354:
ERROR=reqId=97501;symbol=AD-NYSE;code=354;msg=未订阅所请求的市场数据...:AD-NYSE NYSE ADVANCE DECLINE INDEX/TOP/ALLERROR=reqId=97502;symbol=VOL-NYSE;code=354;msg=未订阅所请求的市场数据...:VOL-NYSE NYSE VOLUME INDEX/TOP/ALLERROR=reqId=97503;symbol=TRIN-NYSE;code=354;msg=未订阅所请求的市场数据...:TRIN-NYSE NYSE TRIN (OR ARMS) INDEX/TOP/ALLERROR=reqId=97504;symbol=TICK-NYSE;code=354;msg=未订阅所请求的市场数据...:TICK-NYSE NYSE TICK INDEX/TOP/ALL这说明代码路径和合约写法已经到达 TWS,但行情权限不足。开发时应把 354 当作权限或订阅问题处理,而不是把它误判成 Socket 连接失败。
如果前面的订阅已经被 354 拒绝,后续调用 cancelMktData() 时还可能出现 300。它通常只是取消未建立订阅时的附带结果,不是根因。
| 现象 | 常见原因 | 处理方式 |
|---|---|---|
收到 354 | 未订阅对应市场数据 | 检查账户市场数据订阅和 API 行情权限。 |
收到 200 | 合约字段写错或运行环境找不到证券定义 | 先检查 symbol/secType/exchange/currency。 |
| 没有回调也没有错误 | 等待时间太短或程序没有启动消息线程 | 确认 app.run() 在线程中运行,并等待 nextValidId()。 |
取消后收到 300 | 订阅没有真正建立 | 常见于前面已经因为权限错误被拒绝的请求。 |
市场指标页面的重点不是下单,而是把指标读出来并用于风控、过滤或盘中状态展示。新手可以先用 reqCurrentTime() 确认连接,再用普通股票的一档行情确认 reqMktData() 回调模型,最后再接入这些 NYSE 指标。