Python用单个代码处理多个请求

时间:2019-05-08 17:30:24

标签: python python-3.x visual-studio pycharm interactive-brokers

我正在使用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文件使用多个变量在一次运行中运行多个请求,以便我可以在一次运行中接收多只股票的数据。

这里有人可以帮助我实现这一目标吗?

谢谢!

1 个答案:

答案 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