Mt4 Fine del supporto. - pagina 20

 
Alexey Viktorov:
È meglio non iniziare da lì. Questo è ciò che ti spaventa. Anche io, un sostenitore dell'OOP che lo conosce molto male, sono inciampato a causa di questo testo... ...non ha capito nulla. Ecco perché sto cercando di spiegare la differenza al livello più basso.

Può anche essere più semplice.

OOP - permette di definire una singola interfaccia. Dopo di che, tutte le cose specifiche della piattaforma si "nascondono" e non interferiscono con il lavoro.

Naturalmente, è possibile farlo con un approccio puramente procedurale. Ma, supportare la variante procedurale sarà più complicato, a causa del fatto che in ogni funzione dovremo trattare tutte le piattaforme contemporaneamente.

 

Mi scuso per il leggero ritardo.

Ecco la prima versione della funzione. Potete raffinarlo e svilupparlo ulteriormente. Se qualcuno nota un errore, si prega di commentare.

//+------------------------------------------------------------------+
//|                                                    Новый бар.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 anche senza OOP si può semplificare, pensaci e prova.

Con rispetto.
 
Non appena l'utente chiama la funzione New_bar(), riceverà da essa una risposta sull'evento di una nuova barra sul timeframe richiesto. Allo stesso tempo, dopo che la funzione è stata chiamata, se si è verificato un nuovo evento della barra - il flag dell'evento viene cancellato. Cioè, la notifica di una nuova barra del timeframe desiderato può essere ricevuta solo una volta per barra. Dopo aver ricevuto la notifica di una nuova barra, questa barra non è più nuova.
 
Реter Konow:

Ecco la prima versione della funzione. Potete raffinarlo e svilupparlo ulteriormente. Se qualcuno nota un errore, si prega di commentare.

A prima vista, tutto sembra essere a posto. Non ho scavato molto a fondo.

Personalmente, probabilmente dividerei semplicemente il tempo precedente e quello attuale per la durata della barra, e se il valore è cambiato, appare una nuova barra. Ma è anche possibile farlo in questo modo.

Per quanto riguarda lo stile - personalmente sono un po' infastidito dal fatto che non si può dire che tipo di variabile è (sono abituato alla "notazione ungherese, quando il prefisso di qualsiasi variabile è un'abbreviazione del suo tipo), ma forse non è necessario.

 
Andrey Kisselyov:
@Peter Konow anche senza OOP si può semplificare, pensaci e prova.

Con rispetto.
Certo, è possibile che sia così. Avevo un'ora per farlo. Puoi pensarci e tagliare qualcosa. Tutto questo è possibile.
 
Andrey Kisselyov:
@Peter Konow anche senza OOP puoi renderlo più semplice, pensaci e prova.

Sinceramente.

Se ho capito bene. L'obiettivo è di farlo funzionare. Se avesse pubblicato un file protetto con questa funzione, non avreste mai immaginato che fosse stato scritto in questo modo.

 
George Merts:

A prima vista, tutto sembra a posto. Non ho scavato abbastanza a fondo.

Personalmente, probabilmente dividerei semplicemente il tempo precedente e quello attuale per la durata della barra, e se il valore è cambiato, è arrivata una nuova barra. Ma è anche possibile farlo in questo modo.

Per quanto riguarda lo stile - personalmente sono un po' infastidito dal fatto che non si può dire che tipo di variabile è (sono abituato alla "notazione ungherese, quando il prefisso di qualsiasi variabile è un'abbreviazione del suo tipo), ma forse non è necessario.

Beh, la percezione dello stile è una questione di abitudine. Anche per me è difficile leggere i codici dei rami. Mi fa solo incazzare a volte)).

 
George Merts:

Può anche essere più semplice.

OOP - permette di definire una singola interfaccia. Dopo di che, tutte le cose specifiche della piattaforma si "nascondono" e non interferiscono con il lavoro.

Naturalmente può essere fatto con un approccio puramente procedurale. Ma, supportare la variante procedurale sarebbe più difficile, a causa del fatto che in ogni funzione si avrebbe a che fare con tutte le piattaforme contemporaneamente.

È già stato discusso che una singola interfaccia non è applicabile alla programmazione di qualsiasi compito computazionale... Mettere cose carine sotto forma di interfacce è una procedura puramente estetica che è applicabile solo al codice già completato e che ostacola ulteriormente il supporto e il perfezionamento del codice...

 
Mickey Moose:

Se ho capito bene. L'obiettivo è di farlo funzionare. Se avesse pubblicato un file protetto con questa funzione, non avremmo mai immaginato che fosse stato scritto in questo modo.

È auspicabile che non solo funzioni, ma che funzioni rapidamente, accuratamente, senza errori, che abbia una forma strutturata nella fonte e scritta chiaramente.

i migliori saluti.