Блог им. dataserverdeveloper

Как качать историю котировок (пример на Python, IQFeed)

   IQFeed -  это не самый дешёвый (но и не самый дорогой) провайдер исторических (и real-time) данных финансовых бирж и разнообразных trading venues. Со своими плюсами и минусами.

   В этой короткой статье расскажу, как закачать исторические данные из IQFeed при минимальном знании языка Python.

   Disclosure: я заинтересованное лицо, хоть и не в коммерческом смысле, т.к. ищу тех с кем можно расшарить сервис IQFeed вскладчину. См. подробнее: smart-lab.ru/blog/439522.php

   Из плюсов IQFeed – вполне сносное API для доступа к данным (уступающее по простоте RESTful сервисам, но минус REST – крайне низкая производительность, тяжело качать более или менее объёмные данные). Огромный выбор (акции, фьючерсы, опционы...). Минусы -тики только 180 дней (по SPY, кстати, это примерно 2.5GB). Adjusted данных по акциям нет.

   Скачивание сводится к формированию запроса -“хочу такие-то данные с такой-то по такую-то дату”. Запрос — это текстовая строка, отправленная в канал коммуникации (сокет).

   Вот примеры строки запроса на интрадей (минутки): «HIT,SPY,60,20160226 093000,20170226 160000,,093000,160000,1,,»

   Расшифровка: дайте интрадей (HIT), по SPY, с барами в 60 секунд (т.е. минутки), с 20160226 093000 (YYYYMMDD HHMMSS), по 20170226 160000, без ограничения кол-ва выдаваемых строк, в торговую сессию с 093000 по 160000 (т.е. без extra-hours), с “прямой” (от старого к новому) сортировкой по датам (1),  без RequestID, без DATAPOINTSPERSEND.

   Формально запрос выглядит так:

HTT,SYMBOL,BEGINDATE BEGINTIME,ENDDATE ENDTIME,MAXDATAPOINTS,BEGINFILTERTIME,ENDFILTERTIME,DIRECTION,REQUESTID,DATAPOINTSPERSEND<CR><LF>

 

   <CR><LF> это перевод строки “по-windowsовски” (\r\n). Говорю специально для тех, кто работает на Linux.

   Запрос нужно послать на предварительно открытый сокет localhost:9100 или 127.0.0.1:9100 (под Linux может иметь значение), на котором “висит” работающий клиент IQFeed (в Windows запустить вручную через IQLink Launcher), а дальше вычитывать с него порции (блоки) данных (формат текстовый, кстати там не OHLC, а HLOC) соединяя вместе. Чтение производить до появления слова “!ENDMSG!” к конце очередного блока.

Грубо говоря – всё. Это минимально достаточный набор действий.

Попробуем сделать это на Python:

import sys
import socket

def read_historical_data_socket(sock, fname, recv_buffer=4096):

    buffer = ""
    data = ""
    cont=True
    while cont:
        buffer = sock.recv(recv_buffer).decode('ascii')
        data += buffer
        if "!ENDMSG!" in data[-12:]:
            data = data[:-12]
            cont=False

        firstlines=buffer.split("\n",2)
        if len(firstlines)>1:
            sys.stdout.write("Download progress(%s): %s   \r" % (fname,firstlines[1][0:19]) )
            sys.stdout.flush()
        
    data = "".join(data.split("\r"))
    data = data.replace(",\n","\n")[:-1]
    
    f = open(fname, "w")
    f.write(data)
    f.close()
    return

if __name__ == "__main__":

    host = "127.0.0.1"
    port = 9100
    syms = ["SPY", "AAPL", "GOOG", "AMZN"]
    for sym in syms:
        message = "HIT,%s,60,20140101 000000,20160101 000000,,,,1\n" % sym
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((host, port))

        sock.sendall(message.encode())
        read_historical_data_socket(sock,"%s.csv" % sym)
        sock.close

        sys.stdout.write("Downloaded symbol: %s                          " % sym)
        sys.stdout.flush()

    print

Собственно – всё. Пример  проверен и на Linux (Python 2.7.12) и на Windows (Python 3.5.4).
Примечания:
   Из недостатков скрипта — всё сначала закачивается в память. Тому есть причины: логика работы с сокетом — в получении равномерно нарезанных порций данных (4096 байт по умолчанию). Но сообщение !ENDMSG! может прийтись на границу двух блоков, потому быть «разрезанным» и при последовательном чтении с записью в файл (write-append block by block) просто неотдетектироваться. Для сохранения в файл on-the-fly без больших затрат памяти, нужна слегка усложнённая логика с хранением предыдущего считанного блока и детектом !ENDMSG! в них обоих сразу (в их конкатенации). Это усложняет скрипт. Для минуток особо морочиться не нужно (в худшем случае сотни мегабайт). Кроме того, нужно удалять запятые с конца строк (сделано) и реформатировать сами строки под конкретную программу ТА (не сделано).
   На Linux скрипт работает хорошо.
   И ещё. Не забывайте, что клиент IQFeed вылетает по timeout inactivity. Т.е. запустив клиент IQConnect, через IQLink, и потом поигравшись с скриптом вы долго можете мучиться с «неработающим сокетом», а причина банальна — iqfeed клиент закрылся по timeout inactivity (не пользовались долго).  

Данная публикация является личным мнением автора. Мнение владельца сайта может не совпадать с мнением автора.
5К | ★10



Пользователь запретил комментарии к топику.

Читайте на SMART-LAB:
Фото
Т⁠-⁠Банк представил новое поколение супераппа
В приложении появились новые сферы и данные о счетах и кредитах в других банках, а с главного экрана убрали лишнее Т⁠-⁠Банк объявил новый...
Фото
Курс закончился. Что дальше❓
На курсе всё обычно выглядит проще. Есть преподаватель, разборы, примеры сделок. Вам всё разжёвывают :) Потом курс заканчивается, и трейдер...
Фото
Итоги первичных размещений ВДО и некоторых розничных выпусков на 7 октября 2026 г.
Следите за нашими новостями в удобном формате: Telegram , Youtube , RuTube, Smart-lab , ВКонтакте , Сайт ,...
Фото
Хэдхантер. Рынок труда в сентябре: hh.индекс снизился до 8,5 - становится лучше?
Вышла статистика рынка труда за сентябрь 2026 года (за август можно почитать здесь ), которую Хедхантер публикует ежемесячно, что же там...

теги блога Ромирес

....все тэги



UPDONW
Новый дизайн