Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 2679

 
Yuriy Bykov #:
Если вы рассматриваете код, который должен выполняться внутри OnTick(), то там и эта проверка не нужна, так как тик может прийти и запустить обработчик только при наличии подключения к торговому счёту.

С этим трудно поспорить.

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

В моём исходном вопросе (до ИИ-ответа) речь шла не столько конкретно о функциях состояния терминала и счёта (они были для примера и после них многоточие).

Вопрос был про то, как достоверно убедиться что окружение полностью загрузилось. Проблема в том, что в некоторых случаях (примерно в половине случаев) при перезагрузке после обновления терминала советники могли работать некорректно из-за явной некорректности данных окружения. По очевидным причинам это сложноуловимая и трудновоспроизводимая проблема. Один раз, предположительно, OrderCalcMargin() вернул ноль. В другой раз что-то другое произошло. И это всё в OnTick().

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

 
Aleksey Nikolayev #:
В общем хотелось бы, словами профессора Преображенского, получить окончательную фактическую настоящую бумажку, что окружение полностью прогружено, прежде чем искать прочие баги в коде.

Ладно, вполне понимаю что хочу невозможного.

Надо просто не лениться делать везде проверки на ошибки и их правильную обработку.

Вопрос можно считать снятым.

Извиняюсь за излишнее проявление эмоций.

 
Aleksey Nikolayev #:

Вопрос был про то, как достоверно убедиться что окружение полностью загрузилось. Проблема в том, что в некоторых случаях (примерно в половине случаев) при перезагрузке после обновления терминала советники могли работать некорректно из-за явной некорректности данных окружения. По очевидным причинам это сложноуловимая и трудновоспроизводимая проблема. Один раз, предположительно, OrderCalcMargin() вернул ноль. В другой раз что-то другое произошло. И это всё в OnTick().

Да, всё так. Проблемные ситуации могут встречаются относительно редко и отлаживать их бывает весьма затруднительно. Могу только поделиться своим опытом. С возвратом OrderCalcMargin() числа 0 не столкнулся. Возможно потому, что есть проверка возвращаемое значение равно true. Встречалось ещё вроде, что получение SymbolInfoDouble(symbol, SYMBOL_POINT) или ещё какого-то свойства для символа, не являющегося текущим, возвращала 0 (хотя там этого значения быть не могло). Пришлось добавить проверку этой ситуации. Сейчас быстро уже не смог найти это место в большом объеме кода.

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

 

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

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

Уже писали что TerminalInfoInteger(TERMINAL_CONNECTED) нет смысла вызывать в OnTick(). Но стоит ли вызывать её в OnInit()? Совсем не факт - соединение может просто не успеть установиться, а использование Sleep() в OnInit() считается плохой практикой. Остаётся делать это по таймеру или есть ещё какие-то возможности (но только внутри самого советника)?

 
Aleksey Nikolayev #:

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

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

К огромному сожалению, пользы тут может не быть. В последнее время поведение терминалов в плане стабильности подключения к серверам брокера, похоже, в основном зависит от различных внешних факторов, которые находятся вне рамок нашего контроля. Сталкивался с тем, что терминал начинает каждые 20 секунд терять, а затем восстанавливать подключение к серверу. При этом цены он успевает получать в промежутках восстановления, а советник сделки открывать не может. С такой проблемой дополнительная проверка наличия подключения к серверу никак не поможет. Помогает использование Virtual Private Network или аренда сервера в другой локации. 
 
Aleksey Nikolayev #:

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

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

Уже писали что TerminalInfoInteger(TERMINAL_CONNECTED) нет смысла вызывать в OnTick(). Но стоит ли вызывать её в OnInit()? Совсем не факт - соединение может просто не успеть установиться, а использование Sleep() в OnInit() считается плохой практикой. Остаётся делать это по таймеру или есть ещё какие-то возможности (но только внутри самого советника)?

а причем тут OnInit, если разрыв связи был, то OnInit второй раз не сработает,


а на первом старте надо обязательно запускать что-то типа этого:

https://www.mql5.com/ru/docs/series/timeseries_access

внизу скрипт проверки и загрузки истории,

там еще есть результаты операции в виде разных int кодов, можно приспособить их...


подобная загрузка обязательна особенно для мультисимволов

просто шапку прикручиваем типа такой

