Interactive Brokers - Obtain Historical Data of OPT (MIDPOINT and TRADES)

7.7k views Asked by At

I am trying to obtain both the underlying and options written on SPY via the Interactive Brokers API, and while obtaining current options (with strike, right etc.) is not a problem, I am stuck with obtaining historical data say from 5 months back to now.

The code is as follows:

from ib.ext.Contract import Contract
from ib.ext.ContractDetails import ContractDetails
from ib.opt import ibConnection, message
import time
import datetime

def watcher(msg):
    print(msg)

def contractDetailsHandler(msg):
    contracts.append(msg.contractDetails.m_summary)

def contractDetailsEndHandler(msg):
    global DataWait
    DataWait =  False

def contractHistDetailsHandler(msg):
    contracts.append(msg.contractDetails.m_summary)


con = ibConnection()
con.host = "..."
con.port = ...
con.clientId = 5
con.registerAll(watcher)
con.register(contractDetailsHandler, 'ContractDetails')
con.register(contractDetailsEndHandler, 'ContractDetailsEnd')
con.register(contractHistDetailsHandler, message.historicalData)

con.connect()

contract = Contract()
contract.m_exchange     = "SMART"
contract.m_secType      = "OPT"
contract.m_symbol       = "SPY"
contract.m_currency     = "USD"

endtime = '20170102 01:00:00'

#con.reqContractDetails(1, contract)

con.reqHistoricalData(2,contract,endtime,"5 M","1 sec","TRADES",0,1)
con.reqHistoricalData(3,contract,endtime,"5 M","1 sec","MIDPOINT",0,1)

contracts = []

DataWait = True  ;  i = 0
while DataWait and i < 90:
    i += 1 ; print(i),
    time.sleep(1)

con.disconnect()
con.close()

print(contracts)

All I get is:

<error id=2, errorCode=321, errorMsg=Error validating request:-'yd' : cause - When the local symbol field is empty, please fill all option fields (right, strike, expiry))>

Now I am aware that the Contract object does not contain those, but how can one know the right, strike and expiry? That's basically what I need (with a date and underlying changes during the option). Is there a different method for that?

If you could give me some pointers it'd be most welcome! Or an alternate source of either underlying and options w/ strike, right and expiry for the selected range (be it paid or not; need it for a uni project).

Thank you very much before-hand! Any input is much appreciated.

2

There are 2 answers

0
kbcool On BEST ANSWER

I don't have enough reputation to comment which I would like to on this question rather than submit an answer but everything I have read says that you cannot retrieve historical data for expired options contracts through the IB API.

In fact the URL (https://www.interactivebrokers.com/en/software/api/apiguide/tables/historical_data_limitations.htm) mentioned by Brian quotes the following:

Historical data requests are only available for current expirations.

So you are likely wasting your time. Historical options data can be huge so I understand why. It's also very expensive, cheap enough for end of day - you can get it from http://ivolatility.com but intraday gets expensive. I use https://datashop.cboe.com but their speed of service and customer service skills are certainly lacking but being able to ask for just one instrument, any period of time and frequency you want is flexibility I like.

0
brian On

You are commenting out the request for the contractDetails. You need to do that but you're going to get a lot (I get ~5000). To narrow it down a bit try setting some expiries, strikes, and right.

eg. for all 230 calls

contract.m_strike = 230
contract.m_right = "CALL"

Then I only get 30 contracts.

In contractDetailsEndHandler(msg): you'll know you've received all the contracts. After that just call reqHistData using the Contract from the contracts[] you're making. It will have all the fields filled out.

Note that there's limitations to the amount of historical data you can get. Estimate 2000 bars for each request, so 2000 seconds of 1s bars is all you can get per request. And one request for every 10 seconds. I'm not even sure option historical data goes back 5 months. When asking for historical data on expired contracts you'll need to set contract.m_includeExpired = True

https://www.interactivebrokers.com/en/software/api/apiguide/tables/historical_data_limitations.htm