Mt4 Ende der Unterstützung. - Seite 20

 
Alexey Viktorov:
Am besten fangen Sie gar nicht erst damit an. Das ist es, was Sie abschreckt. Sogar ich, ein Befürworter von OOP, der sich nur sehr schlecht auskennt, bin über diesen Text gestolpert... ...hat nichts verstanden. Deshalb versuche ich, den Unterschied auf der untersten Ebene zu erklären.

Es kann auch einfacher sein.

OOP - ermöglicht es Ihnen, eine einzige Schnittstelle zu definieren. Danach "verstecken" sich alle plattformspezifischen Dinge und stören die Arbeit nicht mehr.

Natürlich können Sie auch einen rein prozeduralen Ansatz wählen. Die Unterstützung der prozeduralen Variante wird jedoch komplizierter sein, da wir in jeder Funktion alle Plattformen auf einmal behandeln müssen.

 

Ich entschuldige mich für die leichte Verzögerung.

Hier ist die erste Version der Funktion. Sie können es weiter verfeinern und entwickeln. Wenn jemand einen Fehler bemerkt, bitte ich um einen Kommentar.

//+------------------------------------------------------------------+
//|                                                    Новый бар.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 auch ohne OOP kann man es einfacher machen, denken Sie darüber nach und versuchen Sie es.

Hochachtungsvoll.
 
Sobald der Benutzer die Funktion New_bar() aufruft, erhält er von ihr eine Antwort über das Auftreten eines neuen Balkens im gewünschten Zeitrahmen. Gleichzeitig wird nach dem Aufruf der Funktion das Ereignisflag gelöscht, wenn ein neues Bar-Ereignis eingetreten ist. Das heißt, die Benachrichtigung über einen neuen Balken des gewünschten Zeitrahmens kann nur einmal pro Balken empfangen werden. Nach Erhalt der Benachrichtigung über einen neuen Balken ist dieser nicht mehr neu.
 
Реter Konow:

Hier ist die erste Version der Funktion. Sie können es weiter verfeinern und entwickeln. Wenn jemand einen Fehler bemerkt, bitte ich um einen Kommentar.

Auf den ersten Blick scheint alles in Ordnung zu sein. Ich habe nicht sehr tief gegraben.

Ich persönlich würde wahrscheinlich einfach die vorherige und die aktuelle Zeit durch die Balkenlänge dividieren, und wenn sich der Wert geändert hat, würde ein neuer Balken erscheinen. Es ist aber auch möglich, es so zu machen.

Was den Stil betrifft, so stört mich persönlich die Tatsache, dass man nicht erkennen kann, um welchen Typ von Variable es sich handelt (ich bin an die "ungarische Notation" gewöhnt, bei der das Präfix jeder Variable eine Abkürzung ihres Typs ist), aber vielleicht ist das unnötig.

 
Andrey Kisselyov:
@Peter Konow auch ohne OOP kann man es einfacher machen, denken Sie darüber nach und versuchen Sie es.

Hochachtungsvoll.
Sicher, es ist möglich, dass Sie das können. Ich hatte dafür eine Stunde Zeit. Sie können darüber nachdenken und etwas streichen. All dies ist möglich.
 
Andrey Kisselyov:
@Peter Konow auch ohne OOP kann man es einfacher machen, überlege es dir und versuche es.

Mit freundlichen Grüßen.

Soweit ich es richtig verstanden habe. Das Ziel ist, dass es funktioniert. Hätte er eine geschützte Datei mit dieser Funktion gepostet, wären Sie nie auf die Idee gekommen, dass sie auf diese Weise geschrieben wurde.

 
George Merts:

Auf den ersten Blick scheint alles in Ordnung zu sein. Ich habe nicht tief genug gegraben.

Ich persönlich würde wahrscheinlich einfach die vorherige und die aktuelle Zeit durch die Dauer des Balkens dividieren, und wenn sich der Wert geändert hat, ist ein neuer Balken eingetroffen. Es ist aber auch möglich, es so zu machen.

Was den Stil betrifft, so stört mich persönlich die Tatsache, dass man nicht erkennen kann, um welchen Typ von Variable es sich handelt (ich bin an die "ungarische Notation" gewöhnt, bei der das Präfix jeder Variable eine Abkürzung ihres Typs ist), aber vielleicht ist das unnötig.

Nun, die Wahrnehmung von Stil ist eine Frage der Gewohnheit. Auch mir fällt es schwer, Codes in Zweigstellen zu lesen. Manchmal nervt es mich einfach.))

 
George Merts:

Es kann auch einfacher sein.

OOP - ermöglicht es Ihnen, eine einzige Schnittstelle zu definieren. Danach "verstecken" sich alle plattformspezifischen Dinge und stören die Arbeit nicht mehr.

Dies kann natürlich auch auf rein verfahrenstechnischem Wege geschehen. Die Unterstützung der prozeduralen Variante wäre jedoch schwieriger, da man sich in jeder Funktion mit allen Plattformen gleichzeitig befassen müsste.

Es wurde bereits erörtert, dass eine einzige Schnittstelle für die Programmierung beliebiger Rechenaufgaben nicht geeignet ist... Schöne Dinge in Form von Schnittstellen einzubauen ist ein rein kosmetisches Verfahren, das nur auf den bereits fertigen Code anwendbar ist und die Unterstützung und Verfeinerung des Codes weiter erschwert...

 
Mickey Moose:

Soweit ich es richtig verstanden habe. Das Ziel ist, dass es funktioniert. Wenn er eine geschützte Datei mit dieser Funktion gepostet hätte, wären wir nie auf die Idee gekommen, dass sie auf diese Weise geschrieben wurde.

Es ist wünschenswert, dass es nicht nur funktioniert, sondern dass es schnell, genau und fehlerfrei funktioniert, eine strukturierte Form in der Quelle hat und klar geschrieben ist.

Mit freundlichen Grüßen.