Search code examples
pythoninteractive-brokerstws

How update parameters of a function tickPrice() with values from contractDetails()?


I want to get values from the function tickPrice() using values from contractDetails().

To do this I'm trying to pass the results from contractDetails() to the parameters for tickPrice(), but when I try setting the parameters in the contractDetails() function I get an error that the variables are not defined.

Here is my code so far:

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.common import *
from ibapi.contract import *
import pandas as pd
from threading import Timer


class TestApp(EWrapper, EClient):
    def __init__(self):
        EWrapper.__init__(self)
        EClient.__init__(self, self)


    def error(self, reqId, errorCode, errorString):
        print("Error: ", reqId, " ", errorCode, " ", errorString)

    def nextValidId(self, orderId):
        self.start()

    def contractDetails(self, reqId, contractDetails):

        contract.lastTradeDateOrContractMonth = contractDetails.realExpirationDate
        contract.strike = contractDetails.contract.strike
        contract.right = contractDetails.contract.right

        def tickPrice(self, reqId, tickType, price, attrib):
            if tickType == 4  and reqId == 1:
                print(price)

    def contractDetailsEnd(self, reqId):
        print("\ncontractDetails End\n")
        self.stop()

    def start(self):

        contract = Contract()
        contract.symbol = 'AAPL'
        contract.secType = 'OPT'
        contract.currency = 'USD'
        contract.exchange = 'SMART'
        contract.multiplier = '100'
        contract.lastTradeDateOrContractMonth = '20200619'
        contract.strike = '180'
        contract.right = 'C'

        self.reqContractDetails(1, contract)
        self.reqMktData(1, contract, '101', False, False, [])

    def stop(self):
        self.done=True
        self.disconnect()
        print('disconnect')

def main():
    print('start')
    app = TestApp()
    app.nextOrderId = 0
    app.connect('127.0.0.1',7497,108)
    #Timer(4, app.stop).start()
    app.run()
    print('finish')
if __name__ == "__main__":
    main()

Error:

contract.lastTradeDateOrContractMonth = contractDetails.realExpirationDate
NameError: name 'contract' is not defined

I'm not able to set the 3 remaining variables:

contract.lastTradeDateOrContractMonth = contractDetails.realExpirationDate
contract.strike = contractDetails.contract.strike
contract.right = contractDetails.contract.right

With the results from contractDetails().

This would allow me to loop through all the parameters.


Solution

  • You're setting fields of the contract object before defining the object. It looks like you want contract to be an instance variable, so I'd add the following code to the __init__ method:

    def __init__(self):
        EWrapper.__init__(self)
        EClient.__init__(self, self)
        self.contract = None
    

    Then replace contract with self.contract throughout the rest of the methods.