Alternative Implementierungen von Standardfunktionen/-ansätzen - Seite 4

 
fxsaber:

Eine Variante von CopyTicks, die manchmal um mehrere Größenordnungen schneller ist als das Original (ab > 0)

Build 1432 - Die Alternative CopyTicks ist nicht mehr relevant.
 
fxsaber:
Build 1432 - die CopyTicks-Alternative ist nicht mehr relevant.

Woher stammt die Zahl 1432? Ich habe die neueste 1430 auf MetaQuotes-Demo

 
Alexey Volchanskiy:

Woher stammt die Zahl 1432? Ich habe die letzten 1430 auf MetaQuotes-Demo.

Er bekam es durch einen Gefallen...
 
prostotrader:
Er bekam sie durch Bestechung...

Sie sollten nicht lachen. Ich habe einmal eine bekommen.

 
Alexey Viktorov:

Sie sollten nicht lachen. Ich habe einmal eine bekommen.

Wie kommen Sie darauf, dass ich lache?
 
prostotrader:
Wie kommen Sie darauf, dass ich lache?
Es schien so.
 

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Merkmale der Sprache mql5, Feinheiten und Tricks

fxsaber, 2018.04.16 13:23

Diese Optionist viel schneller (Release, nicht 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); // Возможна потеря точности при делении
}

Beim Parsen umfangreicher Daten erhalten Sie einen erheblichen Geschwindigkeitszuwachs.

 
Wir kehrten zu der Idee zurück, die Masse der einfachen Systemfunktionen nativ in den resultierenden MQL5-Code einzubetten, was es uns ermöglichte, sie um ein Vielfaches zu beschleunigen, indem wir sie bei der globalen Optimierung des resultierenden Codes verwendeten.

Dies gilt für Funktionen wie NormalizeDouble, String-Operationen usw.

Wird in den nächsten Betas nach der Veröffentlichung in der nächsten Woche verfügbar sein.
 
Renat Fatkhullin:
Wir griffen auf die Idee zurück, eine Vielzahl einfacher Systemfunktionen nativ in den resultierenden MQL5-Code einzubetten, was es uns ermöglichte, diese Funktionen um ein Vielfaches zu beschleunigen, indem wir sie bei der globalen Optimierung des resultierenden Codes verwendeten.

GUT.

 
fxsaber:

GUT.

Willkommen zurück!

ChartXYToTimePrice analog

Es handelt sich zwar nicht um eine vollständige Analogie (in Bezug auf die Parameter), aber diese Variante scheint mir noch bequemer und praktischer zu sein. Sie ist auch schneller (um einige Größenordnungen).
Von der Funktionalität her ist sie völlig analog und sogar noch mehr, denn sie gibt (im Gegensatz zur Originalfunktion) die Nummer des Teilfensters zurück, in dem sich X, Y (Cursor) befinden, wenn -1, dann außerhalb des Fensters (Teilfenster).

Dieses Analogon enthält keine Eingabeparameterchart_id undsub_window, da ich nicht erkennen kann, wie diese Funktion außerhalb des aktuellen Fensters verwendet werden kann. Außerdem ist der Parametersub_window noch unklarer, da die ursprüngliche Funktion unabhängig von ihren Werten genau gleich funktioniert.



// 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);
  }


Diese Funktion kann überall ohne den id-Parameter ausgeführt werden, muss aber immer im OnChartEvent (mit dem id-Parameter) vorhanden sein, um die Notwendigkeit der Aktualisierung der internen Variablen dieser Funktion zu verdeutlichen.

Wenn die Funktion beispielsweise nicht von OnChartEvent aus verwendet wird, muss dem OnChartEvent-Körper eine Zeile hinzugefügt werden, damit sie richtig funktioniert:

if (id==CHARTEVENT_CHART_CHANGE) { double p=0; datetime t=0; XYToTimePrice(0,0,t,p,id);}
Diese Analogie bietet einen spürbaren Vorteil, wenn diese Funktion häufig verwendet wird.
Es macht keinen Sinn, dieses Analogon für einmalige Anwendungen zu verwenden.
Dateien:
TestSpeedXY.mq5  15 kb