Mt4 End of support. - page 43

 
Реter Konow:

What is your result?

Where do you call the function from?


//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   Trading_on_new_bars_strategy();
  }
 
Vitaly Muzichenko:

1. Replace bool type with int type of array All_bars_table[][7]; at the top where global variables are declared.

2. Put call to timer, where it says "Here is your code".

Now I checked it and it works on EURUSD. In short, it works.

 

Here is the variant that prints on the EURUSD minute:

//+------------------------------------------------------------------+
//|                                                  Новый бар 4.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
datetime Last_Bar_Time;

int    Periodicity = 25;
int    All_symbols;

string Symbols[];
int    Timeframes[7] = {PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1};
int    All_Timeframes = 7;


int    All_bars_table[][7];
int    New_Bar_Events[][7];

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetMillisecondTimer(25);
   //-------------------------------------------------------------
   //Записываем время последнего бара на момент загрузки эксперта.  
   //Для корректного начала работы, робота нужно запустить на М1. 
   //-------------------------------------------------------------
   Last_Bar_Time = Time[0];
   //-------------------------------------------------------------   
   //Узнаем сколько символов есть в обзоре рынка.
   //---------------------------------------------------------
   All_symbols = SymbolsTotal(true);
   //---------------------------------------------------------   
   //Устанавливаем размер массива Symbols. Внутри него будут записаны
   //имена всех символов, которые есть в окне обзоре рынка.
   //---------------------------------------------------------
   ArrayResize(Symbols,All_symbols);
   //---------------------------------------------------------
   //Устанавливаем размеры массивов "All_bars_table[]" и "New_Bar_Events[]".
   //В массиве "All_bars_table[]" будет записыватся текущее количество баров каждого символа
   //и каждого таймфрейма. А в массиве "New_Bar_Events[]" устанавливаться флаги
   //события нового бара для каждого символа и каждого таймфрейма. 
   //---------------------------------------------------------
   ArrayResize(All_bars_table,All_symbols);
   ArrayResize(New_Bar_Events,All_symbols);
   //---------------------------------------------------------
   //Записываем наименования символов обзора рынка в массив "Symbols[]".
   //---------------------------------------------------------
   for(int a1 = 0; a1 < All_symbols; a1++)
     {
      Symbols[a1] = SymbolName(a1 + 1,true); 
      //Возможно, нумерация символов в обзора рынка идет с нуля.
      //Тогда: Symbols[a1] = SymbolName(a1,true);
     }
   //---------------------------------------------------------
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
      
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
{
 static bool Start_count;
 static int  Current_period;
 //---------------------------
 //Нам нужен корректный старт отсчета. Это должно быть время начала бара.
 //---------------------------
 if(!Start_count && Last_Bar_Time != Time[0])Start_count = true; 
 //--------------------------- 
 if(Start_count)Current_period++;
 //--------------------------- 
 //В следующем цикле, мы будем обращатся к функции iBars для получения количества баров на 
 //каждом из символов и таймфреймов, которые будем проходить в цикле.
 //Далее, будем сравнивать записанное количество баров с текущим и при 
 //наличии разницы установим флаг события нового бара в массив "New_Bar_Events[]".
 //---------------------------
 if(Current_period*Periodicity >= 1000)
   {
    for(int a1 = 0; a1 < All_symbols; a1++)
      {
       string This_symbol = Symbols[a1];
       //---------------------------------
       for(int a2 = 0; a2 < All_Timeframes; a2++)
         {
          int This_timeframe = Timeframes[a2];
          //------------------------------------------
          int All_current_bars = iBars(This_symbol,This_timeframe);
          //------------------------------------------
          if(All_current_bars > All_bars_table[a1][a2])
            {
             //------------------------------------------------------------
             //Если это не самая первая запись в массив All_bars_table,
             //то фиксируем событие нового бара.
             //------------------------------------------------------------
             if(All_bars_table[a1][a2])
               {
                New_Bar_Events[a1][a2]  = true;
               } 
             //------------------------------------------------------------
             //Устанавливаем новое значение текущего количества баров.
             //------------------------------------------------------------
             All_bars_table   [a1][a2]  = All_current_bars;
            }
          //------------------------------------------
         }
      }
    //---------
    Current_period = 0;
   }
 //-----------------------------------------------
 //Здесь наш код...
 //Здесь наш код...
 //Здесь наш код...
 Trading_on_new_bars_strategy();
 //-----------------------------------------------
 //После завершения всех вызовов на этом событии таймера
 //снимаем флаги событий нового бара.
 if(!Current_period)Refresh_new_bar_events_table();
 //-----------------------------------------------  
}
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//Функция снимает флаги событий нового бара.
//Эта процедура осуществляется после выполнения всего пользовательского
//кода один раз в минуту. Вплоть до момента очищения массива флагов 
//новых баров, все функции могут их видеть обращаясь к массиву напрямую.
//+------------------------------------------------------------------+
void Refresh_new_bar_events_table()
{
 for(int a1 = 0; a1 < All_symbols; a1++)
   {
    for(int a2 = 0; a2 < All_Timeframes; a2++)
      {
       New_Bar_Events[a1][a2] = false;
      }
   }
}
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//Пример использования событий нового бара в пользовательском функционал.
//Просто обращаемся к глобальному массиву "New_Bar_Events[a1][a2]" напрямую
//и используем событие в наших торговых алгоритмах.
//+------------------------------------------------------------------+
void Trading_on_new_bars_strategy()
{
  for(int a1 = 0; a1 < All_symbols; a1++)
   {
    string This_symbol    = Symbols[a1];
    //----------------------------------
    for(int a2 = 0; a2 < All_Timeframes; a2++)
      {
       bool   New_bar      = New_Bar_Events[a1][a2];
       int    This_timeframe = Timeframes[a2];
       //----------------------------------
       if(New_bar && This_symbol == "EURUSD" && This_timeframe == PERIOD_M1)
         {
          //Buy();
          Alert("New_bar !!!");
         }
       //---------------------------------- 
       if(New_bar && This_symbol == "AUDUSD" && This_timeframe == PERIOD_M30)
         {
          //Sell();
         }
       //----------------------------------        
      }
   }
}
//+------------------------------------------------------------------+


 
Реter Konow:

