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

 

МТ4, прошу помощи сообщества.
1. В эксперте, работающем (по тикам или по таймеру 0,5 сек) на графике М1 нужно в момент появления новой свечи на графике H1 сделать вычисления.
   Можно ловить начало свечи М1, следующей за последней свечой М1 каждого часа (NN:00 минут), но это как-то некрасиво ... Да и свеча H1 в этот момент может ещё не нарисоваться.
   Может быть, кто-то сделал это более изящно ?
2. Получение значения индикатора через iCustom() насколько дольше, по сравнению с кодом индикатора в тексте эксперта ?
3. Если код индикатора в тексте эксперта намного быстрее считается, как в эксперте, прикрепленному к графику М1, посчитать значение индикатора по графику H1 ?

 
MikeZv:

МТ4, прошу помощи сообщества.
1. В эксперте, работающем (по тикам или по таймеру 0,5 сек) на графике М1 нужно в момент появления новой свечи на графике H1 сделать вычисления.
   Можно ловить начало свечи М1, следующей за последней свечой М1 каждого часа (NN:00 минут), но это как-то некрасиво ... Да и свеча H1 в этот момент может ещё не нарисоваться.
   Может быть, кто-то сделал это более изящно ?
2. Получение значения индикатора через iCustom() насколько дольше, по сравнению с кодом индикатора в тексте эксперта ?
3. Если код индикатора в тексте эксперта намного быстрее считается, как в эксперте, прикрепленному к графику М1, посчитать значение индикатора по графику H1 ?

Ответ на первый вопрос, функция определяет новый бар.

bool NevBar(int period)
  {
   static datetime StatTime;

   if(StatTime!=iTime(NULL,period,0))
     {
      StatTime=iTime(NULL,period,0);
      return(true);
     }
   return(false);
  }

 

пример использования 

int OnInit()
  {
//---
   NevBar(PERIOD_H1);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   if(NevBar(PERIOD_H1))
     {
      производим вычисления.
     }
  }
//+------------------------------------------------------------------+

 
Sergey Gritsay:

Ответ на первый вопрос, функция определяет новый бар.

Большое спасибо, Сергей, я документацию пролистал, но вот iTime() как-то пропустил ... :
А зачем в OnInit() вызывать NevBar() ?

 
MikeZv:

Первый вызов функции, иначе будет срабатывание сразу. Доработал чтобы в  OnInit() не вызывать

bool NevBar(int period)
  {
   static datetime StatTime;
   
   if(StatTime==0)StatTime=iTime(NULL,period,0);

   if(StatTime!=iTime(NULL,period,0))
     {
      StatTime=iTime(NULL,period,0);
      return(true);
     }
   return(false);
  }
 
Sergey Gritsay:

Первый вызов функции, иначе будет срабатывание сразу. Доработал чтобы в  OnInit() не вызывать

Спасибо, Сергей !  На форуме меня пугали сильно-сильно: " Не используй статические переменные ! "  :)
 
MikeZv:
Спасибо, Сергей !  На форуме меня пугали сильно-сильно: " Не используй статические переменные ! "  :)
Не слушайте, если нужно использовать - используйте смело, но правильно!
 
MikeZv:
Спасибо, Сергей !  На форуме меня пугали сильно-сильно: " Не используй статические переменные ! "  :)
Первый раз о таком слышу, интересно чего в них такого страшного, я ими редко тоже пользуюсь, но для определенных задач они подходят лучше.
 
Sergey Gritsay:
Первый раз о таком слышу, интересно чего в них такого страшного, я ими редко тоже пользуюсь, но для определенных задач они подходят лучше.
Дело в том, что static-переменную можно использовать только в случае, если  NevDay() в течение всего периода работы эксперта вызывается для одного и того же символа и таймфрейма.  Если символа 2 и более, то NevDay() будет возвращать некорректные значения. У меня эксперт спроектирован мультивалютным ... :(
 
MikeZv:
Дело в том, что static-переменную можно использовать только в случае, если  NevDay() в течение всего периода работы эксперта вызывается для одного и того же символа и таймфрейма.  Если символа 2 и более, то NevDay() будет возвращать некорректные значения. У меня эксперт спроектирован мультивалютным ... :(

Если нужно для мультивалютного режима то тогда вот такой пример, работает как в МТ4 так и в МТ5

//+------------------------------------------------------------------+
//|                                                         тест.mq4 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   int SymbolTotal=SymbolsTotal(true);
   Comment("SymbolTotal = ",SymbolTotal);
   for(int i=0;i<SymbolTotal;i++)
     {
      if(NewBar(SymbolTotal,i,SymbolName(i,true),PERIOD_H1))
        {
         Alert(SymbolName(i,true)," Новый бар на Н1");
        }
     }

  }
//+------------------------------------------------------------------+
bool NewBar(int size,int i,string symbol,ENUM_TIMEFRAMES  period)
  {
   datetime curbar[];
   static datetime lastbar[];
   ArrayResize(curbar,size);
   ArrayResize(lastbar,size);

   curbar[i]=(datetime) SeriesInfoInteger(symbol,period,SERIES_LASTBAR_DATE);

   if(lastbar[i]==0)lastbar[i]=(datetime)SeriesInfoInteger(symbol,period,SERIES_LASTBAR_DATE);
   if(lastbar[i]!=curbar[i])
     {
      lastbar[i]=curbar[i];
      return(true);
     }
   return(false);
  }
//+------------------------------------------------------------------+
 
MikeZv:
Дело в том, что static-переменную можно использовать только в случае, если  NevDay() в течение всего периода работы эксперта вызывается для одного и того же символа и таймфрейма.  Если символа 2 и более, то NevDay() будет возвращать некорректные значения. У меня эксперт спроектирован мультивалютным ... :(

Вот еще один вариант с использованием класса

 

//+------------------------------------------------------------------+
//|                                                         тест.mq4 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CNevBar
  {
private:
   datetime          curbar;
   datetime          lastbar;
public:
                     CNevBar();
                    ~CNevBar();
   bool              new_bar(string symbol,ENUM_TIMEFRAMES period);
  };
//+------------------------------------------------------------------+
void CNevBar::CNevBar()
  {

  }
//+------------------------------------------------------------------+
void CNevBar::~CNevBar(void)
  {

  }
//+------------------------------------------------------------------+
bool CNevBar:: new_bar(string symbol,ENUM_TIMEFRAMES period)
  {
   curbar=(datetime) SeriesInfoInteger(symbol,period,SERIES_LASTBAR_DATE);
   if(lastbar==0)lastbar=(datetime)SeriesInfoInteger(symbol,period,SERIES_LASTBAR_DATE);
   if(lastbar!=curbar)
     {
      lastbar=curbar;
      return(true);
     }
   return(false);
  }

CNevBar *eurusd_H1; // объявим экземпляр класса для симмвола EURUSD
CNevBar *eurusd_M15; // объявим экземпляр класса для симмвола EURUSD

CNevBar *audusd_M30; // объявим экземпляр класса для симмвола AUDUSD
CNevBar *audusd_M5; // объявим экземпляр класса для симмвола AUDUSD

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   eurusd_H1=new CNevBar();// создадим экземпляр класса для симмвола EURUSD
   audusd_M30=new CNevBar();// создадим экземпляр класса для симмвола AUDUSD
   eurusd_M15=new CNevBar();// создадим экземпляр класса для симмвола EURUSD
   audusd_M5=new CNevBar();// создадим экземпляр класса для симмвола AUDUSD

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   delete eurusd_H1;// удалим экземпляр класса для симмвола EURUSD
   delete audusd_M30;// удалим экземпляр класса для симмвола AUDUSD
   delete eurusd_M15;// удалим экземпляр класса для симмвола EURUSD
   delete audusd_M5;// удалим экземпляр класса для симмвола AUDUSD

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

   if(eurusd_H1.new_bar("EURUSD",PERIOD_H1))
     {
      Alert("EURUSD"," Новый бар на Н1");
     }

   if(eurusd_M15.new_bar("EURUSD",PERIOD_M15))
     {
      Alert("EURUSD"," Новый бар на M15");
     }

   if(audusd_M30.new_bar("AUDUSD",PERIOD_M30))
     {
      Alert("AUDUSD"," Новый бар на M30");
     }
   if(audusd_M5.new_bar("AUDUSD",PERIOD_M5))
     {
      Alert("AUDUSD"," Новый бар на M5");
     }

//---

  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+

Результат теста 

2016.02.20 21:09:43     2015.01.10 00:00  тест3 test started
2016.02.20 21:09:45     2015.01.12 00:00  тест3 EURUSD,M1: Alert: EURUSD Новый бар на M15
2016.02.20 21:09:47     2015.01.12 00:00  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M30
2016.02.20 21:09:50     2015.01.12 00:00  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M5
2016.02.20 21:09:53     2015.01.12 00:05  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M5
2016.02.20 21:09:59     2015.01.12 00:10  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M5
2016.02.20 21:10:04     2015.01.12 00:15  тест3 EURUSD,M1: Alert: EURUSD Новый бар на M15
2016.02.20 21:10:04     2015.01.12 00:15  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M5
2016.02.20 21:10:10     2015.01.12 00:20  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M5
2016.02.20 21:10:13     2015.01.12 00:25  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M5
2016.02.20 21:10:16     2015.01.12 00:30  тест3 EURUSD,M1: Alert: EURUSD Новый бар на M15
2016.02.20 21:10:16     2015.01.12 00:30  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M30
2016.02.20 21:10:16     2015.01.12 00:30  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M5
2016.02.20 21:10:23     2015.01.12 00:35  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M5
2016.02.20 21:10:26     2015.01.12 00:40  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M5
2016.02.20 21:10:29     2015.01.12 00:45  тест3 EURUSD,M1: Alert: EURUSD Новый бар на M15
2016.02.20 21:10:29     2015.01.12 00:45  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M5
2016.02.20 21:10:34     2015.01.12 00:50  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M5
2016.02.20 21:10:36     2015.01.12 00:55  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M5
2016.02.20 21:10:39     2015.01.12 01:00  тест3 EURUSD,M1: Alert: EURUSD Новый бар на Н1
2016.02.20 21:10:39     2015.01.12 01:00  тест3 EURUSD,M1: Alert: EURUSD Новый бар на M15
2016.02.20 21:10:39     2015.01.12 01:00  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M30
2016.02.20 21:10:39     2015.01.12 01:00  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M5
2016.02.20 21:10:46     2015.01.12 01:05  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M5
2016.02.20 21:10:50     2015.01.12 01:10  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M5
2016.02.20 21:10:55     2015.01.12 01:15  тест3 EURUSD,M1: Alert: EURUSD Новый бар на M15
2016.02.20 21:10:55     2015.01.12 01:15  тест3 EURUSD,M1: Alert: AUDUSD Новый бар на M5
2016.02.20 21:10:57     2015.01.12 01:17  Tester: stop button pressed
Причина обращения: