從IB 取得巿場報價

巿場數據無論是進行交易算法回測,抑或是執行自動化交易,還是只是人手交易都是必需的,而跟據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則可。


You'll only receive email when they publish something new.

More from 13131
All posts