Странное поведение MqlRates + CopyRates, кто-то сталкивался с подобным?

 

Всем привет! Подскажите что за колдунство происходит в MQL5.


Такой код будет ждать нового тика чтобы посчитаться:


// Тут мы будем ждать следующий тик и не будем выходить из функции;
int
TakeIntZeroAndPrintSomething(datetime time) {    MqlRates rates[];    int Arr1 = CopyRates(_Symbol, PERIOD_CURRENT, time, time, rates);    Print("Время: ", TimeToString(time), " Скопировано ", Arr1 ," баров");    // ОЖИДАЕМ СЛЕДУЮЩИЙ ТИК    int Arr2 = CopyRates(_Symbol, PERIOD_CURRENT, time+60, time+60, rates);    Print("Время: ", TimeToString(time), " Скопировано ", Arr2 ," баров");    return (0); }


А этот код выполнится нормально во время одного тика:


// Код выполняется за один тик
int
TakeIntZeroAndPrintSomething(datetime time) {    MqlRates rates[];    int Arr1 = CopyRates(_Symbol, PERIOD_CURRENT, time, time, rates);    Print("Время: ", TimeToString(time), " Скопировано ", Arr1 ," баров");    // ОЖИДАНИЕ ТИКА НЕ ПРОИСХОДИТ, КОД ВЫПОЛНЯЕТСЯ СРАЗУ    MqlRates rates1[];    int Arr2 = CopyRates(_Symbol, PERIOD_CURRENT, time+60, time+60, rates1);    Print("Время: ", TimeToString(time), " Скопировано ", Arr2 ," баров");    return (0); }


А, да, даже если просто два раза подряд вызвать "TakeArraySize" (как в следующем куске кода) мы все равно будем ждать один тик


int TakeArraySize(datetime time)
{
   MqlRates rates[];
   int Arr1 = CopyRates(_Symbol, PERIOD_CURRENT, time, time, rates);
   Print("Время: ", TimeToString(time), " Скопировано ", Arr1 ," баров");

   return (Arr1);
}

В чем прикол? Как это можно исправить? Ну или что я делаю не так в данном примере?

Заранее спасибо.


upd. Как сделать так, чтобы функция TakeArraySize срабатывала без ожидания следующего тика при повторном вызове?

 
Павел:

Всем привет! Подскажите что за колдунство происходит в MQL5.


Такой код будет ждать нового тика чтобы посчитаться:

У меня к вам вопрос: как вы вставляли код? Просто хочу понять, откуда лишние переносы строки. Откуда копипастили?
 
Rashid Umarov:
У меня к вам вопрос: как вы вставляли код? Просто хочу понять, откуда лишние переносы строки. Откуда копипастили?

а, я сначала накидал просто как текст, не знал что тут можно просто "alt+s" тыкнуть. Ну и потом просто скопировал и вставил. По идее компилироваться должно.

upd. криво вставлял, короче)

 
Alexander Laur:

Прикол в том: зачем вам первый запрос в функции, если вы возвращаете значение, полученное во втором запросе?

а, это просто пример. Можно добавить какой нибудь if и возвращать максимальное. Не суть, проблема то абсолютно в другом, он (в первом случае) будет выводить Print в два разных тика, а во втором - в один. Вот я не врубаюсь почему так
 
Alexander Laur:

Даже в "просто пример" нужно делать все правильно.

Теперь еще раз о "проблеме". Обращение в базу должно выполняться ОДИН раз в пределах тика. А дальше уже работать с полученными данными так, как требует ваш алгоритм. Поучение данных - это трудоемкая операция, поэтому разработчики и вводят ограничение ОДИН ТИК = ОДНО ОБРАЩЕНИЕ. Если не ввести такое ограничение, то найдутся "умники", которые в бесконечном цикле на каждой итерации будут запрашивать данные. В результате рухнет сервер. Теперь понятно?

Ситуация, с которой вы столкнулись, относится к вашему алгоритму, а не к платформе и разработчикам. :)

Т.е. MqlRates обращается непосредственно к серверу, а не к данным в терминале?

Так я, в принципе, могу накопипастить кучу всего, просто меняя название переменной "MqlRates" типа:

   MqlRates rates[];
   int Arr1 = CopyRates(_Symbol, PERIOD_CURRENT, time, time, rates);

   MqlRates rates1[];
   int Arr2 = CopyRates(_Symbol, PERIOD_CURRENT, time, time, rates1);

   MqlRates rates2[];
   int Arr2 = CopyRates(_Symbol, PERIOD_CURRENT, time, time, rates2);
// ...
// ...
   MqlRates ratesN[];
   int Arr2 = CopyRates(_Symbol, PERIOD_CURRENT, time, time, ratesN);

и грохнуть их сервер? (данный код будет выполняться в один тик)

Просто мне кажется что данное поведение несколько странное (я его не понимаю). Если бы CopyRates или MqlRates срабатывали только один раз за тик - я бы смирился. Но нет, они срабатывают странно. А в третьем примере вообще колдунство - там переменная локальная (и, как я понимаю) каждый раз должна создаваться заново. Но не создается.

Мне кажется - после работы с ней её нужно удалять, но гугл не захотел мне подсказывать как удалять подобные штуки. delete() и ZeroMemory() не подходят.

 
Не, я могу конечно сразу получить через CopyRates избыточные данные и работать с ними в цикле. Но вдруг это какой-то лютый баг из-за которого трейдеры теряют +100500 ердов на каждый тик? Вот его профиксят и мне статую из бронзы отольют, за старания, ну или хотя-бы бюст)
 
Alexander Laur:

Даже в "просто пример" нужно делать все правильно.


Камон, я ща просто отрдактирую вопрос и вообще буду ретёрнить 0

 
up. Я уже отказался от этой идеи, но вопрос все еще актуален
 
Павел:

upd. Как сделать так, чтобы функция TakeArraySize срабатывала без ожидания следующего тика при повторном вызове?

Не воспроизвести.

 
Павел:

Всем привет! Подскажите что за колдунство происходит в MQL5.

запрос не корректный по своей сути:

CopyRates(_Symbol, PERIOD_CURRENT, time, time, rates);


Обращение по начальной и конечной датам требуемого интервала времени

int  CopyRates( 
   string           symbol_name,       // имя символа 
   ENUM_TIMEFRAMES  timeframe,         // период 
   datetime         start_time,        // с какой даты 
   datetime         stop_time,         // по какую дату 
   MqlRates         rates_array[]      // массив, куда будут скопированы данные 
   );