Построение стакана котировок (FullOrderBook) по историческим данным. Данные биржи


Индексы — Московская Биржа

{{last_values_text}} {{fieldValueFormat(secId, currentValueTable.headerTimeFieldId)}}

{{last_values_text}}{{fieldValueFormat(secId, historyValueTable.headerTimeFieldId,historyValueTable.headerTimeFieldType)}}

{{field.title}} {{fieldValueFormat(secId,field.fieldId, field.type, field.valuePrefix)}}
{{currentValueTable.headerTitle}}
{{fieldValueFormat(secId, currentValueTable.headerFieldId, currentValueTable.headerFieldType, currentValueTable.headerValuePrefix)}}
{{field.title}} {{fieldValueFormat(secId,field.fieldId, field.type, field.valuePrefix)}}
{{closedValueTable.headerTitle}}
{{fieldValueFormat(secId, closedValueTable.headerFieldId, closedValueTable.headerFieldType, closedValueTable.headerValuePrefix)}}
{{field.title}} {{fieldValueFormat(secId,field.fieldId, field.type, field.valuePrefix)}}

Лидеры роста

{{$index+1}} {{fieldLeaderValueFormat(field, item, field.valuePrefix)}}

Лидеры снижения

{{$index+1}} {{fieldLeaderValueFormat(field, item, field.valuePrefix)}}

www.moex.com

