Mt4结束支持。 - 页 43

 
Реter Konow:

你的结果是什么?

你从哪里调用这个函数?


//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   Trading_on_new_bars_strategy();
  }
 
Vitaly Muzichenko:

1.将数组All_bars_table[][7]的bool类型改为int类型;在声明全局变量 的顶部。

2.把呼叫放到定时器上,在它说 "这是你的代码 "的地方。

现在我检查了一下,它对欧元兑美元有效。简而言之,它是有效的。

 

下面是在欧元兑美元分钟上打印的变体。

//+------------------------------------------------------------------+
//|                                                  Новый бар 4.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
datetime Last_Bar_Time;

int    Periodicity = 25;
int    All_symbols;

string Symbols[];
int    Timeframes[7] = {PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1};
int    All_Timeframes = 7;


int    All_bars_table[][7];
int    New_Bar_Events[][7];

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetMillisecondTimer(25);
   //-------------------------------------------------------------
   //Записываем время последнего бара на момент загрузки эксперта.  
   //Для корректного начала работы, робота нужно запустить на М1. 
   //-------------------------------------------------------------
   Last_Bar_Time = Time[0];
   //-------------------------------------------------------------   
   //Узнаем сколько символов есть в обзоре рынка.
   //---------------------------------------------------------
   All_symbols = SymbolsTotal(true);
   //---------------------------------------------------------   
   //Устанавливаем размер массива Symbols. Внутри него будут записаны
   //имена всех символов, которые есть в окне обзоре рынка.
   //---------------------------------------------------------
   ArrayResize(Symbols,All_symbols);
   //---------------------------------------------------------
   //Устанавливаем размеры массивов "All_bars_table[]" и "New_Bar_Events[]".
   //В массиве "All_bars_table[]" будет записыватся текущее количество баров каждого символа
   //и каждого таймфрейма. А в массиве "New_Bar_Events[]" устанавливаться флаги
   //события нового бара для каждого символа и каждого таймфрейма. 
   //---------------------------------------------------------
   ArrayResize(All_bars_table,All_symbols);
   ArrayResize(New_Bar_Events,All_symbols);
   //---------------------------------------------------------
   //Записываем наименования символов обзора рынка в массив "Symbols[]".
   //---------------------------------------------------------
   for(int a1 = 0; a1 < All_symbols; a1++)
     {
      Symbols[a1] = SymbolName(a1 + 1,true); 
      //Возможно, нумерация символов в обзора рынка идет с нуля.
      //Тогда: Symbols[a1] = SymbolName(a1,true);
     }
   //---------------------------------------------------------
   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 Start_count;
 static int  Current_period;
 //---------------------------
 //Нам нужен корректный старт отсчета. Это должно быть время начала бара.
 //---------------------------
 if(!Start_count && Last_Bar_Time != Time[0])Start_count = true; 
 //--------------------------- 
 if(Start_count)Current_period++;
 //--------------------------- 
 //В следующем цикле, мы будем обращатся к функции iBars для получения количества баров на 
 //каждом из символов и таймфреймов, которые будем проходить в цикле.
 //Далее, будем сравнивать записанное количество баров с текущим и при 
 //наличии разницы установим флаг события нового бара в массив "New_Bar_Events[]".
 //---------------------------
 if(Current_period*Periodicity >= 1000)
   {
    for(int a1 = 0; a1 < All_symbols; a1++)
      {
       string This_symbol = Symbols[a1];
       //---------------------------------
       for(int a2 = 0; a2 < All_Timeframes; a2++)
         {
          int This_timeframe = Timeframes[a2];
          //------------------------------------------
          int All_current_bars = iBars(This_symbol,This_timeframe);
          //------------------------------------------
          if(All_current_bars > All_bars_table[a1][a2])
            {
             //------------------------------------------------------------
             //Если это не самая первая запись в массив All_bars_table,
             //то фиксируем событие нового бара.
             //------------------------------------------------------------
             if(All_bars_table[a1][a2])
               {
                New_Bar_Events[a1][a2]  = true;
               } 
             //------------------------------------------------------------
             //Устанавливаем новое значение текущего количества баров.
             //------------------------------------------------------------
             All_bars_table   [a1][a2]  = All_current_bars;
            }
          //------------------------------------------
         }
      }
    //---------
    Current_period = 0;
   }
 //-----------------------------------------------
 //Здесь наш код...
 //Здесь наш код...
 //Здесь наш код...
 Trading_on_new_bars_strategy();
 //-----------------------------------------------
 //После завершения всех вызовов на этом событии таймера
 //снимаем флаги событий нового бара.
 if(!Current_period)Refresh_new_bar_events_table();
 //-----------------------------------------------  
}
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//Функция снимает флаги событий нового бара.
//Эта процедура осуществляется после выполнения всего пользовательского
//кода один раз в минуту. Вплоть до момента очищения массива флагов 
//новых баров, все функции могут их видеть обращаясь к массиву напрямую.
//+------------------------------------------------------------------+
void Refresh_new_bar_events_table()
{
 for(int a1 = 0; a1 < All_symbols; a1++)
   {
    for(int a2 = 0; a2 < All_Timeframes; a2++)
      {
       New_Bar_Events[a1][a2] = false;
      }
   }
}
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//Пример использования событий нового бара в пользовательском функционал.
//Просто обращаемся к глобальному массиву "New_Bar_Events[a1][a2]" напрямую
//и используем событие в наших торговых алгоритмах.
//+------------------------------------------------------------------+
void Trading_on_new_bars_strategy()
{
  for(int a1 = 0; a1 < All_symbols; a1++)
   {
    string This_symbol    = Symbols[a1];
    //----------------------------------
    for(int a2 = 0; a2 < All_Timeframes; a2++)
      {
       bool   New_bar      = New_Bar_Events[a1][a2];
       int    This_timeframe = Timeframes[a2];
       //----------------------------------
       if(New_bar && This_symbol == "EURUSD" && This_timeframe == PERIOD_M1)
         {
          //Buy();
          Alert("New_bar !!!");
         }
       //---------------------------------- 
       if(New_bar && This_symbol == "AUDUSD" && This_timeframe == PERIOD_M30)
         {
          //Sell();
         }
       //----------------------------------        
      }
   }
}
//+------------------------------------------------------------------+


 
Реter Konow:

