Implémentations alternatives de fonctions/approches standard - page 4

 
fxsaber:

Une variante de CopyTicks, qui est parfois plus rapide de plusieurs ordres de grandeur que l'original (de > 0)

Build 1432 - L'alternative CopyTicks n'est plus pertinente.
 
fxsaber:
Build 1432 - l'alternative CopyTicks n'est plus pertinente.

D'où vient le 1432 ? J'ai le dernier 1430 sur MetaQuotes-Demo.

 
Alexey Volchanskiy:

D'où vient le 1432 ? J'ai eu les 1430 derniers sur MetaQuotes-Demo.

Il l'a obtenu grâce à une faveur...
 
prostotrader:
Il l'a obtenu grâce à un pot-de-vin...

Tu ne devrais pas rire. J'en ai eu un une fois.

 
Alexey Viktorov:

Tu ne devrais pas rire. On m'en a donné un une fois.

Qu'est-ce qui te fait croire que je rigole ?
 
prostotrader:
Qu'est-ce qui te fait croire que je rigole ?
C'est ce qu'il semblait.
 

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading

Caractéristiques du langage mql5, subtilités et astuces

fxsaber, 2018.04.16 13:23

Beaucoup plus rapide avec cette option (Release, pas 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); // Возможна потеря точности при делении
}

Lors de l'analyse de données volumineuses, vous obtenez un gain de vitesse significatif.

 
Nous sommes revenus à l'idée d'intégrer nativement la masse des fonctions système simples dans le code MQL5 résultant, ce qui nous a permis de les accélérer plusieurs fois en les utilisant dans l'optimisation globale du code résultant.

Cela s'applique aux fonctions telles que NormalizeDouble, aux opérations sur les chaînes de caractères, etc.

Sera disponible dans les prochaines bêtas après la sortie de la semaine prochaine.
 
Renat Fatkhullin:
Nous avons repris l'idée d'intégrer une masse de fonctions système simples nativement dans le code MQL5 résultant, ce qui nous a permis de les accélérer plusieurs fois en les utilisant dans l'optimisation globale du code résultant.

OK.

 
fxsaber:

OK.

Bienvenue !

analogiqueChartXYToTimePrice

Il ne s'agit pas d'un analogue complet (en termes de paramètres), mais cette variante me semble encore plus commode et pratique. Il est également plus rapide (de quelques ordres de grandeur).
Par sa fonctionnalité, il est tout à fait analogue et même plus, car il retourne (contrairement à la fonction originale) le numéro de la sous-fenêtre, dans laquelle il y a X, Y (curseur), si -1, alors en dehors de la fenêtre (sous-fenêtre).

Cet analogue ne contient pas les paramètres d'entréechart_id etsub_window car je ne vois pas comment cette fonction peut être utilisée en dehors de la fenêtre actuelle. De plus, le paramètresub_window est encore plus flou puisque la fonction originale fonctionne exactement de la même manière quelle que soit sa valeur.



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


Cette fonction peut être exécutée n'importe où sans le paramètre id, mais elle doit toujours être présente dans le OnChartEvent (avec le paramètre id) afin de clarifier la nécessité de mettre à jour les variables internes de cette fonction.

Par exemple, si la fonction n'est pas utilisée depuis OnChartEvent, une ligne doit être ajoutée au corps de OnChartEvent pour qu'elle fonctionne correctement :

if (id==CHARTEVENT_CHART_CHANGE) { double p=0; datetime t=0; XYToTimePrice(0,0,t,p,id);}
Cette analogie donne un avantage notable lorsque cette fonction est utilisée assez souvent.
Il est inutile d'utiliser cet analogue pour des applications ponctuelles.
Dossiers :
TestSpeedXY.mq5  15 kb