Мешает ли Вам продолжение работы расчетной части индикатора после его программного закрытия?

 
  • 29% (27)
  • 12% (11)
  • 5% (5)
  • 6% (6)
  • 8% (7)
  • 17% (16)
  • 23% (21)
Всего проголосовало: 68
 
А так понимаю последний пункт можно прочитать так: "Никогда не пристреливаю индикатор на ходу"
 

Решение получено!

С подсказки fxsaber что ChartIndicatorGet() изменяет счетчик индикатора на +1 и после вызова

ThisIndicatorHandle=ChartIndicatorGet(ChartID(),ChartWindowFind(ChartID(),ThisIndicatorName),ThisIndicatorName);

необходимо использовать IndicatorRelease() для его изменения на -1

IndicatorRelease(ThisIndicatorHandle);

Однако остался нерешенный вопрос:

Где взять список какие функции и насколько увеличивают/уменьшают счетчик индикатора? 

Пока известен следующий список.

ФункцияИзменение счетчика индикатора
iCustom()
+1
ChartIndicatorAdd()
+1
ChartIndicatorDelete()
-1
IndicatorRelease()
-1
ChartIndicatorGet()
+1

=============================================

Ранее написано:

Обнаружено, что расчетная часть индикатора, программно запущенного советником,

выполняется бесконечное количество тиков после его программного удаления.

Это делает невозможным инициализацию индикатора при его последующих запусках.

История вопроса:

https://www.mql5.com/ru/forum/218776

Где живёт индикатор...? Продолжение темы:Где живёт индикатор созданный в режиме тестирования без визуализации?
Где живёт индикатор...? Продолжение темы:Где живёт индикатор созданный в режиме тестирования без визуализации?
  • 2017.11.04
  • www.mql5.com
Продолжаем исследовать взаимодействие экспертов и индикаторов на платформе МТ5...
 
Vladimir Karputov:
А так понимаю последний пункт можно прочитать так: "Никогда не пристреливаю индикатор на ходу"

Что значит на ходу? Всё по регламенту: удаляем с чарта, освобождаем хендл.

советник автоматически удаляет с графика индикаторы по ChartIndicatorDelete() и

уничтожает их хендлы по IndicatorRelease()

Как пристрелить не на ходу?

 

Единственное что можно сказать против: Если работает - значит использует ресурсы. А в остальном какая вам разница? Зачем процесс инициализации больше одного раза? Может просто надо писать более оптимально? 

 

Подробные разъяснения для тех, кто не понял в чём вопрос.

1. Советник запускает индикатор по iCustom() и размещает его на графике по ChartIndicatorAdd()

2. Индикатор инициализируется, выполняется его функция OnInit().

Расчетная часть индикатора срабатывает по необходимости по OnCalculane() либо по OnTimer().

3. Советник программно удаляет индикатор по ChartIndicatorDelete() и удаляет хэндл индикатора по IndicatorRelease().

После этого вопреки ожиданиям расчетная часть индикатора OnCalculate() продолжает работать сколь угодно продолжительное время.

Замечание:

Использован единственный индикатор с примитивной расчетной частью.

После запуска и размещения на чарте никаких обращений к индикатору не производится вовсе.

Использованные советник и индикатор - во вложении.

Файлы:
 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Где живёт индикатор созданный в режиме тестирования без визуализации?

fxsaber, 2017.10.19 09:39

Без обид, но выложенный Вами код - это почти проявление неуважения к другим. Код по проблеме должен быть лаконичным, все лишнее, что не касается проблемы (проверки, логирование и т.д.) должны быть убраны. Только тогда возможно нормально обсуждать. Сейчас же 90% времени любой чтец должен разбираться не в поднятой проблеме, а в огромном коде. Поставьте себя на место другого.

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

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Где живёт индикатор созданный в режиме тестирования без визуализации?

Slava, 2017.10.19 10:46

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

Вам нужен какой-то специальный способ для вывода этих индикаторов из клинча


На тему есть еще обуждение здесь. И еще

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

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

Anton, 2016.09.23 15:31

"Счетчик" есть для всех типов индикаторов. Для кастомных индикаторов проверка на совпадение настроек более жесткая чем для встроенных. Только при полном совпадении всех настроек, включая параметры отрисовки, и только в пределах одного чарта, возможно повторное использование копии кастомного индикатора.


Вот пример вечного индикатора по той же причине невозможности обнулить счетчик

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

fxsaber, 2016.09.23 10:48

  1. Устанавливаем руками на ГОЛЫЙ чарт индикатор
    #property indicator_separate_window
    #property indicator_buffers 1
    #property indicator_plots   1
    
    double Buffer[];
    
    int handle = INVALID_HANDLE;
    
    void OnInit()
    {
      ::SetIndexBuffer(0, Buffer, INDICATOR_DATA);
      
      handle = ChartIndicatorGet(0, 1, ChartIndicatorName(0, 1, 0));  
    }
    
    #define TOSTRING(A) #A + " = " + (string)A + "\n"
    
    int OnCalculate( const int rates_total,
                     const int prev_calculated,
                     const datetime &time[],
                     const double &open[],
                     const double &high[],
                     const double &low[],
                     const double &close[],
                     const long &tick_volume[],
                     const long &volume[],
                     const int &spread[] )
    {
      if (handle != INVALID_HANDLE)
      {
        Buffer[rates_total - 1] = MathRand();
        
        double BufferCopy[];
        
        if (CopyBuffer(handle, 0, 0, 1, BufferCopy) > 0)
          Print(TOSTRING(BufferCopy[0]) + TOSTRING(Buffer[rates_total - 1]));
      }
      
      return(rates_total);
    }
  2. Удаляем руками индикатор с чарта.
  3. В логе видим, что индикатор продолжает выполняться. Можно закрыть все чарты в терминале, но он все равно будет выполняться. И это не поможет, конечно,
    void OnDeinit( const int Reason )
    {
      if (handle != INVALID_HANDLE)  
        IndicatorRelease(handle);
      
      return;
    }
  4. Перезагрузка терминала останавливает выполнение индикатора.
  5. Это сколько же может индикаторов выполняться вот так в холостую, а мы о них ни слухом, ни духом?! Контроля нет совсем.

Из СД

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

Можно либо запретить этот "хак", либо оставить на совести того кто его использует.

Пока вы первый кому такая возможность мешает пользоваться терминалом, за несколько лет.

Это сколько же может индикаторов выполняться вот так в холостую, а мы о них ни слухом, ни духом?! Контроля нет совсем.

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

1) Только специально, осознанно можно написать индикатор с указанным поведением. Кто вас заставляет писать такой код и запускать такой индикатор? Или вы запускаете чужие программы не зная их кода?

2) Вредоносность такого индикатора не больше чем многих других с менее явными логическими ошибками.

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


Так что разбирайтесь, где клинит счетчик, что он не в состоянии обнулиться. 

 
Uladzimir Kirychenka:

Единственное что можно сказать против: Если работает - значит использует ресурсы. А в остальном какая вам разница? Зачем процесс инициализации больше одного раза? Может просто надо писать более оптимально? 


Я бросаю советник на чарт - он запускается и запускает индикатор.

При этом индикатор

1. Появляется на чарте.

2. Инициализируется  - получает начальный набор исходных данных.

3. Выполняет расчетную часть OnCalculate() и вызовы OnTimer().

4. Индикатор можно обнаружить по хэндлу.

5. Индикатор можно обнаружить поиском по окну.

6. Можно получить данные буфера Индикатора.

После прекращения работы советника:

1. Расчетная часть индикатора остается в памяти и бесконечно долго продолжает отрабатывать вызовы OnCalculate() однако игнорируя вызовы OnTimer().

2. Индикатор невозможно обнаружить по хэндлу.

3. Индикатор невозможно обнаружить поиском по окну.

4. Невозможно получить данные буфера Индикатора.

После повторного запуска советника:

1. Индикатор не появляется на чарте.

2. Не инициализируется  - не получает начальный набор исходных данных.

3. Выполняет расчетную часть OnCalculate(), игнорируя вызовы OnTimer().

4. Индикатор невозможно обнаружить по хэндлу.

5. Индикатор невозможно обнаружить поиском по окну.

6. Невозможно получить данные буфера Индикатора.

А в остальном - какая разница...

Удаление остатков индикатора из памяти возможно только перекомпиляцией индикатора или перезапуском терминала.

 

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

Как раз из-за подобных ситуаций.

На чарт вобще индикатор никогда не помещаю, для эксперта это не требуется.  Как правило, индикатор, если он все же используется, создается в функции OnInit() - и удаляется в деструкторе специально класса CDataProvider, который является менеджером символов, таймсерий и индикаторов, затребованных экспертом.

 
fxsaber:

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


На тему есть еще обуждение здесь. И еще


Вот пример вечного индикатора по той же причине невозможности обнулить счетчик

Из СД


Так что разбирайтесь, где клинит счетчик, что он не в состоянии обнулиться. 


Уважаемый! Занимаюсь вопросом не первую неделю.

Вопросы по "счетчику" индикатора решены.

Он гарантированно обнуляется.

Разбирался с этим совместно со Slava, было несколько неточностей, но сейчас:

1. iCustom() - счетчик +1

2. ChartIndicatorAdd() - счетчик +2

3. ChartIndicatorDelete() - счетчик +1

4. IndicatorRelease() - счетчик =0

Все выполняемые операции сообщают о своём корректном выполнении.

Других операций связанных со счетчиком или циклических или рекурсивных вызовов нет.

Ситуация специально упрощена до единственного советника с единственным индикатором.

Кроме того к индикатору даже не производится обращений извне.

Всё что делает индикатор - заносит в буфер текущий Bid и выводит диагностические сообщения.


В Вашем примере использовано рекурсивное обращение индикатора к самому себе - это не мой случай вовсе.

 
George Merts:

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

Как раз из-за подобных ситуаций.

На чарт вобще индикатор никогда не помещаю, для эксперта это не требуется.  Как правило, индикатор, если он все же используется, создается в функции OnInit() - и удаляется в деструкторе специально класса CDataProvider, который является менеджером символов, таймсерий и индикаторов, затребованных экспертом.


Я тоже всегда всё считал в советнике. Но в реализации одного из проектов возникла структура "один советник - два индикатора", при этом нужно было наладить обмен данными между индикаторами. При этом и наткнулся на проблему возникновения фантомных и неуправляемых остатков индикаторов в памяти. После обсуждения со Slava вроде бы определились, что это происходит из-за взаимного обращения индикаторов друг-к другу. Но попытки решить проблему через сначала прекращение взаимных обращений, а только затем выгрузки индикаторов проблему не решали. Затем выяснилось, что даже при наличии единственного примитивного индикатора его расчетная часть не удаляется из памяти никогда (до перекомпиляции или перезапуска терминала). Что очень печально, ибо многие идеи связаны с совместным использованием советников и индикаторов.

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