reqHistoricalData в IBPY ничего не возвращает [python]

Я пытаюсь получить исторические данные от Interactive Brokers (IB) через Ibpy. Я пробовал несколько сценариев для этой задачи, которые я адаптировал от других, которые указывают, что это должно работать. Однако ни один из них не работает для меня! Я новичок в Python, поэтому я признаю, что у меня нет полного понимания работы этих методов - однако, я должен был попробовать самые очевидные исправления. Ниже я перечислил два сценария, которые попробовал. Я использую Python 2x.

В TWS у меня есть следующие настройки:

проверил: включить ActiveX и Socket Clients. снят: включить клиенты DDE. не проверено: API только для чтения. проверил: скачать открытые ордера на соединение. проверил: при отправке портфолио включайте валютные позиции. проверил: отправлять обновления статуса для EEP. Порт сокета = 7496. флажок: использовать отрицательные числа для привязки автоматических заказов. снят: создание файла журнала сообщений API. снят: включение рыночных данных в файл журнала API. Уровень ведения журнала = Ошибка. ИД клиента основного API = 222. Время ожидания для отправки массовых данных в API составляет 30 секунд. Разделитель Exch = пустой. проверил: разрешить соединения только с локального хоста.

API - Проверенные меры предосторожности: Обход мер предосторожности для заказов API. все остальное все не проверено в этой вкладке.

TWS вошел в систему и работает, когда запускаю скрипты на python, и приведенные выше настройки API TWS кажутся правильными по сравнению с тем, что все остальные говорят онлайн. У меня есть реальный счет IB, подписанный на данные по акциям США. Следует также упомянуть, что я пытался запустить другой скрипт, размещая заказ также через IBPY - это сработало, поэтому проблема, кажется, существует только (на данный момент, по крайней мере) в отношении получения исторических данных.

Сценарий 1:

from time import sleep, strftime, localtime  
from ib.ext.Contract import Contract  
from ib.opt import ibConnection, message  


new_symbolinput = ['AAPL']
newDataList = []  
dataDownload = []  

def historical_data_handler(msg):  
    global newDataList  
    print (msg.reqId, msg.date, msg.close)
    if ('finished' in str(msg.date)) == False:  
        new_symbol = new_symbolinput[msg.reqId]  
        dataStr = '%s, %s, %s' % (new_symbol, strftime("%Y-%m-%d", localtime(int(msg.date))), msg.close)  
        newDataList = newDataList + [dataStr]
    else:  
        new_symbol = new_symbolinput[msg.reqId]  
        filename = 'minutetrades' + new_symbol + '.csv'  
        csvfile = open('IBdata/' + filename,'w')
        for item in newDataList:  
            csvfile.write('{} \n'.format(item))
        csvfile.close()  
        newDataList = []  
        global dataDownload  
        dataDownload.append(new_symbol)  


con = ibConnection(port=7496, clientId=222)  
con.register(historical_data_handler, message.historicalData)  
con.connect()  

symbol_id = 0  
for i in new_symbolinput:  
    print (i)  
    qqq = Contract()  
    qqq.m_symbol = i  
    qqq.m_secType = 'STK'  
    qqq.m_exchange = 'SMART'  
    qqq.m_currency = 'USD'
    con.reqHistoricalData(symbol_id, qqq, '20161101', '1 W', '1 D', 'MIDPOINT', 1, 2)  

    symbol_id = symbol_id + 1  
    sleep(10)  

print (dataDownload) 
filename = 'downloaded_symbols.csv'  
csvfile = open('IBdata/' + filename,'w')  
for item in dataDownload:  
    csvfile.write('%s \n' % item)  
csvfile.close()

это должно вернуть данные в CSV-файл. Файл CSV создан, но он пуст.

Отклик:

Server Version: 76
TWS Time at connection:20170315 14:18:06 CET
AAPL
[]

Так что это явно ничего не возвращает.

Сценарий 2:

from time import sleep, strftime
from ib.ext.Contract import Contract
from ib.opt import ibConnection, message

def my_account_handler(msg):
    print(msg)

def my_tick_handler(msg):
    print(msg)

def my_hist_data_handler(msg):
    print(msg)


if __name__ == '__main__':

    con = ibConnection(port=7496,clientId=222)
    con.register(my_account_handler, 'UpdateAccountValue')
    con.register(my_tick_handler, message.tickSize, message.tickPrice)
    con.register(my_hist_data_handler, message.historicalData)
    con.connect()

    print(con.isConnected())

    def inner():

        qqqq = Contract()
        qqqq.m_secType = "STK" 
        qqqq.m_symbol = "AAPL"
        qqqq.m_currency = "USD"
        qqqq.m_exchange = "SMART"
        endtime = strftime('%Y%m%d %H:%M:%S')
        print(endtime)
        print(con.reqHistoricalData(1,qqqq,endtime,"1 W","1 D","MIDPOINT",1,2))



    sleep(10)

    inner()
    sleep(5)
    print('disconnected', con.disconnect())
    print(con.isConnected())

Ответ здесь:

Server Version: 76
TWS Time at connection:20170315 14:29:53 CET
True
20170315 14:30:05
None
('disconnected', True)
False

Снова ничего не возвращается. Я понятия не имею, почему, как кажется, работает на других. Я мог пропустить что-то фундаментальное, так как я совсем новичок в Python?

Любая помощь очень ценится.

1 ответ

Всегда реализуйте обработчик ошибок, и API скажет вам, что не так. В этом случае он говорит, что используйте "1 день" для размера бара.

Там нет необходимости спать. использование nextValidId знать, когда соединение готово. Используйте разные конечные методы, чтобы знать, когда вы закончите. historicalDataEnd кажется, еще не реализован в IBpy, так что просто ищите "готово"

Не отключайте протоколирование API, оно показало бы ошибку, а также все различные сообщения, отправленные в и из TWS. Вы можете отключить рыночные данные в файле журнала, так как их довольно много. Найдите файл 'api.222.Wed.log' в вашем каталоге jts.

from time import sleep, strftime
from ib.ext.Contract import Contract
from ib.opt import ibConnection, message
import pandas as pd
import numpy as np

def nextValidId_handler(msg):
    print(msg)
    inner()

hist = []

def my_hist_data_handler(msg):
    print(msg)
    if "finished" in msg.date:
        print('disconnecting', con.disconnect())
        df = df = pd.DataFrame(index=np.arange(0, len(hist)), columns=('date', 'close', 'volume'))
        for index, msg in enumerate(hist):
            df.loc[index,'date':'volume'] = msg.date, msg.close, msg.volume
        print(df )
    else:
        hist.append(msg)    

def error_handler(msg):
    print(msg)

if __name__ == '__main__':

    con = ibConnection(port=7497,clientId=222)
    con.register(error_handler, message.Error)
    con.register(nextValidId_handler, message.nextValidId)
    con.register(my_hist_data_handler, message.historicalData)
    con.connect()

    print(con.isConnected())

    def inner():

        qqqq = Contract()
        qqqq.m_secType = "STK" 
        qqqq.m_symbol = "AAPL"
        qqqq.m_currency = "USD"
        qqqq.m_exchange = "SMART"
        endtime = strftime('%Y%m%d %H:%M:%S')
        print(endtime)
        con.reqHistoricalData(1,qqqq,endtime,"1 W","1 day","MIDPOINT",1,2)

    print(con.isConnected())
Другие вопросы по тегам