IB証券 API |商品先物、株価指数先物、先物オプションなどの過去データ(ヒストリカルデータ)の取得

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

前提

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

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

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

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

API での先物の過去データ(ヒストリカルデータ)の取得

APIで過去データ(ヒストリカルデータ)の取得については以下に記載しています。
IB証券 API 過去データ(ヒストリカルデータ)の取得

しかし、先物データに関しては少し特殊なので、ここで紹介します。

ここではダウ30ミニ(Mini Sized Dow Jones Industrial Average)の株価指数先物の過去データ(ヒストリカルデータ)の取得します。

商品や株価指数の先物は動作確認していますが、先物オプションも基本的には同じです。
オプションの場合は商品情報が少し異なるだけです。商品情報については以下を参照してください。
IB証券 API接続での商品情報の設定

現在は、日本時間の2020年6月24日10時ごろです。

金融商品のアクティブな限月を確認

アクティブな限月の確認自体は過去データ(ヒストリカルデータ)の取得と直接関係ありませんが、取得する過去データの限月の再確認という意味合いです。

contract = Future(symbol = "YM", exchange = "ECBOT")

Details = ib.reqContractDetails(contract)
for Detail in Details:
    print(Detail.contract.lastTradeDateOrContractMonth)
20200918
20201218
20210318
20210617

上記のような結果が表示されます。

日付がなくても過去データ(ヒストリカルデータ)を取得できますので、限月は以下の4つということになります。

  • 3月限
  • 6月限
  • 9月限
  • 12月限

アクティブな限月の過去データ(ヒストリカルデータ)の取得

現在取引されているアクティブな限月の一つ(202009)の日足の過去データを1年分取得して、データフレームに格納します。

contract = Future(symbol = "YM", exchange = "ECBOT", lastTradeDateOrContractMonth='202009')

bars = ib.reqHistoricalData(
        contract,
        endDateTime='',
        durationStr='1 Y',
        barSizeSetting='1 day',
        whatToShow='TRADES',
        useRTH=True,
        formatDate=1)

df = util.df(bars)
print(df.head())
print(df.tail())

出力結果

         date     open     high      low    close  volume  average  barCount
0  2019-09-23  26824.0  26824.0  26824.0  26824.0       0  26824.0         0
1  2019-09-24  26668.0  26668.0  26668.0  26668.0       0  26668.0         0
2  2019-09-25  26818.0  26818.0  26818.0  26818.0       0  26818.0         0
3  2019-09-26  26756.0  26756.0  26756.0  26756.0       0  26756.0         0
4  2019-09-27  26668.0  26668.0  26668.0  26668.0       0  26668.0         0
           date     open     high      low    close  volume   average  barCount
181  2020-06-17  26252.0  26265.0  25923.0  26025.0  128373  26114.25     86639
182  2020-06-18  25797.0  26020.0  25703.0  25899.0  115646  25896.05     78969
183  2020-06-19  26301.0  26320.0  25509.0  25529.0  173094  25909.00    110754
184  2020-06-22  25655.0  25987.0  25534.0  25953.0   99093  25778.25     66181
185  2020-06-23  26154.0  26190.0  25944.0  26020.0  103332  26096.40     67810

2020年09月限のデータを取得しましたので、1年分とリクエストしましたが、2019-09-23以降のデータのみとなります。

クローズした限月の過去データ(ヒストリカルデータ)の取得

2020年09月限と同じ9月限のクローズした前年の2019年09月限の日足の過去データを1年分取得して、データフレームに格納します。

ポイントとしては、以下の2つがあります。

  • クローズした限月を指定する際は、includeExpired=Trueとする。
  • ib.reqHistoricalDataendDateTimeで終了日を指定しないと現在からn年分取得することになる。
    今回は9月末として2年分取得することにします。それによって漏れることなく全ての日足データを取得することができます。
  • 先物のデータは取得できますが、オプション、先物オプション、ワラント、ストラクチャード商品は制限事項のため取得できません。
TWS API v9.72+: Historical Data Limitations
from datetime import datetime, date

contract = Future(symbol='YM', exchange='ECBOT', lastTradeDateOrContractMonth='201909', includeExpired=True)

bars = ib.reqHistoricalData(
        contract,
        endDateTime=date(2019, 9, 30),
        durationStr='2 Y',
        barSizeSetting='1 day',
        whatToShow='TRADES',
        useRTH=True,
        formatDate=1)

df = util.df(bars)
print(df.head())
print(df.tail())

出力結果

         date     open     high      low    close  volume  average  barCount
0  2018-09-24  26745.0  26745.0  26745.0  26745.0       0  26745.0         0
1  2018-09-25  26653.0  26653.0  26653.0  26653.0       0  26653.0         0
2  2018-09-26  26551.0  26551.0  26551.0  26551.0       0  26551.0         0
3  2018-09-27  26616.0  26616.0  26616.0  26616.0       0  26616.0         0
4  2018-09-28  26619.0  26619.0  26619.0  26619.0       0  26619.0         0
           date     open     high      low    close  volume   average  barCount
245  2019-09-17  27020.0  27121.0  26988.0  27114.0   21943  27048.45     13683
246  2019-09-18  27083.0  27185.0  26909.0  27148.0   29565  27042.40     18367
247  2019-09-19  27198.0  27274.0  27065.0  27086.0   17455  27188.00     11236
248  2019-09-20  27141.0  27141.0  27141.0  27141.0       0  27141.00         0
249  2019-09-23  27141.0  27141.0  27141.0  27141.0       0  27141.00         0

2019年09月限の限月(日)を確認

contract = Future(symbol = "YM", exchange = "ECBOT", lastTradeDateOrContractMonth='201909', includeExpired=True)

Details = ib.reqContractDetails(contract)
for Detail in Details:
    print(Detail.contract.lastTradeDateOrContractMonth)
20190920

上記のことから2019-09-23は不要なデータということがわかります。

特定の限月の複数年分の過去データ(ヒストリカルデータ)の取得

アクティブな2020年09月限を含めて、過去5年分のデータを取得して、データフレームに格納します。

ポイントは、以下の2つです。

  • ib.reqContractDetails(contract)にて商品情報を取得しますが、存在しない場合があります。今回の場合では、3年分しか取得できていません。
  • endDateTimeで日付を指定していますが、IB証券ではその日を含めてとなっています。
from datetime import datetime, date

df_master = {}

for year in range(2016, 2021):
    contract = Future(symbol='YM', exchange='ECBOT', lastTradeDateOrContractMonth=str(year)+'09', includeExpired=True)

    Details = ib.reqContractDetails(contract)
#     print(len(Details))
    
    if len(Details) > 0:
        for Detail in Details:
            EndDate = Detail.contract.lastTradeDateOrContractMonth

        bars = ib.reqHistoricalData(
                contract,
                endDateTime=datetime.strptime(EndDate, '%Y%m%d'),
                durationStr='2 Y',
                barSizeSetting='1 day',
                whatToShow='TRADES',
                useRTH=True,
                formatDate=1)
        
        df_master[year] = util.df(bars)


df = pd.DataFrame()

for df_year in df_master.values():
#     print(df_year.head())
#     print(df_year.tail())

    if df.empty:
        df = df_year
    else:
        df = pd.concat([df, df_year])
    
print(df.head())
print(df.tail())

出力結果

以下のように2年分はエラーになりますが、3年分は問題なく取得できています。

Error 200, reqId 105: リクエストされたセキュリティ定義は見つかりませんでした, contract: Future(symbol='YM', lastTradeDateOrContractMonth='201609', exchange='ECBOT', includeExpired=True)
Error 200, reqId 106: リクエストされたセキュリティ定義は見つかりませんでした, contract: Future(symbol='YM', lastTradeDateOrContractMonth='201709', exchange='ECBOT', includeExpired=True)
         date     open     high      low    close  volume  average  barCount
0  2017-09-18  22200.0  22200.0  22200.0  22200.0       0  22200.0         0
1  2017-09-19  22236.0  22236.0  22236.0  22236.0       0  22236.0         0
2  2017-09-20  22278.0  22278.0  22278.0  22278.0       0  22278.0         0
3  2017-09-21  22231.0  22231.0  22231.0  22231.0       0  22231.0         0
4  2017-09-22  22202.0  22202.0  22202.0  22202.0       0  22202.0         0
           date     open     high      low    close  volume   average  barCount
181  2020-06-17  26252.0  26265.0  25923.0  26025.0  128373  26114.25     86639
182  2020-06-18  25797.0  26020.0  25703.0  25899.0  115646  25896.05     78969
183  2020-06-19  26301.0  26320.0  25509.0  25529.0  173094  25909.00    110754
184  2020-06-22  25655.0  25987.0  25534.0  25953.0   99093  25778.25     66181
185  2020-06-23  26154.0  26190.0  25944.0  26020.0  103332  26096.40     67810

全ての限月の複数年分の過去データ(ヒストリカルデータ)の取得

全てのアクティブな限月を含めて、過去5年分のデータを取得して、データフレームに格納します。
今回の場合は、以下の4つの限月となります。

  • 3月限
  • 6月限
  • 9月限
  • 12月限
from datetime import datetime, date

df = {}

for month in range(3,13,3):
#     print(month)

    df_master = {}

    for year in range(2017, 2021):
        
        ContractMonth = str(year)+str(month).zfill(2)
        
        contract = Future(symbol='YM', exchange='ECBOT', lastTradeDateOrContractMonth=ContractMonth, includeExpired=True)

        Details = ib.reqContractDetails(contract)
    #     print(len(Details))

        if len(Details) > 0:
            for Detail in Details:
                EndDate = Detail.contract.lastTradeDateOrContractMonth

            bars = ib.reqHistoricalData(
                    contract,
                    endDateTime=datetime.strptime(EndDate, '%Y%m%d'),
                    durationStr='2 Y',
                    barSizeSetting='1 day',
                    whatToShow='TRADES',
                    useRTH=True,
                    formatDate=1)

            df_master[year] = util.df(bars)

    df_temp = pd.DataFrame()

    for df_year in df_master.values():
    #     print(df_year.head())
    #     print(df_year.tail())

        if df_temp.empty:
            df_temp = df_year
        else:
            df_temp = pd.concat([df_temp, df_year])
            
    df[str(month)] = df_temp

for df_month in df.values():
    print(df_month.head())
    print(df_month.tail())

出力結果

Error 200, reqId 147: リクエストされたセキュリティ定義は見つかりませんでした, contract: Future(symbol='YM', lastTradeDateOrContractMonth='201703', exchange='ECBOT', includeExpired=True)
Error 200, reqId 148: リクエストされたセキュリティ定義は見つかりませんでした, contract: Future(symbol='YM', lastTradeDateOrContractMonth='201803', exchange='ECBOT', includeExpired=True)
Error 200, reqId 153: リクエストされたセキュリティ定義は見つかりませんでした, contract: Future(symbol='YM', lastTradeDateOrContractMonth='201706', exchange='ECBOT', includeExpired=True)
Error 200, reqId 154: リクエストされたセキュリティ定義は見つかりませんでした, contract: Future(symbol='YM', lastTradeDateOrContractMonth='201806', exchange='ECBOT', includeExpired=True)
Error 200, reqId 159: リクエストされたセキュリティ定義は見つかりませんでした, contract: Future(symbol='YM', lastTradeDateOrContractMonth='201709', exchange='ECBOT', includeExpired=True)
Error 200, reqId 166: リクエストされたセキュリティ定義は見つかりませんでした, contract: Future(symbol='YM', lastTradeDateOrContractMonth='201712', exchange='ECBOT', includeExpired=True)
         date     open     high      low    close  volume  average  barCount