//+------------------------------------------------------------------+
//| Вызов загрузки истории                                           |
//+------------------------------------------------------------------+
void LoadingHistory()
  {
   if(LoadHistory)
     {
      if(MQLInfoInteger(MQL_TESTER))
         return;
      //--- Загрузка истории
      for(int s=0; s<TRADE_SYMBOLS; s++)
        {
         //--- Если торговля по этому символу разрешена
         if(Symbols[s]!="")
            //---
            History(Symbols[s],PERIOD_H1,D'2020.01.01');
        }
     }
//иначе выходим
  }


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

Документация по MQL5: Организация доступа к данным / Доступ к таймсериям и индикаторам
Документация по MQL5: Организация доступа к данным / Доступ к таймсериям и индикаторам
  • www.mql5.com
В этом разделе рассматриваются вопросы, связанные с получением, хранением и запросами ценовых данных ( таймсерий ). Прежде чем ценовые данные будут...
 
Aleksey Nikolayev #:

Уже писали что TerminalInfoInteger(TERMINAL_CONNECTED) нет смысла вызывать в OnTick(). Но стоит ли вызывать её в OnInit()? Совсем не факт - соединение может просто не успеть установиться, а использование Sleep() в OnInit() считается плохой практикой. Остаётся делать это по таймеру или есть ещё какие-то возможности (но только внутри самого советника)?

Проще, наверное сделать так: если в OnInit() выясняется, что сейчас нет подключения, то запоминаем это в какой-нибудь переменной и выходим. А в OnTick() проверяем эту переменную, если она говорит, что инициализация не выполнена, то вначале запускаем из OnTick() ещё раз OnInit(). В этот раз, так как уже запустился OnTick(), то соединение есть и OnInit(), скорее всего, отработает корректно. Если снова (вдруг!) нет, то выходим из OnTick() до следующего тика. В случае корректного завершения OnInit() запоминаем в этой переменой, что всё прошло успешно.
 
срипт который выше, он еще полезен для индикаторов которые глубоко смотрят в Историю, при обычном старте Терминал (раньше) ограничивал доступ к данным, пока не крутанешь график в сторону, скрипт проверки истории эту проблему решил в свое время
 
Yuriy Bykov #:
В последнее время поведение терминалов в плане стабильности подключения к серверам брокера, похоже, в основном зависит от различных внешних факторов, которые находятся вне рамок нашего контроля. Сталкивался с тем, что терминал начинает каждые 20 секунд терять, а затем восстанавливать подключение к серверу.

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

Имхо, нужно решать проблемы по отдельности - первичная установка связи для инициализации советника это одна проблема, а разрывы связи инициализированного советника с сервером - другая.

Yuriy Bykov #:
С такой проблемой дополнительная проверка наличия подключения к серверу никак не поможет. Помогает использование Virtual Private Network или аренда сервера в другой локации. 

Не поспоришь. Но и в эксперте это тоже должно как-то обрабатываться.

Yuriy Bykov #:
Проще, наверное сделать так: если в OnInit() выясняется, что сейчас нет подключения, то запоминаем это в какой-нибудь переменной и выходим. А в OnTick() проверяем эту переменную, если она говорит, что инициализация не выполнена, то вначале запускаем из OnTick() ещё раз OnInit(). В этот раз, так как уже запустился OnTick(), то соединение есть и OnInit(), скорее всего, отработает корректно. Если снова (вдруг!) нет, то выходим из OnTick() до следующего тика. В случае корректного завершения OnInit() запоминаем в этой переменой, что всё прошло успешно.

А если вдруг связь так и не появится (OnTick() не сработает ни разу), то советник так и будет зря висеть на графике сколь угодно долго? С помощью таймера можно же задать какие-то временные рамки для проверки.

 
Aleksey Nikolayev #:

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

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

Уже писали что TerminalInfoInteger(TERMINAL_CONNECTED) нет смысла вызывать в OnTick(). Но стоит ли вызывать её в OnInit()? Совсем не факт - соединение может просто не успеть установиться, а использование Sleep() в OnInit() считается плохой практикой. Остаётся делать это по таймеру или есть ещё какие-то возможности (но только внутри самого советника)?

А, что, с Вами говорить). Если тут пишешь, а тебя потом удаляют " Причина: Размещение ответов от ИИ, не проверенных полностью на работоспособность не приветствуется и может наказываться баном " потом банят, хотя,я с ии я не знаком. Другие, тут пишут, "что этот чат для разработчиков и ИИ полностью под, запретом!". А Вы  выкладываете, "простынь от ИИ" и Вас не удаляют и не банят. Одним словом, двойные стандарты, мать иху! Вот по этому ту и не пишут, что и как можно исправить. Одним, словом, чат для своих.