표준 기능/접근법의 대체 구현 - 페이지 4

 
fxsaber :

CopyTicks의 변형으로 원본보다 몇 배 더 빠른 경우도 있습니다(> 0부터).

빌드 1432 - CopyTicks의 대안은 더 이상 관련이 없습니다.
 
fxsaber :
빌드 1432 - CopyTicks의 대안은 더 이상 관련이 없습니다.

1432는 어디에서 왔습니까? MetaQuotes-Demo에 최신 1430이 있습니다.

 
Alexey Volchanskiy :

1432는 어디에서 왔습니까? MetaQuotes-Demo에 최신 1430이 있습니다.

그들은 그에게 호의를 베풀었다 ...
 
prostotrader :
그들은 그에게 호의를 베풀었다 ...

정말 웃으시네요. 그들은 나에게 한 번 주었다.

 
Alexey Viktorov :

정말 웃으시네요. 그들은 나에게 한 번 주었다.

내가 웃는거 어디서 났어?
 
prostotrader :
내가 웃는거 어디서 났어?
그래서 보였다.
 

거래, 자동 거래 시스템 및 거래 전략 테스트에 관한 포럼

mql5 언어의 특징, 미묘함 및 작업 방법

fxsaber , 2018.04.16 13:23

이 옵션이 훨씬 빠름 (디버그가 아닌 릴리스)

 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); // Возможна потеря точности при делении
}

체적 데이터를 구문 분석할 때 상당한 가속이 얻어집니다.

 
우리는 결과 MQL5 코드에 기본적으로 많은 간단한 시스템 기능을 포함한다는 아이디어로 돌아갔고, 이를 통해 전역 최적화에서 결과 코드를 사용하여 1배의 속도를 낼 수 있었습니다.

이는 NormalizeDouble , 문자열 작업 등과 같은 함수에 적용됩니다.

다음 주 릴리스 후 다음 베타에서 사용할 수 있습니다.
 
Renat Fatkhullin :
우리는 결과 MQL5 코드에 기본적으로 많은 간단한 시스템 기능을 포함한다는 아이디어로 돌아갔고, 이를 통해 전역 최적화에서 결과 코드를 사용하여 1배의 속도를 낼 수 있었습니다.

확인.

 
fxsaber :

확인.

다시 오신 것을 환영합니다!

ChartXYToTimePrice 과 유사함

완전한 아날로그는 아니지만(매개변수 측면에서) 이 옵션이 훨씬 더 편리하고 실용적인 것 같습니다. 또한 더 빠릅니다(몇 배 정도).
기능면에서 그것은 완전한 아날로그이며 그 이상입니다. 원래 함수와 달리 X, Y(커서)가 있는 하위 창의 번호를 반환하고 -1이면 창 외부(하위 창)를 반환합니다.

이 아날로그에는 현재 창 외부에서 이 함수의 사용을 볼 수 없기 때문에 입력 매개변수 chart_idsub_window 가 없습니다. 게다가 sub_window 매개변수는 일반적으로 이해할 수 없습니다. 값에 관계없이 원래 기능은 정확히 동일하게 작동합니다.



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


이 함수는 id 매개변수 없이 어디에서나 시작할 수 있지만 이 함수의 내부 변수를 업데이트할 필요성을 결정하기 위해 OnChartEvent(id 매개변수 포함)에서 필수여야 합니다.

예를 들어 함수가 OnChartEvent에서 사용되지 않은 경우 OnChartEvent 본문에서 정상 작동하려면 다음 행을 추가해야 합니다.

 if (id== CHARTEVENT_CHART_CHANGE ) { double p= 0 ; datetime t= 0 ; XYToTimePrice( 0 , 0 ,t,p,id);}
이 아날로그는 이 기능을 충분히 자주 사용할 때 눈에 띄는 이득을 제공합니다.
일회성 통화의 경우이 아날로그를 사용하는 것은 의미가 없습니다.
파일:
TestSpeedXY.mq5  15 kb
사유: