Как избавиться от Sleep после CopyRates.

 

После CopyRates надо ставить Sleep т.к. без него не хотят загружаться. Примерно 150-200 .

Даже после Symbolselect надо иногда ставить.

Т.е. CopyRates работает асинхронно . 


Вот так написано в документации:

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

Как сделать чтобы программа ждала пока не загрузятся все данные.  Т.е. если у терминала есть 100 баров, и мне надо 200 и он выдаст 100 только. И это както глупо. Я хочу 200 и ждать сколько надо. А не получить обрубок и потом самому выяснять, что там загрузилось, что там не загрузилось.

После каждой CopyRates  надо ставить Loop чтобы считать загруженые бары и выходить когда всё загрузится.  Что за бред .

А Sleep не удобен т.к. не всегда он нужен, а ставить его приходится ко всем.

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

Документация по MQL5: Доступ к таймсериям и индикаторам / Организация доступа к данным
Документация по MQL5: Доступ к таймсериям и индикаторам / Организация доступа к данным
  • www.mql5.com
В этом разделе рассматриваются вопросы, связанные с получением, хранением и запросами ценовых данных ( таймсерий ). Прежде чем ценовые данные будут...
 
andreysneg:

После CopyRates надо ставить Sleep т.к. без него не хотят загружаться. Примерно 150-200 .

Даже после Symbolselect надо иногда ставить.

Т.е. CopyRates работает асинхронно . 


Вот так написано в документации:

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

Как сделать чтобы программа ждала пока не загрузятся все данные.  Т.е. если у терминала есть 100 баров, и мне надо 200 и он выдаст 100 только. И это както глупо. Я хочу 200 и ждать сколько надо. А не получить обрубок и потом самому выяснять, что там загрузилось, что там не загрузилось.

После каждой CopyRates  надо ставить Loop чтобы считать загруженые бары и выходить когда всё загрузится.  Что за бред .

А Sleep не удобен т.к. не всегда он нужен, а ставить его приходится ко всем.

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

см. SeriesInfoInteger() https://www.mql5.com/ru/docs/series/seriesinfointeger

Документация по MQL5: Доступ к таймсериям и индикаторам / SeriesInfoInteger
Документация по MQL5: Доступ к таймсериям и индикаторам / SeriesInfoInteger
  • www.mql5.com
Возвращает информацию о состоянии исторических данных. Существует 2 варианта функции. Непосредственно возвращает значение свойства. Возвращает true...
 

Что там смотреть.

Вот написал какуюто функцию, только она не работает. В тестере. Без тестера сложно , там всегда всё загружено.

available_bars - показывает 350 баров. Мне надо 500.

CopyRates возвращает 350 баров и никак не хочет больше. Я пытаюсь ставить паузы 10 и потом опять грузить, но не хочет. Символ USDJPY с 2023.05.09
Attempts - нужно для защиты от нуля и от долго исполнения.


   int available_bars = Bars(Symbol(), PERIOD_D1); // 350 
   int bars=500;
   long copied = CopyRates(Symbol(), PERIOD_D1, 0, bars, rates);  
   
   int attempts;
   while (copied < bars) {
      Sleep(10);      
      copied = CopyRates(Symbol(), PERIOD_D1, 0, bars, rates);
      available_bars = Bars(Symbol(), PERIOD_D1); // 350 показывает всегда
      attempts++;
      if (attempts==10 && copied==0) break; // Если не загружается

      if (attempts==10000) break; // Если долго
   }


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


Или вот AI написал. Тоже не работает. Не грузит больше 350

bool LoadBarsWithWait(string symbol, ENUM_TIMEFRAMES timeframe, int requiredBars, MqlRates &rates[]) {
    int attempts = 0;
    int maxAttempts = 10; // Максимальное количество попыток
    int sleepTime = 1000; // Время ожидания между попытками (в миллисекундах)

    while (attempts < maxAttempts) {
        int copiedBars = CopyRates(symbol, timeframe, 0, requiredBars, rates);

        if (copiedBars == requiredBars) {
            // Все бары загружены успешно
            Print("Загружено ", copiedBars, " баров для ", symbol, ", ", EnumToString(timeframe));
            return true;
        } else if (copiedBars > 0) {
            // Загружено меньше баров, чем требуется
            Print("Загружено ", copiedBars, " из ", requiredBars, " баров для ", symbol, ", ", EnumToString(timeframe), ". Ожидание...");
            Sleep(sleepTime);
            attempts++;
        } else {
            // Ошибка загрузки
            Print("Ошибка загрузки баров для ", symbol, ", ", EnumToString(timeframe), ". Код ошибки: ", GetLastError());
            return false;
        }
    }

    // Превышено максимальное количество попыток
    Print("Превышено максимальное количество попыток загрузки баров для ", symbol, ", ", EnumToString(timeframe));
    return false;
}
 
