Чудеса отладчика ? - страница 2

 
Alexander Bereznyak:
хендл индикатора создается не мгновенно
вот это объяснение думаю имеет место быть, но сразу но: если хендл ещё не создан то почему он не возвращает инвалид?
Сейчас с саппортом решаем данный вопрос. Потом напишу ответ.
 
Alexander Bereznyak:
хендл индикатора создается не мгновенно
Да, вполне логично. Поэтому его и создают обычно в OnInit
 
Alexey Oreshkin:
вот это объяснение думаю имеет место быть, но сразу но: если хендл ещё не создан то почему он не возвращает инвалид?
Сейчас с саппортом решаем данный вопрос. Потом напишу ответ.

Хендл создаётся и возвращается сразу. Но данные не сразу рассчитываются.

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

 
Slawa:

Хендл создаётся и возвращается сразу. Но данные не сразу рассчитываются.

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

Наверное, об этом тесте вы говорите? Тут фишка в другом, на первом тике данных еще нет, на втором тике опять содается хендл индикатора, причем он по значению такой же, как и в первый раз - 4806. И уже на втором тике появляются данные.

А что происходит с хендлом из первого тика? Он автоматически закрывается при выходе из OnTick?

Тут с хендлами что-то мутное. Если в виндах мы явно можем закрыть хендл через CloseHandle, то тут какая-то непонятная автоматика.

2016.06.29 11:58:32.610 2016.06.28 00:02:00   x=100  4806

2016.06.29 11:58:31.536 2016.06.28 00:02:00   x=100  4806

2016.06.29 11:58:30.314 2016.06.28 00:02:00   x=100  4806

--- второй тик отладки ---------- 

2016.06.29 11:57:55.796 2016.06.28 00:01:30   x=-1  4806

2016.06.29 11:57:53.161 2016.06.28 00:01:30   x=-1  4806

2016.06.29 11:57:50.365 2016.06.28 00:01:30   x=-1  4806

2016.06.29 11:57:20.358 2016.06.28 00:01:30   x=-1  4806

2016.06.29 11:57:10.689 2016.06.28 00:01:30   x=-1  4806 

--- первый тик отладки ----------

 
Alexey Volchanskiy:

Наверное, об этом тесте вы говорите? Тут фишка в другом, на первом тике данных еще нет, на втором тике опять содается хендл индикатора, причем он по значению такой же, как и в первый раз - 4806. И уже на втором тике появляются данные.

А что происходит с хендлом из первого тика? Он автоматически закрывается при выходе из OnTick?

Тут с хендлами что-то мутное. Если в виндах мы явно можем закрыть хендл через CloseHandle, то тут какая-то непонятная автоматика.

2016.06.29 11:58:32.610 2016.06.28 00:02:00   x=100  4806

2016.06.29 11:58:31.536 2016.06.28 00:02:00   x=100  4806

2016.06.29 11:58:30.314 2016.06.28 00:02:00   x=100  4806

--- второй тик отладки ---------- 

2016.06.29 11:57:55.796 2016.06.28 00:01:30   x=-1  4806

2016.06.29 11:57:53.161 2016.06.28 00:01:30   x=-1  4806

2016.06.29 11:57:50.365 2016.06.28 00:01:30   x=-1  4806

2016.06.29 11:57:20.358 2016.06.28 00:01:30   x=-1  4806

2016.06.29 11:57:10.689 2016.06.28 00:01:30   x=-1  4806 

--- первый тик отладки ----------

О чём и речь.

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

И после 10 000 тиков отладки будет всего 5 уникальных хендлов макд, а не 50 000

 
Slawa:

О чём и речь.

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

И после 10 000 тиков отладки будет всего 5 уникальных хендлов макд, а не 50 000

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

