IB証券 API接続での先物やオプションの限月や権利行使価格の取得

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

前提

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

取得できるリアルタイムデータ

リアルタイムデータは購読しているマーケット・データによって取得できないものがあります。

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

取得方法1.原産価格であるインデックスから取得

SPX(S&P 500*ミニは駄目)やVIXであれば、この方法でオプションの限月や権利行使価格を取得することができます。

Cont = Index('SPX', 'CBOE')
ib.qualifyContracts(Cont)

chains = ib.reqSecDefOptParams(Cont.symbol, '', Cont.secType, Cont.conId)
print(util.df(chains))
#   exchange underlyingConId tradingClass multiplier  \
# 0    SMART          416904          SPX        100   
# 1     CBOE          416904         SPXW        100   
# 2    SMART          416904         SPXW        100   
# 3     CBOE          416904          SPX        100   

#                                          expirations  \
# 0  [20200820, 20200917, 20201015, 20201119, 20201...   
# 1  [20200731, 20200803, 20200805, 20200807, 20200...   
# 2  [20200731, 20200803, 20200805, 20200807, 20200...   
# 3  [20200820, 20200917, 20201015, 20201119, 20201...   

#                                              strikes  
# 0  [100.0, 200.0, 300.0, 400.0, 500.0, 600.0, 650...  
# 1  [100.0, 200.0, 300.0, 400.0, 500.0, 600.0, 650...  
# 2  [100.0, 200.0, 300.0, 400.0, 500.0, 600.0, 650...  
# 3  [100.0, 200.0, 300.0, 400.0, 500.0, 600.0, 650... 
    
chain = next(c for c in chains if c.tradingClass == 'SPX' and c.exchange == 'CBOE')
print(chain)
# OptionChain(exchange='CBOE', underlyingConId='416904', tradingClass='SPX', multiplier='100', expirations=['20200820', '20200917', '20201015', '20201119', '20201217', '20210114', '20210318', '20210617', '20210916', '20211216', '20220616', '20221215'], strikes=[100.0, 200.0, 300.0, 400.0, 500.0, 600.0, 650.0, 700.0, 750.0, 800.0, 850.0, 900.0, 950.0, 1000.0, 1050.0, 1100.0, 1150.0, 1200.0, 1225.0, 1250.0, 1275.0, 1300.0, 1325.0, 1350.0, 1375.0, 1400.0, 1425.0, 1450.0, 1475.0, 1500.0, 1525.0, 1550.0, 1575.0, 1600.0, 1625.0, 1650.0, 1675.0, 1700.0, 1725.0, 1750.0, 1775.0, 1800.0, 1825.0, 1850.0, 1875.0, 1900.0, 1925.0, 1950.0, 1960.0, 1970.0, 1975.0, 1980.0, 1990.0, 2000.0, 2010.0, 2020.0, 2025.0, 2030.0, 2040.0, 2050.0, 2060.0, 2070.0, 2075.0, 2080.0, 2090.0, 2100.0, 2110.0, 2120.0, 2125.0, 2130.0, 2140.0, 2150.0, 2160.0, 2170.0, 2175.0, 2180.0, 2190.0, 2200.0, 2210.0, 2220.0, 2225.0, 2230.0, 2240.0, 2250.0, 2260.0, 2270.0, 2275.0, 2280.0, 2290.0, 2300.0, 2310.0, 2320.0, 2325.0, 2330.0, 2340.0, 2350.0, 2360.0, 2370.0, 2375.0, 2380.0, 2390.0, 2400.0, 2405.0, 2410.0, 2415.0, 2420.0, 2425.0, 2430.0, 2435.0, 2440.0, 2445.0, 2450.0, 2455.0, 2460.0, 2465.0, 2470.0, 2475.0, 2480.0, 2485.0, 2490.0, 2495.0, 2500.0, 2505.0, 2510.0, 2515.0, 2520.0, 2525.0, 2530.0, 2535.0, 2540.0, 2545.0, 2550.0, 2555.0, 2560.0, 2565.0, 2570.0, 2575.0, 2580.0, 2585.0, 2590.0, 2595.0, 2600.0, 2605.0, 2610.0, 2615.0, 2620.0, 2625.0, 2630.0, 2635.0, 2640.0, 2645.0, 2650.0, 2655.0, 2660.0, 2665.0, 2670.0, 2675.0, 2680.0, 2685.0, 2690.0, 2695.0, 2700.0, 2705.0, 2710.0, 2715.0, 2720.0, 2725.0, 2730.0, 2735.0, 2740.0, 2745.0, 2750.0, 2755.0, 2760.0, 2765.0, 2770.0, 2775.0, 2780.0, 2785.0, 2790.0, 2795.0, 2800.0, 2805.0, 2810.0, 2815.0, 2820.0, 2825.0, 2830.0, 2835.0, 2840.0, 2845.0, 2850.0, 2855.0, 2860.0, 2865.0, 2870.0, 2875.0, 2880.0, 2885.0, 2890.0, 2895.0, 2900.0, 2905.0, 2910.0, 2915.0, 2920.0, 2925.0, 2930.0, 2935.0, 2940.0, 2945.0, 2950.0, 2955.0, 2960.0, 2965.0, 2970.0, 2975.0, 2980.0, 2985.0, 2990.0, 2995.0, 3000.0, 3005.0, 3010.0, 3015.0, 3020.0, 3025.0, 3030.0, 3035.0, 3040.0, 3045.0, 3050.0, 3055.0, 3060.0, 3065.0, 3070.0, 3075.0, 3080.0, 3085.0, 3090.0, 3095.0, 3100.0, 3105.0, 3110.0, 3115.0, 3120.0, 3125.0, 3130.0, 3135.0, 3140.0, 3145.0, 3150.0, 3155.0, 3160.0, 3165.0, 3170.0, 3175.0, 3180.0, 3185.0, 3190.0, 3195.0, 3200.0, 3205.0, 3210.0, 3215.0, 3220.0, 3225.0, 3230.0, 3235.0, 3240.0, 3245.0, 3250.0, 3255.0, 3260.0, 3265.0, 3270.0, 3275.0, 3280.0, 3285.0, 3290.0, 3295.0, 3300.0, 3305.0, 3310.0, 3315.0, 3320.0, 3325.0, 3330.0, 3335.0, 3340.0, 3345.0, 3350.0, 3355.0, 3360.0, 3365.0, 3370.0, 3375.0, 3380.0, 3385.0, 3390.0, 3395.0, 3400.0, 3405.0, 3410.0, 3415.0, 3420.0, 3425.0, 3430.0, 3435.0, 3440.0, 3445.0, 3450.0, 3455.0, 3460.0, 3465.0, 3470.0, 3475.0, 3480.0, 3485.0, 3490.0, 3495.0, 3500.0, 3505.0, 3510.0, 3520.0, 3525.0, 3530.0, 3540.0, 3550.0, 3560.0, 3570.0, 3575.0, 3580.0, 3590.0, 3600.0, 3625.0, 3650.0, 3675.0, 3700.0, 3725.0, 3750.0, 3775.0, 3800.0, 3850.0, 3900.0, 3950.0, 4000.0, 4050.0, 4100.0, 4200.0, 4300.0, 4400.0, 4500.0, 4600.0, 4700.0, 4800.0, 4900.0])

strikes = [strike for strike in chain.strikes
        if strike % 5 == 0 and 3000 < strike < 3500]

print(strikes)
# [3005.0, 3010.0, 3015.0, 3020.0, 3025.0, 3030.0, 3035.0, 3040.0, 3045.0, 3050.0, 3055.0, 3060.0, 3065.0, 3070.0, 3075.0, 3080.0, 3085.0, 3090.0, 3095.0, 3100.0, 3105.0, 3110.0, 3115.0, 3120.0, 3125.0, 3130.0, 3135.0, 3140.0, 3145.0, 3150.0, 3155.0, 3160.0, 3165.0, 3170.0, 3175.0, 3180.0, 3185.0, 3190.0, 3195.0, 3200.0, 3205.0, 3210.0, 3215.0, 3220.0, 3225.0, 3230.0, 3235.0, 3240.0, 3245.0, 3250.0, 3255.0, 3260.0, 3265.0, 3270.0, 3275.0, 3280.0, 3285.0, 3290.0, 3295.0, 3300.0, 3305.0, 3310.0, 3315.0, 3320.0, 3325.0, 3330.0, 3335.0, 3340.0, 3345.0, 3350.0, 3355.0, 3360.0, 3365.0, 3370.0, 3375.0, 3380.0, 3385.0, 3390.0, 3395.0, 3400.0, 3405.0, 3410.0, 3415.0, 3420.0, 3425.0, 3430.0, 3435.0, 3440.0, 3445.0, 3450.0, 3455.0, 3460.0, 3465.0, 3470.0, 3475.0, 3480.0, 3485.0, 3490.0, 3495.0]

expirations = sorted(exp for exp in chain.expirations)[:3]
print(expirations)
# ['20200820', '20200917', '20201015']

取得方法2.商品情報から取得

先物オプションのES(S&P 500ミニ(E-mini S&P 500))などの場合は、このような方法を使用します。
もちろん他に方法があるかも知れませんが、これでも取得することが可能です。

以下の例は、取引所やトレーディングクラス、権利行使価格を限定にしています。全て取得する場合は、コメントアウトを外してください。

Cont = [cd.contract for cd in ib.reqContractDetails(FuturesOption(symbol='ES'))]

exchanges = []
tradingClasses = []
strikes = []
expirations = []

for Details in Cont:
    exchanges.append(Details.exchange)
    tradingClasses.append(Details.tradingClass)
#     expirations.append(Details.lastTradeDateOrContractMonth)
#     strikes.append(Details.strike)
    if Details.exchange == 'GLOBEX' and Details.tradingClass == 'ES':
        expirations.append(Details.lastTradeDateOrContractMonth)
        if 3000 < Details.strike < 3500:
            strikes.append(Details.strike)

exchanges = sorted(set(exchanges))
tradingClasses = sorted(set(tradingClasses))
strikes = sorted(set(strikes))
expirations = sorted(set(expirations))

print(exchanges)
# ['GLOBEX']

print(tradingClasses)
# ['E1A', 'E1C', 'E2A', 'E2C', 'E3A', 'E3C', 'E4A', 'E4C', 'E5C', 'ES', 'EW', 'EW1', 'EW2', 'EW3', 'EW4']

print(strikes)
# [3010.0, 3020.0, 3025.0, 3030.0, 3040.0, 3050.0, 3060.0, 3070.0, 3075.0, 3080.0, 3090.0, 3100.0, 3110.0, 3120.0, 3125.0, 3130.0, 3140.0, 3150.0, 3160.0, 3170.0, 3175.0, 3180.0, 3190.0, 3200.0, 3210.0, 3220.0, 3225.0, 3230.0, 3240.0, 3250.0, 3260.0, 3270.0, 3275.0, 3280.0, 3290.0, 3300.0, 3310.0, 3320.0, 3325.0, 3330.0, 3340.0, 3350.0, 3360.0, 3370.0, 3375.0, 3380.0, 3390.0, 3400.0, 3410.0, 3420.0, 3425.0, 3430.0, 3440.0, 3450.0, 3460.0, 3470.0, 3475.0, 3480.0, 3490.0]

print(expirations)
# ['20200918', '20201218', '20210319', '20210618']

補足

商品情報のまとめ方

TICKデータなどの取得の際に、限月や権利行使価格などの違いの商品情報をまとめる必要があります。

上記のように取得したあとのまとめ方の例を紹介します。

expirationstrikeは上記の取得したリスト型データになります。

rights = ['P', 'C']

contracts = [
    Contract(
        secType='FOP', 
        symbol='ES', 
        lastTradeDateOrContractMonth=expiration, 
        strike=strike, 
        right=right, 
        exchange='GLOBEX', 
        tradingClass='ES'
    )
        for right in rights
        for expiration in expirations
        for strike in strikes
]
contracts = ib.qualifyContracts(*contracts)

以下のようにした方が、スッキリするかも知れません。

rights = ['P', 'C']

contracts = [Option('SPX', expiration, strike, right, 'CBOE', tradingClass='SPX')
        for right in rights
        for expiration in expirations
        for strike in strikes]

contracts = ib.qualifyContracts(*contracts)
secTypeには、Option(OPT)とFuturesOption(FOP)がありますので注意してください。

コメント

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