andreysneg #:

Что там смотреть.

Вот написал какуюто функцию, только она не работает.

available_bars - показывает 350 баров. Мне надо 500.

CopyRates возвращает 350 баров и никак не хочет больше. Я пытаюсь ставить паузы 10 и потом опять грузить, но не хочет. Символ USDJPY с 2023.05.09
Attempts - нужно для защиты от нуля и от долго исполнения.



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

что смотреть, что смотреть...ссылки и примеры по ним

в самом начале раздела есть https://www.mql5.com/ru/docs/series/timeseries_access (организация доступа к данным)

и там прекрасная своей кривизной унитарностью (она только для скриптов) функция CheckLoadHistory - "загрузить данные до заданного времени". Для врагов и маркета можно использовать без правок, а для себя делать класс с конечным автоматом внутри и использовать как первую стадию инициализации советника (пока нужные данные отсутвуют, работать нельзя).

Документация по MQL5: Доступ к таймсериям и индикаторам / Организация доступа к данным
Документация по MQL5: Доступ к таймсериям и индикаторам / Организация доступа к данным
  • www.mql5.com
В этом разделе рассматриваются вопросы, связанные с получением, хранением и запросами ценовых данных ( таймсерий ). Прежде чем ценовые данные будут...
 
andreysneg #:

Что там смотреть.
Вот написал какуюто функцию, только она не работает. В тестере. Без тестера сложно , там всегда всё загружено.
available_bars - показывает 350 баров. Мне надо 500.

На дневных барах так и есть . Максимальная глубина истории от стартового значения 350 баров.

Например поставили вы дату 01.01.2020, и в начале тестирования запросите историю баров, она будет максимум 350 баров. Это как я понял ограничение тестера и никакие  CheckLoadHistory  тут не помогут(в тестере).

 
Maxim Kuznetsov #:

что смотреть, что смотреть...ссылки и примеры по ним

Так может надо давать ссылку на нужную статью,   а не ссылку на статью со ссылкой на нужную статью.

Всё равно спасибо . Одно понял , что это та еще жесть. 

Одно выносит мозг, что эту функцию надо выполнять Абсолютно всегда, Абсолютно везде , Абсолютно в каждом скрипте и эксперте вместо простого CopyRates .  Так почему ее не встроят прямо в MQL ? WHYYYY ??? Дефолтная CopyRates вообще бысмысленный обрубок который нельзя использовать. 

В стандартной библиотеке, то может есть уже готовая ? 


Другой прикол . Я удалил из файлов History / 3M все файлы.

А эта функция: SeriesInfoInteger("3M",PERIOD_M1,SERIES_FIRSTDATE));

Загрузила 5 лет hcc файлов истории. И показало что первая дата - D'2022.01.03 16:30:00'
Так FIRSTDATE что показывает - всё что есть на серваке у брокера или то что загружено у MT5 ?


Судя по тому, что она загрузила 5 лет, то первую дату у брокера ?
Так какже ее можно использовать для проверки уже загружженого, если она делает совсем не то ?


Третий прикол , что оказывается не надо 3М подключать через SymbolSelect, чтобы получить бары CopyRates.


Четвертый прикол -  CopyRates("3M", PERIOD_M1, 0, 100, rates);  
Тоже загрузила всю историю за 5 лет !!! Как это понимать ? Мне 100 минут надо, а не 5 лет.


Вообщем такая фигня. При любом первом обращении к CopyRates и подобным или SeriesInfoInteger. Он тупо грузит всё что есть у брокера. Зато потом всё быстро.
Поэтому функция - CheckLoadHistory  , вообще делает какуюто фигню. Подгружать частями смысла нет.

А 
CopyRates в тестере зависает пока не загрузит всю историю, даже если мне нужно 10 баров минутных только. Т.е. хотябы дальше не идет, но это только при Debug. В реальности нужно Sleep ставить ... и в документации написано , что надо ждать и грузить частями.

Я рехнусь ща.

 
andreysneg #:

Дефолтная CopyRates вообще бысмысленный обрубок который нельзя использовать. 

В стандартной библиотеке, то может есть уже готовая ? 


Четвертый прикол -  CopyRates("3M", PERIOD_M1, 0, 100, rates);  

