IB証券 API リアルタイムデータの取得

スポンサーリンク
スポンサーリンク

前提

このページでは接続後のみのサンプルを記載しています。接続方法は以下を参照してください。
IB証券 APIの接続方法

取得できる過去データ(ヒストリカルデータ)

過去データ(ヒストリカルデータ)は購読しているマーケット・データによって取得できないものがあります。

IB証券のマーケットデータの購読は以下を参照してください。
IB証券 マーケットデータの購読

仕様

contracts = Forex('USDJPY', exchange='IDEALPRO')で取得する金融商品を設定します。
詳しくは以下を参照してください。
IB証券 API接続での商品情報の設定

ib.reqMktData(contracts, '', False, False)については気にせずこのままでいいかと思います。
気になる方はドキュメントを参照してください。
https://ib-insync.readthedocs.io/api.html#ib_insync.ib.IB.reqMktData

ib.sleep(0.1)を入れないと取得できないようです。0.1でも取得できない時があります。

制限

上記の仕様に関連するのですが、1秒間に何回取得してもいいのかと考えていたのですが、そのような考えはないみたいです。そもそもIB証券のAPIがPUTしてきているようにも思えます。

以下を見ると、制限はいくつリクエストしていいかということかもしれません。よくわかりませんでした。

ただ、デモ環境ではib.sleep(0.5)にして6つの通貨ペアなら取得できました。
それを同時に3つのシステムで接続していたので合計18個の通貨ペアになりますが、問題なさそうでした。

Limitations

Given the potentially high amount of data being sent, market depth request’s are much more limited. Just as with historical data requests, the amount of active depth requests is related to the amount of market data lines, with a minimum of three and maximum of 60:

Number of linesMax. Requests
0 – 3993
400 – 4994
500 – 5995
600 – 6996
etc…
TWS API v9.72+: Market Depth (Level II)

リアルタイムデータの取得

基本

contracts = Forex('USDJPY', exchange='IDEALPRO')

ib.qualifyContracts(contracts)
ib.reqMktData(contracts, '', False, False)

ticker = ib.ticker(contracts)

ib.sleep(0.1)

ticker.marketPrice()
# 107.8015

リアルタイムデータの一覧

from IPython.display import display, clear_output
import pandas as pd

contracts = [Forex(pair) for pair in ('USDJPY', 'EURJPY', 'GBPJPY', 'CHFJPY', 'AUDJPY', 'EURUSD')]
ib.qualifyContracts(*contracts)

for contract in contracts:
    ib.reqMktData(contract, '', False, False)

df = pd.DataFrame(
    index=[c.pair() for c in contracts],
    columns=['bidSize', 'bid', 'ask', 'askSize', 'high', 'low', 'close'])

def onPendingTickers(tickers):
    for t in tickers:
        df.loc[t.contract.pair()] = (
            t.bidSize, t.bid, t.ask, t.askSize, t.high, t.low, t.close)
        clear_output(wait=True)
    display(df)        

ib.pendingTickersEvent += onPendingTickers
ib.sleep(30)
ib.pendingTickersEvent -= onPendingTickers

上記のテーブルの値がリアルタイムで更新されます。

実践?

例えば以下のようにすれば、取得したリアルデータをトレードに活かすことができます。

class trading:
    def __init__(self):
        self.currency = ""
        self.ask = None
        self.bid = None

    def onPendingTickers(self, tickers):
        for t in tickers:
            self.currency, self.ask, self.bid = t.contract.pair(), t.ask, t.bid
        

trading_ins = trading()

contracts = [Forex(pair) for pair in ('USDJPY', 'EURJPY', 'GBPJPY', 'CHFJPY', 'AUDJPY', 'EURUSD')]

for contract in contracts:
    ib.reqMktData(contract, '', False, False)
ib.pendingTickersEvent += trading_ins.onPendingTickers

while True:
    
    print("currency:{}, ask:{}, bid:{}".format(trading_ins.currency,trading_ins.ask,trading_ins.bid))
    
    ib.sleep(1)
    
    
# currency:, ask:None, bid:None
# currency:GBPJPY, ask:132.194, bid:132.184
# currency:GBPJPY, ask:132.194, bid:132.184
# currency:GBPJPY, ask:132.193, bid:132.183
# currency:CHFJPY, ask:111.127, bid:111.12
# currency:EURJPY, ask:117.935, bid:117.932
# currency:EURJPY, ask:117.935, bid:117.932
# currency:GBPJPY, ask:132.19, bid:132.182
# currency:GBPJPY, ask:132.19, bid:132.182

過去のリアルタイムデータを取得

以下の例では、直近の10件を取得して、最後(最新)の1件のデータを表示させています。

import datetime

symbol     = 'ES'
expiration = '20200918'
exchange   = 'GLOBEX'
strike     = "3330"
right      = "C"

contracts = Contract(
    secType  ='FOP', 
    symbol   =symbol, 
    lastTradeDateOrContractMonth=expiration, 
    strike   =strike, 
    right    =right, 
    exchange =exchange, 
    tradingClass=symbol
)

start = ''
end = datetime.datetime.now()
ticker = ib.reqHistoricalTicks(contracts, start, end, 10, 'BID_ASK', useRth=False)

print(ticker[-1])

# HistoricalTickBidAsk(time=datetime.datetime(2020, 8, 17, 5, 37, 34, tzinfo=datetime.timezone.utc), tickAttribBidAsk=TickAttribBidAsk(), priceBid=98.0, priceAsk=98.75, sizeBid=1, sizeAsk=11)

ib.reqHistoricalTicks

  • contract:商品情報
  • start:開始日時
  • end:終了日時
  • numberOfTicks:取得する数量、1回のリクエストで最大1000件まで
  • whatToShow:Bid_Ask, Midpoint, or Trades
  • useRth:True(標準の取引時間のみ)、Flase(すべての時間)

先物オプションのリアルタイムデータの取得

以下のページを参照してください。

IB証券 API 先物オプションのリアルタイムデータの取得

リアルタイムデータの取得のキャンセル

取得しているリアルタイムデータのキャンセルは以下のように取得している商品情報をセットすれば良いだけです。

ib.cancelMktData(contracts)

複数の商品をどんどん追加していくと、制限にひかかったり、パソコンに負荷がかかったりしますので、不要になった商品はキャンセルしておいた方が良いでしょう。

 

コメント

タイトルとURLをコピーしました