I created a variable conID
in one function and I want to use it in another. Both functions are inside a class.
The problem is that in the second function the first function is called, so self.reqSecDefOptParams
calls the first function. And after that conID
receives it value. If I try to output condID
in the second function I can't, it says its value is still None
. Is there a way to first call the first function and then output the value in the same function?
The first function:
def contractDetails(self, reqId: int, contractDetails: ContractDetails):
string = str((contractDetails))
letter_list = string.split(",")
print(letter_list)
conID = letter_list[90] # the variable I need
The second function:
def start(self):
# using the variable again
self.reqSecDefOptParams(1, contract.symbol, "", "STK", conID)
Update: I get an error connecting to the socket. What can I do?
Error: 4 10167 Requested market data is not subscribed. Displaying delayed market data. Error: 4 10090 Part of requested market data is not subscribed. Subscription-independent ticks are still active.Delayed market data is available.AAPL NASDAQ.NMS/TOP/ALL unhandled exception in EReader thread Traceback (most recent call last): File "C:\Programming\TWS\source\pythonclient\ibapi\reader.py", line 34, in run data = self.conn.recvMsg() File "C:\Programming\TWS\source\pythonclient\ibapi\connection.py", line 99, in recvMsg buf = self._recvAllMsg() File "C:\Programming\TWS\source\pythonclient\ibapi\connection.py", line 119, in _recvAllMsg buf = self.socket.recv(4096) OSError: [WinError 10038] An operation was attempted on something that is not a socket
Process finished with exit code 0
Your last question had more information, I upvoted so I could find it but it disappeared. I will just fix up that code so you can see how it works in interaction with the API.
There are at least 2 ways to get option contracts. The first is just ask for them but don't fill out all the parameters, then contractDetails will return all matching contracts. The second is to just ask for all parameters but you won't know if all contracts are traded.
I put numbers in the code comments for an idea of how the program flow works.
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.common import TickerId, SetOfFloat, SetOfString, MarketDataTypeEnum
from ibapi.contract import Contract, ContractDetails
from ibapi.ticktype import TickType
class TestApp(EClient, EWrapper):
def __init__(self):
EClient.__init__(self, self)
self.underlyingContract = None
self.opts = []
self.optParams = ()
self.greeks = []
def error(self, reqId:TickerId, errorCode:int, errorString:str):
print("Error: ", reqId, "", errorCode, "", errorString)
def nextValidId(self, orderId):
self.start() #1
def contractDetails(self, reqId:int, contractDetails:ContractDetails, ):
if contractDetails.contract.secType == "OPT":#2,3 (2 contracts, P+C)
self.opts.append(contractDetails.contract)
if contractDetails.contract.secType == "STK":#4
self.underlyingContract = contractDetails.contract
self.reqSecDefOptParams(3,self.underlyingContract.symbol,"","STK",
self.underlyingContract.conId)#5
def contractDetailsEnd(self, reqId):
print("\ncontractDetails End\n")#3,4
def securityDefinitionOptionParameter(self, reqId:int, exchange:str,
underlyingConId:int, tradingClass:str, multiplier:str,
expirations:SetOfString, strikes:SetOfFloat):
#6
self.optParams = (exchange, underlyingConId, tradingClass, multiplier, expirations, strikes)
def securityDefinitionOptionParameterEnd(self, reqId:int):
print("SecurityDefinitionOptionParameterEnd. ReqId",reqId)
# make a contract out of params or just use contract from earlier
if len(self.opts) > 0:
self.reqMktData(4,self.opts[0],"",False,False,[])#7
def tickOptionComputation(self, reqId:TickerId, tickType:TickType,
impliedVol:float, delta:float, optPrice:float, pvDividend:float,
gamma:float, vega:float, theta:float, undPrice:float):
self.greeks.append([optPrice,delta,impliedVol,undPrice]) #8
# just stop after first callback but you could set a time or something else
# if you don't get data, the program won't end unless you ctrl-c or something
self.stop() #9
def start(self):
# get some option contracts, not all
opts = Contract()
opts.symbol = 'AAPL'
opts.secType = 'OPT'
opts.exchange = 'SMART'
opts.currency = 'USD'
opts.strike="140"
#opts.right="P" # ambiguous so as to get multiple contracts
opts.multiplier="100"
opts.lastTradeDateOrContractMonth = '20211015'
self.reqContractDetails(1, opts) #2
# get just underlying conId
underlying = Contract()
underlying.symbol = 'AAPL'
underlying.secType = 'STK'
underlying.exchange = 'SMART'
underlying.currency = 'USD'
self.reqContractDetails(2, underlying) #4
# in case you don't have data subscription
self.reqMarketDataType(MarketDataTypeEnum.DELAYED)
def stop(self):
self.disconnect() #10
app = TestApp()
app.connect("127.0.0.1", 7497, 123)
app.run() # starts a reader thread that will block until disconnect()
#11 after disconnect, program can continue
# I just do this so I can use spyder variable inspector but you could print
uc = app.underlyingContract
opts = app.opts
params = app.optParams
greeks = app.greeks