Тоже загрузила всю историю за 5 лет !!! Как это понимать ? Мне 100 минут надо, а не 5 лет.


Вообщем такая фигня. При любом первом обращении к CopyRates и подобным или SeriesInfoInteger. Он тупо грузит всё что есть у брокера. Зато потом всё быстро.
Поэтому функция - CheckLoadHistory  , вообще делает какуюто фигню. Подгружать частями смысла нет.

А 
CopyRates в тестере зависает пока не загрузит всю историю, даже если мне нужно 10 баров минутных только. Т.е. хотябы дальше не идет, но это только при Debug. В реальности нужно Sleep ставить ... и в документации написано , что надо ждать и грузить частями.

Я рехнусь ща.

А если в OnInit() один раз загрузить максимально вам нужное количество? Они останутся в кеше сервера и, по идее, время будет уходить только на формирование новых баров на сервере. Но надо проверять. 

 
Alexey Volchanskiy #:

А если в OnInit() один раз загрузить максимально вам нужное количество? Они останутся в кеше сервера и, по идее, время будет уходить только на формирование новых баров на сервере. Но надо проверять. 

Forum on trading, automated trading systems and testing trading strategies

Getting Indicator Values in EA OnInit() functions to be processed.

William Roeder, 2020.09.30 16:39

Не пытайтесь использовать какие-либо функции, связанные с ценами или сервером, в OnInit (или при загрузке), поскольку соединение/график еще могут отсутствовать:

  1. Терминал запускается.
  2. Индикаторы/EAs загружены. Статические и глобально объявленные переменные инициализированы. (Не зависят от определенного порядка.)
  3. Вызывается OnInit .
  4. Для индикаторов OnCalculate вызывается с любой существующей историей.
  5. Человеку, возможно, придется ввести пароль, начнется подключение к серверу .
  6. Получена новая история, OnCalculate вызывается снова.
  7. Получен новый тик, вызывается OnCalculate / OnTick . Теперь TickValue , TimeCurrent , информация о счете и цены действительны.
 
Maxim Kuznetsov #:

что смотреть, что смотреть...ссылки и примеры по ним

в самом начале раздела есть https://www.mql5.com/ru/docs/series/timeseries_access (организация доступа к данным)

и там прекрасная своей кривизной унитарностью (она только для скриптов) функция CheckLoadHistory - "загрузить данные до заданного времени". Для врагов и маркета можно использовать без правок, а для себя делать класс с конечным автоматом внутри и использовать как первую стадию инициализации советника (пока нужные данные отсутвуют, работать нельзя).

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

при мультисимволе крайне необходим

закинул в Include скрипт, подключил к роботу

поменял void OnStart()

на функцию с входными параметрами

void History(string InpLoadedSymbol,ENUM_TIMEFRAMES InpLoadedPeriod,datetime InpStartDate)

добавил вызов функции в цикле по рабочим символам, осталось массив подкинуть со списком

//+------------------------------------------------------------------+
//| Вызов загрузки истории                                           |
//+------------------------------------------------------------------+
void LoadingHistory()
  {
   if(LoadHistory)
     {
      if(MQLInfoInteger(MQL_TESTER))
         return;
      //--- Загрузка истории
      for(int s=0; s<TRADE_SYMBOLS; s++)
        {
         //--- Если торговля по этому символу разрешена
         if(Symbols[s]!="")
            //---
            History(Symbols[s],PERIOD_H1,D'2020.01.01');
        }
     }
//иначе выходим
  }
 

Так функция бесмысленная MT5 грузит всю историю символа с брокера при первом обращении к сериям . Посмотри папку History . Сотри там всё у символа и вызови любой CopyRates или подобное.

Или у вас не так ?

 

скрипт из справки загрузились 400 баров H1

void OnStart() 
  { 
//--- 
   MqlRates rates[]; 
   ArraySetAsSeries(rates,true); 
   int copied=CopyRates(Symbol(),0,0,400,rates); 
   if(copied>0) 
     { 
      Print("Скопировано баров: "+copied); 
      string format="open = %G, high = %G, low = %G, close = %G, volume = %d"; 
      string out; 
      int size=fmin(copied,400); 
      for(int i=0;i<size;i++) 
        { 
         out=i+":"+TimeToString(rates[i].time); 
         out=out+" "+StringFormat(format, 
                                  rates[i].open, 
                                  rates[i].high, 
                                  rates[i].low, 
                                  rates[i].close, 
                                  rates[i].tick_volume); 
         Print(out); 
        } 
     } 
   else Print("Не удалось получить исторические данные по символу ",Symbol()); 
  }