Активируйте JavaScript для полноценного использования elitetrader.ru Проверьте настройки браузера.
Получение внутридневных данных c IQFeed » Элитный трейдер
Элитный трейдер
Искать автора

Получение внутридневных данных c IQFeed

26 июля 2015 QuantAlgos

Статья о загрузке внутридневных котировок от поставщика данных IQFeed на языке Python опубликована в блоге www.quantstart.com. DTN IQFeed - популярный вендор, поставляющий данные со многих американских и европейских рынков по широкому спектру инструментов. Тем трейдерам, кто практикует алгоритмическую торговлю на зарубежных площадках или использует данные с них для поиска корреляций с российскими активами, будет очень полезен нижеследующий перевод.


С IQFeed возможно получение данных через сокет соединение к локальному серверу IQLink, который предоставляется при создании аккаунта у этого поставщика данных. В этой статье мы будем использовать потоковое сокет соединение на языке программирования Python для буферизации данных и создадим файл CSV с внутридневной маркет датой для американских акций.

Python сокет соединение с IQFeed

Мы предполагаем, что вы уже имеете аккаунт на IQFeed. Если еще нет, то возможно получение двухнедельного бесплатного испытательного периода при регистрации. После подписки на необходимые вам биржевые площадки и требуемый уровень дискретизации данных, вам будет предложена загрузка IQLink Launcher. Этот инструмент работает только под Windows, но может быть запущен и на Mac или Linux под WINE (с небольшим количеством настроек). При запуске IQLink появляется диалог, представленный на рисунке в заглавии статьи.

Нажатие кнопки "Start IQLink" запустит сервер. Вам будет предложено ввести логин и пароль. Когда сервер будет запущен, необходимо создать потоковое сокет соединение к локальному порту (9100 задан по умолчанию). Затем вы сможете посылать сообщения через этот сокет и получать данные в режиме буферизации.

Первая задача - создать файл iqfeed.py и загрузить системную библиотеку и библиотеку сокетов:

# iqfeed.py

import sys
import socket


За буферизацию данных отвечает функция read_historical_data_socket. В качестве параметров в нее предаются сокет объект и число байтов для буфера чтения. Эта функция просто преобразует последний полученный пакет данных в строку и возвращает ее когда получена строка "!ENDMSG!" ( то есть когда буфер достиг конца данных):

# iqfeed.py

def read_historical_data_socket(sock, recv_buffer=4096):
"""
Чтение информации из сокета в буфер, размер которого равен 4096 байтов

Параметры:
sock - объект сокет
recv_buffer - Количество байтов для чтения за один раз
"""
buffer = ""
data = ""
while True:
data = sock.recv(recv_buffer)
buffer += data

# Проверка прихода конца сообщения
if "!ENDMSG!" in buffer:
break

# Удаление строки конца сообщения
buffer = buffer[:-12]
return buffer


Сокет должен присоединяться к локальной машине через порт 9100. Для примера мы собираемся загрузить данные для четырех акций:SPY, AAPL, GOOG и AMZN с начала 2014 года до настоящего времени.

IQFeed принимает сообщения в следующем формате: CMD,SYM,[options]\n

Мы будем использовать для примера следующее сообщение: "HIT,GOOG,60,20140101 075000,,,093000,160000,1\n" . Это запрос на получение исторических данных (HIT) для тикера GOOG c шагом один раз в 60 секунд (то есть минутные бары), с 07:50:00 1 января 2014 года до настоящего времени (т.е до вчерашнего дня). Данные фильтруются для представления только в диапазоне с 9:30:00 до 16:00:00, который является временем торговой сессии NYSE, используются новые данные.

Первая задача это определить хост, порт и тикеры для получения. Каждый из 4 тикеров добавляется в цикле конструирования сообщения. Затем открывается сокет. AF_INET определяет пару (хост,порт), которая нужна для соединения. SOCK_STREAM устанавливает, что сокет должен быть потоковым.

Когда сокет открыт, сообщение послано и исторические данные загружены в буфер, после сокет закрывается. Все окончания строк удаляются и данные записываются в файл "sym.csv" в ту же директорию. где находится код, и "sym" означает символ тикера:

# iqfeed.py

if __name__ == "__main__":
# Задаем хост, порт и символы для получения
host = "127.0.0.1" # Localhost
port = 9100 # Historical data socket port
syms = ["SPY", "AAPL", "GOOG", "AMZN"]

# Зашружаем каждый тикер на диск
for sym in syms:
print "Downloading symbol: %s..." % sym

# Конструируем сообщение для IQFeed для получения данных
message = "HIT,%s,60,20140101 075000,,,093000,160000,1\n" % sym

# Открываем потоковый сокет к IQFeed серверу локально
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))

# Отсылаем запрос на данные
# сообщение и буфер данных
sock.sendall(message)
data = read_historical_data_socket(sock)
sock.close

# Удаляем все окончания строк
# разделитель - запятая для каждой записи
data = "".join(data.split("\r"))
data = data.replace(",\n","\n")[:-1]

# Пишем поток данных на диск
f = open("%s.csv" % sym, "w")
f.write(data)
f.close()


Получаемый формат данных следующий:

[YYYY-MM-DD HH:mm:SS],[OPEN],[LOW],[HIGH],[CLOSE],[VOLUME],[OPEN INTEREST]

Типичный набор данных в файле должен быть такой:

2012-01-03 09:31:00,30.6400,30.5000,30.6400,30.5100,6128,6128
2012-01-03 09:32:00,30.5600,30.4900,30.4900,30.5600,6528,400
2012-01-03 09:33:00,30.5000,30.5000,30.5000,30.5000,6672,144
2012-01-03 09:34:00,30.3800,30.3400,30.3400,30.3500,8423,1751
2012-01-03 09:35:00,30.5300,30.5300,30.5300,30.5300,8623,200
2012-01-03 09:36:00,30.6400,30.5500,30.5500,30.6400,9423,800
2012-01-03 09:37:00,30.6500,30.6500,30.6500,30.6500,10329,906
2012-01-03 09:38:00,30.6900,30.6600,30.6900,30.6600,12329,2000
2012-01-03 09:39:00,30.7200,30.6400,30.6500,30.7200,13729,1400
2012-01-03 09:40:00,30.7500,30.6900,30.7200,30.7500,17029,3300


Данные поставляются за достаточно большое период в смысле доступности по годам. Загрузка может занять некоторое время, если вы запрашиваете много тикеров за пять лет и более. Если вы хотите загружать не только данные по акциям, то обратитесь к списку символов IQFeed. Очевидно, что вы должны подписаться на соответствующую площадку для получения запрашиваемых данных.

Обратите внимание, что внутридневные данные, поставляемые IQFeed не адаптированы к корпоративным действиям, таким, как дивиденты и сплиты. Вам нужно будет самим позаботиться об их учете в ваших тестах.