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.
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.