Обсуждение статьи "Ордерa, позиции и сделки в MetaTrader 5"

 

Опубликована статья Ордерa, позиции и сделки в MetaTrader 5:

Надежный торговый робот не может быть создан без понимания механизмов работы торговой системы MetaTrader 5. Клиентский терминал получает от торгового сервера информацию о позициях, ордерах и сделках. Чтобы правильно обработать эти данные средствами MQL5 необходимо хорошо представлять как происходит взаимодействие mql5-программы и среды исполнения терминала.


Автор:  MetaQuotes

 

После прочтения не нашел для себя оптимального ответа на вот такой вопрос.

Как загрузить в кэш к примеру только 1 последний ордер из истории (для усложнения задачи пусть нужно еще последний по символу).

К примеру у советника разная частота ордеров. Может в день делать 30 ордеров а может "молчать" несколько дней или недель.

Есть варианты после отправки ордера на сервер запоминать где то его тикет и после уже по тикету доставать этот ордер - не проблема. Запоминать можно как в глобальных переменных так и внутри логики эксперта. Но вот задача если к примеру советник подключается к счету  из другого терминала\компьютера и тикета последнего ордера у него нет.

Приходится загружать историю по средствам HistorySelect. с конечной датой более менее ясно а вот как высчитать начальную.

Потому как даже в маленький диапазон могут попасть несколько ордеров - не проблема но не оптимально в плане загрузки лишних данных. Или могут не попасть не одного.

Можно брать еще меньше диапазон дат и крутить в цикле (сдвигать диапазон в историю) на предмет заполнения кеша - не оптимально в плане логики работы - лишние циклы, запросы к базе истории.

Предложение- организовать загрузку необходимого количества по ордерам\сделкам по инструменту.

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

select * from HistiryOrder where a_date_send>@datestart and a_date_send<@dateend

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






 
olyakish:

После прочтения не нашел для себя оптимального ответа на вот такой вопрос.

Как загрузить в кэш к примеру только 1 последний ордер из истории (для усложнения задачи пусть нужно еще последний по символу).

К примеру у советника разная частота ордеров. Может в день делать 30 ордеров а может "молчать" несколько дней или недель.

Есть варианты после отправки ордера на сервер запоминать где то его тикет и после уже по тикету доставать этот ордер - не проблема. Запоминать можно как в глобальных переменных так и внутри логики эксперта. Но вот задача если к примеру советник подключается к счету  из другого терминала\компьютера и тикета последнего ордера у него нет.

Приходится загружать историю по средствам HistorySelect. с конечной датой более менее ясно а вот как высчитать начальную.

Потому как даже в маленький диапазон могут попасть несколько ордеров - не проблема но не оптимально в плане загрузки лишних данных. Или могут не попасть не одного.

Можно брать еще меньше диапазон дат и крутить в цикле (сдвигать диапазон в историю) на предмет заполнения кеша - не оптимально в плане логики работы - лишние циклы, запросы к базе истории.

Предложение- организовать загрузку необходимого количества по ордерам\сделкам по инструменту.

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

select * from HistiryOrder where a_date_send>@datestart and a_date_send<@dateend

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


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

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

Запускаете полную загрузку истории в OnInit(). Запоминаете нужные даты. После чего в OnTicket() можно крутить историей "как цыган солнцем".

 
Urain:

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

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

Запускаете полную загрузку истории в OnInit(). Запоминаете нужные даты. После чего в OnTicket() можно крутить историей "как цыган солнцем".

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

 

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

//--- начальную границу установим на 3 дня назад
   datetime start=end-3*PeriodSeconds(PERIOD_D1);

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

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

Например, вот по такому шаблону:

  1. OnInit() - загрузка всей истории в кэш, поиск последнего значимого для эксперта ордера (например, по мейджику или просто по инструменту), сохранение его времени в переменную.
  2. OnTrade() - обновление загруженной в кэш истории (начиная с запомненного времени), обновление времени последнего ордера (если появился новый значимый).
  3. OnTick() - работа с текущим загруженным кэшем или, если есть необходимость, загрузка кэша от запомненного времени.

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


В любом случае, еще раз спасибо за статью. Такие "спецификации от разработчиков" нужны, иначе не будет нормального кода.

 

В статье дается пример загрузки торговой истории за один день (в одном коде есть пример загрузки истории за 3 дня). Да, это есть ограничение и пример не является универсальным. Но если читатель понимает при прочтении статьи эту особенность, то он сможет самостоятельно решить для себя вопрос - за какой интервал и с какого момента ему нужно подгружать в кэш торговую историю.

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

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

Я уверен, что после прочтения статьи дальше все будет уже просто.


 

Скажите, а есть ли где-то описание работы терминала в режиме OfLine. Дело в том, что у меня не смог загрузиться терминал из-за отсутствия обновления данных графика. Хотел заняться тестированием на работе (там нет интернента), но так и не смог: графики ждут обновления, а в тестере нет ни одного символа. В статье сказано, что после запуска терминала выполняется синхронизация данных с сервером. А что же происходит, если нет соединения (собстственно оно и не предполагается). Может есть смысл явно указать терминалу, что предполагается работа в OfLine и не крутить это несчастное колёсико. Возможно и сбоев будет меньше для работы тестера. Справедливости ради следует сказать, что у меня давно такого не было, но на форуме люди преиодически жалуются на эту проблему. Может есть какие-то приёмчики (ну там какой-нибудь файлик убрать), чтобы расклинить ситуацию(я пытался - ничего не помогло, пока дома не установил связь с сервером).

Документация по MQL5: Получение рыночной информации / SymbolIsSynchronized
Документация по MQL5: Получение рыночной информации / SymbolIsSynchronized
  • www.mql5.com
Получение рыночной информации / SymbolIsSynchronized - Документация по MQL5
 

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

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

 
Renat:

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

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


 

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

 
Erm955:

 

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

Приведите полный скриншот всего окна терминала, включая все зоны Market Watch, чарта и тестера, пожалуйста.

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

 
Renat:

Приведите полный скриншот всего окна терминала, включая все зоны Market Watch, чарта и тестера, пожалуйста.

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

 

 

   Этого ничего не требуется, так как всё работает как и раньше. Видимо это был случайный сбой. Ранее терминал запрашивал авторизацию, сейчас запускается без неё. Проверил около 10 раз с перезагрузкой и без перезагрузки компьютера. Всё нормально, спасибо. 

Причина обращения: