Mt4 Fin de soporte. - página 43

 
Реter Konow:

¿Cuál es su resultado?

¿Desde dónde se llama a la función?


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

1. Sustituir el tipo bool por el tipo int del array All_bars_table[][7]; en la parte superior donde se declaran las variables globales.

2. Ponga la llamada al temporizador, donde dice "Aquí está su código".

Ahora lo he comprobado y funciona en el EURUSD. En resumen, funciona.

 

Esta es la variante que se imprime en el minuto del EURUSD:

//+------------------------------------------------------------------+
//|                                                  Новый бар 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:

Aquí hay una variante que se imprime en un minuto en EURUSD:

Funciona, pero hay que ponerlo en un plazo pequeño.

Aun así, debo admitir que la solución OOP se ve más bonita y hay unas cuantas veces menos código.

 
Vitaly Muzichenko:

Esto funciona, pero hay que ponerlo en un plazo pequeño.

Aun así, vale la pena admitir que la solución OOP tiene un aspecto más bonito, y hay unas cuantas veces menos código.

Usa lo que quieras.

No seas ridículo - no es agradable, no es agradable. Compárelos en términos de consumo de recursos.

No tienes que ponerlo en un plazo pequeño.

En su lugar:

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

Solo deja:

Current_period++;
 
Vitaly Muzichenko:


... y el código es varias veces menor.

Aquí está todo el código de la solución:

//+------------------------------------------------------------------+
//|                                                  Новый бар 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;
      }
   }
}
//+------------------------------------------------------------------+


No te olvides del código OOP oculto. Hay menos código porque no se ve.

 

Si lo necesitas, aquí tienes una función multiplataforma que funciona (para MT5 y MT4)

A diferencia del código de Peter, funciona y es un orden de magnitud más rápido.

//+---------------------------------------------------------------------------------------------------+
//|   Функция определения нового бара по всем ТФ всех инструментов в окне "Обзор рынка"               |
//|   два режима работы:                                                                              |
//|   - режим сбора информации, 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);
  }
Archivos adjuntos:
 
Nikolai Semko:

Si lo necesitas, aquí tienes una función multiplataforma que funciona (para MT5 y MT4)

A diferencia del código de Peter, funciona y es mucho más rápido.

El objetivo era uno, pero logró otro...

Pero si... alguien, la visión general del mercado muestra TODOS los símbolos, pero funciona con un solo ... Prefiero no decir nada más...

¿Por qué intentas medir... código, el propósito era bastante diferente.........

 
Alexey Viktorov:

El objetivo era uno y la consecución de otro...

Si alguien tiene... alguien, el resumen del mercado muestra TODOS los símbolos y sólo funciona con uno... Prefiero no decir nada más...

Por qué medir... código, el objetivo era bastante diferente.........

Se me encomendó una tarea: hacer una forma de obtener los eventos de una nueva barra de un conjunto de símbolos, en un conjunto de timeframes, sin OOP, y que sea un código corto y eficiente.

Ahora dígame: ¿he cumplido el objetivo?

 
Nikolai Semko:

Si lo necesitas, aquí tienes una función multiplataforma que funciona (para MT5 y MT4)

A diferencia del código de Peter, funciona y es mucho más rápido.

Nikolai, veo que no te has olvidado de utilizar los nombres de mis variables en tu código:

New_Bar_Events

All_bars_table


Ciertamente no me importa, pero ¿por qué "rebajar" mi código por debajo del suyo? ))

No es agradable...