Робот создает много индикаторов при переключении таймфреймов. - страница 2

[Удален]  
Stanislav Korotky #:

Можете не бояться функции ChartIndicatorAdd и применять её, когда надо показать используемый в эксперте индикатор на графике (это бывает полезно). Только не забывайте освобождать дескриптор после добавления индюка на график, потому что его привязка к эксперту в этом случае уже лишняя (получается 2 "хозяина", и индюк не освобождается).

Спасибо, Станислав, мне удалось ! Всем спасибо, задача по итогу филигранно решена
 
Stanislav Korotky #:

Можете не бояться функции ChartIndicatorAdd и применять её, когда надо показать используемый в эксперте индикатор на графике (это бывает полезно). Только не забывайте освобождать дескриптор после добавления индюка на график, потому что его привязка к эксперту в этом случае уже лишняя (получается 2 "хозяина", и индюк не освобождается).

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

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

При таких же условиях shortname в индикаторе может назначаться не так как ожидалось:

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

Станислав, правильно ли я понимаю вашу идею, что мне нужно:

1. Получить handle1 индикатора для копирования данных в советник.

2. Получить handle2 индикатора с теми же настройками, добавить его на график для визуализации и сделать IndicatorRelease(handle2).

3. В OnDeinit() советника:

     if(reason !=3) // Это прекращение работы эксперта. Освобождение хэндлов и удаление индикаторов
     {
      IndicatorRelease(handle1);
      RemoveBotIndicatorsFromChart(ChartID()); // Процедура перебора индикаторов по всем окнам графика и их удаления
      IndicatorRelease(handle2);
     }
   else // Это смена TF. Освобождение handle1 для переинициализации скрытого индикатора на новом TF, а отображаемый индикатор переключится сам
     {
      IndicatorRelease(hadle1);
      handle1 = INVALID_NANDLE;
     }
 
Sunriser #:

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


в аналогичном случае, чтобы видеть индикаторы советника - они в OnInit создаются iCustom и далее ChartIndicatorAdd, в OnDeinit при любом reason - если индикатор был успешно добавлен то он удаляется ChartIndicatorDelete

единственный нюанс - все индикаторы самопальные (или перелицованные стандартные) их ShortName назначается советником и передаётся в параметрах. Иначе с именованиями и уникальностью индикаторов чехарда.

 
Maxim Kuznetsov #:

в аналогичном случае, чтобы видеть индикаторы советника - они в OnInit создаются iCustom и далее ChartIndicatorAdd, в OnDeinit при любом reason - если индикатор был успешно добавлен то он удаляется ChartIndicatorDelete

единственный нюанс - все индикаторы самопальные (или перелицованные стандартные) их ShortName назначается советником и передаётся в параметрах. Иначе с именованиями и уникальностью индикаторов чехарда.

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

Пробовал добавлять //#include <Init_Sync.mqh> // Делает синхронизированными Init/Deinit индикаторов - не помогло, впрочем у меня и не получилось воспроизвести ту проблему, из-за которой fxsaber написал эту библиотеку.

ChartIndicatorDelete может возвращать true, но при этом индикатор может не удалиться с первого раза, приходится повторно вызывать до тех пор, пока за цикл перебора никаких индикаторов найдено не будет. Разные костыли уж пробовал. Про shortname написал в предыдущем сообщении.

 
Sunriser #:

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

Пробовал добавлять //#include <Init_Sync.mqh> // Делает синхронизированными Init/Deinit индикаторов - не помогло, впрочем у меня и не получилось воспроизвести ту проблему, из-за которой fxsaber написал эту библиотеку.

ChartIndicatorDelete может возвращать true, но при этом индикатор может не удалиться с первого раза, приходится повторно вызывать до тех пор, пока за цикл перебора никаких индикаторов найдено не будет. Разные костыли уж пробовал. Про shortname написал в предыдущем сообщении.

Можете приложить минимальный код для воспроизведения? Обычно важны какие-то мелкие нюансы, которые из текстового описания не удается оценить. Зачем два хендла (если индикатор один) - не понятно.

