Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 984

 
Ihor Herasko:


По факту же вопроса. Sleep не должен никак влиять на пересчет данных в индикаторе. Что-то не так с заполнением буферов. Может есть воспроизводимый кусок кода?

Индикатор писался на заказ - там дикий ООП, я его не понимаю :(

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

 
Aleksey Vyazmikin:

Столкнулся с проблемой, советник на базе индикатора работает на реальном счете корректно, а в тестере врет, во режимах генерации тиков как по OHLC так и по всем тикам - результат одинаковый. Результатом ошибки является незаполненный буфер индикатора на нулевом баре (только когда появляется новый бар на верхнем TF, по которому идет расчет индикатора). Однако, мне удалось заставить считать индикатор, добавив Sleep в советник, и тут было выявлено, что в зависимости от режима генерации тиков этот Sleep должен быть разным - для генерации по всем тикам достаточно Sleep(15000), а для OHLC нужно уже Sleep(30000).

Поэтому возникает вопрос, нормальна ли ситуация со Sleep, ведь получается логически, что там разное время задержки моделируется в зависимости от режима генерации тиков!?

Уважаемые разработчики, прошу Вас пояснить по поводу описанной ситуации с индикатором, так-как сам я не могу понять в чем причина - ошибка в коде или в тестере!

Индикатор и советник готов предоставить в личку, только скажите кому.

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

это кривые руки программиста, если он об этом не знал

слип это не нормально
 
void OnChartEvent(            const int id,        // идентификатор события   
                              const long& lparam,  // параметр события типа long 
                              const double& dparam,// параметр события типа double 
                              const string& sparam // параметр события типа string 
                              )
   {
   Print(My_Name, " ---  ", id, "    lparam = ", lparam, "    dparam = ", dparam, "    sparam = ", sparam, "    ChartID() = ", ChartID() );        // <<|+|+|+<<  // 

   }                              

Объясните, пожалуйста..

Нажимаю клавишу = получаю событие  id = 0. Это можно повторять многократно. Результат получается тот же до тех пор, пока не нажат пробел.

Нажат пробел = получаю событие id = 0. После этого никакие манипуляции с клавиатурой к событиям не приводят.

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

Вопрос: Это я дурак чего-то не понимаю или так не должно быть? Прошу указать ссылку.

 
Nikita Chernyshov:

Здравствуйте, коллеги.

Вопрос такой: в mql4 для того, чтобы посчитать количество позиций можно было прописать функцию, к примеру, такую

Как это дело реализуется в mql5? Как можно посчитать позиции по магику? или по типу?

Добавьте перед MQL4-функцией эту строку

#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006

и она станет работать в MT5.

 
Maxim Dmitrievsky:

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

это кривые руки программиста, если он об этом не знал

слип это не нормально

Как такое возможно в тестере? Я понимаю, если проблема на реале или в тестере там нет истории... Впрочем, как должна выглядеть эта проверка?

Разработчики игнорируют моё сообщение, прискорбно.

 
Aleksey Vyazmikin:

Как такое возможно в тестере? Я понимаю, если проблема на реале или в тестере там нет истории... Впрочем, как должна выглядеть эта проверка?

Разработчики игнорируют моё сообщение, прискорбно.

проверка скоприровались ли цены, если Copyclose или что там возвращает -1 значит не скопировались

 
Maxim Dmitrievsky:

проверка скоприровались ли цены, если Copyclose или что там возвращает -1 значит не скопировались

Индикатор рассчитывается 1 раз при появление нового бара, что реализовано, если я правильно понимаю таким образом:

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
   static int counted_bars=0;
   if(rates_total==prev_calculated) return(rates_total);

это подтверждается и простым принтом.

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

 
Aleksey Vyazmikin:

Индикатор рассчитывается 1 раз при появление нового бара, что реализовано, если я правильно понимаю таким образом:

это подтверждается и простым принтом.

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

может, таймером надо засекать тогда

 
Maxim Dmitrievsky:

может, таймером надо засекать тогда

Да, с таймером в советнике тест проходит чуть дальше, чем без таймера, но хуже чем со Sleep, да и таймер по сути тот же Sleep.

Кажется, я понял в чем проблема, индикатор рассчитывается по данным двух других индикаторов, в коде происходит запрос числа посчитанных баров других индикаторов

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int CChannel::BarsCalculated(void)
  {
   int upchbars=BarsCalculated(m_upch);
   int dnchbars=BarsCalculated(m_dnch);
   if(upchbars<=dnchbars) return(upchbars);
   return(dnchbars);
  }

и ожидаемое расчетное число баров

int barsch=(InpChPeriod==PERIOD_CURRENT?rates_total:Bars(_Symbol,InpChPeriod));

Если эти два значения не совпадают и получается, что буфер не заполняется.

   if(!channel.CreateChannel() || barsch<=0 || barsch!=channel.BarsCalculated() || channel.FillChBuffers(rates_total,calculated,time)==0)
     {
      for(;counted_bars<rates_total;counted_bars++)
        {
         ZigzagBuffer[counted_bars]=0.0;
         ZigzagStepBuffer[counted_bars]=0.0;
         UpChBuffer[counted_bars]=0.0;
         DnChBuffer[counted_bars]=0.0;
         InfoZigzagBuffer[counted_bars]=0.0;
         InfoUpChBuffer[counted_bars]=0.0;
         InfoDnChBuffer[counted_bars]=0.0;
         InfoDirectBuffer[counted_bars]=0.0;
         InfoBegPriceBuffer[counted_bars]=0.0;
         InfoEndPriceBuffer[counted_bars]=0.0;
         InfoBegTimeBuffer[counted_bars]=0.0;
         InfoEndTimeBuffer[counted_bars]=0.0;
         InfoStartPriceBuffer[counted_bars]=0.0;
         InfoStartTimeBuffer[counted_bars]=0.0;
         InfoZigzagTotal[counted_bars]=InfoZigzagTotal[counted_bars-1];
        }
      if(InpInfEnd) CopyInfoBuffers(rates_total-1,(int)InfoZigzagTotal[rates_total-1]);
      return(calculated);
     }

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

В принте видно, что если поставить Sleep достаточного размера, то происходит перерасчет в индикаторе(пока не понимаю как), и почему только через 13 секунд?

2019.01.22 19:50:16.992 2019.01.21 23:45:00   barsch=6275
2019.01.22 19:50:16.992 2019.01.21 23:45:00   BarsCalculated=6274

2019.01.22 19:50:16.993 2019.01.21 23:45:13   barsch=6275
2019.01.22 19:50:16.993 2019.01.21 23:45:13   BarsCalculated=6275

В индикаторе таймера нет.

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

 
Здравствуйте! Хотел внедрить в свой EA трейлинг-стоп с шагом. Кроме шаблона в Кодобазе и в Macd Sample ничего не нашел. Может есть ещё варианты?