我正在使用IB API检索历史股票数据,我希望我的代码可以使用不同的变量(不同的股票和时间范围)多次运行。
当前我正在使用以下代码:
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
def print_to_file(*args):
with open('text6.txt', 'a') as fh:
fh.write(' '.join(map(str,args)))
fh.write('\n')
print = print_to_file
class TestApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
Layout = "{!s:1} {!s:2} {!s:3} {!s:4} {!s:5} {!s:6} {!s:7} {!s:8} {!s:8} '\n'"
print(Layout.format("Ticker;", "Date;", "None;", "Time;", "Open;", "High;", "Low;", "Close;", "Volume"))
def historicalData(self, reqId, bar):
print("AAPL", ";", bar.date.replace(' ', '; '), ";", bar.open, ";", bar.high, ";", bar.low, ";", bar.close, ";", bar.volume)
def main():
app = TestApp()
app.connect("127.0.0.1", 7497, 0)
contract = Contract ()
contract.symbol = "AAPL"
contract.secType = "STK"
contract.exchange = "SMART"
contract.currency = "USD"
contract.primaryExchange = "NASDAQ"
app.reqHistoricalData(0, contract, "20180201 10:00:00", "1 M", "1 min", "TRADES", 0, 1, False, [])
app.run()
if __name__ == "__main__":
main()
我尝试了以下多种股票:
contract.symbol = ["AAPL", "GOOG"]
但这给了我错误信息:
No security definition has been found for the request
并使用以下代码表示时间和日期:
app.reqHistoricalData(0, contract, ["20180201 10:00:00", "20180301 10:00:00"], "1 M", "1 min", "TRADES", 0, 1, False, [])
给我错误消息:
Error validating request:-'bP' : cause - Historical data query end date/time string [['20180201 10:00:00', '20180301 10:00:00']] is invalid. Format is 'YYYYMMDD{SPACE}hh:mm:ss[{SPACE}TMZ]'.
基本上,我希望此.py文件使用多个变量在一次运行中运行多个请求,以便我可以在一次运行中接收多只股票的数据。
这里有人可以帮助我实现这一目标吗?
谢谢!
答案 0 :(得分:0)
您可以创建一个从Contract类派生的类,以便一次创建多个Contract对象。然后,进行一个循环,将您的Contract对象传递到客户端,以获取数据。您当前正在做的事情与任何实际可行的实现都相去甚远。请查看此博客,以获取有关工作系统设置的帮助-> https://qoppac.blogspot.com/2017/03/interactive-brokers-native-python-api.html 至于合同类,请查看文档中的相关参数并根据需要创建一个类。这是我的期货课程的一个例子:
class IBFutures(Contract):
def __init__(self, symbol:str, exchange:str, secType:str,
currency = 'USD', localSymbol = ""):
Contract.__init__(self)
self.symbol = symbol
self.secType = secType
self.exchange = exchange
self.currency = currency
self.localSymbol = localSymbol
然后,在您的客户端对象中,创建类似于以下功能:
def getHistoricalData(self, contracts, durationStr="3 D", barSizeSetting="30 mins", whatToShow = "TRADES"):
"""
Returns historical prices for a contract, up to today
ibcontract is a Contract
:returns list of prices in 4 tuples: Open high low close volume
"""
defaultid = 80
prices = {}
for symbol in contracts:
defaultid += 1 # update defaultid
# Make a place to store the data we're going to return
historic_data_queue = finishableQueue(self.init_historicprices(defaultid))
# Should endDateTime be set to 9:00AM EST??
# Request some historical data. Native method in EClient
self.reqHistoricalData(reqId=defaultid, contract = contracts[symbol],
endDateTime=datetime.datetime.today().strftime("%Y%m%d %H:%M:%S"),
durationStr=durationStr, barSizeSetting=barSizeSetting,
whatToShow=whatToShow, useRTH=0, formatDate=1,
keepUpToDate=False, chartOptions=[])
# Wait until we get a completed data, an error, or time-out
MAX_WAIT_SECONDS = 30
logger.info("Getting %s historical data from the server..." % symbol)
historic_data = historic_data_queue.get(timeout=MAX_WAIT_SECONDS)
clean_data = cleanPrice(data=historic_data)
prices[symbol] = clean_data
if historic_data_queue.timed_out():
logger.info("Exceeded maximum wait for wrapper to confirm finished")
self.cancelHistoricalData(defaultid)
logger.info("Prices retrieved for %d contracts" % len(prices))
return prices