我正在编写一个服务,通过基于Python语言的TWS API工作。在获取历史数据时遇到问题。底线是,当您使用正确的参数请求app.reqHistoricalData()时,脚本会正常运行,并在执行后退出。如果将false参数传递给app.reqHistoricalData()(例如contract。currency = 'US'),那么在这种情况下,我在控制台中得到一个错误&;error 123 321请求验证失败。-'b ':原因-美元是不允许的"。脚本不会结束并挂起,直到手动停止为止。也许你遇到过这样的问题,你能建议如何处理这种情况吗?下面是我脚本的代码。
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
from ibapi.order import Order
import pandas as pd
import threading
import time
class IBapi(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
self.open_orders = list()
self.historical_data = list()
self.df = None
self.data_end = False
def nextValidId(self, orderId: int):
super().nextValidId(orderId)
self.nextorderId = orderId
print('The next valid order id is: ', self.nextorderId)
def openOrder(self, orderId, contract, order, orderState):
# print('OpenOrder ID:', orderId, contract.symbol, contract.secType, '@', contract.exchange, ':', order.action,
# order.orderType, order.totalQuantity, orderState.status)
self.open_orders.append(('OpenOrder ID:', orderId, contract.symbol, contract.secType, '@',
contract.exchange, ':', order.action, order.orderType, order.totalQuantity,
orderState.status))
def historicalData(self, reqId, bar):
self.historical_data.append(vars(bar))
def historicalDataUpdate(self, reqId, bar):
line = vars(bar)
self.df.loc[pd.to_datetime(line.pop('date'))] = line
def historicalDataEnd(self, reqId: int, start: str, end: str):
self.df = pd.DataFrame(self.historical_data)
self.data_end = True
class Connect:
app = None
def __init__(self):
self.app = IBapi()
self.app.connect('127.0.0.1', 7497, 123)
# self.app.nextorderId = None
# Start the socket in a thread
api_thread = threading.Thread(target=self.run_loop, daemon=True)
api_thread.start()
time.sleep(1) # Sleep interval to allow time for connection to server
print('Соединились')
def run_loop(self):
self.app.run()
def get_historical_data(symbol, sectype, exchange, currency, duration=None, barsize=None,
whattoshow=None, enddatetime=None, userth=None, format_date=None) -> list:
print('nGET HISTORYn-------------------------------')
app = Connect().app
contract = Contract() # Создание объекта Contract, который описывает интересующий актив
contract.symbol = symbol # символ актива
contract.secType = sectype # 'CASH' # тип ценной бумаги
contract.exchange = exchange # 'IDEALPRO' # биржа
contract.currency = currency # 'USD' # валюта базового актива
if format_date is None:
format_date = 1 # 1- datetime, 2 - unix
if enddatetime is None:
enddatetime = ''
if barsize is None:
barsize = '1 hour'
if duration is None:
duration = '1 D'
if whattoshow is None:
whattoshow = 'BID'
if userth is None:
userth = 1 # 1 - обычные торговые часы, 0 - предторговля
app.reqHistoricalData(reqId=123, contract=contract, endDateTime=enddatetime, durationStr=duration,
barSizeSetting=barsize, whatToShow=whattoshow, useRTH=userth, formatDate=format_date,
keepUpToDate=False, chartOptions=[])
while not app.data_end:
time.sleep(1)
result = app.df.to_dict('records')
print(result)
app.disconnect()
return result
if __name__ == '__main__':
# get_historical_data(symbol='EUR', sectype='CASH', exchange='IDEALPRO', currency='USD')
get_historical_data(symbol='EUR', sectype='CASH', exchange='IDEALPRO', currency='US') # wrong params
data_end
只在historicalDataEnd
中被设置为True,所以如果有错误,它将永远不会被调用,程序将永远休眠。
不要使用睡眠的另一个原因。