这里有一个变体,在欧元兑美元的分钟上打印。

这很有效,但你必须把它放在一个小的时间框架内。

不过,我必须承认,OOP的解决方案看起来更漂亮,而且代码也少了几倍。

 
Vitaly Muzichenko:

这很有效,但你必须把它放在一个小的时间框架内。

不过,值得承认的是,OOP的解决方案看起来更漂亮,而且代码也少了几倍。

使用你想要的任何东西。

别傻了--这不好看,不好看。在资源消耗方面对它们进行比较。

你不必把它放在一个小的时间框架上。

而不是。

 if(!Start_count && Last_Bar_Time != Time[0])Start_count = true; 
 //--------------------------- 
 if(Start_count)Current_period++;
 //--------------------------- 

仅仅离开。

Current_period++;
 
Vitaly Muzichenko:


...而代码则少了好几倍。

这里是解决方案的所有代码。

//+------------------------------------------------------------------+
//|                                                  Новый бар 4.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
int    Periodicity = 25;
int    All_symbols;

string Symbols[];
int    Timeframes[7] = {PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1};
int    All_Timeframes = 7;


int    All_bars_table[][7];
int    New_Bar_Events[][7];

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetMillisecondTimer(25);
   //-------------------------------------------------------------   
   All_symbols = SymbolsTotal(true);
   //---------------------------------------------------------   
   ArrayResize(Symbols,All_symbols);
   //---------------------------------------------------------
   ArrayResize(All_bars_table,All_symbols);
   ArrayResize(New_Bar_Events,All_symbols);
   //---------------------------------------------------------
   for(int a1 = 0; a1 < All_symbols; a1++)Symbols[a1] = SymbolName(a1 + 1,true); 
   //---------------------------------------------------------
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
      
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
{
 static int  Current_period;
 //---------------------------
 Current_period++;
 //--------------------------- 
 if(Current_period*Periodicity >= 1000)
   {
    for(int a1 = 0; a1 < All_symbols; a1++)
      {
       string This_symbol = Symbols[a1];
       //---------------------------------
       for(int a2 = 0; a2 < All_Timeframes; a2++)
         {
          int This_timeframe = Timeframes[a2];
          //------------------------------------------
          int All_current_bars = iBars(This_symbol,This_timeframe);
          //------------------------------------------
          if(All_current_bars > All_bars_table[a1][a2])
            {
             if(All_bars_table[a1][a2])New_Bar_Events[a1][a2]  = true;
             All_bars_table   [a1][a2]  = All_current_bars;
            }
         }
      }
    //---------
    Current_period = 0;
   }
 //-----------------------------------------------
 
 //-----------------------------------------------
 if(!Current_period)Refresh_new_bar_events_table();
 //-----------------------------------------------  
}
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
void Refresh_new_bar_events_table()
{
 for(int a1 = 0; a1 < All_symbols; a1++)
   {
    for(int a2 = 0; a2 < All_Timeframes; a2++)
      {
       New_Bar_Events[a1][a2] = false;
      }
   }
}
//+------------------------------------------------------------------+


不要忘记隐藏的OOP代码。代码更少,因为你看不到它!

 

如果你需要,这里有一个跨平台的工作功能(适用于MT5和MT4)。

与彼得的代码不同,它可以工作,而且速度快一个数量级。

//+---------------------------------------------------------------------------------------------------+
//|   Функция определения нового бара по всем ТФ всех инструментов в окне "Обзор рынка"               |
//|   два режима работы:                                                                              |
//|   - режим сбора информации, out=false (значение по умолчанию). Достаточно запустить IsNewBar();   |
//|   - режим вывода информации, out=true                                                             |
//|   tf - период таймфрейма, по умолчанию текущий ТФ (необходим только при выводе информации)        |
//|   Sym - символ инструмента, по умолчанию текущий символ (необходим только при выводе информации)  |
//+---------------------------------------------------------------------------------------------------+
bool IsNewBar(bool out=false,int tf=PERIOD_CURRENT,string Sym="")
  {
#ifdef __MQL5__
   static int allTF=21;
   static const ENUM_TIMEFRAMES TF[21]=
     {
      PERIOD_M1,PERIOD_M2,PERIOD_M3,PERIOD_M4,PERIOD_M5,PERIOD_M6,PERIOD_M10,PERIOD_M12,PERIOD_M15,PERIOD_M20,PERIOD_M30,
      PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1,PERIOD_W1,PERIOD_MN1
     };
#else
   static int allTF=9;
   static const ENUM_TIMEFRAMES TF[9]={PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1,PERIOD_W1,PERIOD_MN1};
#endif
   static bool New_Bar_Events[];
   static long All_bars_table[]; // array of current bars
   static int N_Sym=0;
   static string symbName[]; // массив имен символов
   if(Sym=="") Sym=Symbol();
   int total=SymbolsTotal(true);
   if(total!=N_Sym) // если первый раз, или добавлен, или удален новый символ
     {
      ArrayResize(symbName,total);
      for(int i=0; i<total; i++) symbName[i]=SymbolName(i,true);
      ArrayResize(All_bars_table,allTF*total); ArrayInitialize(All_bars_table,0);
      ArrayResize(New_Bar_Events,allTF*total); ArrayInitialize(New_Bar_Events,false);
      N_Sym=total;
     }
   int n_cur=-1;
   for(int i=0; i<total; i++) if(Sym==symbName[i]){ n_cur=i; break;}
   if(n_cur<0) { Print("данного символа нет в списке MarketWatch(окошко слева - Обзор рынка)"); return(false);}
   if(out && N_Sym>0) // если режим вывода информации 
     {
      int curtf=0;
      if(tf==PERIOD_CURRENT) tf=_Period;
      while(TF[curtf]!=tf) curtf++;
      return (New_Bar_Events[n_cur*allTF+curtf]);
     }
// режим сбора информации
   for(int j=0,j1=0; j<total; j++,j1+=allTF) // перебор символов
      for(int i=0;i<allTF;i++)               // перебор таймфреймов
        {
         #ifdef __MQL5__
         long CurBars=SeriesInfoInteger(symbName[j],TF[i],SERIES_LASTBAR_DATE);
         #else
         long CurBars=iTime(symbName[j],TF[i],0);
         #endif
         if(All_bars_table[j1+i]<CurBars) // пришел новый бар
           {
            //if (All_bars_table[j1+i]>0) Print ("Новый бар: "+SymbolName(j,true)+"   "+EnumToString(TF[i]));
            All_bars_table[j1+i]=CurBars;
            New_Bar_Events[j1+i]=true;
           }
         else                       // еще не пришел новый бар
           {
            New_Bar_Events[j1+i]=false;
            if(i==0) for(;i<allTF;i++) New_Bar_Events[j1+i]=false;   // если минутный бар тот же, то нет смысла продолжать проверять старшие ТФ
           }
        }
   return(false);
  }
附加的文件:
 
Nikolai Semko:

如果你需要,这里有一个跨平台的工作功能(适用于MT5和MT4)。

与彼得的代码不同,它可以工作,而且速度更快。

目标是一个,但它实现了另一个...

如果...有人说,市场概览显示了所有的符号,但只适用于一个 ...我宁愿不说别的...

你为什么要测量...代码,目的是相当不同的.........

 
Alexey Viktorov:

目标是一个,实现的是另一个......

如果有人有...有人说,市场概览显示了所有的符号,只对一个符号起作用...我宁愿不说别的...

为什么要测量...代码,目标是相当不同的.........

我被赋予了一项任务:在不使用OOP的情况下,制作一种方法来获取一组符号的新条形图事件,并使其成为简短而有效的代码

现在告诉我--我是否达到了目标?

 
Nikolai Semko:

如果你需要,这里有一个跨平台的工作功能(适用于MT5和MT4)。

与彼得的代码不同,它可以工作,而且速度更快。

尼古拉,我看到你没有忽略在你的代码中使用我的变量的名字。

New_Bar_Events

All_bars_table


我当然不介意,但为什么把我的代码 "降低 "到你的下面?))

这不是很好...