As the title indicates, I am trying to get the price of a given security from TWS API and use it as a variable in my program elsewhere. The below code (straight from one of Interactive Broker's tutorials) will run and print the price out on the screen but I haven't been able to alter it in a way that works in getting to create a variable/object that contains the price. The code also only works about once in every ten tries, if there is something I'm doing wrong there, please let me know.
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
from ibapi.ticktype import TickTypeEnum
class TestApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
def error(self, reqId, errorCode, errorString):
print('Error: ', reqId, ' ', errorCode, ' ', errorString)
def tickPrice(self, reqId, tickType, price, attrib):
print('Tick Price. Ticker Id:', reqId, 'tickType:', TickTypeEnum.to_str(tickType),
'Price:', price, end=' ')
def main():
app = TestApp()
app.connect('127.0.0.1', 7496, 0)
contract = Contract()
contract.symbol = 'AAPL'
contract.secType = 'STK'
contract.currency = 'USD'
contract.exchange = 'SMART'
app.reqMarketDataType(1)
app.reqMktData(1, contract, '', False, False, [])
app.run()
if __name__ == '__main__':
main()
The program doesn't take into account the asynchronous nature of the api.
#here you are asking to connect, you must wait for a connection
app.connect('127.0.0.1', 7496, 0)
contract...
# you may not have a connection and you're not listeneing for responses yet.
app.reqMarketDataType(1)
app.reqMktData(1, contract, '', False, False, [])
# here is where you start listening for responses, that's what run() does
app.run()
I would write it like this
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
from ibapi.ticktype import TickTypeEnum
from ibapi.common import *
class TestApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
# here you can add variables to the TestApp class, just use self.var in the class
self.last = 0;
# ib suggests waiting for this response to know that you have a connection
def nextValidId(self, orderId:int):
self.reqMarketDataType(MarketDataTypeEnum.REALTIME) # or DELAYED
contract = Contract()
contract.symbol = "AAPL"
contract.secType = "STK"
contract.currency = "USD"
contract.exchange = "SMART"
self.reqMktData(1, contract, "", False, False, None)
def error(self, reqId, errorCode, errorString):
print('Error: ', reqId, ' ', errorCode, ' ', errorString)
def tickPrice(self, reqId, tickType, price, attrib):
print('Tick Price. Ticker Id:', reqId, 'tickType:', TickTypeEnum.to_str(tickType),
'Price:', price)
if tickType == TickTypeEnum.LAST or tickType == TickTypeEnum.DELAYED_LAST :
self.last = price;
print("disconnecting")
self.disconnect() # just for testing, normally the program would do something
def main():
app = TestApp()
app.connect('127.0.0.1', 7497, 123)
app.run() # this blocks the program until disconnect()
print("app.last:", app.last) # now you refer to the variable by class.var
if __name__ == '__main__':
main()