Насколько я помню, расчетная часть индикатора удаляется отложенным образом - MQ это сделали в расчете на быстрый старт индикатора, если он снова понадобится. Но с позиции кода, который запрашивает индикатор, это обычно не критично. Вы можете определить, получили хэндл от "старого"  закешированного индикатора или нового, вызвав BarsCalculated сразу после получения хендла: новый индикатор еще не будет рассчитан.

 
Sunriser #:
else // Это смена TF. Освобождение handle1 для переинициализации скрытого индикатора на новом TF, а отображаемый индикатор переключится сам

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

всегда удаляйте созданные экзепляры. 

 
Stanislav Korotky #:

Можете приложить минимальный код для воспроизведения? Обычно важны какие-то мелкие нюансы, которые из текстового описания не удается оценить. Зачем два хендла (если индикатор один) - не понятно.

Насколько я помню, расчетная часть индикатора удаляется отложенным образом - MQ это сделали в расчете на быстрый старт индикатора, если он снова понадобится. Но с позиции кода, который запрашивает индикатор, это обычно не критично. Вы можете определить, получили хэндл от "старого"  закешированного индикатора или нового, вызвав BarsCalculated сразу после получения хендла: новый индикатор еще не будет рассчитан.

Вот пример советника и индикатора.

Эксперт передает в индикатор строковый ключ IDKey = "madebyea", чтобы иметь возможность в будущем отличить индикатор, созданный советником от добавленного вручную.

Завершение инициализации советника иногда происходит позже инициализации индикатора и shortname с присутствующим IDKey эксперт начинает видеть не с первого принта, но далее принтуется нормально.

При смене TF эксперт находит индикатор с shortname снова без IDKey, не считает за своего и поэтому не пытается удалить его с графика:

2025.12.27 16:02:47.744 Indicator_01 (LTCUSDT_binance,M30)      PERIOD_M30 madebyea_CustomBB_PERIOD_M30 qTick: 10
2025.12.27 16:02:47.745 Expert_01 (LTCUSDT_binance,M30) indicatorsEnumeration win: 1 of: 2 i: 0 of: 1 Вижу индикатор: madebyea_Custom_PERIOD_M30
2025.12.27 16:02:47.745 Expert_01 (LTCUSDT_binance,M30) Expert. ind_buf[0]:10.0
2025.12.27 16:02:47.857 Indicator_01 (LTCUSDT_binance,M30)      PERIOD_M30 madebyea_Custom_PERIOD_M30 qTick: 11
2025.12.27 16:02:47.858 Expert_01 (LTCUSDT_binance,M30) indicatorsEnumeration win: 1 of: 2 i: 0 of: 1 Вижу индикатор: madebyea_Custom_PERIOD_M30
2025.12.27 16:02:47.858 Expert_01 (LTCUSDT_binance,M30) Expert. ind_buf[0]:11.0
2025.12.27 16:02:48.282 Expert_01 (LTCUSDT_binance,M30) Expert OnDeinit REASON_CHARTCHANGE: Символ или период графика был изменен
2025.12.27 16:02:48.295 Expert_01 (LTCUSDT_binance,M30) RemoveBotIndicatorsFromChart win: 1 of: 2 i: 0 of: 1 Вижу индикатор: Indicator_01
2025.12.27 16:02:48.295 Expert_01 (LTCUSDT_binance,M30) RemoveBotIndicatorsFromChart Индикатор с IDKey madebyea НЕ НАЙДЕН!
2025.12.27 16:02:48.296 Expert_01 (LTCUSDT_binance,H2)  Expert OnInit
2025.12.27 16:02:48.296 Expert_01 (LTCUSDT_binance,H2)  Expert. Получен новый ind_handle: 10
2025.12.27 16:02:48.297 Indicator_01 (LTCUSDT_binance,H2)       OnInit PERIOD_H2 createdBy?: madebyea

Билд 5440

Файлы: