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

 
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 ничего не нашел. Может есть ещё варианты?
[Удален]  

do { ... код заполнения буфера

}

while(эти два значения не совпадают)

короче получать значения до тех пор в цикле, пока они не совпадут, только после этого выполнять следующий код
 
Maxim Dmitrievsky:

do { ... код заполнения буфера

}

while(эти два значения не совпадают)

короче получать значения до тех пор в цикле, пока они не совпадут, только после этого выполнять следующий код

Так дело в том, что пока не отработает один индикатор, данные (поток) не передаются другому, т.е. цикл в индикаторе без окончания работы OnCalculate этого индикатора не поможет. А как только OnCalculate заканчивается, то сразу отдаются данные советнику, а они ошибочны.

Или я не понял Вашу идею.