Alternative implementations of standard functions/approaches - page 4

 
fxsaber:

A variant of CopyTicks, which is sometimes several orders of magnitude faster than the original (from > 0)

Build 1432 - CopyTicks alternative is no longer relevant.
 
fxsaber:
Build 1432 - the CopyTicks alternative is no longer relevant.

Where did the 1432 come from? I have the latest 1430 on MetaQuotes-Demo

 
Alexey Volchanskiy:

Where did the 1432 come from? I got the last 1430 on MetaQuotes-Demo.

He got it through a favor...
 
prostotrader:
He got it through a bribe...

You shouldn't laugh. I got one once.

 
Alexey Viktorov:

You shouldn't laugh. I was given one once.

What makes you think I'm laughing?
 
prostotrader:
What makes you think I'm laughing?
It seemed that way.
 

Forum on trading, automated trading systems and trading strategies testing

Features of mql5 language, subtleties and tricks

fxsaber, 2018.04.16 13:23

Much faster this option (Release, not Debug)

double StringToDouble2( const string Str, const uint StartPos = 0 )
{
  const uint Size = StringLen(Str);
  
  bool Sign = false;  
  uint i = StartPos;
  
  while (i < Size)
  {
    const int Digit = Str[i];

    if ((Digit != ' ') && (Digit != '\t') && (Digit != '\n') && (Digit != '\r'))
    {
      if ((Sign = (Digit == '-')) || (Digit == '+'))
        i++;
      
      break;
    }
      
    i++;
  }

  long Res = 0;
  int point = 0;
  
  while (i < Size)
  {
    const int Digit = Str[i];
    
    if (!point && (Digit == '.'))
      point = 1;
    else if (((Digit >= '0') && (Digit <= '9')))
    {
      Res = Res * 10 + Digit - '0';
      
      if (point)
        point *= 10;
    }
    else
      break;
      
    i++;
  }
  
  if (Sign)
    Res = -Res;
  
  return((point > 1) ? Res / (double)point : Res); // Возможна потеря точности при делении
}

When parsing voluminous data you get a significant speedup.

 
We returned to the idea of embedding the mass of simple system functions natively into the resulting MQL5 code, which allowed us to speed them up many times over by using them in the global optimization of the resulting code.

This applies to functions like NormalizeDouble, string operations, etc.

To be available in the next betas after next week's release.
 
Renat Fatkhullin:
We went back to the idea of embedding a mass of simple system functions natively in the resulting MQL5 code, which allowed us to speed them up many times over by using them in the global optimization of the resulting code.

OK.

 
fxsaber:

OK.

Welcome back!

ChartXYToTimePrice analog

It's not a full analogue (in terms of parameters), but this variant seems to me even more convenient and practical. It is also faster (by a couple of orders of magnitude).
By functionality it is full analogue and even more, because it returns (unlike original function) subwindow number, in which there is X, Y (cursor), if -1, then outside the window (subwindow).

This analogue doesn't contain input parameterschart_id andsub_window as I can't see how this function can be used outside the current window. Moreover, thesub_window parameter is even more unclear since the original function operates in exactly the same way regardless of its values.



// Fast Analog ChartXYToTimePrice function (https://www.mql5.com/ru/docs/chart_operations/chartxytotimeprice)
int XYToTimePrice(int x,int y,datetime &time,double &price,int id=0) // возвращает номер подокна в котором находится X,Y (курсор), если -1 - то вне окна
  {
   static int left_bar; // номер самого левого бара на экране
   static int Wid;
   static int Hei[10];
   static double y_min[10];
   static double y_max[10];
   static int PerSec=PeriodSeconds();
   static bool ChartChange=true;
   static int windowsTotal=(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL);
   static int Cur_wind=-1;
   static int WidthBar=int(1<<ChartGetInteger(0,CHART_SCALE));
   if(id==CHARTEVENT_CHART_CHANGE) if(!ChartChange) {ChartChange=true; return(Cur_wind);}
   if(ChartChange) // если было изменение чатра после последнего вычисления
     {
      windowsTotal=(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL);
      if(windowsTotal>10) {Print("Too many subwindows"); return(-1);}
      for(int i=0;i<windowsTotal;i++) if(i>0) Hei[i]=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,i)+Hei[i-1]+2;
      else Hei[0]=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0);
      left_bar=(int)ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR, 0);        // номер самого левого бара на экране
      Wid=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS, 0);               // ширина экрана в пикселях
      WidthBar=int(1<<ChartGetInteger(0,CHART_SCALE));                    // растояние между барами в пикселях
                                                                          
      for(int i=0;i<windowsTotal;i++)
        {
         y_min[i]=ChartGetDouble(0,CHART_PRICE_MIN, i);                         // макс. цена на экране
         y_max[i]=ChartGetDouble(0,CHART_PRICE_MAX, i);                         // мин. цена на экране
        }
     }
   if(x>(Wid+1) || x<0 || y<0 || y>=(Hei[windowsTotal-1]+1)) return(-1);  // выходим если точка (x,y) за пределами экрана
   Cur_wind=-1;
   if(y>=0 && y<=Hei[0]) Cur_wind=0;
   else if(windowsTotal>1) for(int i=1;i<windowsTotal;i++) if(y>(Hei[i-1]+1) && y<=Hei[i]) { Cur_wind=i; break; }
   if(Cur_wind>=0)
     {
      if(Cur_wind>0) y=y-Hei[Cur_wind-1]-2;
      int hh=Hei[Cur_wind];
      if(Cur_wind>0) hh-=Hei[Cur_wind-1]+2;
      price=y_min[Cur_wind]+(hh-y)*(y_max[Cur_wind]-y_min[Cur_wind])/hh;

      double NrBar=left_bar-(double)x/(double)WidthBar;
      datetime TT[2];
      if(NrBar>0) { CopyTime(NULL,0,(int)NrBar,2,TT); time=TT[0]+(datetime)((TT[1]-TT[0])*(1.0-NrBar+(int)NrBar)); }
      else        { CopyTime(NULL,0,0,1,TT);          time=TT[0]+(datetime)(fabs(NrBar)*PerSec); }
     }
   ChartChange=false;

   return(Cur_wind);
  }


This function can be run anywhere without the id parameter, but it must always be present in the OnChartEvent (with the id parameter) in order to clarify the necessity of updating internal variables of this function.

For example, if the function is not used from OnChartEvent, a line must be added to the OnChartEvent body for it to work properly:

if (id==CHARTEVENT_CHART_CHANGE) { double p=0; datetime t=0; XYToTimePrice(0,0,t,p,id);}
This analogue gives a noticeable benefit when this function is used quite often.
There is no point in using this analogue for one-off applications.
Files:
TestSpeedXY.mq5  15 kb