void OnTick()
  {
      int handle=INVALID_HANDLE; // локальная переменная

И еще вопрос. Если данные не отдаются сразу, можно ли подождать их через Sleep() или лучше дождаться следующего тика?

 
Alexey Volchanskiy:

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

не прямой но косвенный ответ такой

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

Функция позволяет удалять хэндл индикатора, если он больше не нужен, и таким образом позволяет экономить память.
Удаление хендла производится сразу, удаление расчетной части индикатора производится через некоторое небольшое время (если обращений к ней больше нет).

получается что ради скорости загруженные в память индикаторы живут своей жизнью. А ваш хендл фактически просто "индекс" для этого массива.


И еще вопрос. Если данные не отдаются сразу, можно ли подождать их через Sleep() или лучше дождаться следующего тика?

тут как угодно ждите.
 
o_O:

не прямой но косвенный ответ такой

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

Функция позволяет удалять хэндл индикатора, если он больше не нужен, и таким образом позволяет экономить память.
Удаление хендла производится сразу, удаление расчетной части индикатора производится через некоторое небольшое время (если обращений к ней больше нет).

получается что ради скорости загруженные в память индикаторы живут своей жизнью. А ваш хендл фактически просто "индекс" для этого массива.


тут как угодно ждите.

Ок, но почему эта фича с ожиданием проявляется только при отладке на исторических данных через CTRL-F5? Если запустить такой вот код в терминале, без отладки, все будет ОК. Специально перезапустил терминал, вот результат. И при отладке на реальных данных через F5 тоже все считывается сразу. 

Налицо баг или фича отладчика на ист. данных. 

int TickCount = 0;
void OnTick()
{
    int handle=INVALID_HANDLE;
    int x=0;         
  
    for(int i=5;i<10;i++)
    {
  
        handle=iMACD(Symbol(),Period(),i,26,9,PRICE_CLOSE);  
        if (handle==INVALID_HANDLE) continue;
        double mx[];
        x=CopyBuffer(handle,0,0,100,mx);
        if(TickCount < 2)
            Print("TickCount=", IntegerToString(TickCount), "x=", IntegerToString(x), "  ", IntegerToString(GetLastError()));         
    }    
    TickCount++;
}

2016.06.29 13:59:46.932 TestHandle (EURUSD,M1) TickCount=1x=100  0

2016.06.29 13:59:46.932 TestHandle (EURUSD,M1) TickCount=1x=100  0

2016.06.29 13:59:46.932 TestHandle (EURUSD,M1) TickCount=1x=100  0

2016.06.29 13:59:46.932 TestHandle (EURUSD,M1) TickCount=1x=100  0

2016.06.29 13:59:46.932 TestHandle (EURUSD,M1) TickCount=1x=100  0

2016.06.29 13:59:46.351 TestHandle (EURUSD,M1) TickCount=0x=100  0

2016.06.29 13:59:46.251 TestHandle (EURUSD,M1) TickCount=0x=100  0

2016.06.29 13:59:46.150 TestHandle (EURUSD,M1) TickCount=0x=100  0

2016.06.29 13:59:46.050 TestHandle (EURUSD,M1) TickCount=0x=100  0

2016.06.29 13:59:45.950 TestHandle (EURUSD,M1) TickCount=0x=100  0

 

Поговорили с саппортом, вопрос решён. Суммирую ответ саппорта и Slawa: несмотря на то что хендл создаётся сразу, доступ к данным будет на следующем тике (через некоторое время).
Рекомендуют создавать хендлы в ините, что логично.

Почему я не создаю в данном примере хендлы в ините : 
Передо мной стоит задача провести в советнике некоторые расчёты по всему рынку. Часть расчётов полностью совпадает с результатами индикатора макд, поэтому я и решил вызвать его а не писать логику самому.
А теперь займёмся расчётами, для примера обратимся на демосервер метаквотов. Валюта+сфд даёт мне 96 доступных для торговли инструментов.
мне нужно проверить результаты макд в следующем диапазоне: fastEma 5-20, slowEma 20-100, sigbalMA 3-9.  Итого 7200 вариантов по каждому символу, в общем 7200х96=691200 хендлов.
Эти расчёты мне нужно проводить 1 раз в день, вполне логично создать эти хендлы в онтике, посчитать всё что надо и релизнуть их до следующей необходимости.
Теперь, учитывая все новые знания наверное создам массив всех хендлов и вызову их в ините, пусть болтаются в памяти, благо места занимают не много, менее 3 МБ (691200 *4/1024/1024)

 
Alexey Volchanskiy:

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

И еще вопрос. Если данные не отдаются сразу, можно ли подождать их через Sleep() или лучше дождаться следующего тика?

1. Да.

2. Из индикатора точно нет, и Sleep не поможет. Из эксперта можно попробовать. Но я не готов точно ответить на этот вопрос.