Reputation: 452
I am trying to build option chain data much like the major exchanges present it on their websites IE: Sort by expiration dates, then strike prices and display the bids/asks for the puts/calls etc.
I am trying to get the data but have only been able to obtain the expiry and strike prices.
I am using their ibapi library with TWS
I have tried using the reqSecDefOptParams()
but keep receiving errors like: Error: 1 321 Error validating request.-'cB' : cause - Invalid security type -
Here is my code:
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
class OptionDataApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
def error(self, reqId, errorCode, errorString):
print("Error:", reqId, errorCode, errorString)
def contractDetails(self, reqId, contractDetails):
contract = contractDetails.contract
print("Symbol:", contract.symbol)
print("Expiry:", contract.lastTradeDateOrContractMonth)
print("Strike Price:", contract.strike)
self.request_option_chain(contract)
def request_option_chain(self, contract):
self.reqSecDefOptParams(
1, contract.exchange, "", contract.tradingClass, contract.conId
)
def contractDetailsEnd(self, reqId):
self.disconnect()
def main():
app = OptionDataApp()
app.connect("127.0.0.1", 7496, clientId=0)
contract = Contract()
contract.symbol = "AAPL" # Specify the symbol for which you want option data
contract.secType = "OPT"
contract.exchange = "SMART"
contract.currency = "USD"
app.reqContractDetails(1, contract)
app.run()
if __name__ == "__main__":
main()
This codes prints what appears to be all the Expiry/Strike prices one after the other like this:
Symbol: AAPL
Expiry: 20230811
Strike Price: 105.0
Symbol: AAPL
Expiry: 20230811
Strike Price: 115.0
And then at the end(with a few mixed in the above data), many errors like this:
Error: 1 321 Error validating request.-'cB' : cause - Invalid security type -
Error: 1 321 Error validating request.-'cB' : cause - Invalid security type -
Error: 1 321 Error validating request.-'cB' : cause - Invalid security type -
Error: 1 321 Error validating request.-'cB' : cause - Invalid security type -
Any help would be appreciated, Thanks
Upvotes: 3
Views: 6146
Reputation: 21
You have two main problems with your code. reqContractDetails can build the options chain if you leave it ambiguous (not fully specified) but is slow and throttled. You just need to save each received contract at contractDetails like:
def contractDetails(self, reqId, contractDetails):
super().contractDetails(reqId, contractDetails)
self.chain.append(contractDetails.contract)
of course you need to set chain = []
at some place like __init__
or reqContractDetails
.
Now that you have the chain (list of contracts) you need to request the prices for each one and process them tick by tick.
reqSecDefOptParams
is faster but then you have to loop to create the chain like:
for expiry in expirations:
for strike in strikes:
for right in ["C", "P"]:
# create a contract object
self.temp = Contract()
self.temp.secType = 'OPT' # mandatory
self.temp.exchange = exchange # mandatory
self.temp.currency = 'USD'
# either localSymbol
#self.temp.localSymbol = f"{self.underlyingSymbol;<6}{expiry[-6:]}C{int(strike*1000):08d}")
# or
self.temp.symbol = self.underlyingSymbol
self.temp.right = right
self.temp.lastTradeDateOrContractMonth = expiry
self.temp.strike = strike
self.chain.append(self.temp)
inside securityDefinitionOptionParameter
Remember that this is all asynchronous, so if you call app.run()
main will be blocked until app.disconnect()
You may want to put it in a thread.
Upvotes: 2
Reputation: 2563
You already obtained the option contract parameters (strike, expiry etc) and then you're running the same request again in request_option_chain
which doesn't make sense.
As per the official API page: "IBApi::EClient::reqSecDefOptParams returns a list of expiries and a list of strike prices."
You're already getting this when making a reqContractDetails
request.
Bids and asks are received via a call to request ticks, for example reqTickByTickData
.
Upvotes: 1