Часто задаваемые вопросы — Московская Биржа

  • Требуется ли заключение дистрибьюторского информационного договора с Биржей, если клиент участника торгов (брокера) использует Quik, который соединяется с сервером брокера, а дальше связка шлюз — Биржа?

    Если клиент участника торгов (брокера) зарегистрирован на биржевом рынке, с которого он получает Биржевую информацию, то дистрибьюторский информационный договор не нужен, если такой клиент не зарегистрирован на этом рынке, то участнику торгов (брокеру) нужно заключить с Биржей дистрибьюторский договор.

  • Требуется ли заключение информационного договора с Биржей, если сотрудники компании, не осуществляющие непосредственных торговых операций (напр. "аналитик", "клиентский менеджер/ help- desk") или сотрудники, осуществляющие ввод в биржевую систему торгов клиентских заявок с торгового терминала, получают на свои терминалы Биржевую информацию?

    Если речь идет о Биржевой информации с тех рынков, где компания зарегистрирована как участник торгов, и если терминалы перечисленных сотрудников не предназначены для расчета публичных индексов и индикаторов на основе полученной Биржевой информации, то информационного договора с Биржей заключать не требуется.

  • Является ли торговая система Quik, предназначенная для отображения клиентам участника торгов Биржевой информации, сбора от клиентов и заявок и проведение претрейд-контроля этих заявок на соответствие правилам торгов) Non-display системой? Если да, то при каких условиях? (Например, есть ли разница — торгует Клиент самостоятельно через Quik или торгует робот?)

    В соответствии с Правилами торгов и "Порядком использования Биржевой информации" (http://moex.com/ru/datapolicy/) вы можете использовать систему Quik без заключения информационного договора с Биржей при условии, если эта система используется только для:

    1) получения от Биржи информации о торгах (котировки и сделки) и передачи этой информации вашим зарегистрированным на Бирже клиентам по тем рынкам, где они зарегистрированы

    2) получения от зарегистрированных клиентов заявок на заключение сделок (в т.ч. сгенерированных "роботами" клиентов, подключенными к вашему Quik-серверу) для дальнейшей передачи в Торговую систему Биржи.

    Однако, если используемый вами Quik-сервер сам содержит модуль алготрейдинга (автоматическое принятие решений о выставлении/невыставлении заявок) и/или модуль риск-менеджмента (например, автоматическое отклонение заявок, не отвечающих заданным риск-параметрам), то такой Quik-сервер рассматривается как Non-display система и требует заключения отдельного информационного договора с Биржей.

  • Является ли Non- display системой модуль Colibri, и требуется ли для использования этого модуля заключать информационный договор с Биржей на Non- display системы?

    В случае, если модуль Colibri взаимодействует с серверной частью системы QUIK, которая может использовать Биржевую информацию для решения задач риск-менеджмента и автоматического принятия или отклонения заявок, то это использование Биржевой информации в серверной части системы QUIK является основанием для заключения с Биржей договора на Non-display системы. Не требует заключения с Биржей информационного договора использование Биржевой информации в терминальном модуле Colibri рабочего места QUIK участника торгов, т.к. такой торговый терминал с модулем Colibri не используется для автоматического принятия или отклонения заявок.

  • Что включает в себя тариф на использование Биржевой информации в собственных котировальных системах валютного рынка?

    Тариф на использование Биржевой информации в собственных котировальных системах валютного рынка включает в себя:

    • использование Биржевой информации с валютного рынка Биржи в собственных котировальных системах;
    • использование Биржевой информации со всех рынков Биржи в неограниченном количестве Non-display систем (для алготрейдинга и риск-менеджмента)
  • Являются ли консенсус-прогнозы на открытие торгов, рассчитанные на основе биржевых котировок закрытия предыдущего дня, Производной информацией, и требуется ли заключение информационного договора с Биржей для размещения таких консенсус-прогнозов в открытом доступе на собственном интернет-сайте?

    Консенсус-прогнозы, рассчитанные на основе цен вчерашнего дня, являются Производной информацией, рассчитанной на основе Биржевой информации. Однако, такое использование Биржевой информации не требует заключения информационного договора с Биржей, т.к. при расчете Производной информации использовалась Биржевая информация по итогам торгового дня, которая раскрывается Биржей в свободном доступе для любых заинтересованных лиц. Информационный договор на использование Биржевой информации для расчета (создания) Производной информации требуется заключать в тех случаях, когда для расчета (создания) Производной информации, используется Биржевая информация, не являющаяся предметом раскрытия Биржей в свободном доступе для любых заинтересованных лиц, например, Биржевая информация в режиме реального времени о ходе торгов в рамках текущей торговой сессии.

  • Существует собственная котировальная система Банка, выполненная в формате хостируемого решения. Система получает рыночную информацию (market data) от Московской Биржи по протоколу FAST Multicast через сеть SFTI NYSE и закачивает её в агрегатор, где она преобразовывается, например, путем увеличением спреда и транслируется далее конечному клиенту в измененном виде. В исходном виде рыночная информация доступна только трейдерам Банка и далее вышеупомянутой собственной котировальной системой либо (а) не транслируется, либо (б) транслируется в другие котировальные системы, принадлежащие Банку или арендуемые Банком (напр. система Bloomberg FXGO). Все перечисленные системы служат одной цели – создавать собственные измененные котировки Банка. Клиенты, получающие измененную рыночную информацию в перечисленных выше системах – юридические лица, которые могут, как являться участниками торгов, так и не являться таковыми (информация об этом Банку не доступна). Выставление и исполнение заявок происходит на Point of Presence Московской биржи в Лондоне. Заявки выставляются и сделки совершаются при помощи протокола FIX Transactional.

    Представленные кейсы полностью соответствуют критериям использования Биржевой информации в собственных котировальных системах валютного рынка и требуют заключения с Биржей соответствующего информационного договора, действие которого будет распространяться на котировальные системы только валютного рынка. В соответствии с информационной политикой Московской Биржи (http://www.moex.com/ru/datapolicy/) такой договор предусматривает ежемесячные платежи в размере 25500 руб. в месяц (для банка, являющегося Участником торгов на валютном рынке Московской Биржи), или 93750 руб. (для российской компании, не являющейся Участником торгов на валютном рынке Московской Биржи), или 3125 долл. США (для иностранной компании, не являющейся Участником торгов на валютном рынке Московской Биржи). Указанные платежи не включают НДС, который начисляется в случаях, предусмотренных российским законодательством. Такой договор покрывает неограниченное число собственных котировальных систем валютного рынка, которые могут являться как (1) собственными разработками, так и (2) системами, арендуемыми у других разработчиков. Принципиальным во втором случае является то, что контроль за доступом конечных клиентов к котировальной системе осуществляет не разработчик системы, а использующий её банк (компания). Также любая из котировальных систем может выполнять функцию ретрансляции биржевых котировок в другую котировальную систему банка, где они изменяются в соответствии с параметрами, заданными банком для каждой группы клиентов. Клиентами с доступом к таким котировальным системам могут быть любые лица, в том числе не зарегистрированные на Бирже.

  • Как (по каким критериям) определить, что компания использует Биржевую информацию только в одной, а не в нескольких Non-display системах?

    Non-display система может состоять из одного или нескольких серверов, её программное обеспечение может состоять из одного или нескольких функциональных модулей. При этом, если при отключении любого из серверов или любого функционального модуля, входящего в состав Non-display системы, функционирование системы прекращается, то в этом случае речь идёт об использовании Биржевой информации в одной Non-display системе. Если при отключении какого-либо из серверов или функциональных модулей получение, обработка и иное использование Биржевой информации не прекращается, то в этом случае речь идёт об использовании Биржевой информации в нескольких Non-display системах.

  • Является ли наличие резервной Non-display системы в дополнение к основной признаком использования Биржевой информацию в нескольких Non-display системах?

    Наличие резервной Non-display системы в дополнение к основной не является признаком использования Биржевой информации в нескольких Non-display системах при условии, что обе системы не осуществляют одновременную обработку Биржевой информации в целях, предусмотренных определением Non-display системы.

  • www.moex.com

    Построение стакана котировок (FullOrderBook) по историческим данным / Хабр

    Совсем недавно решал задачу построения стакана котировок на основе исторических данных Московской Биржи. В открытых источниках ничего подобного не нашел, пришлось начинать с нуля и копать самому. Есть некоторые нюансы, о которых нужно знать. Про них буду упоминать по ходу.

    Про биржевую торговлю, инфраструктуру и тестирование алгоритмов на исторических данных много писал и пишет IT Invest, спасибо ему. От себя добавлю, что на данных OrderLogs мы анализируем глубину рынка, ликвидность, спреды и еще много чего. Результаты используем в наших торговых алгоритмах.

    Специально выбрал Фондовый рынок, так как тут больше всего вопросов. Валютный и Срочный рынок имеют свои особенности, но там проще. Реализация алгоритма на Java, код на GitHub.

    Цель: Получить стакан котировок на любой момент времени.

    Что на входе?
    Файл со всеми заявками/сделками (Full Order Log), полученный от Биржи за 1 день, простой CSV формат, объем ~ 1 Гб. Описание формата и примеры данных есть на сайте Биржи. Вот фрагмент файла:

    • Код бумаги — торговый код инструмента
    • Buy/Sell — напраление заявки купить или продать
    • Время — в формате HHMMSSZZZ (101738829 = 10 ч 17 мин 38 сек 829 мс)
    • ID заявки — по нему отслеживаем жизнь заявки
    • Тип события — {1 — пришла заявка, 0 — удалена заявка, 2 — сделка}
    • Цена — цена в руб. за 1 бумагу
    • Объем — объем заявки/сделки в количестве бумаг
    • ID сделки — заполняется если тип события=2
    • Цена сделки — заполняется если тип события=2
    Так как данные получены прямо из торговой системы, то поле «Время» — это время фиксации событий в торговой системе. Это надо принять к сведению. Кто получает маркетдату через FAST, тем данные приходят с задержкой (latency ~ 0.1 мс в зоне колокации). Это я к тому, что, если вы тестируете алгоритмы на данных Биржи, то там во времени не учитываются задержки, которые есть в наших реалиях. Так что если такие времена не критичны, можно «забить» на latency.

    Фондовый рынок стартует в 9:50 и закрывается в 18:50, проходя 3 фазы:

    09:50 – 10:00 — Аукцион открытия (Формируется цена открытия) 10:00 – 18:40 — Основные торги 18:40 – 18:50 — Аукцион закрытия (формируется цена закрытия)

    Файл содержит только «Основные торги» + неисполенные заявки с аукциона открытия.

    Алгоритм сборки
    Понадобится 2 типа объекта «Orders» и «OrderBook». Orders — это дискретные заявки (строка в файле). А объект OrderBook — это агрегированные по цене заявки имеющий 2 поля: цена и объем, т.е. складываем все объемы с одинаковой ценой.

    Давайте соберем стакан для инструмента «XXXX» на момент времени AABBCCDDD. С первой строки начинаем собирать заявки (объекты Orders), касающиеся бумаги «XXXX» в коллекции. Заявки Buy в одну, Sell в другую. И будем перебирать все заявки пока time<=AABBCCDDD.

    Если тип события = 1 (поставить заявку), добавляем заявку в коллекцию Buy или Sell в зависимости от направления заявки. Если тип события = 0 (удалить заявку), то по номеру заявки находим ее в коллекции и удаляем. Она там непременно должна быть, ибо по логике, нельзя удалить то, чего нет. Если не нашли нужную заявку, надо бить тревогу (либо ошибка в самих данных, либо ошиблись мы сами). Если тип события = 2 (сделка), то по номеру заявки находим ее в коллекции и смотрим на ее объем:

    • Если V1=V2 (V1 — объем заявки в коллекции, V2 — объем сделки), то заявку удаляем из коллекции. Это значит, что заявка исполнилась полностью;
    • Если V1>V2, то в коллекции изменяем объем V1 на V1-V2. Это значит, что заявка исполнилась частично. А часть осталась в стакане;
    • Если V1<V2 (да-да и такое может быть, т.е. объем заявки 10, а сделка произошла на 20) это признак «айсберг» заявки. В таком случае, заявку удаляем из коллекции.
    Типы событий = 2 всегда идут попарно — две стороны сделки. Как только нарушается условие time
    Заявки типа «По рынку»
    У рыночныех заявок в поле цена указывается «0». Такие заявки, так же обрабатываем как обычные. Они исполняются в моменте.
    Заявки типа «Айсберг»
    Айсберг заявки также встречаются в ордерлогах. Как показала практика, их невозможно идетифицировать наверняка. При формировании данных Биржа применяет свой алгоритм, который скрывает «айсберги». Но все равно, в некоторых случаях они мелькают, например висит заявка с объемом 10, а когда превращается в сделку — объем уже 100.

    Знание этой информации достаточно, чтобы собирать стаканы, анализировать спреды и глубину рынка.

    А теперь самое вкусное: давайте проверим наш алгоритм на практике. 2 февраля 2016 специально сделал скриншоты с терминала Bloomberg со стаканом, зафиксировав время. Инструменты брал не самые ликвидные: Яндекс (YNDX), Камаз (KMAZ)… дабы избежать сложности с синхронизацией времени. Паралельно собрал стакан на Биржевых данных описанным выше алгоритмом. Вот результат на 16:56:21:

    Данные идентичны.

    Пару слов о скорости
    В потоке около 15 млн записей, где содержится около 300 инструментов. Самый ликвидный инструмент SBER за целый торговый день прогоняет за 20 сек. Для SBERа глубина стакана в ту или другую сторону — 500-600 ценовых уровней. Если через каждый «час» сохранять состояние стакана, время обработки сокращается до секунды, что меня вполне устраивает. А если еще записать нужный инструмет в отдельный поток, время сократится до десятых секунд.

    Таким образом, стакан по любому инструменту на любой момент времени получаем менее чем за 1 секунду. Уверен, кто-то сможет предложить более эффективный алгоритм, буду рад.

    P.S.: Кусок исторических данных можно взять на сайте Биржи бесплатно. Если нужны данные имено за 2 февраля, выгружу на Я.Диск (~1Gb). Дайте знать.

    habr.com

    Выкачиваем информацию с биржи в Excel

    Давайте что-нибудь проанализируем.. Например, историю торгов? Это и в принципе полезно, и скиллы набьются полезные… В общем план такой – научиться вытаскивать нужные данные с биржи, экспортировать в Excel, ну и что-нибудь с ними делать. Понятно, что не руками :) Поехали!

    Подготовка.

    Нам потребуется

    а) Установленный питон с модулем requests (как установить читайте тут)

    б) Установленный модуль openpyxl – но тут всё просто, запустите командную строку и вбейте pip install openpyxl

    Проверка

    После того, как вы все установили, давайте проверим, создаются ли валидные Excel файлы. Простейший пример (взятый с официального сайта) показывает, как создать новую книгу, внести туда данные и сохранить:

    from openpyxl import Workbook wb = Workbook() # Выбрать активную книгу ws = wb.active # Запишем число 42 в ячейку А1 ws['A1'] = 42 # Добавим строку с данными ws.append([1, 2, 3]) # В поле А2 запишем текущую дату и время import datetime ws['A2'] = datetime.datetime.now() # Сохраним файл рядом со скриптом import os wb.save(os.path.dirname(os.path.abspath(__file__)) + "/sample.xlsx")

    Копируем этот код, вставляем в IDLE (опять же, подробности тут), сохраняем под каким-нибудь именем (у меня это excel_test.py) и запускаем (F5). В папке рядом со скриптом должен появиться файл sample.xlsx. 

    Можно открыть его экселем и посмотреть, что внутри:

    Реклама

    История торгов из Exmo в Excel

    Ок, работает, писать данные можем. Теперь давайте попробуем забрать с exmo.me всю историю торгов. Точнее не так – всю историю Эксмо не дает, а дает максимум 10 000 последних торгов по паре.

    Вот код – вставим в IDLE, сохраним как exmo_excel.py и запустим (о том, что такое API и как работать с ним на Exmo читайте в других статьях цикла – ссылки в конце статьи, над комментариями).

    import urllib, http.client import os import time import json # эти модули нужны для генерации подписи API import hmac, hashlib from openpyxl import Workbook from datetime import datetime, timezone # ключи API, которые предоставила exmo API_KEY = 'K-...' # обратите внимание, что добавлена 'b' перед строкой API_SECRET = b'S-...' # базовые настройки API_URL = 'api.exmo.com' API_VERSION = 'v1' # Свой класс исключений class ScriptError(Exception): pass class ScriptQuitCondition(Exception): pass # все обращения к API проходят через эту функцию def call_api(**kwargs): payload = {'nonce': int(round(time.time()*1000))} if kwargs: payload.update(kwargs) payload = urllib.parse.urlencode(payload) H = hmac.new(key=API_SECRET, digestmod=hashlib.sha512) H.update(payload.encode('utf-8')) sign = H.hexdigest() headers = {"Content-type": "application/x-www-form-urlencoded", "Key":API_KEY, "Sign":sign} conn = http.client.HTTPSConnection(API_URL, timeout=60) conn.request("POST", "/"+API_VERSION + "/" + kwargs['method'], payload, headers) response = conn.getresponse().read() conn.close() try: obj = json.loads(response.decode('utf-8')) if 'error' in obj and obj['error']: raise ScriptError(obj['error']) return obj except json.decoder.JSONDecodeError: raise ScriptError('Ошибка анализа возвращаемых данных, получена строка', response) # Получим список всех пар, по которым торгует биржа pairs_list = [] pairs = call_api(method='pair_settings') for pair in pairs: pairs_list.append(pair) # сложим их в словарь pairs_str = ','.join(pairs_list) # из словаря создадим строку, с парами, разделенными запятыми # Получим историю торгов по всем парам trades = call_api(method='user_trades', pair=pairs_str, limit=10000) for pair in trades: # пройдемся по каждой паре if not trades[pair]: #пропускаем пары, по которым не было торгов continue # Теперь проходим по всем торгам этой пары print(pair, len(trades[pair]))

    Должны увидеть список пар, по которым торговали, и кол-во полученных сделок по каждой их них. У меня это выглядит так:

    Не лишним будет упомянуть, что есть торги по сути. Когда вы выставляете ордер на продажу, например 1 BTC, биржа подбирает для вас покупателей. Ваш ордер может быть исполнен в одну сделку – если кто-то сразу купит ваш биткоин целиком, либо в несколько – когда ваш биткойн раскупят по частям. Так вот, история торгов – это история именно таких сделок.

    Вообще, стоило бы сравнить с историей торгов на сайте Эксмо, но там как будто специально неудобно сделано.. В общем, похоже на правду, на этом и остановимся пока. Если что, историю торгов можно смотреть тут (раздел сделки):

    Теперь, собственно, нужно объединить оба скрипта, что бы получить историю торгов и выгрузить в эксель. Немного магии и вуаля:

    import urllib, http.client import os import time import json # эти модули нужны для генерации подписи API import hmac, hashlib from openpyxl import Workbook from datetime import datetime, timezone # ключи API, которые предоставила exmo API_KEY = 'K-...' # обратите внимание, что добавлена 'b' перед строкой API_SECRET = b'S-...' # базовые настройки API_URL = 'api.exmo.com' API_VERSION = 'v1' # Свой класс исключений class ScriptError(Exception): pass class ScriptQuitCondition(Exception): pass # все обращения к API проходят через эту функцию def call_api(**kwargs): payload = {'nonce': int(round(time.time()*1000))} if kwargs: payload.update(kwargs) payload = urllib.parse.urlencode(payload) H = hmac.new(key=API_SECRET, digestmod=hashlib.sha512) H.update(payload.encode('utf-8')) sign = H.hexdigest() headers = {"Content-type": "application/x-www-form-urlencoded", "Key":API_KEY, "Sign":sign} conn = http.client.HTTPSConnection(API_URL, timeout=60) conn.request("POST", "/"+API_VERSION + "/" + kwargs['method'], payload, headers) response = conn.getresponse().read() conn.close() try: obj = json.loads(response.decode('utf-8')) if 'error' in obj and obj['error']: raise ScriptError(obj['error']) return obj except json.decoder.JSONDecodeError: raise ScriptError('Ошибка анализа возвращаемых данных, получена строка', response) # Получим список всех пар, по которым торгует биржа pairs_list = [] pairs = call_api(method='pair_settings') for pair in pairs: pairs_list.append(pair) # сложим их в словарь pairs_str = ','.join(pairs_list) # из словаря создадим строку, с парами, разделенными запятыми # Создадим Excel файл wb = Workbook() ws = wb.active # Вставим заголовки ws.append(["Дата сделки", "Пара сделки", "ID ордера", "ID сделки", "Тип сделки", "Кол-во по сделке", "Цена сделки", "Сумма сделки"]) # Получим историю торгов по всем парам trades = call_api(method='user_trades', pair=pairs_str, limit=10000) for pair in trades: # пройдемся по каждой паре if not trades[pair]: #пропускаем пары, по которым не было торгов continue # Теперь проходим по всем торгам этой пары for trade in trades[pair]: # Мы бы могли использовать метод dict.values(), но нам нужны данные в определенном порядке, причем каждый раз для каждого массива, так что немного усложним код # Форматируем и вставляем строку с данными в Excel ws.append([ datetime.fromtimestamp(trade['date'], timezone.utc), # дата сделки pair, # Пара сделки trade['order_id'], # ID ордера trade['trade_id'], # ID сделки 'Покупка' if trade['type'] == 'buy' else 'Продажа', float(trade['quantity']), # Кол-во по сделке float(trade['price']), # Цена сделки float(trade['amount']) * (-1 if trade['type'] == 'buy' else 0.998), # сумма сделки, если buy то отрицательная - так удобнее считать потом ]) # Сохраняем файл wb.save(os.path.dirname(os.path.abspath(__file__)) + "/exmo_excel.xlsx") print('Работу закончил')

    Вставляем этот код в IDLE, сохраняем, запускаем.. У вас должен появиться Excel-файл exmo_excel.xlsx рядом со скриптом. Откроем, посмотрим.

    Я поставил фильтр по паре LTC_RUB, что бы еще раз акцентировать внимание на сделках, так в файле все торги по всем парам (точнее, последние 10 000 торгов). В первой колонке время сделки (по времени биржи), в остальных вроде понятно, объясню про ID ордера и ID сделки.

    Смотреть стоит по времени, т.е. снизу вверх. 14 августа я на почти 150р купил 0, 618LTC по курсу 242,38. Для этого я создавал отложенный ордер (52466257), который был исполнен в рамках одной сделки (5227092).

    После этого я, видимо, выставил отложенный ордер на продажу купленного (52466294), который исполнился опять же одной сделкой.

    После этого я создал отложенный ордер на покупку (62752648), который был исполнен частями –обратите внимание, что тут две строки с одним и тем же номером ордера и одной и той же ценой, но разными суммами, временем и id сделки. Т.е. сначала кто-то купил почти всё, а потом кто-то еще докупил, что осталось.

    Ну а потом сработала еще одна продажа купленного.

    Если сложить все суммы сделки (вот почему покупку мы делали отрицательной), то получим сальдо или как там его – мне больше нравится слово профит, хотя и «прибыль» тоже ничего. В данном случае вроде бы 63 копейки прибыли, но….. Тут, насколько я вижу, хотя надо бы и проверить, сумма указывается ДО вычета комиссии биржи – 0.2%.

    Если еще раз обратите внимание, то первую сделку я провел за 150 рублей, купив 0,618LTC, а продаю 0,617LTC – потому что часть купленного в LTC съела комиссия (рубли не псотрадали). Когда же я продаю купленное, комиссия берется с рублей – но тут я не вижу, что бы это отражалось. Поэтому, наверное, более точно было считать так (дополнил столбец руками):

    Для положительных сумм сделок мы вычитаем комиссию 0.2% (формула видна на рисунке), отрицательные считаем как есть – так правильно. Итого, профит составил 2,8 копейки, юхууу))

    Не помню, что я тестил на этой паре год назад, и какие настройки прибыльности стояли, но в общем имейте в виду такую выдачу инфы, что через API, что на сайте.

    Если хотите, можете сразу выводить в эксель прибыль за вычетом комиссии. Для этого строку

    float(trade['amount']) * (-1 if trade['type'] == 'buy' else 1),

    нужно заменить на

    float(trade['amount']) * (-1 if trade['type'] == 'buy' else 0.998),

    итог будет правильным:

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

    Реклама

    История торгов из Yobit в Excel

    Ну и как бонус давайте сделаем тоже самое для биржи yobit.net. Тут уже будет меньше комментариев, т.к. по сути ничего не меняется, только немного кода. Более детально о том, как работать с API yobit, читайте так же по ссылкам в конце статьи.

    В общем, вот код, вбивайте свои ключи, запускайте.. Он будет работать мучительно долго, т.к. во первых очень много пар, а во вторых, после каждой пары добавлено time.sleep(1), что бы вас Yobit не забанил.. Хотя, он может быть и так не забанит, так что можете удалить эту строку и все пойдет шустрее, но это на свой страх и риск.

    import os import json import requests import math import time import urllib, http.client import hmac, hashlib from openpyxl import Workbook from datetime import datetime, timezone # Вписываем свои ключи API_KEY = '...' API_SECRET = b'...' """ Каждый новый запрос к серверу должен содержать увеличенное число в диапазоне 1-2147483646 Поэтому храним число в файле поблизости, каждый раз обновляя его """ nonce_file = "./nonce" if not os.path.exists(nonce_file): with open(nonce_file, "w") as out: out.write('1') # Будем перехватывать все сообщения об ошибках с биржи class YobitException(Exception): pass def call_api(**kwargs): # При каждом обращении к торговому API увеличиваем счетчик nonce на единицу with open(nonce_file, 'r+') as inp: nonce = int(inp.read()) inp.seek(0) inp.write(str(nonce+1)) inp.truncate() payload = {'nonce': nonce} if kwargs: payload.update(kwargs) payload = urllib.parse.urlencode(payload) H = hmac.new(key=API_SECRET, digestmod=hashlib.sha512) H.update(payload.encode('utf-8')) sign = H.hexdigest() headers = {"Content-type": "application/x-www-form-urlencoded", "Key":API_KEY, "Sign":sign} conn = http.client.HTTPSConnection("yobit.net", timeout=60) conn.request("POST", "/tapi/", payload, headers) response = conn.getresponse().read() conn.close() try: obj = json.loads(response.decode('utf-8')) if 'error' in obj and obj['error']: raise YobitException(obj['error']) return obj except json.decoder.JSONDecodeError: raise YobitException('Ошибка анализа возвращаемых данных, получена строка', response) res = requests.get('https://yobit.net/api/3/info') # получаем данные info res_obj = json.loads(res.text) # переводим полученный текст в объект с данными pairs = [pair for pair in res_obj['pairs']] # создадим массив названий пар # Создадим Excel файл wb = Workbook() ws = wb.active # Вставим заголовки ws.append(["Дата сделки", "Пара сделки", "ID ордера", "ID сделки", "Тип сделки", "Цена сделки", "Сумма сделки"]) for pair in pairs: try: print ('Получаем историю торгов по паре %s' % pair, '*'*30) data = call_api(method="TradeHistory", pair=pair) if(data.get('return')): for t in data['return']: trade = data['return'][t] ws.append([ datetime.fromtimestamp(int(trade['timestamp']), timezone.utc), # дата сделки pair, # Пара сделки trade['order_id'], # ID ордера t, # ID сделки 'Покупка' if trade['type'] == 'buy' else 'Продажа', float(trade['rate']), # Цена сделки float(trade['amount']) * (-1 if trade['type'] == 'buy' else 1), # сумма сделки, если buy то отрицательная - так удобнее считать потом ]) else: print('Торгов не было') #time.sleep(1) except YobitException as e: print("Облом:", e) wb.save(os.path.dirname(os.path.abspath(__file__)) + "/yobit_excel.xlsx") print('Работу закончил')

    Когда оно всё доработает, рядом с файлом появится файл yobit_excel.xslx, можете открывать и делать выводы. Опять же, если нужно вычитать комиссию, то воспользуйтесь советом выше, для эксмо. Если что-то не будет работать или будет работать не так, пишите, поправим.

    Удачи!

     

     

    bablofil.ru

    Чего бы с биржи стянуть? Изучаем API и способы работы с ним.

    Биржам выгодно, что бы вы писали роботов.

    И для этого они облегчают работу по их созданию

    Для того, что бы автоматизировать и ускорить свою работу на бирже, надо как то научиться с биржей взаимодействовать. Специально для этого, биржи предоставляют специальный интерфейс для программистов. Более того – бирже ВЫГОДНО, что бы вы делали ставки чаще и прокручивали бОльшие суммы – это приносит бирже деньги за счет комиссии, и увеличивает объем торгов, что привлекает новых игроков.

    Этот программный интерфейс называется API – аббревиатура от «application programming interface».На русский язык можно перевести как «интерфейс программирования приложений», «интерфейс прикладного программирования» и так далее. Не пугайтесь, все просто – вам достаточно зайти на нужную страницу на сайте биржи, и дело будет сделано.

    Например, если вы зайдете на страницу https://api.exmo.com/v1/currency/, вы увидите список валют, по которым торгует биржа.

    Данные предоставлены в специальном формате, удобном для программ, но и человеку не очень сложно понять их – например, в данном  случае вы видите список – USD, EUR, RUB и так далее, остальные символы разделяют и упорядочивают данные. Этот формат представления данных называется JSON, и он весьма популярен в Интернете.

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

    Например, первым делом программа должна узнать свой баланс на бирже, узнать есть ли у вас открытые неисполненные ордера, потом узнать какие предложения сейчас существуют, создать новый ордер или отменить текущий и так далее. В общем, должна делать все то, что вы обычно делаете руками, и все данные для этого у неё есть.

    Некоторые разделы API (страницы) общедоступны – например, последние совершенные сделки и текущие чужие открытые ордера. Такие разделы обычно именуются Public API, и для получения этой информации не требуется авторизация, получить данные может любой желающий.

    Другие разделы, влияющие на личные данные пользователя или операции, связанные с деньгами – например, покупка валюты или запрос баланса, требуют определенных прав доступа, и их нужно настраивать отдельно. Такие методы доступа называются Private API. Работа с ними идет точно так же к с Public API, но требуются дополнительные действия при подключении. К таким операциям мы подойдем в следующих статьях, когда будем автоматизировать покупку/продажу.

    В этой статье будет рассмотрена работа с Public API – тем более, что вам все равно нужны будут эти данные для полноценной работы робота. Все методы, доступные без авторизации, описаны на этой странице https://exmo.me/ru/api_doc#/public_api

    Реклама

    Ладно, в общем, понятно, но как написать программу для работы с биржей?

    В принципе, на картинке указан код, который получает те же данные, что и мы в начале статьи. Обратите внимание – всего три строчки кода.

    Вот сам код:

    import requests r = requests.get('https://api.exmo.com/v1/currency/') print(r.text)

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

    А вот результат вывода программы:

    То же самое, что мы и видели на странице, не так ли? Давайте упорядочим полученные данные. Для этого надо немного изменить код. Пусть теперь он выглядит вот так:

    import requests import json r = requests.get('https://api.exmo.com/v1/currency/') obj = json.loads(r.text) print(json.dumps(obj, sort_keys=True, indent=4, separators=(',',': ')))

    Сохраним, запустим, что получилось?

    Ура, оно вертится! Значит, программа получает и обрабатывает данные с биржи. Теперь надо научиться использовать это в практических целях – данный учебный пример, по большому счету, бесполезен.

    Реклама

    Пишем что-то полезное

    Что может быть полезным? Ну, например получение списка текущих сделок – мы сможем узнавать, кто что продает и покупает, выводить средний курс и вообще ориентироваться в происходящем.

    За эти данные отвечает, как обычно, отдельный метод API, он доступен по этому адресу: https://api.exmo.com/v1/order_book/?pair=BTC_USD. Откроем его в браузере:

    Эти данные посложнее для человеческого восприятия, и сходу выглядят как набор непонятных данных. Давайте пойдем по тому же пути, и для начала научимся получать их и выводить в окне программы. Поменяем адрес API (помните, я выделял желтым выше? Код возьмем оттуда же). И вот результат:

    Все равно тарабарщина. А ведь это только 100 последних записей, что бы получить тысячу нужно в конец адреса добавить &limit=1000, итоговый адрес будет выглядеть вот так: https://api.exmo.com/v1/order_book/?pair=BTC_USD&limit=1000

    Давайте выведем данные покрасивее и поймем, что там за структура – все данные в формате JSON имеют структуру, одни элементы вкладываются в другие и так далее.

    ХИНТ: вы можете отформатировать JSON для комфортного просмотра online – перейдите на сайт http://jsoneditoronline.org/, вставьте код в левую колонку и нажмите на кнопку сверху слева. Получится примерно так:

    Напишем код, что бы выводить в таком же виде в окне программы

    import requests import json r = requests.get('https://api.exmo.com/v1/order_book/?pair=BTC_USD') obj = json.loads(r.text) print(json.dumps(obj, sort_keys=True, indent=4, separators=(',',': ')))

    И выполняем его:

    Стало читабельнее, не так ли? Давайте разберем структуру данных – я удалил ненужные пока записи, что бы умещалось на один экран. Вот так выглядит документ по сути:

    В корневой узел BTC_USD вложены дочерние узлы:

    ask_quantity - объем всех ордеров на продажуask_amount - сумма всех ордеров на продажуask_top - минимальная цена продажиbid_quantity - объем всех ордеров на покупкуbid_amount - сумма всех ордеров на покупкуbid_top - максимальная цена покупкиbid - список ордеров на покупку, где каждая строка это цена, количество и суммаask - список ордеров на продажу, где каждая строка это цена, количество и сумма

    Некоторые параметры представлены готовым значением. Некоторые содержат в себе дополнительные списки. Например “ask” по сути является контейнером, в котором лежат другие записи. Если бы мы могли свернуть “ask”, он выглядел бы примерно вот так:

    Эти квадратные скобки – открывающие и закрывающие, являются как бы началом и концом контейнера. Внутри него есть другие элементы, которые так же являются контейнерами и обозначены квадратными скобками.

    Каждый такой контейнер внутри “ask” как раз определяет чье-то предложение на покупку. Первая цифра обозначает цену (в данном случае, в долларах) по которой этот человек хочет продать, вторая – сколько валюты он готов отдать(в данном случае, в BTC), а третья – итоговая сумма сделки. В этом примере человек хочет продать 0.001 BTC по цене 1068 долларов. Итоговая цена составит 1068*0.001 = 1.068. долларов. Человек хочет продать биткоинов на доллар, грубо говоря.

    Что это вообще дает?

    Давайте напишем программу, которая выводит максимальные цены покупки и продажи на текущий момент времени.

    Код меняется не сильно, но теперь мы будем обращаться к конкретным полям документа – сейчас нас интересуют поля bid_top и ask_top. Давайте их выведем.

     Немного изменим код:

    import requests import json r = requests.get('https://api.exmo.com/v1/order_book/?pair=BTC_USD') obj = json.loads(r.text) print( "минимальная цена продажи", obj['BTC_USD']['ask_top'], "максимальная цена покупки", obj['BTC_USD']['bid_top'] )

    Запустим программу – получим текущие данные. Если будем запускать время от времени – они будут меняться, так как меняется максимальная сумма покупки и продажи.

    Оно работает, но каждый раз запускать руками не хочется – давайте добавим цикличность. Пусть оно работает, и каждые 30 секунд обновляет информацию.

    import requests import json import time while True: r = requests.get('https://api.exmo.com/v1/order_book/?pair=BTC_USD') obj = json.loads(r.text) print( "минимальная цена продажи", obj['BTC_USD']['ask_top'], "максимальная цена покупки", obj['BTC_USD']['bid_top'] ) time.sleep(30)

    Работает, показывает данные (для выключения закройте окно программы)

    Но.. как то скучно. Цена редко меняется, да и по одной валюте всего. Давайте используем другой метод - https://api.exmo.com/v1/ticker/.

    Вот что он нам вернет (по всем валютам):

    high - максимальная цена сделки за 24 часаlow - минимальная цена сделки за 24 часаavg - средняя цена сделки за 24 часаvol - объем всех сделок за 24 часаvol_curr - сумма всех сделок за 24 часаlast_trade - цена последней сделкиbuy_price - текущая максимальная цена покупкиsell_price - текущая минимальная цена продажиupdated - дата и время обновления данных

    Немного поменяем код – как всегда, и выведем поля «текущая максимальная цена покупки» и «текущая минимальная цена продажи» для каждой валюты.

    import requests import json import time # программа будет работать бесконечно while True: # получить данные с биржи r = requests.get('https://api.exmo.com/v1/ticker/') # переводим данные во понятный программе формат obj = json.loads(r.text) # находим все валюты, перечисленные в файле for pair in obj: print( "Валюта", pair, "текущая максимальная цена покупки", obj[pair]['buy_price'], "текущая минимальная цена продажи", obj[pair]['sell_price'] ) # подождать три секунды и начать заново time.sleep(3)

    Вы можете спросить – зачем мне все это делать, если курсы я и так могу глазами посмотреть? Логично, но это нужно для того, что бы потом отрабатывать условия и давать роботу указания – например, если текущая цена такой-то валютной пары ниже такой-то суммы, то продавай.  Если программирование вас увлечет, вы можете эти данные не просто выводить на экран, а сохранять, анализировать, строить графики и т.п. Как вы уже видели, много кода писать не надо – все делается в несколько строк.

    Для домашних экспериментов и практики могу посоветовать вам научиться получать и выводить информацию по всем методам, описанным на этой странице https://exmo.me/ru/api_doc#/public_api (от раздела  PUBLIC API до раздела AUTHENTICATED API – всего 5 методов).

    Так же я особо не налегаю на разъяснение языка программирования, который использую здесь, так как это отдельная большая тема для изучения, но может быть стоит какие-то моменты прояснять подробнее? Для человека, пока далекого от программирования, биржевой торговли и прочего этот материал может показаться сложным.

    В любом случае, жду ваших вопросов и замечаний в комментариях, а вам желаю хороших заработков и удачи!

    bablofil.ru

    прямой доступ на биржу / Блог компании ITI Capital / Хабр

    В предыдущих топиках мы уже рассмотрели общее устройство российского фондового рынка, поговорили о торговых терминалах, которые используют инвесторы, и коснулись темы создания роботов для автоматизированной торговли благодаря API брокерских систем. Однако, во времена, когда на бирже для многих трейдеров все решают доли секунды, работа по схеме «пользователь — брокерская система — ядро биржи» подойдет не всем. Именно поэтому появилась технология, позволяющая максимально оптимизировать эту цепочку – прямой доступ на биржу.

    image

    Зачем это нужно?
    Ситуация на биржевых площадках во всем мире в последние годы развивается по одному сценарию – трейдеры со всех концов земли сошлись в борьбе за достижение наивысшей скорости совершения торговых операций. Прежде всего это связано с подъемом так называемой алгоритмической торговли при которой операции совершаются специальными роботами.

    Как правило, роботы совершают огромное количество таких операций за одну торговую сессию (от тысяч до сотен тысяч), зарабатывая на каждой из них не очень много, но благодаря объему, обеспечивая своему владельцу стабильный доход. При таком способе торговли на первый план выходит скорость. Если заявка, посланная в рынок вашим роботом, задержится по пути хоть на пару миллисекунд, то вы можете недосчитаться прибыли. И точно также, если информация о ситуации на рынке (market data) будет поступать к роботу с задержкой, он не сможет в рамках заданного алгоритма быстро реагировать на изменения, что также чревато убытками.

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

    Что такое прямой доступ на биржу?
    Прямой доступ (Direct Market Access, DMA)представляет собой технологию высокоскоростного доступа на биржевые площадки, при котором заявка выставляется в торговую систему биржи напрямую, минуя торговую систему брокера. Все это позволяет существенно сократить время доставки заявки на биржу и получения информации о ее состоянии.

    При такой организации процесса торговли трейдер может рассчитывать на значительный выигрыш по времени. Например, при прямом подключении к фондовому и валютному рынкам Московской биржи время обработки заявки снижается до 0.5 мс, а на рынках FORTS и Standard – не превышает 3 мс. При использовании же брокерской системы, заявки обрабатываются за время от 5 -10 мс до 150- 500 мс в зависимости от брокерской системы, типа рынка и способа подключения. Т.е. через брокерские системы заявки обрабатываются в 10-100 раз медленнее, чем при прямом подключении (хотя и такая скорость вполне устраивает многих торговцев).

    Естественно, использование технологии прямого доступа стоит дороже (зачастую значительно) и подходит только тем, кто совершает большое количество операций в день и готов платить за их скорость.

    Где используется?
    Несмотря на то, что технически, благодаря прямому доступу на биржу трейдеры могут совершать торговые операции минуя брокера, «документально» доступ все равно осуществляется именно через компании-брокеров. То есть для того, чтобы получить возможность напрямую торговать на, допустим, фондовом рынке Московской биржи, инвестору необходимо заключить договор с брокером и уже у него приобрести услугу прямого доступа на биржу.

    image

    В результате, российские клиенты могут получить доступ, главным образом, к рынкам, входящим в состав Московской биржи:

    • Фондовый рынок – крупнейший фондовый рынок стран СНГ, Восточной и Центральной Европы. Доступ предоставляется к секторам «Основной рынок» и к сектору рынка Standard.
    • Срочный рынок (бывший FORTS) – ведущая площадка по торговле производными финансовыми инструментами в России и странах Восточной Европы.
    • Рынок валют и драгоценных металлов – один из наиболее значимых сегментов финансового рынка России.
    Кроме того, некоторые брокеры могут организовать прямой доступ на зарубежные площадки, например на London Stock Exchange (LSE), рынки СМЕ (фьючерсы и опционы) и т.д.
    Разновидности протоколов и способов подключения
    В целом, схема прямого доступа выглядит следующим образом: сервер с торговым роботом подключается к промежуточному серверу, который размещен в максимальной близости от ядра биржевой торговой системы. На этом сервере установлено специальное ПО – так называемые шлюзы, которые используются для передачи заявок и рыночной информации непосредственно в торговую систему. При этом, для совершения операций и получением данных используются различные протоколыи способы подключения.

    Протокол FIX (Financial Information eXchange) – протокол обмена финансовой информацией, который является мировым стандартом для обмена данными между участниками биржевых торгов в режиме реального времени. Поддерживается крупнейшими мировыми биржевыми площадками, в том числе Московской биржей.

    Для получения рыночной информации (Market Data) используется протокол FAST (Fix Adapted for STreaming) – стандарт, разработанный создателями протокола FIX, который позволяет добиться значительных возможностей компрессии данных для передачи больших объемов рыночной информации с минимальными временными задержками. Помимо Московской биржи, используется на NYSE, Nasdaq-OMX и многих других мировых площадках.

    Также для прямого подключения используются нативные протоколы. Данные протоколы возникли еще до объединения бирж ММВБ и РТС в Московскую биржу.

    Так на рынках относившихся к бирже РТС (FORTS – фьючерсы и опционы, Standard), для прямого совершения операций и получения данных в режиме подключения используется протокол Plaza II.

    Для выполнения торговых операций и получения биржевых данных на площадках, ранее относившихся к бирже ММВБ (валютный и фондовый рынки) используется двунаправленный шлюз MICEXBridge (TEAP).

    Технически подклюние к Московское бирже возможно несколькими способами, такими как подключение через интернет, подключение с использованием универсальной схемы подключения или используя колокацию биржи.

    imageУниверсальная схема подключения

    Более подробно протоколы передачи финансовой информации и способы подключения мы рассмотрим в одной из следующих статей.

    Софт
    Для тех трейдеров, кто не пользуется для торговли роботами, есть возможность торговать на прямом подключении используя более привычный им торговый терминал. Однако программное обеспечение, которое работает с брокерской торговой системой, не работает по биржевым протоколам прямого подключения, поэтому для него создаются отдельные программы (некоторые из них представлены здесь).

    Кроме того, благодаря тому, что технологии прямого подключения являются открытыми, инвесторы могут самостоятельно разрабатывать программное обеспечение для себя. Однако так как эти программы в конечном итоге имеют практически непосредственный доступ к ядру торговой системы, биржа внедрила процедуру сертификации торговых решений от сторонних разработчиков, чтобы исключить вероятность, когда «взбесившийся робот» наповал уложит всю систему. Эту процедуру проходят как разработки индивидуальных инвесторов, так и ПО, созданное специальными компаниями на заказ.

    Что еще?
    Если продолжать двигаться по цепочке сокращения времени на совершение операций, то становится очевидно, что нужно размещать торгового робота не только логически, но и физически как можно ближе к серверам с ядром биржевой торговой системы.

    Робот может размещаться как на отдельном сервере, который можно поставить в стойку в дата-центре (эта услуга называется Colocation), так и на виртуальной машине (Hosting), которая в свою очередь запускается вместе с виртуалками других клиентов на сервере, также установленном в ЦОД, рядом с биржевыми серверами. Услуги хостинга предоставляют, как правило, только крупные брокеры, обладающие собственными стойками в дата-центрах.

    Сейчас, торговые сервера Московской биржи размещены в ЦОД М1. Торгвоые роботы, подключаемые к биржевым серверам, могут размещаться в двух зонах – так называемой DMA-зоне свободной коллокации и зоне непосредственной коллокации биржи.

    image

    Размещение в зоне коллокации биржи имеет очевидные преимущества: виртуальные машины и серверы подключаются непосредственно к ядру биржи, в то время как из свободной зоны подключение идет через промежуточные серверы MICEX Gate и Plaza II. Кроме того, получение данных по протоколу FAST и выделенный канал для подключения к рынку IOB London Stock Exchange (торговля российскими ADR в Лондоне) доступны только из зоны коллокации биржи.

    Одним из способов существенного снижения затрат на инфраструктуру является размещение робота в зоне свободной колокации. Услуги, предоставляемые в ней, практически аналогичны услугам зоны биржевой колокации. Однако бесплатный сыр бывает только в мышеловке, за относительную дешевизну размещения робота придется «заплатить» несколькими миллисекундами увеличения скорости обработки транзакций.

    Кроме того, поскольку интерфейсы для создания программного обеспечения прямого подключения изначально не предполагают никаких графических возможностей вывода информации о торгах, то возможность синхронизации приказов и позиций, приказов и позиций, сформированных на прямом подключении, с торговой системой брокера в реальном времени – практически необходимая вещь для контроля торговых операций. Поэтому многие брокеры стараются предоставлять своим клиентам такие возможности.

    Все это, конечно, стоит денег и, в сравнении, с обычным доступом на биржу через брокерские системы, довольно больших. Однако, для тех инвесторов, которые вышли на определенный уровень доходов – такие траты имеют смысл. По данным представителей биржи, владельцы роботов, победивших на конкурсе «Лучший частный инвестор» в 2011 году тратили на услуги, связанные с прямым доступом от 100 до 500 тысяч руб. в месяц. Однако, с учетом того, что некоторым торговцам (хотя таких было не так уж и много) удавалось выходить на доходность равную 8000% и зарабатывать миллионы рублей в месяц (учитывая все комиссии брокера и биржи), эти расходы довольно быстро окупались.

    На сегодня все! Всем спасибо за внимание, будем рады ответить на вопросы в комментариях.

    habr.com


    Смотрите также

    .