循环中对 IB 的请求响应不同
request to IB responds differently when in a loop
我只是不明白这是怎么回事。我对包装器和 IB 有点陌生。这是我的函数,它覆盖并解析 XML。 XML 应该在 main 中解析吗?我只想获取 CSV 文件中所有交易品种的基本数据。当我注释掉循环和 运行 一个单独的请求时,它有时会起作用。这是怎么回事?
class TestApp(EWrapper, EClient):
def __init__(self):
EWrapper.__init__(self)
EClient.__init__(self, wrapper=self)
self.csv = pd.read_csv('getfund.csv');
self.symbols = self.csv['Symbol']
self.exchanges = self.csv['Exchange']
def nextValidId(self, reqId: int):
reqs_do()
def reqs_do():
for i in range(len(symbols)):
contract = Contract()
contract.symbol = self.symbols[i]
contract.secType = "STK"
contract.exchange = self.exchanges[i]
contract.currency = "USD"
contract.primaryExchange = "NASDAQ"
print(contract)
print(symbols[i])
print(exchanges[i])
print(i)
app.reqFundamentalData(8001 , contract, "ReportsFinSummary", [])
def error(self, reqID:TickerId, errorCode:int, errorString:str):
print("Error: ", reqID, " " , errorCode, " ", errorString)
def fundamentalData(self, reqId: TickerId, data: str):
super().fundamentalData(reqId, data)
print("FundamentalData. ", reqId, data)
e = ET.fromstring(data)
e.tag
e.attrib
##code to parse the XML file returned from the ib reqfundamentaldata function.
##there are multiple report types and I am uncertain what they mean, worth
##looking into later.
row_list = []
for atype in e.iter('TotalRevenue'):
if atype.attrib['reportType']=="A" and atype.attrib['period']=="3M":
dict1 = {"Date": atype.attrib['asofDate'],
'Revenue':atype.text}
row_list.append(dict1)
columns = ['Date', 'Revenue']
tr = pd.DataFrame(row_list, columns=columns)
row_list = []
for atype in e.iter('DividendPerShare'):
if atype.attrib['reportType']=="A" and atype.attrib['period']=="3M":
dict1 = {"Date": atype.attrib['asofDate'],
'Dividend':atype.text}
row_list.append(dict1)
columns = ['Date', 'Dividend']
dps = pd.DataFrame(row_list, columns=columns)
row_list = []
for atype in e.iter('EPS'):
if atype.attrib['reportType']=="A" and atype.attrib['period']=="3M":
dict1 = {"Date": atype.attrib['asofDate'],
'EPS':atype.text}
row_list.append(dict1)
columns = ['Date', 'EPS']
eps = pd.DataFrame(row_list, columns=columns)
temp = tr.merge(dps, left_on='Date', right_on='Date', how='left')
fin = temp.merge(eps, left_on='Date', right_on='Date', how='left')
print(fin)
#fin.to_csv("fin.csv", sep=',')
if done: app.disconnect()
def main():
app = TestApp()
app.connect("127.0.0.1", 4001, clientId=123)
print("serverVersion:%s connectionTime:%s" % (app.serverVersion(),
app.twsConnectionTime()))
app.run()
if __name__ == "__main__":
main()
您的逻辑是连接然后请求所有数据,同时在两次请求之间等待 60 秒....然后监听响应 (app.run)。
app.run() 启动一个从套接字读取响应的循环。没有一些线程,你不能在这个调用之后做任何事情。您可以编写程序以异步方式执行操作。
通过读取循环运行建立连接后,您就可以开始请求数据了。 nextValidId 用于此目的,因为它是 TWS(IBG) 发送的第一个响应。所以在 nextValidId 中你才真正开始你的程序。
您的代码永远不会断开连接,因为 app.run() 正在阻塞线程。您需要使用异步逻辑来决定何时断开连接。在这个简单的例子中,只需计算请求数。
不是真正的程序,只是为了说明逻辑流程。
class TestApp(EWrapper, EClient):
def __init__(self):
#other stuff
#make the following members instead of global
self.csv = pd.read_csv('getfund.csv');
self.symbols = csv['Symbol']
self.exchanges = csv['Exchange']
def nextValidId(self, reqId: int):
reqs_do()
def reqs_do():
for i in range(len(symbols)):
# same, just use self.symbols etc..
def fundamentalData(self, reqId: TickerId, data: str):
# similar but disconnect after everything has been rec'd
if done: app.disconnect()
def main():
app = TestApp()
app.connect("127.0.0.1", 4001, clientId=123)
app.run()
if __name__ == "__main__": main()
- 该程序将首先创建 TestApp 并读取 csv
文件。
- 然后您将通过套接字连接到 IB 网关,但不是
一直读到 app.run().
- 一旦你开始阅读,你就会
rec'v nextValidId 和一些关于
联系。
- 一旦接收到 nextValidiD,您就可以开始请求数据了。
- 它可以随时来,但通常马上就来,也许星期五除外
一切都关闭的夜晚。
- 如果收到,它将打印在您拥有的数据回调中。
我只是不明白这是怎么回事。我对包装器和 IB 有点陌生。这是我的函数,它覆盖并解析 XML。 XML 应该在 main 中解析吗?我只想获取 CSV 文件中所有交易品种的基本数据。当我注释掉循环和 运行 一个单独的请求时,它有时会起作用。这是怎么回事?
class TestApp(EWrapper, EClient):
def __init__(self):
EWrapper.__init__(self)
EClient.__init__(self, wrapper=self)
self.csv = pd.read_csv('getfund.csv');
self.symbols = self.csv['Symbol']
self.exchanges = self.csv['Exchange']
def nextValidId(self, reqId: int):
reqs_do()
def reqs_do():
for i in range(len(symbols)):
contract = Contract()
contract.symbol = self.symbols[i]
contract.secType = "STK"
contract.exchange = self.exchanges[i]
contract.currency = "USD"
contract.primaryExchange = "NASDAQ"
print(contract)
print(symbols[i])
print(exchanges[i])
print(i)
app.reqFundamentalData(8001 , contract, "ReportsFinSummary", [])
def error(self, reqID:TickerId, errorCode:int, errorString:str):
print("Error: ", reqID, " " , errorCode, " ", errorString)
def fundamentalData(self, reqId: TickerId, data: str):
super().fundamentalData(reqId, data)
print("FundamentalData. ", reqId, data)
e = ET.fromstring(data)
e.tag
e.attrib
##code to parse the XML file returned from the ib reqfundamentaldata function.
##there are multiple report types and I am uncertain what they mean, worth
##looking into later.
row_list = []
for atype in e.iter('TotalRevenue'):
if atype.attrib['reportType']=="A" and atype.attrib['period']=="3M":
dict1 = {"Date": atype.attrib['asofDate'],
'Revenue':atype.text}
row_list.append(dict1)
columns = ['Date', 'Revenue']
tr = pd.DataFrame(row_list, columns=columns)
row_list = []
for atype in e.iter('DividendPerShare'):
if atype.attrib['reportType']=="A" and atype.attrib['period']=="3M":
dict1 = {"Date": atype.attrib['asofDate'],
'Dividend':atype.text}
row_list.append(dict1)
columns = ['Date', 'Dividend']
dps = pd.DataFrame(row_list, columns=columns)
row_list = []
for atype in e.iter('EPS'):
if atype.attrib['reportType']=="A" and atype.attrib['period']=="3M":
dict1 = {"Date": atype.attrib['asofDate'],
'EPS':atype.text}
row_list.append(dict1)
columns = ['Date', 'EPS']
eps = pd.DataFrame(row_list, columns=columns)
temp = tr.merge(dps, left_on='Date', right_on='Date', how='left')
fin = temp.merge(eps, left_on='Date', right_on='Date', how='left')
print(fin)
#fin.to_csv("fin.csv", sep=',')
if done: app.disconnect()
def main():
app = TestApp()
app.connect("127.0.0.1", 4001, clientId=123)
print("serverVersion:%s connectionTime:%s" % (app.serverVersion(),
app.twsConnectionTime()))
app.run()
if __name__ == "__main__":
main()
您的逻辑是连接然后请求所有数据,同时在两次请求之间等待 60 秒....然后监听响应 (app.run)。
app.run() 启动一个从套接字读取响应的循环。没有一些线程,你不能在这个调用之后做任何事情。您可以编写程序以异步方式执行操作。
通过读取循环运行建立连接后,您就可以开始请求数据了。 nextValidId 用于此目的,因为它是 TWS(IBG) 发送的第一个响应。所以在 nextValidId 中你才真正开始你的程序。
您的代码永远不会断开连接,因为 app.run() 正在阻塞线程。您需要使用异步逻辑来决定何时断开连接。在这个简单的例子中,只需计算请求数。
不是真正的程序,只是为了说明逻辑流程。
class TestApp(EWrapper, EClient):
def __init__(self):
#other stuff
#make the following members instead of global
self.csv = pd.read_csv('getfund.csv');
self.symbols = csv['Symbol']
self.exchanges = csv['Exchange']
def nextValidId(self, reqId: int):
reqs_do()
def reqs_do():
for i in range(len(symbols)):
# same, just use self.symbols etc..
def fundamentalData(self, reqId: TickerId, data: str):
# similar but disconnect after everything has been rec'd
if done: app.disconnect()
def main():
app = TestApp()
app.connect("127.0.0.1", 4001, clientId=123)
app.run()
if __name__ == "__main__": main()
- 该程序将首先创建 TestApp 并读取 csv 文件。
- 然后您将通过套接字连接到 IB 网关,但不是 一直读到 app.run().
- 一旦你开始阅读,你就会 rec'v nextValidId 和一些关于 联系。
- 一旦接收到 nextValidiD,您就可以开始请求数据了。
- 它可以随时来,但通常马上就来,也许星期五除外 一切都关闭的夜晚。
- 如果收到,它将打印在您拥有的数据回调中。