從IB 取得巿場報價
January 2, 2021•139 words
巿場數據無論是進行交易算法回測,抑或是執行自動化交易,還是只是人手交易都是必需的,而跟據IB的文檔,獲取數據有好幾種方法,包括以下四種 :
- reqMktData: 據知每秒鐘會更新數次
- reqRealTimeBars: 每5秒鐘提供一支新的陰陽蠋數據,就是OHLC
- reqHistoricalData (當 ‘keepUpToDate’ 設定為True時):會提供(應該是分鐘計的)陰陽蠋數據
- reqTickByTickData: 據文檔說明是每一筆新交易都會送來
而第三個reqHistoricalData 我們多用於每日下戴分鐘為單位的數據作儲存日後Backtest用途,稍後會示範,至於即巿交易,由於有上面更好的選擇,也沒有必要使用這個功能了。
這裏就先講reqMktData,因為它是最常用的方法。如前文所說,我們要Implement EWrapper以及EClient,一搬情況下,都會在同Class Implement。關於使用reqMktData網上是有案例提供的,故此,我們會以據該案例「本地化」,改以詢問恒生指數期貨,即「期指」的報價。
首先,這裡是Implement EWrapper和EClient;
class IBapi(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
def tickPrice(self, reqId, tickType, price, attrib):
if tickType == 2 and reqId == 1:
print('The current ask price is: ', price)
然後就定義合約Contract 的Object,早前亦有寫過,期貨的話比股票複一點,而股票我們沒有付費訂購報價的話,會出現錯誤:
ERROR 1 10167 Requested market data is not subscribed. Displaying delayed market data...
期貨合約共有五個options要設定,Symbol就很簡單了,大期是HSI,細期是MHI,國期是HHI.HK,而細國期...太細沒有做過所以我也不知道。secType 就是類型,股票是STK應該是stock的簡寫,期貨簡寫是FUT。而exchange要注意,港交所我們一搬叫HKEX,但在IB香港的股票交易所是SEHK,而期交所反而英文比較像官方寫法HKFE。而貨幣當然是HKD(美股就是USD,但不是本篇討論範圍)。最後是股票沒有而期貨才有的lastTradeDateOrContractMonth,這裡輸入最後交易日(yyyymmdd格式)或合約月份(yyyymm)格式也可以,下面是下筆時本月的細期:
contract = Contract()
contract.symbol = 'MHI'
contract.secType = 'FUT'
contract.exchange = 'HKFE'
contract.currency = 'HKD'
contract.lastTradeDateOrContractMonth='202101'
有了合約之後,咱們就可以問TWS拿取報價,以下程式是initial 一個IBapi() object 然後連接本地的TWS,關於TWS設定可參看這裏。
app = IBapi()
app.connect('127.0.0.1', 7496, 123)
time.sleep(1) #Sleep interval to allow time for connection to server
app.reqMarketDataType(MarketDataTypeEnum.FROZEN) # **1**
app.reqMktData(1, contract, '', False, False, [])
app.run()
在這裡要停一下說明,第四行程式是可以不用加,因為有預設值是1,即Live,MarketDataType有分四類,詳細可參看官方的文檔。IB的文檔跟世上大部份程式文檔一樣,都是奇芭,在官方文檔中使用的MarketDataTypeEnum.FROZEN
這個ENUM 在文檔中是找不到的,至少在marketdatatype這一頁沒有直接說明的來源處,而跟Table 的keyword大小寫也不對,亂試之後發現在ibapi.client
下,所以要是使用要在Python程式檔案最頂加入:
from ibapi.client import MarketDataTypeEnum
如果不想「折騰」的話直接打1234則可。