mql5 언어의 특징, 미묘함 및 작업 방법 - 페이지 89

 
니콜라이 셈코 :

  1. 내 이전 게시물을 참조하십시오
  2. 마이크로초를 실제로 사용한 예가 많이 있습니다.

지금까지 언급한 GetTickCount의 단점은 시스템 타이머 의 해상도에 의해 제한된다는 한 가지뿐입니다. 예, 이것은 심각한 문제입니다. 나머지는 거의 실용적이지 않습니다. 15밀리초라는 매우 짧은 테스트를 실행하고 있다는 사실 - 아무도 하지 않습니다. 이러한 결과는 불안정합니다. 테스트가 0.5초 이상 지속되어야 하며, 그런 다음 이미 무언가에 대해 이야기할 수 있습니다.

 
알렉세이 나보이코프 :

15밀리초라는 매우 짧은 테스트를 실행하고 있다는 사실 - 아무도 하지 않습니다. 이러한 결과는 불안정합니다. 테스트가 0.5초 이상 지속되어야 하며, 그런 다음 이미 무언가에 대해 이야기할 수 있습니다.

당신은 잘못. 이 15밀리초 동안 GetTickCount() 함수 는 6,000,000번 이상 호출됩니다.

내 계산이 맞습니다. GetTickCount() 값을 1/(2^6)=1/64초(15625마이크로초)마다 변경합니다.
개발자님 확인 부탁드립니다.

 
이콜라이 셈코 :

당신은 잘못. 이 15밀리초 동안 GetTickCount() 함수 는 6,000,000번 이상 호출됩니다.

작업 코드(진공 상태의 구형 말이 아님)의 성능이 측정되면 충분한 시간(수백 밀리초 이상) 동안 경주합니다. 이는 시스템의 성능과 작업 부하가 지속적으로 변하기 때문입니다. 그녀는 한 순간에 하나이고 다음 그녀는 다릅니다. 그리고 짧은 간격으로 결과는 테스트마다 크게 다를 것입니다. 따라서 더 긴 간격이 필요하며 마이크로초는 더 이상 역할을 하지 않습니다.

더 나아가. 견적은 밀리초 단위입니다. Ping도 밀리초 단위로 계산됩니다. 따라서 여기에 마이크로초를 첨부할 위치가 표시되지 않습니다. 그러나 이것이 요점이 아닙니다.

이제 우리는 두 기능의 단점을 극복하기 위해 상황에서 벗어나는 방법에 대한 솔루션을 마련해야 합니다. 개발자에게 희망은 거의 없습니다.

 
알렉세이 나보이코프 :

이제 우리는 두 기능의 단점을 극복하기 위해 상황에서 벗어나는 방법에 대한 솔루션을 마련해야 합니다. 개발자에게 희망은 거의 없습니다.

첫 번째 근사치에 대한 다음과 같은 공식으로 가능하다고 생각합니다.

 ulong RealGetMicrosecondCount=( GetTickCount ()-StartGetTickCount)*1000+x+ GetMicrosecondCount ()% 15625 ;

현재로서는 이것은 단지 생각일 뿐입니다.

 

마이크로초를 사용하는 일부 장소

  • 사용자 지정 TimeCurrent, 대략적인 정확도는 최대 ms입니다.
  • 거래 주문 의 실행 시간 계산 .
  • 터미널에서 거래 내역 동기화 시간 계산.
  • 터미널 지연(~ 5ms) - OnTick/OnCalculate 시점까지 틱이 몇 살인지.
  • 모든 시간 이벤트 사이의 거리가 지정된 시간의 배수가 되도록 OnTimer를 조정합니다.
 
fxsaber :

마이크로초를 사용하는 일부 장소

  • 모든 시간 이벤트 사이의 거리가 지정된 시간의 배수가 되도록 OnTimer를 조정합니다.

따라서 타이머는 먼저 밀리초입니다. 둘째, 그 오류는 GetTickCount() 와 동일합니다. 15밀리초. 따라서 여기서 마이크로초의 요점이 무엇인지는 명확하지 않습니다. 마이크로의 정확도로 간격을 계산했다고 가정해 봅시다.

 
알렉세이 나보이코프 :

