前提
このページでは接続後のみのサンプルを記載しています。接続方法は以下を参照してください。
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 lines Max. Requests 0 – 399 3 400 – 499 4 500 – 599 5 600 – 699 6 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.cancelMktData(contracts)
複数の商品をどんどん追加していくと、制限にひかかったり、パソコンに負荷がかかったりしますので、不要になった商品はキャンセルしておいた方が良いでしょう。
コメント