我写了下面复制的程序。当我尝试在输入文件中执行以下数据时: ADBE,USD,纳斯达克 CSCO,USD,纳斯达克 GOOGL,美元,纳斯达克
它仅对第一个库存ADBE运行,之后不执行任何操作。想法是该程序应针对输入文件中的每个条目运行,并从InteractiveBrokers下载相应的分析师预测并将其写入XML文件。
能否请您帮助我确定问题,为什么它仅在输入文件的第一行运行?
非常感谢。
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
import time
class TestApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
def error(self, reqId, errorCode, errorString):
print("Error: ", reqId, "", errorCode, "", errorString)
def fundamentalData(self, reqId, fundamental_data):
Filename = str(Symbol) + '_Anal_Est.xml'
print("Filename: ", Filename)
f_out = open(Filename, "w")
f_out.write(fundamental_data)
f_out.close()
def main():
global Symbol
# The input file need to contain in each line: company ticker,currency,exchange - no spaces between them
Company_tickers = open("IB_FD_input.txt", 'r').readlines() # reads a file with companies tickers in one column
#print("Company_tickers: ", Company_tickers)
Number_compnaies = len(Company_tickers)
Company_count = 0
for stock in Company_tickers:
aa = stock.split(",")
Symbol = aa[0].replace(" ", "") # in case there is a space
Currency = aa[1].replace(" ", "")
Exchange = aa[2].replace("\n", "").replace(" ","") # need to remove the \n as it is the last field in the entry line
contract = Contract() # defining the stock to download the fundamental data from IB
contract.symbol = Symbol
contract.secType = "STK"
contract.exchange = "SMART"
contract.currency = Currency
contract.primaryExchange = Exchange
print("Contract: ", contract)
Company_count += 1 # To show progress on screen
print("\n\n" + "**********************" + "\n")
print(" " + Symbol + ": # " + str(Company_count) + " / " + str(Number_compnaies))
print("\n" + "**********************" + "\n")
app = TestApp()
app.connect("127.0.0.1", 7496, 0)
time.sleep(10)
app.reqFundamentalData(8001, contract, "RESC", [])
time.sleep(10)
app.run()
if __name__ == "__main__":
main()
答案 0 :(得分:0)
除非您要制作一个多线程应用程序,否则必须异步计划它,以便处理程序流中的每个逻辑请求->响应。
一旦调用app.run(),程序就会陷入从tws循环读取的过程中。
我将在代码中发表评论以进行解释。
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
import time
class TestApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
self.firstReqId = 8001 # remember starting id
self.contracts={} # keep in dict so you can lookup
self.contNumber = self.firstReqId
def addContracts(self, cont):
self.contracts[self.contNumber]=cont # add to dict using 8001 first time
self.contNumber+=1 # next id will be 8002 etc.
def nextValidId(self, orderId:int):
# now you are connected, ask for data, no need for sleeps
# this isn't the only way to know the api is started but it's what IB recommends
self.contNumber = self.firstReqId # start with first reqId
self.getNextData()
def error(self, reqId, errorCode, errorString):
print("Error: ", reqId, "", errorCode, "", errorString)
# if there was an error in one of your requests, just contimue with next id
if reqId > 0 and self.contracts.get(self.contNumber):
# err in reqFundametalData based on reqid existing in map
print('err in', self.contracts[reqId].symbol)
self.getNextData() # try next one
def fundamentalData(self, reqId, fundamental_data):
# note no need for globals, we have a dict of contracts
Filename = self.contracts[reqId].symbol + '_Anal_Est.xml'
print("Filename: ", Filename)
f_out = open(Filename, "w")
f_out.write(fundamental_data)
f_out.close()
self.getNextData() # finished on request see if there are more
def getNextData(self):
if self.contracts.get(self.contNumber):# means a contract exists
# so req data
self.reqFundamentalData(self.contNumber, self.contracts[self.contNumber], "RESC", [])
self.contNumber += 1 # now get ready for next request
else: # means no more sequentially numbered contracts
print('done')
self.disconnect() # just exit
def main():
app = TestApp() #just instantiate, don't run
# The input file need to contain in each line: company ticker,currency,exchange - no spaces between them
#Company_tickers = open("IB_FD_input.txt", 'r').readlines() # reads a file with companies tickers in one column
Company_tickers = ['IBKR,USD,','RY,USD,']
#print("Company_tickers: ", Company_tickers)
Number_compnaies = len(Company_tickers)
Company_count = 0
for stock in Company_tickers:
aa = stock.split(",")
Symbol = aa[0].replace(" ", "") # in case there is a space
Currency = aa[1].replace(" ", "")
Exchange = aa[2].replace("\n", "").replace(" ","") # need to remove the \n as it is the last field in the entry line
contract = Contract() # defining the stock to download the fundamental data from IB
contract.symbol = Symbol
contract.secType = "STK"
contract.exchange = "SMART"
contract.currency = Currency
contract.primaryExchange = Exchange
print("Contract: ", contract)
Company_count += 1 # To show progress on screen
print("\n\n" + "**********************" + "\n")
print(" " + Symbol + ": # " + str(Company_count) + " / " + str(Number_compnaies))
print("\n" + "**********************" + "\n")
#add the contracts to apps dict
app.addContracts(contract)
app.connect("127.0.0.1", 7496, 123)
# this method will start a socket read loop and will block until disconnect
app.run()
main()