Implementaciones alternativas de funciones/enfoques estándar - página 4

 
fxsaber:

Una variante de CopyTicks, que a veces es varios órdenes de magnitud más rápida que la original (desde > 0)

Build 1432 - La alternativa CopyTicks ya no es relevante.
 
fxsaber:
Build 1432 - la alternativa CopyTicks ya no es relevante.

¿De dónde viene el 1432? Tengo el último 1430 en MetaQuotes-Demo

 
Alexey Volchanskiy:

¿De dónde viene el 1432? Tengo los últimos 1430 en MetaQuotes-Demo.

Lo consiguió a través de un favor...
 
prostotrader:
Lo consiguió a través de un soborno...

No deberías reírte. Una vez conseguí uno.

 
Alexey Viktorov:

No deberías reírte. Una vez me dieron uno.

¿Qué te hace pensar que me estoy riendo?
 
prostotrader:
¿Qué te hace pensar que me estoy riendo?
Eso parecía.
 

Foro sobre trading, sistemas de trading automatizados y pruebas de estrategias de trading

Características del lenguaje mql5, sutilezas y trucos

fxsaber, 2018.04.16 13:23

Mucho más rápida esta opción (Release, no 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); // Возможна потеря точности при делении
}

Cuando se analizan datos voluminosos se obtiene un aumento significativo de la velocidad.

 
Volvimos a la idea de incrustar la masa de funciones simples del sistema de forma nativa en el código MQL5 resultante, lo que nos permitió acelerarlas muchas veces al utilizarlas en la optimización global del código resultante.

Esto se aplica a funciones como NormalizeDouble, operaciones de cadena, etc.

Estará disponible en las próximas betas después del lanzamiento de la próxima semana.
 
Renat Fatkhullin:
Volvimos a la idea de incrustar una masa de funciones simples del sistema de forma nativa en el código MQL5 resultante, lo que nos permitió acelerarlas muchas veces al utilizarlas en la optimización global del código resultante.

DE ACUERDO.

 
fxsaber:

DE ACUERDO.

Bienvenido de nuevo.

ChartXYToTimePrice analógico

No es un análogo completo (en términos de parámetros), pero esta variante me parece aún más conveniente y práctica. También es más rápido (en un par de órdenes de magnitud).
Por funcionalidad es totalmente análogo y aún más, porque devuelve (a diferencia de la función original) número de subventana, en la que hay X, Y (cursor), si -1, entonces fuera de la ventana (subventana).

Este análogo no contiene los parámetros de entradachart_id ysub_window, ya que no veo cómo se puede utilizar esta función fuera de la ventana actual. Además, el parámetrosub_window es aún más confuso, ya que la función original opera exactamente igual independientemente de sus valores.



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


Esta función puede ejecutarse en cualquier lugar sin el parámetro id, pero siempre debe estar presente en el OnChartEvent (con el parámetro id) para aclarar la necesidad de actualizar las variables internas de esta función.

Por ejemplo, si la función no se utiliza desde OnChartEvent, hay que añadir una línea al cuerpo de OnChartEvent para que funcione correctamente:

if (id==CHARTEVENT_CHART_CHANGE) { double p=0; datetime t=0; XYToTimePrice(0,0,t,p,id);}
Este análogo da un beneficio notable cuando esta función se utiliza con bastante frecuencia.
No tiene sentido utilizar este análogo para aplicaciones puntuales.
Archivos adjuntos:
TestSpeedXY.mq5  15 kb
Razón de la queja: