跳转到内容

请求行情类型

reqMarketDataType() 要放在 reqMktData() 前面调用。它告诉 TWS:接下来的行情订阅优先按哪种行情类型请求。

官方参考:

app.reqMarketDataType(marketDataType)
参数类型中文含义可选值
marketDataTypeint行情类型1 实时,2 冻结,3 延迟,4 延迟冻结。

这个设置会影响之后发出的行情请求。不同合约、不同交易所、不同权限和不同交易时段,最终可能收到不同的 marketDataType() 回调。

reqMarketDataType() 只切换请求类型,不会创建行情订阅。要拿到价格,还必须继续调用 reqMktData()

app.reqMktData(
reqId,
contract,
genericTickList,
snapshot,
regulatorySnapshot,
mktDataOptions,
)
参数类型中文含义说明
reqIdint行情请求编号自己分配的唯一编号,用来匹配后续回调。
contractContract合约对象股票、期权、期货等都要先写清楚合约。
genericTickListstr额外 tick 列表例如 "233" 请求 RTVolume;延迟行情只支持部分 generic tick。普通价格可传空字符串。
snapshotbool是否快照False 表示流式订阅,True 表示只要一次快照。
regulatorySnapshotbool是否监管快照美股监管快照场景使用,可能产生费用;普通延迟行情传 False
mktDataOptionslist额外选项Python API 通常传空列表 []
from ibapi.contract import Contract
def make_aapl_contract():
contract = Contract()
contract.symbol = "AAPL"
contract.secType = "STK"
contract.exchange = "SMART"
contract.currency = "USD"
contract.primaryExchange = "NASDAQ"
return contract
# 3 表示延迟行情。这个调用必须放在 reqMktData 前面。
app.reqMarketDataType(3)
# 发起行情订阅。snapshot=False 表示持续接收行情更新。
app.reqMktData(
95223,
make_aapl_contract(),
"",
False,
False,
[],
)
app.reqMarketDataType(3)
app.reqMktData(
95253,
make_aapl_contract(),
"",
True, # True 表示只请求一次快照。
False,
[],
)

快照请求结束时可能收到 tickSnapshotEnd(reqId)。如果权限或市场状态不满足,也可能只收到错误回调。

from ibapi.client import EClient
from ibapi.contract import Contract
from ibapi.wrapper import EWrapper
import threading
import time
class App(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
self.ready = threading.Event()
def nextValidId(self, orderId):
self.ready.set()
def marketDataType(self, reqId, marketDataType):
print("行情类型:", reqId, marketDataType)
def tickPrice(self, reqId, tickType, price, attrib):
print("价格:", reqId, tickType, price)
def tickSize(self, reqId, tickType, size):
print("数量:", reqId, tickType, size)
def tickSnapshotEnd(self, reqId):
print("快照结束:", reqId)
def error(self, reqId, errorTime, errorCode, errorString, advancedOrderRejectJson=""):
print("错误:", reqId, errorCode, errorString)
def make_aapl_contract():
contract = Contract()
contract.symbol = "AAPL"
contract.secType = "STK"
contract.exchange = "SMART"
contract.currency = "USD"
contract.primaryExchange = "NASDAQ"
return contract
app = App()
app.connect("127.0.0.1", 7497, clientId=95200)
thread = threading.Thread(target=app.run, daemon=True)
thread.start()
if app.ready.wait(10):
app.reqMarketDataType(3)
app.reqMktData(95253, make_aapl_contract(), "", True, False, [])
time.sleep(8)
app.disconnect()

AAPL 延迟快照请求返回:

REQUEST_SENT=reqId=95253;name=delayed_snapshot;requestedMarketDataType=3;snapshot=True
MARKET_DATA_TYPE=reqId=95253;name=delayed_snapshot;marketDataType=3
SNAPSHOT_ENDS=95224,95253
PRICE=reqId=95253;name=delayed_snapshot;tickType=68;price=291.52
PRICE=reqId=95253;name=delayed_snapshot;tickType=72;price=297.14
PRICE=reqId=95253;name=delayed_snapshot;tickType=73;price=289.62
PRICE=reqId=95253;name=delayed_snapshot;tickType=75;price=295.63
SIZE=reqId=95253;name=delayed_snapshot;tickType=71;size=66
SIZE=reqId=95253;name=delayed_snapshot;tickType=74;size=38959800388997

解释:

输出含义
requestedMarketDataType=3程序请求的是延迟行情。
marketDataType=3TWS 实际使用延迟行情。
tickType=68延迟最新价。
tickType=72 / 73 / 75延迟最高价、最低价、收盘价。
tickType=71 / 74延迟最新成交量、延迟成交量。

部分字段可能返回 -10 或明显不适合作为正常数量的值,这表示该字段在当前时刻不可用或没有实际意义。程序应按 tick 类型和字段语义过滤,不要把所有回调值直接展示为有效行情。

reqMarketDataType(3) 不是权限开关。它不能替代市场数据订阅,也不能保证所有合约都有延迟行情。

正确顺序是:

确认 Contract
-> reqMarketDataType(3)
-> reqMktData()
-> 同时检查 marketDataType / tickPrice / tickSize / error