Арбитраж: коллектор 1/2

Арбитраж: коллектор 1/2

25 июля 2024, 21:04
Maxim Kuznetsov
0
11

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

Что и почему собираем

Внезапно для почти всех MT-шников: события OnTick и соответствующие CopyTicks нельзя непосредственно использовать в анализе и при торговле. MT-Тик это о далёком прошлом и вообще «вещь в себе». Не существует публичных критериев генерации тика.

Нас не интересуют «тики» которые прошли. Нас интересует минимальная цена лимиток в стакане предлагаемая к продажам (Ask - то есть потенциальная цена нашей покупки) и максимальная цена лимиток к покупкам (Bid - потенциальная цена наших продаж). При торговле мы будем либо открываться по рынку в этих ценах либо ставить лимитку в этот спред.

В других биржах нет такого как понятия как «тик». Есть тикер - периодическая трансляция, есть поток сделок, есть поток изменений стакана. Последние два имеют перекрёстные ссылки. В MetaTrader этого нет, поэтому в нём работа только со стаканом (как бы двусмысленно это не звучало).

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

Какие данные точно надо собирать :

  • серверное время события (изменения bid или ask) с максимально возможной точностью, в микросекундах. И приведённое к общему отсчёту, GMT+0 или UTC.
  • пинг до сервера в момент события.
  • прошедшее время от предыдущего события. Опционально, его можно и после считать, но в момент записи это делать сильно проще
  • конечно-же цены bid,ask и объёмы стакана при них.
  • если в книге более 1 уровня, то невредно сохранить следующий уровень bid2,ask2 и объемы. Можно и всю книгу хранить, это на вкус и цвет.

Проблемы времени

У сервера и терминала разные часовые пояса. У них разные настройки времени, где-то NTP работает где-то нет. Между ними есть задержки в передаче данных (пинг) и обработке данных. При этом системное время ещё и «плывёт» и там и там. Доступные в Mt5 якоря TimeLocal(), TimeCurrent() и относительные GetTickCount64(), GetMicrosecondCount() тоже «плывут». Первые плывут от эффекта работы NTP на обеих сторонах, вторые неизвестно от каких таймеров взяты да и те в виртуализации плавают.

Периодически и довольно часто (не реже раз в день) придётся синхронизоваться - считать разницу TimeLocal, TimeCurrent и набегающую ошибку в счётчиках. Для точности лучше чаще, но практика говорит раз в день доcтаточно и лучше это делать в неторговое время, иначе возникают другие проблемы. При перемене дат почти идеально, и точность соблюдаем и не мешаем торговле (в окрест 24:00 никто не торгует) и ничего не сбиваем

Траблы с котировками

Лучше на примерах: то что в MT4/5 USDJPY, в прочих местах обычно JPYUSD. И с соответствующими множителями (ту-же йену надо делить на 100 - котировка в MT это на самом деле USD/100JPY, доллар за сотню йен). Надо конвертировать и сохранять в каком-то общем виде. Для себя решите что при этом делать с _Point и _Digits;

Куда и как сохранять

Очень важный момент. Штатно, то есть без DLL, MetaTrader умеет сохранять данные 1) в файлы 2) в базу SQLite 3) через WebRequest 3.5) посредством TcpSocket; То есть не разбежишься  :-)

При этом данных много и они следуют часто и существенных задержек процедура записи не должна давать; Если не используете DLL то единственный путь, это писать в файл на Ram-диск. Или база SQLite в памяти. Вроде несложно, но проблем не оберёшься. Данных много, память не бесконечна, придётся что-то удалять и контролировать переполнения. Писать дополнительный код «это переносим в долговременный архив», «это удаляем».

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

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

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

Пока что использую InfluxDB. У него есть своя гора минусов, и немного плюсов. Почему именно он, там мои соображения, мои личные тараканы так проголосовали. Главное - база независимая от сборщика данных

Подсказка про моменты

MetaTrader событийно ориентирован. Когда произошло какое-то событие, оно ставится(буферизуется) в очередь и когда дошёл черёд то вызывается обработчик. Приоритеты событий/обработчиков не документированы и могут меняться от релизов/версий. Ровно как и правила буферизации/пропуска

Всего обработчиков событий (за деталями и для точности - в справочник):

  • OnInit() - при инициализации экземпляра советника
  • OnDeinit() - при деинициализации
  • OnTick() - есть тик в текущем инструменте
  • OnTimer() - истёк промежуток таймера
  • OnChartEvent() - есть событие от интерфейса чарта
  • OnBook() - изменения стакана одного из подписных инструментов
  • OnTrade() - сработка или изменение отложки
  • OnTradeTransaction() - оповещения о результате торгового приказа

Ещё есть тестерные, но они нас не волнуют

Просто намёк - так как приоритеты неизвестны, то проверку «наступило нужное событие» надо делать во всех доступных колбеках кроме, конструкторов/деструкторов. А чтобы жизнь мёдом не казалась - то и проверку на дубликат событий