따라서 타이머는 먼저 밀리초입니다. 둘째, 그 오류는 GetTickCount()와 동일합니다. 15밀리초. 따라서 여기서 마이크로초의 요점이 무엇인지는 명확하지 않습니다. 마이크로의 정확도로 간격을 계산했다고 가정해 봅시다.


명령이 대기열에 있고 차례로 실행은 5초가 될 수 있습니다.

 
알렉세이 나보이코프 :

이제 우리는 두 기능의 단점을 극복하기 위해 상황에서 벗어나는 방법에 대한 솔루션을 마련해야 합니다. 개발자에게 희망은 거의 없습니다.


아아.
이 옵션만 제안할 수 있습니다.

 ulong RealMicrosecondCount()
  {
   static bool first= true ;
   static ulong sum= 0 ;
   static long delta;
   static long shift= 0 ;
   static ulong   lasttickcount;
   ulong i= GetTickCount ()+sum;
   ulong t= GetMicrosecondCount ();
   if (first) // если первый вход, то вычисляем разницу GetMicrosecondCount и GetTickCount
     {
      lasttickcount=i;
      delta=(( long )i* 1000 - long (t));
      first= false ;
     }
   long curdelta=(( long )i* 1000 - long (t));
   long d=curdelta-delta;
   if ( fabs (d-shift)> 20000 ) shift=d;
   if (i<lasttickcount) sum+= 0x100000000 ;
   lasttickcount=i;
   return (t+shift);
  }

왜 그래?
현지 시간 이 변경되거나 소프트웨어가 정지되는 경우 RealMicrosecondCount 함수에 최대 16밀리초의 오류가 추가될 수 있기 때문입니다. 이 문제를 해결할 방법이 없습니다.
그러나 반면에 겨울(여름) 시간으로 전환하거나 벨트를 교체하거나 인터넷을 통해 시간을 업데이트할 때 치명적인 결과는 없습니다.

 
니콜라이 셈코 :


아아.
이 옵션만 제안할 수 있습니다.

왜 그래?
현지 시간이 변경되거나 소프트웨어가 정지되는 경우 RealMicrosecondCount 함수에 최대 16밀리초의 오류가 추가될 수 있기 때문입니다. 이 문제를 해결할 방법이 없습니다.
그러나 반면에 겨울(여름) 시간으로 전환하거나 벨트를 교체하거나 인터넷을 통해 시간을 업데이트할 때 치명적인 결과는 없습니다.

아직 테스트하지 않았지만 16ms에 대해 잘 모르겠습니다. 이 주제에 대해 구글링했을 때 시스템 타이머 의 오류는 일반적으로 약 10ms 또는 10-16으로 제공됩니다.

 

다음 은 3.8e-07 초의 정확도를 제공하는 고해상도 winapi 타이머를 사용하는 변형입니다.

 #import "Kernel32.dll"
   int QueryPerformanceCounter( ulong &lpPerformanceCount);
   int QueryPerformanceFrequency( ulong &lpFrequency);
#import


ulong QueryPerfomanceCounter() { ulong value;   if (QueryPerformanceCounter(value)) return value;   return 0 ; } 

ulong QueryPerformanceFrequency() { ulong freq;   if (QueryPerformanceFrequency(freq)) return freq;   return 0 ; }  


long GetPerfomanceCount_mcs()
{ 
   static long freq= QueryPerformanceFrequency();
   return freq ? QueryPerfomanceCounter()* 1000000 /freq : 0 ;
}


void OnStart ()
{
   Print ( "Resolution of perfomance counter:  " , 1.0 /QueryPerformanceFrequency(), " s" );
   ulong   perfcount= GetPerfomanceCount_mcs(); 
  
   while (! IsStopped ())
  {
     Comment ((GetPerfomanceCount_mcs()-perfcount)/ 1000000.0 );
     Sleep ( 10 );
  }
}
사유: