0

I'm using python to connect to TWS API and pull values.

My first script:

#use option chain csv to get prics

from datetime import datetime
from threading import Thread
import time
from ibapi.client import EClient, Contract
from ibapi.wrapper import EWrapper
from ibapi.utils import iswrapper
import math
import pandas as pd
import numpy as np

#import ticker and option expiry from option_chain
from option_chain_06 import ticker, option_dates

global q_up, q_down, vt
q_down = 0
q_up = 0
vt = 0
#set ticker variable
#ticker = 'AAPL'

#df = pd.read_csv('C:/Users/Mischa/Documents/Options/'+ticker+'option_chain.csv')

class TestApp(EWrapper, EClient):

    def __init__(self, addr, port, client_id):
        EWrapper.__init__(self)
        EClient. __init__(self, self)

        self.current_price = 0
        self.current_IV = 0
        self.opt_bid_price = 0
        self.opt_ask_price = 0
        self.opt_last_price = 0
        self.opt_close_price = 0
        self.opt_mid_price = 0


        # Connect to TWS
        self.connect(addr, port, client_id)
        print('connect')
        # Launch the client thread
        thread = Thread(target=self.run)
        thread.start()

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

    @iswrapper
    def tickByTickMidPoint(self, reqId, time, midpoint):
        self.current_price = midpoint

    @iswrapper
    def tickGeneric(self, reqId, tickType, value):
        if tickType == 24:  
        
def get_option_price(client, ticker, option_dates, q_up, q_down, vt):

    df = pd.read_csv('C:/Users/Mischa/Documents/Options/'+ticker+'option_chain.csv')

    a = 1.5

    date = option_dates[0]
    current_date = datetime.today().date()
    exp_date = datetime.strptime(date, '%Y%m%d').date()
    interval = (exp_date - current_date).days

    #define contract
    contract = Contract()
    contract.symbol = ticker
    contract.secType = 'STK'
    contract.multiplier = '100'
    contract.exchange = 'SMART'
    contract.currency = 'USD'

    client.reqTickByTickData(0, contract, "MidPoint",1 , True)
    time.sleep(4)   
    print(client.current_price)

    #get IV
    client.reqMktData(1, contract, '106', False, False, [])
    time.sleep(1)

    #get q up and q down
    vt = client.current_IV * math.sqrt(interval/365)

    q_up = client.current_price * math.exp(a*vt)
    q_down = client.current_price * math.exp(-a*vt)
    
    #round q_down down, round q_up up
    q_down = math.floor(q_down)
    q_up = math.ceil(q_up)
    
    return q_down, q_up, vt


def main(ticker, option_dates, q_up, q_down, vt):
    client = TestApp('127.0.0.1', 7497, 129)

    q_down, q_up, vt = get_option_price(client, ticker, option_dates, q_up, q_down, vt)
    print(q_down, q_up, vt)
    return q_down, q_up, vt
    client.done=True
    client.disconnect()


if __name__  == '__main__':
    main(ticker, option_dates, q_up, q_down, vt)

It prints out the values for the 3 variables I want in def(main)

Then I try importing those 3 vairables (q_up, q_down, vt) into another script:

#use option chain csv to get prics

from datetime import datetime
from threading import Thread
import time
from ibapi.client import EClient, Contract
from ibapi.wrapper import EWrapper
from ibapi.utils import iswrapper
import math
import pandas as pd
import numpy as np
#import q's, IV from other file
from option_prices_03 import q_up, q_down, vt, ticker
print(ticker, q_down, q_up, vt)

And I get error:

ImportError: cannot import name 'q_up' from 'option_prices_03' (C:\TWS API\source\pythonclient\tests\option_prices_03.py)

I've tested just setting the 3 variables at the beginning of the first script (option_prices_03.py) and importing them and that works. But it won't import the variables as they are being assigned.

EDIT: tried making the variables global:

def get_option_price(client, ticker, option_dates):

    df = pd.read_csv('C:/Users/Mischa/Documents/Options/'+ticker+'option_chain.csv')
    global q_up, q_down, vt
    q_down = 0
    q_up = 0
    vt = 0
    a = 1.5
    date = option_dates[0]
    current_date = datetime.today().date()
    exp_date = datetime.strptime(date, '%Y%m%d').date()
    interval = (exp_date - current_date).days

Still get the same error.

Tried adding a "return" to if __name__ == '__main__': and got a Syntax error:

if __name__  == '__main__':
    main(ticker, option_dates, q_up, q_down, vt)
    return q_up

> SyntaxError: 'return' outside function
Mitch
  • 553
  • 1
  • 9
  • 24
  • 1
    You have not defined `q_up` globally. – Countour-Integral Feb 12 '21 at 20:49
  • I added "global q_up, q_down, vt" in the get_option_price() function and it still doesn't work – Mitch Feb 12 '21 at 20:56
  • Place the variable definitions outside the function. – Countour-Integral Feb 12 '21 at 20:58
  • It just imports the variables originally set to 0. basically ignoring anything done to them in the functions – Mitch Feb 12 '21 at 21:02
  • You have to call a function in order for it to get executed and right now you are doing it inside of the `if __name__ == '__main__' ` block which fails when you import something – Countour-Integral Feb 12 '21 at 21:04
  • So how do I make the variables available outside the if __name__ == '__main__'? – Mitch Feb 12 '21 at 21:08
  • **how do I make the variables available outside** You just put them outside of `name == 'main'` to be globally available. You probably expect them to have a specific value from the function `get_option_price` (which then you should be calling outside of the if block) but it is not clear what you are trying to do. Your code is far from reproducible and we cannot reliably help unless you provide a [MRE](https://stackoverflow.com/help/minimal-reproducible-example) – Countour-Integral Feb 12 '21 at 21:16
  • Ok updated it with the full code from the first script, showing where I set them as global variables. And updated the functions to import them – Mitch Feb 12 '21 at 21:23

1 Answers1

0

It prints out the values for the 3 variables I want

Based on this, I assume you want q_up, q_down, vt to have the values that are printed in main, when you import them, so you declare them as global there.

# ... all the code before 
# global q_up, q_down, vt <- This makes no sense, remove it, they are already global 
q_down = 0
q_up = 0
vt = 0
# ... rest of the code

def main(ticker, option_dates): # Remove the globals from parameters
    global q_up, q_down, vt # Here as global
    client = TestApp('127.0.0.1', 7497, 129)

    q_down, q_up, vt = get_option_price(client, ticker, option_dates, q_up, q_down, vt)
    print(q_down, q_up, vt)
    return q_down, q_up, vt

After this it would probably be better to remove the global from get_option_price and have it only inside main function.

def get_option_price(client, ticker, option_dates):

    df = pd.read_csv('C:/Users/Mischa/Documents/Options/'+ticker+'option_chain.csv')
    # Remove this -> global q_up, q_down, vt
    q_down = 0
    # ...

All that is left to do is call main before the if

main(ticker, option_dates, q_up, q_down, vt)
if __name__  == '__main__':
    pass  # Why do you even have this?

Now since they are defined globally, there will be no import problems.

Not sure if this is exactly what you want, but it gives a possible solution to the problem. Defenitely check on variable scope (here for example)

Countour-Integral
  • 1,138
  • 2
  • 7
  • 21