Ошибки, баги, вопросы - страница 1669

 

Всегда ли MQ5-программа после завершения выполнения автоматически делает IndicatorRelease всех хэндлов, что насоздавала?

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

 

https://www.mql5.com/ru/docs/basis/preprosessor/compilation

Константа

Тип

Описание

tester_indicator

string

Имя пользовательского индикатора в формате "имя_индикатора.ex5". Необходимые для тестирования индикаторы определяются автоматически из вызова функций iCustom(), если соответствующий параметр задан константной строкой. Для остальных случаев (использование функции IndicatorCreate()или использование неконстантной строки в параметре, задающем имя индикатора) необходимо данное свойство

 

IndicatorCreate - почти (нет ограничений на количество входных параметров) рудимент? 

Документация по MQL5: Основы языка / Препроцессор / Свойства программ (#property)
Документация по MQL5: Основы языка / Препроцессор / Свойства программ (#property)
  • www.mql5.com
Основы языка / Препроцессор / Свойства программ (#property) - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
IndicatrorRelease ошибочно возвращает true, если вызывается после связки iCustom+ChartIndicatorAdd. Поправьте.
 
fxsaber:
Что за счетчик?
Вчера обсуждали, страница 1687. :) Но читать лучше вот с этого сообщения на 1686-й странице: https://www.mql5.com/ru/forum/1111/page1686#comment_2790746 Кстати, человек на Ваш же вопрос отвечал. Просто получается, что схема такая. Запрос на вызов индикатора попадает в Терминал. Т.е. советник или скрипт не вызывают индикатор напрямую, терминал выступает посредником. В терминале происходит проверка, существует ли уже такой индикатор с указанными параметрами. Если да, то он возвращает программе, вызвавшей индикатор, хэндл (ссылку) на уже существующий индикатор. А в своих терминальных недрах помечает в счётчике, что был ещё один вызов на данный индикатор. Т.е. он ведёт учёт, сколько хэндлов на данный индикатор вернул. Когда кто-то делает IndicatorRelease, это не значит, что остальным, кто вызвал этот же индикатор с такими же параметрами, этот индикатор больше не нужен. Поэтому Терминал уменьшает счётчик на единицу, но оставляет индикатор активным, потому-что им ещё кто-то пользуется. Так будет продолжаться до тех пор, пока счётчик не обнулится. А вот когда он обнулится, тогда Терминал окончательно и бесповоротно удалит данный индикатор из оперативной памяти.
Если Вы попробуете создать код, который будет содержать IndicatorRelease, но при этом не будет содержать вызова самого индикатора, то я думаю, что Вы его просто-напросто не откомпилируете, потому-что в IndicatorRelease нужно передавать хэндл, а если индикатор не вызывался из программы, то и хэндл вы не узнаете.
Ошибки, баги, вопросы
Ошибки, баги, вопросы
  • отзывов: 8
  • www.mql5.com
Форум трейдеров MQL5.community
 

BlackTomcat:
Вчера обсуждали, страница 1687. :) Но читать лучше вот с этого сообщения на 1686-й странице: https://www.mql5.com/ru/forum/1111/page1686#comment_2790746 Кстати, человек на Ваш же вопрос отвечал. Просто получается, что схема такая. Запрос на вызов индикатора попадает в Терминал. Т.е. советник или скрипт не вызывают индикатор напрямую, терминал выступает посредником. В терминале происходит проверка, существует ли уже такой индикатор с указанными параметрами. Если да, то он возвращает программе, вызвавшей индикатор, хэндл (ссылку) на уже существующий индикатор. А в своих терминальных недрах помечает в счётчике, что был ещё один вызов на данный индикатор. Т.е. он ведёт учёт, сколько хэндлов на данный индикатор вернул. Когда кто-то делает IndicatorRelease, это не значит, что остальным, кто вызвал этот же индикатор с такими же параметрами, этот индикатор больше не нужен. Поэтому Терминал уменьшает счётчик на единицу, но оставляет индикатор активным, потому-что им ещё кто-то пользуется.

Спасибо! Получается отличная экономия.

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

Хэндл через глобальные переменные могу передать. Поэтому вполне возможно им воспользоваться.
 
fxsaber:


Хэндл через глобальные переменные могу передать. Поэтому вполне возможно им воспользоваться.
А вы не передавайте. :) Или хотя бы не вызывайте IndicatorRelease() для полученного таким образом хэндла. Если же вы так сделаете, то это будет уже ваша ошибка, а не баг языка, согласны?
 
Sergei Vladimirov:
А вы не передавайте. :) Или хотя бы не вызывайте IndicatorRelease() для полученного таким образом хэндла. Если же вы так сделаете, то это будет уже ваша ошибка, а не баг языка, согласны?

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

Такой скрипт накроет все советники и индикаторы терминала, что использовали iCustom без ChartIndicatorAdd

 

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

Кстати, этот разговор начался с вашего вопроса, как проверить хэндл индикатора перед его использованием. Так вот, хэндл проверить нельзя, но при попытке использования хэндла закрытого индикатора получите ошибку 4807 - вот, её и отcлеживайте после каждого вызова CopyBuffer(), если она вернёт -1.

 
fxsaber:
Хэндл через глобальные переменные могу передать. Поэтому вполне возможно им воспользоваться.
Эмм... Глобальные переменные чего? Терминала или советника? С переменными Терминала никогда не работал, поэтому рассуждать на эту тему не буду. А что касается глобальных переменных советника, то тут это основной способ. Если индикаторы инициализируются в OnInit, а IndicatorRelease происходит в OnDeinit, то тут только глобальными переменными (советника) и получится передать хэндлы.
 
A100:
Ошибка при выполнении: 'invalid pointer access' (*)
А на что у вас здесь A::а указывает?
Причина обращения: