Ещё раз о IndicatorCounted()

 
Привет.

Что-то я упустил из виду, потому как не знаю, что делать со следующей странностью:

Я использую седующий код для расчёта индикаторов и экспертов:
    int start = Bars - IndicatorCounted() - 1;
    int shift;

    for (shift = start; shift > 0; shift--)
    {
         Print("OnHistoryBar, shift="+shift);
         OnHistoryBar(shift);
    }



Тестер запускается в режиме "По ценам открытия". Эксперт Е использует инндикатор И. Индикатор, как и положено, на каждом баре выдаёт в журнал запись "И OnHistoryBar, shift=1". А вот эксперт, в какой-то момент времени, вдруг начинает выдавать:

Е OnHistoryBar, shift=2
Е OnHistoryBar, shift=1

на следующем баре

Е OnHistoryBar, shift=3
Е OnHistoryBar, shift=2
Е OnHistoryBar, shift=1

и так далее, т.е. IndicatorCounted(), если я правильно понимаю, перестаёт увеличиваться.

Что это означает, коллеги?

 
IndicatorCounted() - эта функция имеет смысл лишь только для индикаторов.
************
int IndicatorCounted( )
Функция возвращает количество баров, не измененных после последнего вызова индикатора. Большинство подсчитанных баров не нуждается в пересчете. Функция используется для оптимизации вычислений.
************
В советниках она совершенно бессмысленна.
 
IndicatorCounted() - эта функция имеет смысл лишь только для индикаторов.
В советниках она совершенно бессмысленна.


Хорошо, вы правы. Я не до конца осознал этот факт, когда читал доку. Но ситуация всё равно не до конца ясна.
Оставим в разговоре только индикатор. Вот его журнал:


11:19:01 2007.03.12 01:00 И EURUSD,H1: OnHistoryBar, shift=1, time=2007.03.12 00:00
11:19:01 2007.03.12 02:00 И EURUSD,H1: OnHistoryBar, shift=2, time=2007.03.12 00:00
11:19:01 2007.03.12 02:00 И EURUSD,H1: OnHistoryBar, shift=1, time=2007.03.12 01:00
11:19:01 2007.03.12 03:00 И EURUSD,H1: OnHistoryBar, shift=3, time=2007.03.12 00:00
11:19:01 2007.03.12 03:00 И EURUSD,H1: OnHistoryBar, shift=2, time=2007.03.12 01:00
11:19:01 2007.03.12 03:00 И EURUSD,H1: OnHistoryBar, shift=1, time=2007.03.12 02:00
11:19:01 2007.03.12 04:00 И EURUSD,H1: OnHistoryBar, shift=3, time=2007.03.12 01:00
11:19:01 2007.03.12 04:00 И EURUSD,H1: OnHistoryBar, shift=2, time=2007.03.12 02:00
11:19:01 2007.03.12 04:00 И EURUSD,H1: OnHistoryBar, shift=1, time=2007.03.12 03:00
...


Как видите, в какоё-то момент времени индикатор начинает считать два, потом три бара назад и так считает, по три бара, долго, до конца лога по крайней мере.

Вопрос: Почему так? Что значит "посчитаный бар"? Кем посчитан, мной, этим же самым индикатором И? По какому признаку определяется, что бар посчитан или непосчитан? Почему, вдруг, бар "2007.03.12 00:00" не считается с первого раза? Что-то я этого никак не понимаю.
 
Судя по фрагменту
Print("OnHistoryBar, shift="+shift);

CopyPaste Вы не использовали, поэтому первый вопрос: Вы уверены, что логи принадлежат именно этому коду?
Если же истинный код формально безупречен, то крайне желателен полный код индикатора и зксперта. На всякий случай ткну пальцем наугад: параметры индикатора не могут меняться от вызова к вызову? Дело в том, что судя по всему изменение параметров эквивалентно вызову нового экземпляра индикатора. Естественно, для каждого экземпляра бары подсчитываются независимо.

 
Итак, я подготовился тщательнее и готов задать два конкретных вопроса.
Исходные:
Имеем тот же индикатор И и эксперт Е, его использующий. Тестируем всё это используя «быстрый метод». Я тестировал и на «тиках», но результат аналогичный.

Вопросы:
1. Почему в конце тестового периода IndicatorCounted() становится равным нулю и пытается снова просчитать последние бары ( в данном случае MIN_INDICATOR_BARS)?. Я проверял, это тот же самый индикатор на тех же данных.
2. Почему терминал не отображает сигнал индикатора 2007.03.13 00:00 - 2007.03.13 01:00? Это при том, что мои сигналы, как можно заметить на графике держаться два бара подряд (!), эксперт этот сигнал ловит и отрабатывает. А на графике он где?

Привожу схематичный код индикатора И.
int start()
{
    if (Bars < MIN_INDICATOR_BARS) return (0);
          int start = Bars - (IndicatorCounted() + 1);
      start = MathMin(start, MIN_INDICATOR_BARS);

Print("Bars="+Bars+", IndicatorCounted="+IndicatorCounted()+", start="+start);

	// просчитываем все непросчитанные НЕ включая текущий
	for (int shift = start; shift > 0; shift--)
	{
	    Print("OnHistoryBar, shift="+shift+", time="+TimeToStr(Time[shift]));
	    Calculate(shift);
	}

       Calculate(0); // OnTick

    return(0);
}


Функция Calculate рассчитывает сигнал для бара со сдвигом shift. Этот сигнал анализирует эксперт, а на графике он рисуется белыми пиками.

Лог, который генерируют индикатор и эксперт.


22:25:31 2007.03.01 00:00 И EURUSD,H1: Bars=5001, IndicatorCounted=0, start=100
22:25:31 2007.03.01 00:00 И EURUSD,H1: OnHistoryBar, shift=100, time=2007.02.22 19:00
22:25:31 2007.03.01 00:00 И EURUSD,H1: OnHistoryBar, shift=99, time=2007.02.22 20:00

22:25:31 2007.03.01 00:00 И EURUSD,H1: OnHistoryBar, shift=1, time=2007.02.28 23:00
22:25:31 2007.03.01 01:00 И EURUSD,H1: Bars=5002, IndicatorCounted=5000, start=1
22:25:31 2007.03.01 01:00 И EURUSD,H1: OnHistoryBar, shift=1, time=2007.03.01 00:00
22:25:31 2007.03.01 02:00 И EURUSD,H1: Bars=5003, IndicatorCounted=5001, start=1

22:25:35 2007.03.13 01:00 Е EURUSD,H1: Command=-2.00000000, time=2007.03.13 01:00

2:25:48 2007.04.12 23:00 И EURUSD,H1: Bars=5738, IndicatorCounted=5736, start=1
22:25:48 2007.04.12 23:00 И EURUSD,H1: OnHistoryBar, shift=1, time=2007.04.12 22:00
22:25:48 2007.04.12 23:00 И EURUSD,H1: Bars=5738, IndicatorCounted=0, start=0

Как видите, сначала индикатор правильно инициализируется, отрабатывает исторические бары при загрузке (их количество ограничено переменной MIN_INDICATOR_BARS, равной 100). Далее он начинает обсчитывать по одному последнему бару, как и задумано. А для меня это критично, поскольку мой индикатор задуман так, что он не может повторно обсчитывать бары.
Потом видно, что эксперт поймал сигнал 2007.03.13 01:00, он же виден на графике, как закрытие позиции на покупку и открытие на продажу. В конце лога можно наблюдать, как индикатор досчитал до конца тестового периода - 2007.04.13, и последняя запись лога показывает, что IndicatorCounted() обнулился. Я не показал записи, на которых снова просчитываются 100 последних исторических баров, но, поверьте, они есть.

График тестера.



 
Опубликуйте полный код индикатора, пожалуйста.
 
Progonite v vizualnom rezhime - dolzhny poyavitsya novye voprosy.
 
Опубликуйте полный код индикатора, пожалуйста.


Renat, полный код привести затруднительно, поскольку индикатор довольно большой. Да и нет в этом большой необходимости, мне кажется. Если вы задатите наводящие вопросы, я отвечу и примеры кода приведу.
Сейчас я скажу, предпологая ваш возможный вопрос, что я записываю значения в буфер индикатора только для элементов 1 и 0. Сегодня я ещё немного упростил алгоритм и оставил работу только с последним завершённым баром, т.е. элемент 1. Картина на графике немного изменилась, но вопрос остался.
 
Progonite v vizualnom rezhime - dolzhny poyavitsya novye voprosy.


Rosh, вы правы вопросы по визуальному режиму есть, но появились они ещё до этой темы, я не решался об этом писать, дабы не засорять... но раз уж вы об этом упомянули...
Я не знаю как у вас, а в моём терминале (билд 203) в визуально режиме отрисовывается только ценовой график с родер-командами, а индикатора не видно до конца тестового периода. Но, что самое интересное, в конце теста, индикатор появляется. И, вот, ваш вопорс, Rosh, застав меня в размышлениях над моей ситуацией, натолкнул меня на мысль, что, возможно, мои 100 баров в конце тестового периода, это и есть момент, когда тестер-движок отрисовывает график индикатора?!
Если бы он (движок) создавал для этой операции новый буфер (т.е. новый индикатор), то небыло бы никаких проблем, а в данном случае, я склонен думать, что это - баг.

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