Here is a variant that prints on a minute on EURUSD:

It works, but you have to put it on a small timeframe.

Still, I must admit that the OOP solution looks nicer and there is a few times less code.

 
Vitaly Muzichenko:

This works, but you need to put it on a small timeframe.

Still, it's worth admitting that the OOP solution looks nicer, and there's a few times less code.

Use whatever you want.

Don't be ridiculous - it is not nice, not nice. Compare them in terms of resources consumption.

You don't have to put it on a small timeframe.

Instead:

 if(!Start_count && Last_Bar_Time != Time[0])Start_count = true; 
 //--------------------------- 
 if(Start_count)Current_period++;
 //--------------------------- 

Leave only:

Current_period++;
 
Vitaly Muzichenko:


... and the code is several times less.

Here is all the code for the solution:

//+------------------------------------------------------------------+
//|                                                  Новый бар 4.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
int    Periodicity = 25;
int    All_symbols;

string Symbols[];
int    Timeframes[7] = {PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1};
int    All_Timeframes = 7;


int    All_bars_table[][7];
int    New_Bar_Events[][7];

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetMillisecondTimer(25);
   //-------------------------------------------------------------   
   All_symbols = SymbolsTotal(true);
   //---------------------------------------------------------   
   ArrayResize(Symbols,All_symbols);
   //---------------------------------------------------------
   ArrayResize(All_bars_table,All_symbols);
   ArrayResize(New_Bar_Events,All_symbols);
   //---------------------------------------------------------
   for(int a1 = 0; a1 < All_symbols; a1++)Symbols[a1] = SymbolName(a1 + 1,true); 
   //---------------------------------------------------------
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
      
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
{
 static int  Current_period;
 //---------------------------
 Current_period++;
 //--------------------------- 
 if(Current_period*Periodicity >= 1000)
   {
    for(int a1 = 0; a1 < All_symbols; a1++)
      {
       string This_symbol = Symbols[a1];
       //---------------------------------
       for(int a2 = 0; a2 < All_Timeframes; a2++)
         {
          int This_timeframe = Timeframes[a2];
          //------------------------------------------
          int All_current_bars = iBars(This_symbol,This_timeframe);
          //------------------------------------------
          if(All_current_bars > All_bars_table[a1][a2])
            {
             if(All_bars_table[a1][a2])New_Bar_Events[a1][a2]  = true;
             All_bars_table   [a1][a2]  = All_current_bars;
            }
         }
      }
    //---------
    Current_period = 0;
   }
 //-----------------------------------------------
 
 //-----------------------------------------------
 if(!Current_period)Refresh_new_bar_events_table();
 //-----------------------------------------------  
}
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
void Refresh_new_bar_events_table()
{
 for(int a1 = 0; a1 < All_symbols; a1++)
   {
    for(int a2 = 0; a2 < All_Timeframes; a2++)
      {
       New_Bar_Events[a1][a2] = false;
      }
   }
}
//+------------------------------------------------------------------+


Don't forget about the hidden OOP code. There's less code because you can't see it!

 

If you need it, here is a working cross-platform function (for MT5 and MT4)

Unlike Peter's code works and is an order of magnitude faster.