0  2018-03-19  24819.0  24819.0  24819.0  24819.0       0  24819.0         0
1  2018-03-20  24888.0  24888.0  24888.0  24888.0       0  24888.0         0
2  2018-03-21  24848.0  24848.0  24848.0  24848.0       0  24848.0         0
3  2018-03-22  24600.0  24600.0  24099.0  24099.0       1  24600.0         1
4  2018-03-23  23753.0  23753.0  23753.0  23753.0       0  23753.0         0
           date     open     high      low    close  volume   average  barCount
246  2020-03-13  22392.0  23147.0  21237.0  22988.0  120560  22025.20     87131
247  2020-03-16  21484.0  21762.0  20062.0  20399.0   89171  21037.60     72842
248  2020-03-17  20634.0  21380.0  19872.0  20966.0   57622  20678.05     47036
249  2020-03-18  19720.0  20472.0  18904.0  19981.0   60063  19752.20     50577
250  2020-03-19  19774.0  20441.0  19174.0  20003.0   26284  19924.95     21658
         date     open     high      low    close  volume  average  barCount
0  2018-06-18  25121.0  25121.0  25121.0  25121.0       0  25121.0         0
1  2018-06-19  24827.0  24827.0  24827.0  24827.0       0  24827.0         0
2  2018-06-20  24777.0  24777.0  24777.0  24777.0       0  24777.0         0
3  2018-06-21  24540.0  24540.0  24540.0  24540.0       0  24540.0         0
4  2018-06-22  24659.0  24659.0  24659.0  24659.0       0  24659.0         0
           date     open     high      low    close  volume   average  barCount
241  2020-06-12  25817.0  25952.0  25064.0  25536.0  163561  25482.65    110317
242  2020-06-15  24942.0  25884.0  24825.0  25805.0   78315  25352.65     59288
243  2020-06-16  26633.0  26638.0  25789.0  26320.0   68777  26297.90     53373
244  2020-06-17  26386.0  26393.0  26049.0  26150.0   21500  26248.20     15781
245  2020-06-18  25929.0  26148.0  25835.0  26024.0   10773  26019.85      8384
         date     open     high      low    close  volume  average  barCount
0  2017-09-18  22200.0  22200.0  22200.0  22200.0       0  22200.0         0
1  2017-09-19  22236.0  22236.0  22236.0  22236.0       0  22236.0         0
2  2017-09-20  22278.0  22278.0  22278.0  22278.0       0  22278.0         0
3  2017-09-21  22231.0  22231.0  22231.0  22231.0       0  22231.0         0
4  2017-09-22  22202.0  22202.0  22202.0  22202.0       0  22202.0         0
           date     open     high      low    close  volume   average  barCount
181  2020-06-17  26252.0  26265.0  25923.0  26025.0  128373  26114.25     86639
182  2020-06-18  25797.0  26020.0  25703.0  25899.0  115646  25896.05     78969
183  2020-06-19  26301.0  26320.0  25509.0  25529.0  173094  25909.00    110754
184  2020-06-22  25655.0  25987.0  25534.0  25953.0   99093  25778.25     66181
185  2020-06-23  26154.0  26190.0  25944.0  26020.0  103332  26096.40     67810
         date     open     high      low    close  volume  average  barCount
0  2017-12-18  24840.0  24840.0  24840.0  24840.0       0  24840.0         0
1  2017-12-19  24807.0  24807.0  24807.0  24807.0       0  24807.0         0
2  2017-12-20  24801.0  24801.0  24801.0  24801.0       0  24801.0         0
3  2017-12-21  24840.0  24840.0  24840.0  24840.0       0  24840.0         0
4  2017-12-22  24825.0  24825.0  24825.0  24825.0       0  24825.0         0
           date     open     high      low    close  volume   average  barCount
121  2020-06-17  26004.0  26053.0  25940.0  25940.0       6  26001.00         6
122  2020-06-18  25809.0  25809.0  25809.0  25809.0       0  25809.00         0
123  2020-06-19  26060.0  26060.0  25410.0  25410.0      34  25758.20        28
124  2020-06-22  25452.0  25836.0  25444.0  25836.0      13  25552.25        13
125  2020-06-23  26002.0  26050.0  25842.0  25902.0      23  25968.15        21

 

コメント

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