Python несколько запросов с одним кодом - PullRequest
0 голосов
/ 08 мая 2019

Я использую 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 голосов
/ 09 мая 2019

Вы можете создать класс, производный от класса 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
...