Mt4 Fin de soporte. - página 20

 
Alexey Viktorov:
Es mejor no empezar por ahí. Esto es lo que te asusta. Incluso yo, un partidario de la POO que la conoce muy mal, tropecé por este texto... ...no entendía nada. Por eso intento explicar la diferencia en el nivel más bajo.

También puede ser más sencillo.

OOP - permite definir una única interfaz. Después, todas las cosas específicas de la plataforma se "esconden" y no interfieren con el trabajo.

Por supuesto, puede hacerlo con un enfoque puramente procedimental. Pero, soportar la variante procedimental será más complicado, debido a que en cada función tendremos que tratar con todas las plataformas a la vez.

 

Pido disculpas por el ligero retraso.

Esta es la primera versión de la función. Puedes perfeccionarla y desarrollarla aún más. Si alguien se da cuenta de un error, por favor, coméntelo.

//+------------------------------------------------------------------+
//|                                                    Новый бар.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//------------------------
datetime Время_последнего_бара;
//------------------------
//Счетчики
//------------------------
int Частота_таймера = 25;
int Минута;
int 5_Минут;
int 15_Минут;
int 30_Минут;
int 1_Час;
int 4_Часа;
int 1_День;
//------------------------
//Флаги
//------------------------
bool Новый_минутный_бар;
bool Новый_5_минутный_бар;
bool Новый_15_минутный_бар;
bool Новый_30_минутный_бар;
bool Новый_часовой_бар;
bool Новый_4_часовой_бар;
bool Новый_дневной_бар;
//--------------------------------------------
//Значения временных периодов в миллесекундах.
//--------------------------------------------
#define  M1    60000
#define  M5    300000
#define  M15   900000
#define  M30   1800000
#define  H1    3600000
#define  H4    14000000
#define  D1    84000000
//------------------------
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetMillisecondTimer(25);
   //-------------------------------------------------------------
   //Записываем время последнего бара на момент загрузки эксперта.  
   //Для корректного начала работы, робота нужно запустить на М1. 
   //-------------------------------------------------------------
   Время_последнего_бара = Time[0];
   //-------------------------------------------------------------
   
   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 Ведется_отсчет;
   //---------------------------
   if(!Ведется_отсчет && Time[0] != Время_последнего_бара) 
     {
      Ведется_отсчет = true;
     }   
   //---------------------------
   if(Ведется_отсчет)
     {
      Минута ++;
      5_Минут  ++;
      15_Минут ++;
      30_Минут ++;
      1_Час    ++;
      4_Часа   ++;
      1_День   ++;
      //--------------------------
      if(Минута*Частота_таймера >= M1)
        {
         Новый_минутный_бар = true;
         Минута = 0;
        } 
      //--------------------------
      if(5_Минут*Частота_таймера >= M5)
        {
         Новый_5_минутный_бар = true;
         5_Минут = 0;
        } 
      //--------------------------   
      if(15_Минут*Частота_таймера >= M15)
        {
         Новый_15_минутный_бар = true;
         15_Минут = 0;
        } 
      //--------------------------   
      if(30_Минут*Частота_таймера >= M30)
        {
         Новый_30_минутный_бар = true;
         30_Минут = 0;
        } 
      //--------------------------   
      if(1_Час*Частота_таймера >= H1)
        {
         Новый_часовой_бар = true;
         1_Час = 0;
        } 
      //--------------------------  
      if(4_Часа*Частота_таймера >= H4)
        {
         Новый_4_часовой_бар = true;
         4_Часа = 0;
        } 
      //--------------------------  
      if(1_День*Частота_таймера >= D1)
        {
         Новый_дневной_бар = true;
         1_День = 0;
        } 
   //-------------------------- 
   }          
}
//--------------------------





//--------------------------
bool Новый_бар(int Таймфрейм = M1)
{
 bool Новый_бар;
 //-----------------------
 switch(Таймфрейм)
   {
    case M1: 
          //-----------------------
          Новый_бар  = Новый_минутный_бар;
          if(Новый_бар)Новый_минутный_бар = false;
          return(Новый_бар);
          //-----------------------
          break;
    //-----------------------------      
    case M5: 
          //-----------------------
          Новый_бар  = Новый_5_минутный_бар;
          if(Новый_бар)Новый_5_минутный_бар = false;
          return(Новый_бар);
          //-----------------------
          break;
    //-----------------------------  
    case M15: 
          //-----------------------
          Новый_бар  = Новый_15_минутный_бар;
          if(Новый_бар)Новый_15_минутный_бар = false;
          return(Новый_бар);
          //-----------------------
          break;
    //-----------------------------  
    case M30: 
          //-----------------------
          Новый_бар  = Новый_30_минутный_бар;
          if(Новый_бар)Новый_30_минутный_бар = false;
          return(Новый_бар);
          //-----------------------
          break;
    //-----------------------------  
    case H1: 
          //-----------------------
          Новый_бар  = Новый_часовой_бар;
          if(Новый_бар)Новый_часовой_бар = false;
          return(Новый_бар);
          //-----------------------
          break;
    //-----------------------------      
    case H4: 
          //-----------------------
          Новый_бар  = Новый_4_часовой_бар;
          if(Новый_бар)Новый_4_часовой_бар = false;
          return(Новый_бар);
          //-----------------------
          break;
    //-----------------------------              
    case D1: 
          //-----------------------
          Новый_бар  = Новый_дневной_бар;
          if(Новый_бар)Новый_дневной_бар = false;
          return(Новый_бар);
          //-----------------------
          break;
    //-----------------------------     
   }
 //-----------------------
 return(false);
}
//--------------------------
//+------------------------------------------------------------------+
 
@Peter Konow incluso sin OOP puedes hacerlo más fácil, piénsalo y pruébalo.

Respetuosamente.
 
En cuanto el usuario llame a la función New_bar(), recibirá una respuesta de ésta sobre el evento de una nueva barra en el marco temporal solicitado. Al mismo tiempo, después de llamar a la función, si se ha producido un nuevo evento de barra - la bandera del evento se borra. Es decir, la notificación de una nueva barra del marco temporal deseado sólo puede recibirse una vez por barra. Después de recibir la notificación de una nueva barra, ésta deja de ser nueva.
 
Реter Konow:

Esta es la primera versión de la función. Puedes perfeccionarla y desarrollarla más. Si alguien se da cuenta de un error, por favor, coméntelo.

A primera vista, todo parece estar bien. No he cavado muy profundamente.

Personalmente, probablemente sólo dividiría el tiempo anterior y el actual por la duración de la barra, y si el valor ha cambiado, aparecería una nueva barra. Pero, también es posible hacerlo de esta manera.

En cuanto al estilo - personalmente me molesta un poco el hecho de que no se pueda saber qué tipo de variable es (estoy acostumbrado a la "notación húngara, cuando el prefijo de cualquier variable es una abreviatura de su tipo), pero tal vez eso sea innecesario.

 
Andrey Kisselyov:
@Peter Konow incluso sin OOP se puede hacer más fácil, piénsalo y pruébalo.

Respetuosamente.
Claro, es posible que sí. Tenía una hora para hacerlo. Puedes pensar en ello y recortar algo. Todo esto es posible.
 
Andrey Kisselyov:
@Peter Konow incluso sin OOP puedes hacerlo más sencillo, piénsalo y prueba.

Sinceramente.

Por lo que he entendido correctamente. El objetivo es que funcione. Si hubiera publicado un archivo protegido con esta función, nunca habrías adivinado que estaba escrito de esta manera.

 
George Merts:

A primera vista, todo parece estar bien. No he cavado lo suficiente.

Personalmente, probablemente dividiría el tiempo anterior y el actual por la duración de la barra, y si el valor ha cambiado, ha llegado una nueva barra. Pero, también es posible hacerlo de esta manera.

En cuanto al estilo - personalmente me molesta un poco el hecho de que no se pueda saber de qué tipo de variable se trata (estoy acostumbrado a la "notación húngara, cuando el prefijo de cualquier variable es una abreviatura de su tipo), pero quizás sea innecesario.

Bueno, la percepción del estilo es una cuestión de costumbre. A mí también me cuesta leer los códigos que se dan en las sucursales. Es que a veces me cabrea)).

 
George Merts:

También puede ser más sencillo.

OOP - permite definir una única interfaz. Después, todas las cosas específicas de la plataforma se "esconden" y no interfieren con el trabajo.

Por supuesto, puede hacerse con un enfoque puramente procesal. Pero, el apoyo a la variante procedimental sería más difícil, debido a que en cada función habría que tratar con todas las plataformas a la vez.

Ya se ha comentado que una única interfaz no es aplicable a la programación de cualquier tarea computacional... Poner cosas bonitas en forma de interfaces es un procedimiento puramente cosmético que sólo es aplicable al código ya terminado y que dificulta aún más el soporte y el refinamiento del código...

 
Mickey Moose:

Por lo que he entendido correctamente. El objetivo es que funcione. Si hubiera publicado un archivo protegido con esta función, nunca habríamos adivinado que estaba escrito de esta manera.

Es deseable que no sólo funcione, sino que lo haga de forma rápida, precisa, sin errores, que tenga una forma estructurada en la fuente y que esté claramente escrita.

Saludos cordiales.
Razón de la queja: