Mt4 End of support. - page 27

 
Реter Konow:
Linear, non-linear... Are you talking about opera in programming again?

no way.

 
Реter Konow:

OK. Your solution only works on ticks. Mine is on a timer. Do you think my method of timing with bar appearances has a drawback. Okay. Let it be like this. I will add a check for the arrival of a quote before setting a new bar flag. I will add another parameter to the function - a symbol. The user will choose the symbol by which they want to receive the new bar event and send it to the function. The function will check the time of the last quote of this symbol. Then we will compare the time of the bar formal appearance and the time of quotation and set the event flag.

I have just started studying this subject, but I do not see any difficulties.

Forum on trading, automated trading systems and strategy testing

Mt4 End of support.

Artyom Trishkin, 2017.09.10 22:27

I know how to get quotes :)

In a multi-currency program - in a timer in a loop on the right symbols. And the opening of a new bar (physical, not virtual - erroneous - as with you) is controlled by the time of the last quote and comparing that time with the time of the zero bar symbol.

You, on the other hand, are making at random - a virtual bar that may not exist. On the weekend they don't exist, but you supposedly have them - that's the simplest thing to give as an example.

And, you see, you're the only one who wouldn't do it that way. The rest of us do it the right and reliable way. But that, of course, is only your own business.

I wanted to tell you how to do it right and show the big difference in simplicity of writing in OOP and complicated twists in procedural style when solving the same task.

But you probably know more and don't need it. I don't dare to look like I know anything more. Sorry.


 
Galina Bobro:

No problem. Hedge to save comparison of string operations, well, if the customer is a maniac and will trade on all characters simultaneously.

But it seems there is nowhere else to save operations and memory - everything is minimal

void OnTimer(){

   Alert(Fn_new_bar("EURUSD", PERIOD_D1)); }

//+------------------------------------------------------------------+

uint Sp_Adler32(string line){

   ulong s1 = 1;

   ulong s2 = 0;

   uint buflength=StringLen(line);

   uchar char_array[];

   ArrayResize(char_array, buflength,0);

   StringToCharArray(line, char_array, 0, -1, CP_ACP);

   for (uint n=0; n<buflength; n++){

      s1 = (s1 + char_array[n]) % 65521;

      s2 = (s2 + s1)     % 65521;}

   return ((s2 << 16) + s1);}

//+------------------------------------------------------------------+

bool Fn_new_bar(string symb, ENUM_TIMEFRAMES tf){

   static datetime st_time[]; 

   static uint     st_id[];

   

   //---- set

   datetime new_time = iTime(symb, tf, 0);     if(new_time==0) return(false); 

   uint     new_id   = Sp_Adler32(StringConcatenate(symb,EnumToString(tf))); 

   datetime old_time = 0; 

   uint     old_id   = 0;

   

   //---- find

   int size = ArraySize(st_time); 

   for(int i=0; i<size; i++){

      if(st_id[i]!=new_id) continue; 

      old_id   = st_id  [i]; 

      old_time = st_time[i];

      break;}

   

   //----add new element

   if(old_time==0){

      ArrayResize(st_time, size+1); st_time[size]=new_time;

      ArrayResize(st_id,   size+1); st_id  [size]=new_id; }

   

   //----

   return(old_time>0 && old_time<new_time);}


It seems to be the most structurally sensible code so far. It has a check for a new symbol and a tf, does not check everything, but only what you need, no unnecessary operations, which means it should run pretty fast.

best regards.

P.S. the only little thing that could be added here is to combine the arrays st_time and st_id into a structure, as they are interrelated, this would reduce the number of array increment operations in the code.

 
Artyom Trishkin:

I had a goal to have his procedural style code end up working in a loop like this:

 ENUM_TIMEFRAMES array_timeframes[]=
      {
      PERIOD_M1,PERIOD_M2,PERIOD_M3,PERIOD_M4,PERIOD_M5,PERIOD_M6,PERIOD_M10,PERIOD_M12,PERIOD_M15,PERIOD_M30,
      PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1,PERIOD_W1,PERIOD_MN1
      };
   int total=SymbolsTotal(true), total_tf=ArraySize(array_timeframes);
   for(int i=0; i<total; i++){
      string symbol_name=SymbolName(i,true);
      for(int j=0; j<total_tf; j++){
         if(IsNewBar(symbol_name,array_timeframes[j])){
            Print("Новый бар на ",symbol_name," ",EnumToString(array_timeframes[j]));
            }
         }
      }


something like this (code for MQL5):

int OnInit()
  {
   IsNewBar();  // сбор информации - можно включить здесь, но не обязательно
   EventSetMillisecondTimer(100);
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   EventKillTimer();
  }

void OnTimer()
  {
   IsNewBar();   // сбор информации - можно включить здесь, но не обязательно
                 // различные варианты проверки новых баров
   if(IsNewBar(true)) Print("Пришел новый бар текущего ТФ текущего инструмента");   // режим вывода информации
   if(IsNewBar(true,PERIOD_H4)) Print("Пришел новый бар H4 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_D1)) Print("Пришел новый бар D1 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_M1,"GBPUSD.m")) Print("Пришел новый бар M1 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M3,"GBPUSD.m")) Print("Пришел новый бар M3 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M2,"USDCHF.m")) Print("Пришел новый бар M2 USDCHF");     // режим вывода информации
  }

void OnTick()
  {
   IsNewBar();   // сбор информации - можно включить здесь, но не обязательно
                 // различные варианты проверки новых баров
   if(IsNewBar(true)) Print("Пришел новый бар текущего ТФ текущего инструмента");   // режим вывода информации
   if(IsNewBar(true,PERIOD_H4)) Print("Пришел новый бар H4 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_D1)) Print("Пришел новый бар D1 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_M1,"GBPUSD.m")) Print("Пришел новый бар M1 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M3,"GBPUSD.m")) Print("Пришел новый бар M3 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M2,"USDCHF.m")) Print("Пришел новый бар M2 USDCHF");     // режим вывода информации
  }
//+---------------------------------------------------------------------------------------------------+
//|   Функция определения нового бара по всем ТФ всех инструментов в окне "Обзор рынка"               |
//|   два режима работы:                                                                              |
//|   - режим сбора информации, out=false (значение по умолчанию). Достаточно запустить IsNewBar();   |
//|   - режим вывода информации, out=true                                                             |
//|   tf - период таймфрейма, по умолчанию текущий ТФ (необходим только при выводе информации)        |
//|   Sym - символ инструмента, по умолчанию текущий символ (необходим только при выводе информации)  |
//+---------------------------------------------------------------------------------------------------+
bool IsNewBar(bool out=false, ENUM_TIMEFRAMES tf=PERIOD_CURRENT, string Sym="") 
  {
   static const ENUM_TIMEFRAMES TF[22]=
     {
      PERIOD_CURRENT,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
     };
   static bool newbar[];
   static long acb[]; // array of current bars
   static int N_Sym=0;
   if(Sym=="") Sym=Symbol();
   int total=SymbolsTotal(true);
   int n_cur=-1;
   for(int i=0; i<total; i++) if(Sym==SymbolName(i,true)){ n_cur=i; break;}
   if(n_cur<0) { Print("данного символа нет в списке MarketWatch(окошко слева - Обзор рынка)"); return(false);}
   if(out && N_Sym>0) // если режим вывода информации 
     {
      int curtf=0;
      while(TF[curtf]!=tf) curtf++;
      return (newbar[n_cur*22+curtf]);
     }
// режим сбора информации
   if (total!=N_Sym) {ArrayResize(acb,22*total);ArrayInitialize(acb,0); ArrayResize(newbar,22*total); ArrayInitialize(newbar,false); N_Sym=total;}
   for(int j=0,j1=0; j<total; j++,j1+=22)
      for(int i=0;i<22;i++)
        {
         long CurBars=SeriesInfoInteger(SymbolName(j,true),TF[i],SERIES_LASTBAR_DATE);
         if(acb[j1+i]<CurBars) // пришел новый бар
           {
            //if (acb[j1+i]>0) Print ("Новый бар: "+SymbolName(j,true)+"   "+EnumToString(TF[i]));
            acb[j1+i]=CurBars;
            newbar[j1+i]=true;
           }
         else
           {
            newbar[j1+i]=false;
            if(i==1) for(;i<22;i++) newbar[j1+i]=false;   // если минутный бар тот же, то нет смысла продолжать проверять старшие ТФ
           }
        }
   return(false);
  }

But I'll say it again - I'm a proponent of OOP.
Just a really unfortunate example to show what cannot be done in procedural programming.

 
Andrey Kisselyov:
It's not about calling a function in an EA, it's about writing universal interfaces (handlers).

you have 1000s of tasks to write robots; in fact, each of them consists of
1 function of obtaining a signal to open
2. function of order opening
3 function of order tracking
4) The function of receiving a signal to close an order.
and so on.
These functions are different for each robot, but they are repeated within 1000 projects. As a consequence, you can combine the functions into universal modules and, depending on the task, call the right one.

Well, if you have these functions, you don't need to do anything else. The input parameters of the function is the interface. Every extra intricacy increases the number of possible errors and increases the programmer's working time.

 
Nikolai Semko:

something like that (code for MQL5):

But I repeat - I'm a supporter of OOP.
It's just really an unfortunate example to show what cannot be done in procedural programming.

Is there such an example in principle? Even if not yours? I have deep doubts. In early 2000's I stopped counting the number of debugged and working lines of code, which I had written, because it exceeded a million - it became uninteresting. And I've never encountered a necessity to create my own class, although the variety and scale of my tasks were very diverse. I had to use procedure-type variables when it was necessary to parallelize work for several people but no more. Why so?

By the way, why do you speak of procedural programming as an alternative to OOP? There are languages without OOP, non-procedural in principle (SQL), there is even a direction of languages development - functional programming https://ru.wikipedia.org/wiki/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5:"Some concepts and paradigms are specific to functional programming and are mostly alien to imperative programming (including object-oriented programming)", "Another advantage of functional programs is that they provide vast opportunities for automatic It turns out that OOP prevents automatic paralleling of calculations. This should now be considered a very serious disadvantage, the perspective is not for OOP.

 
Vladimir:

Is there, in principle, an example of this? Even if not yours? I have deep doubts.


I think it is quite possible that such an example is not to be found. Personally, I believe that the main advantages of OOP are more convenient programming of large projects and a convenient mechanism for using your developments in the future. This has been rightly stated here many times before.

 
Andrei:

It has already been discussed that a single interface is not applicable to programming any computational tasks at all... Putting nice things in the form of interfaces is a purely cosmetic procedure, which is applicable only to already ready code and which also prevents further support and refinement of the code...

No. It's not "not applicable at all" but "there's no point in using them".

Interfaces are not "a purely cosmetic procedure applicable to ready-made code".

Quite the opposite - interfaces are at the core of the system's architecture. It's where the design starts. Interfaces do not "get in the way of support and rework" at all, but rather help them by clearly delineating the boundaries of what is permissible. If there are no interfaces, it is easy to cross these boundaries and make changes where they were not intended, resulting in hard to compute errors.

Any complex system (not only in programming) begins with the development of the basic principles of interaction between its parts. But in programming, because the initial task is usually very small, they go in the opposite direction. The parts are written first and then combined into a whole, often encountering the fact that the parts are not compatible with each other - by the way, this explains the desire to "have access to all available variables".

 

It's OK, except for the fact that the isNewBar() function shouldn't exist at all. It's funny that there's so much dancing around such a trivial thing.

It's just a variable, and it's simply compared to the time of the bar; if all the cases are successful, the variable is assigned the time of the new bar at the end. Otherwise only one attempt is allocated to all cases.

 
Dmitry Fedoseev:

It's OK, except for the fact that the isNewBar() function shouldn't exist at all. It's funny that there's so much dancing around such a trivial thing.

It's just a variable, and it's simply compared to the time of the bar; if all the cases are successful, the variable is assigned the time of the new bar at the end. Otherwise only one attempt is allocated to all cases.


+1