Implementazioni alternative di funzioni/approcci standard - pagina 4

 
fxsaber:

Una variante di CopyTicks, che a volte è diversi ordini di grandezza più veloce dell'originale (da > 0)

Build 1432 - L'alternativa CopyTicks non è più rilevante.
 
fxsaber:
Build 1432 - l'alternativa CopyTicks non è più rilevante.

Da dove viene il 1432? Ho l'ultimo 1430 su MetaQuotes-Demo

 
Alexey Volchanskiy:

Da dove viene il 1432? Ho ottenuto l'ultimo 1430 su MetaQuotes-Demo.

L'ha ottenuto grazie a un favore...
 
prostotrader:
L'ha ottenuto con una tangente...

Non dovresti ridere. Ne ho avuto uno una volta.

 
Alexey Viktorov:

Non dovresti ridere. Una volta me ne hanno dato uno.

Cosa ti fa pensare che stia ridendo?
 
prostotrader:
Cosa ti fa pensare che stia ridendo?
Sembrava così.
 

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Caratteristiche del linguaggio mql5, sottigliezze e trucchi

fxsaber, 2018.04.16 13:23

Molto più veloce questa opzione (Release, non 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); // Возможна потеря точности при делении
}

Quando si analizzano dati voluminosi si ottiene un aumento significativo della velocità.

 
Siamo tornati all'idea di incorporare la massa di semplici funzioni di sistema nativamente nel codice MQL5 risultante, che ci ha permesso di velocizzarle molte volte usandole nell'ottimizzazione globale del codice risultante.

Questo vale per funzioni come NormalizeDouble, operazioni con le stringhe, ecc.

Sarà disponibile nelle prossime beta dopo il rilascio della prossima settimana.
 
Renat Fatkhullin:
Siamo tornati all'idea di incorporare una massa di semplici funzioni di sistema nativamente nel codice MQL5 risultante, il che ci ha permesso di velocizzarle molte volte usandole nell'ottimizzazione globale del codice risultante.

OK.

 
fxsaber:

OK.

Bentornato!

analogicoChartXYToTimePrice

Non è un'analogia completa (in termini di parametri), ma questa variante mi sembra ancora più conveniente e pratica. È anche più veloce (di un paio di ordini di grandezza).
Per funzionalità è un analogo completo e anche di più, perché restituisce (a differenza della funzione originale) il numero di sottofinestra, in cui c'è X, Y (cursore), se -1, allora fuori dalla finestra (sottofinestra).

Questo analogo non contiene i parametri di inputchart_id esub_window perché non vedo come questa funzione possa essere utilizzata al di fuori della finestra corrente. Inoltre, il parametrosub_window è ancora meno chiaro poiché la funzione originale opera esattamente allo stesso modo indipendentemente dai suoi valori.



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


Questa funzione può essere eseguita ovunque senza il parametro id, ma deve essere sempre presente nell'OnChartEvent (con il parametro id) per chiarire la necessità di aggiornare le variabili interne di questa funzione.

Per esempio, se la funzione non è usata da OnChartEvent, una linea deve essere aggiunta al corpo di OnChartEvent perché funzioni correttamente:

if (id==CHARTEVENT_CHART_CHANGE) { double p=0; datetime t=0; XYToTimePrice(0,0,t,p,id);}
Questo analogo dà un beneficio notevole quando questa funzione è usata abbastanza spesso.
Non ha senso usare questo analogo per applicazioni una tantum.
File:
TestSpeedXY.mq5  15 kb
Motivazione: