Мт4 Конец поддержке. - страница 20

 
Alexey Viktorov:
С этого лучше не начинать. Именно это и отпугивает. Даже я, сторонник ООП плохо его знающий от этого текста встал в ступор... ничего не понял. Поэтому стараюсь объяснить разницу на самом низком уровне.

Можно и проще.

ООП - позволяет определить единый интерфейс. После чего - все платформоспецифические вещи "прячутся", и не мешают при работе. 

Это можно, конечно, сделать и в чисто процедурном подходе. Но, поддержка процедурного варианта будет сложнее, за счет того, что в каждой функции придется иметь дело со всеми платформами сразу.

 

Прошу прощения за небольшую задержку.

Вот первый вариант функции. Можно дорабатывать и развивать дальше. Если кто заметит ошибку, пожалуйста комментируйте.

//+------------------------------------------------------------------+
//|                                                    Новый бар.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);
}
//--------------------------
//+------------------------------------------------------------------+
 
@Реter Konow даже без ООП можно сделать проще, подумайте и попробуйте.

с уважением.
 
Как только пользователь вызывает функцию Новый_бар(), то он получает от нее ответ о событии нового бара на запрашиваемом таймфрейме. При этом, после вызова функции, если событие нового бара произошло, - флаг события снимается. То есть, получить уведомление о новом баре нужного таймфрейма можно только один раз за каждый бар. Ведь после получения уведомления о новом баре, этот бар уже новым не является.
 
Реter Konow:
 

Вот первый вариант функции. Можно дорабатывать и развивать дальше. Если кто заметит ошибку, пожалуйста комментируйте.

Навскидку - вроде все нормально. Глубоко не копал.

Лично я, наверно, просто делил бы предыдущее и текущее время на продолжительность бара, если значение изменилось - то пришел новый бар. Но, можно и так.

Что касается стиля - лично меня несколько напрягает, что по виду переменных нельзя определить, какого она типа (я привык к "венгерской нотации, когда префиксом любой переменной является сокращенное наименование ее типа), но, возможно, это излишне.

 
Andrey Kisselyov:
@Реter Konow даже без ООП можно сделать проще, подумайте и попробуйте.

с уважением.
Конечно, возможно что можно. У меня час был на это. Можно подумать и сократить что нибудь. Все это можно.
 
Andrey Kisselyov:
@Реter Konow даже без ООП можно сделать проще, подумайте и попробуйте.

с уважением.

Насколько я правильно понимаю. Цель - сделать так чтоб работало. Выложи бы он защищенный файл с этой функцией - в жизни бы не догадались что написана именно так.

 
George Merts:

Навскидку - вроде все нормально. Глубоко не копал.

Лично я, наверно, просто делил бы предыдущее и текущее время на продолжительность бара, если значение изменилось - то пришел новый бар. Но, можно и так.

Что касается стиля - лично меня несколько напрягает, что по виду переменных нельзя определить, какого она типа (я привык к "венгерской нотации, когда префиксом любой переменной является сокращенное наименование ее типа), но, возможно, это излишне.

Ну, восприятие стиля это дело привычки. Мне вот тоже тяжело читать коды приводимые на ветках. Просто бесит иногда.))

 
George Merts:

Можно и проще.

ООП - позволяет определить единый интерфейс. После чего - все платформоспецифические вещи "прячутся", и не мешают при работе. 

Это можно, конечно, сделать и в чисто процедурном подходе. Но, поддержка процедурного варианта будет сложнее, за счет того, что в каждой функции придется иметь дело со всеми платформами сразу.

Вроде ведь уже обсуждали, что единый интерфейс совершенно не применим для программирования любых вычислительных задач... Наведение красивостей в виде интерфейсов - это чисто косметическая процедура, которая применима только к уже готовому коду и которая к тому же мешает далее поддержке и доработке кода...

 
Mickey Moose:

Насколько я правильно понимаю. Цель - сделать так чтоб работало. Выложи бы он защищенный файл с этой функцией - в жизни бы не догадались что написана именно так.

желательно чтоб оно не просто работало, а работало быстро, точно, без ошибок, имело структурированный вид в исходнике и понятное написание.

с уважением.