Блог им. 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 (не пользовались долго).  

4.8К | ★10



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

Читайте на SMART-LAB:
5 идей в российских акциях. Индекс МосБиржи снова на грани 2700
Индекс МосБиржи опять торгуется на грани значимого уровня 2700 п. Сейчас не исключен очередной отскок от указанного уровня. Кроме того, рынок...
Фото
Саратовэнерго. Надбавки на 26г. установлены, но это уже не важно. Изменение целевой цены и рейтинга
Комитет государственного регулирования тарифов Саратовской области опубликовал постановление №390 от 26.12.2025г. об установлении сбытовой...
ПАО «ГЛОРАКС» может показать сильные финансовые результаты за 2025 год
Сегодня на снижающемся российском фондовом рынке небольшой рост показывают акции ПАО «ГЛОРАКС», дорожающие на 0,11% до 63,41 руб. за акцию....
Фото
Хэдхантер. Ситуация на рынке труда в декабре идет ко дну - хуже не было никогда
Вышла статистика рынка труда за декабрь 2025 года, которую Хедхантер публикует ежемесячно, что же там интересного: Динамика...

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

....все тэги



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