//+---------------------------------------------------------------------------------------------------+
//|   Функция определения нового бара по всем ТФ всех инструментов в окне "Обзор рынка"               |
//|   два режима работы:                                                                              |
//|   - режим сбора информации, out=false (значение по умолчанию). Достаточно запустить IsNewBar();   |
//|   - режим вывода информации, out=true                                                             |
//|   tf - период таймфрейма, по умолчанию текущий ТФ (необходим только при выводе информации)        |
//|   Sym - символ инструмента, по умолчанию текущий символ (необходим только при выводе информации)  |
//+---------------------------------------------------------------------------------------------------+
bool IsNewBar(bool out=false,int tf=PERIOD_CURRENT,string Sym="")
  {
#ifdef __MQL5__
   static int allTF=21;
   static const ENUM_TIMEFRAMES TF[21]=
     {
      PERIOD_M1,PERIOD_M2,PERIOD_M3,PERIOD_M4,PERIOD_M5,PERIOD_M6,PERIOD_M10,PERIOD_M12,PERIOD_M15,PERIOD_M20,PERIOD_M30,
      PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1,PERIOD_W1,PERIOD_MN1
     };
#else
   static int allTF=9;
   static const ENUM_TIMEFRAMES TF[9]={PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1,PERIOD_W1,PERIOD_MN1};
#endif
   static bool New_Bar_Events[];
   static long All_bars_table[]; // array of current bars
   static int N_Sym=0;
   static string symbName[]; // массив имен символов
   if(Sym=="") Sym=Symbol();
   int total=SymbolsTotal(true);
   if(total!=N_Sym) // если первый раз, или добавлен, или удален новый символ
     {
      ArrayResize(symbName,total);
      for(int i=0; i<total; i++) symbName[i]=SymbolName(i,true);
      ArrayResize(All_bars_table,allTF*total); ArrayInitialize(All_bars_table,0);
      ArrayResize(New_Bar_Events,allTF*total); ArrayInitialize(New_Bar_Events,false);
      N_Sym=total;
     }
   int n_cur=-1;
   for(int i=0; i<total; i++) if(Sym==symbName[i]){ n_cur=i; break;}
   if(n_cur<0) { Print("данного символа нет в списке MarketWatch(окошко слева - Обзор рынка)"); return(false);}
   if(out && N_Sym>0) // если режим вывода информации 
     {
      int curtf=0;
      if(tf==PERIOD_CURRENT) tf=_Period;
      while(TF[curtf]!=tf) curtf++;
      return (New_Bar_Events[n_cur*allTF+curtf]);
     }
// режим сбора информации
   for(int j=0,j1=0; j<total; j++,j1+=allTF) // перебор символов
      for(int i=0;i<allTF;i++)               // перебор таймфреймов
        {
         #ifdef __MQL5__
         long CurBars=SeriesInfoInteger(symbName[j],TF[i],SERIES_LASTBAR_DATE);
         #else
         long CurBars=iTime(symbName[j],TF[i],0);
         #endif
         if(All_bars_table[j1+i]<CurBars) // пришел новый бар
           {
            //if (All_bars_table[j1+i]>0) Print ("Новый бар: "+SymbolName(j,true)+"   "+EnumToString(TF[i]));
            All_bars_table[j1+i]=CurBars;
            New_Bar_Events[j1+i]=true;
           }
         else                       // еще не пришел новый бар
           {
            New_Bar_Events[j1+i]=false;
            if(i==0) for(;i<allTF;i++) New_Bar_Events[j1+i]=false;   // если минутный бар тот же, то нет смысла продолжать проверять старшие ТФ
           }
        }
   return(false);
  }
Files:
 
Nikolai Semko:

If you need it, here is a working cross-platform function (for MT5 and MT4)

Unlike Peter's code, it works and is much faster.

The goal was one, but it achieved another...

If ... someone, the market overview shows ALL symbols, but works with only one ... I'd rather not say anything else...

Why are you trying to measure... code, the purpose was quite different.........

 
Alexey Viktorov:

The goal was one and the achievement of another...

If someone has... someone, the market overview shows ALL the symbols and only works with one... I'd rather not say anything else...

Why measure ... code, the goal was quite different.........

I was given a task: to make a way to get events of a new bar of a set of symbols, on a set of timeframes, without OOP, and to make it short and efficient code.

Now tell me - did I meet the objective?

 
Nikolai Semko:

If you need it, here is a working cross-platform function (for MT5 and MT4)

Unlike Peter's code, it works and is much faster.

Nikolai, I see that you have not neglected to use the names of my variables in your code:

New_Bar_Events

All_bars_table


I certainly do not mind, but why "lower" my code below yours? ))

It's not nice...

Reason: