Mt4结束支持。 - 页 20

 
Alexey Viktorov:
最好不要从那里开始。这就是把你吓跑的原因。即使是我,一个对OOP了解甚少的支持者,也因为这段文字而跌倒了。......什么都不明白。这就是为什么我试图在最低层次上解释两者的区别。

它也可以更简单。

OOP - 允许你定义一个单一的接口。此后,所有平台特有的东西都 "隐藏 "起来,不干扰工作。

当然,你可以用纯粹的程序性方法来做。但是,支持程序性变体将更加复杂,因为在每个函数中,我们将不得不同时处理所有平台。

 

我对稍有延迟表示歉意。

下面是该函数的第一个版本。你可以进一步完善和发展它。如果有人发现错误,请发表意见。

//+------------------------------------------------------------------+
//|                                                    Новый бар.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 即使没有OOP,你也可以让它变得更简单,想想看,试试吧。

恭敬地说。
 
一旦用户调用 New_bar()函数,他就会从该函数中收到关于在所要求的时间框架上出现新条形的事件的响应。同时,在该函数被调用后,如果发生了一个新的酒吧事件--事件标志被清除。也就是说,所需时间框架的新条形的通知,每个条形只能收到一次。在收到一个新酒吧的通知后,这个酒吧就不再是新的了。
 
Реter Konow:

下面是该函数的第一个版本。你可以进一步完善和发展它。如果有人发现错误,请发表意见。

乍一看,一切似乎都很好。我还没有深入挖掘。

我个人可能只是用前一个和当前的时间 除以条形持续时间,如果数值发生了变化,就会出现一个新的条形。但是,这样做也是可以的。

至于风格--我个人对你无法知道它是什么类型的变量感到有点困扰(我习惯于 "匈牙利符号,当任何变量的前缀是其类型的缩写时),但也许那是不必要的。

 
Andrey Kisselyov:
@Peter Konow 即使没有OOP也可以变得更容易,想一想,试试吧。

恭敬地说。
当然,有可能你可以。我有一个小时的时间来做这件事。你可以考虑一下,把一些东西砍下来。所有这些都是可能的。
 
Andrey Kisselyov:
@Peter Konow 即使没有OOP,你也可以把它变得更简单,仔细想想,试试吧。

真诚的。

就我的理解而言,是正确的。其目的是使其发挥作用。如果他用这个功能发布了一个受保护的文件,你绝对猜不到它是这样写的。

 
George Merts:

乍一看,一切似乎都很好。我还没有挖得够深。

就个人而言,我可能只是用前一个和当前的时间 除以条形图的持续时间,如果数值发生了变化,就说明一个新的条形图已经到来。但是,这样做也是可以的。

至于风格--我个人对你无法知道它是什么类型的变量感到有点困扰(我习惯于 "匈牙利符号,当任何变量的前缀是其类型的缩写时),但也许那是不必要的。

嗯,对风格的看法是一个习惯问题。我也发现很难读懂分支中给出的代码。它只是有时会让我生气。))

 
George Merts:

它也可以更简单。

OOP - 允许你定义一个单一的接口。此后,所有平台特有的东西都 "隐藏 "起来,不干扰工作。

当然,它也可以用纯粹的程序性方法来完成。但是,支持程序性变体将更加困难,因为在每个函数中,你必须同时处理所有平台。

前面已经讨论过,单一的界面不适用于任何计算任务的编程。把漂亮的东西放在接口的形式中,纯粹是一种表面程序,只适用于已经完成的代码,而且会进一步阻碍对代码的支持和完善......。

 
Mickey Moose:

就我的理解而言,是正确的。其目的是使其发挥作用。如果他用这个功能发布了一个受保护的文件,我们绝不会猜到它是这样写的。

理想的情况是,它不仅能工作,而且能快速、准确地工作,没有错误,在源头上有一个结构化的形式,而且写得很清楚。

最好的问候。