从其他脚本导入变量时出现“ImportError: cannot import name ...”

问题描述

我正在使用 python 连接到 TWS API 并提取值

我的第一个脚本:

#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,client_id)
        print('connect')
        # Launch the client thread
        thread = Thread(target=self.run)
        thread.start()

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

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

    @iswrapper
    def tickGeneric(self,tickType,value):
        if tickType == 24:  
        
def get_option_price(client,ticker,option_dates,q_up,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,'106',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,vt


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

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


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

它在 def(main) 中打印出我想要的 3 个变量的值

然后我尝试将这 3 个变量(q_up、q_down、vt)导入另一个脚本:

#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,vt,ticker
print(ticker,vt)

我得到错误

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

我已经测试过在第一个脚本 (option_prices_03.py) 的开头设置了 3 个变量并导入它们,这很有效。但它不会在分配变量时导入它们。

编辑:尝试将变量设为全局:

def get_option_price(client,option_dates):

    df = pd.read_csv('C:/Users/Mischa/Documents/Options/'+ticker+'option_chain.csv')
    global q_up,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

仍然出现同样的错误

尝试向 if __name__ == '__main__': 添加“返回”并出现语法错误

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

> SyntaxError: 'return' outside function

解决方法

它打印出我想要的 3 个变量的值

基于此,我假设您希望 q_up,q_down,vt 具有打印在 main 中的值,当您导入它们时,因此您在那里将它们声明为全局。

# ... all the code before 
# global q_up,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,vt # Here as global
    client = TestApp('127.0.0.1',7497,129)

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

在此之后,最好从 global 中删除 get_option_price 并将其仅包含在 main 函数中。

def get_option_price(client,option_dates):

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

剩下要做的就是在 if 之前调用 main

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

现在因为它们是全局定义的,所以不会有导入问题。

不确定这是否正是您想要的,但它为问题提供了可能的解决方案。绝对检查变量范围(例如here