기능 수면 대안

 

안녕하세요 MQL4 커뮤니티 여러분,

전략 테스터 에서 Sleep() 함수를 포함하는 EA를 실행하는 동안 문제가 발생했습니다. 분명히 테스터는 코드에 포함된 함수 Sleep()을 포함하여 EA를 제대로 실행하지 않을 것입니다.

참석한 코더가 EA가 테스터에서 실행되는 동안 특정 시간 동안 "대기"하도록 EA를 코딩하기 위해 함수 Sleep()에서 대체 방법을 발견한 적이 있습니까?


고맙습니다

 
WhooDoo22 :

안녕하세요 MQL4 커뮤니티 여러분,

전략 테스터에서 Sleep() 함수를 포함하여 EA를 실행하는 동안 문제가 발생했습니다. 분명히 테스터는 코드에 포함된 함수 Sleep()을 포함하여 EA를 제대로 실행하지 않을 것입니다.

참석한 코더가 EA가 테스터에서 실행되는 동안 특정 시간 동안 "대기"하도록 EA를 코딩하기 위해 함수 Sleep()에서 대체 방법을 발견한 적이 있습니까?

Strategy Tester 에서 sleep()이 작동하는 논리적인 이유는 없습니다. . . 당신은 무엇을 하려고 합니까? 이벤트 시간을 측정하려는 경우 시간을 사용하고 필요한 시간 동안 일시 중지하려고 하지 마십시오. 이것이 sleep()의 목적이 아닙니다.
 

사이먼,

내가 'Sleep()' 함수 를 사용하기로 선택한 이유는 Seconds()가 마지막으로 알려진 서버 시간에서 값을 반환하기 때문입니다(마지막으로 알려진 서버 시간에서 데이터를 검색하면 초가 건너뛰거나 일시 중지됨). 나는 보편성이 아니라 신뢰성을 원한다.

이에 대해 뭐라고 합니까?


고맙습니다

 
WhooDoo22 :

사이먼,

내가 'Sleep()' 함수를 사용하기로 선택한 이유는 Seconds()가 마지막으로 알려진 서버 시간에서 값을 반환하기 때문입니다(마지막으로 알려진 서버 시간 에서 데이터를 검색하면 초가 건너뛰거나 일시 중지됨).

이것에 대한 당신의 증거는 무엇입니까? 틱이 있는 시간에 대해서만 시간을 "볼" 수 있습니다. 30초 동안 틱이 없으면 30초 건너뛰기가 표시됩니다. . . 당신이 이것에 대해 할 수 있는 것은 아무것도 없습니다. 전략 테스터 의 틱 시간은 틱이 실제가 아니라 합성이므로 합리적으로 균일해야 합니다.
 

사이먼,

따라서 내가 이러한 "건너뛰기" 및/또는 "일시 중지"라고 부르는 이유는 [초 x]와 [초 y] 사이에 틱이 생성되지 않기 때문입니다. 평신도 용어로 틱이 생성되고 이제 '초 x'가 저장됩니다. 3초 동안 틱이 생성되지 않은 다음 틱이 생성됩니다. 이제 '초 y'가 저장됩니다. ('초 y' = (초 x +3초)) as ('초 x' = (초 y-3초)).

이에 대해 뭐라고 합니까?


당분간 옵션을 고려하겠습니다.

귀하의 응답에 감사드립니다.

 
  1. 처음부터 돌아올 때까지. 테스터에서 틱이 생성되지 않습니다. TimeCurrent()를 static/common(global) 변수에 저장합니다. 다음 틱 int deltaSec = TimeCurrent() - 이전.
  2. https://www.mql5.com/en/forum/127483 은 DayOfWeek()가 테스터에서 항상 5를 반환한다고 보고했습니다(Ask 및 Bid와 같이 지표에서는 확실히 동일하지 않음). 현재 서버 시간을 원하지 않고 테스터의 틱 시간을 원하기 때문에 Seconds(), DayOfWeek() 등을 사용하지 않습니다. 지금 = TimeCurrent(), 초 = TimeSeconds(지금); int DOW=TimeDayOfWeek(지금) ..
 
WhooDoo22 :

사이먼,

따라서 내가 이러한 "건너뛰기" 및/또는 "일시 중지"라고 부르는 이유는 [초 x]와 [초 y] 사이에 틱이 생성되지 않기 때문입니다. 평신도 용어로 틱이 생성되고 이제 '초 x'가 저장됩니다. 3초 동안 틱이 생성되지 않은 다음 틱이 생성됩니다. 이제 '초 y'가 저장됩니다. ('초 y' = (초 x +3초)) as ('초 x' = (초 y-3초)).

이에 대해 뭐라고 합니까?

예, 실제 세계에서와 같이 틱 사이에 3초가 쉽게 있을 수 있습니다. 자정 GMT의 통화 쌍을 살펴보면 틱 사이에 여러 초가 큰 것을 볼 수 있습니다. . . 당신은 1분 이상 틱이 없고 M1 막대가 누락될 수도 있습니다. . . 드문 일이 아닙니다.
 

윌리엄,

귀하의 응답에 감사드립니다.

1. 처음부터 돌아올 때까지. 테스터에서 틱이 생성되지 않습니다. TimeCurrent()를 static/common(global) 변수에 저장합니다. 다음 틱 int deltaSec = TimeCurrent() - 이전.

"처음부터 다시 돌아올 때까지"가 무슨 말인지 이해가 되지 않습니다. 설명해 주시겠습니까?


"테스터에서 틱이 생성되지 않습니다."

테스터에서 실제 틱이 생성되지 않는다는 뜻이 아닙니다. 테스터에서 인공 진드기가 생성된다는 데 동의하지 않습니까?


"정적/공통(전역) 변수에 TimeCurrent()를 저장합니다. 다음 틱 int deltaSec = TimeCurrent() - 이전."

TimeCurrent()를 변수에 저장합니다 . 다음 틱이 도착하면 int deltaSec =TimeCurrent() - 이전.

"이전" 변수는 TimeCurrent()가 저장되는 변수가 아닌가요...

deltaSec = TimeCurrent() - ( 이전에 변수에 저장된 TimeCurrent() )

윌리엄을 명확히 해주세요.


https://www.mql5.com/en/forum/127483 은 DayOfWeek()가 테스터에서 항상 5를 반환한다고 보고했습니다. 나는 현재 서버 시간을 원하고 테스터의 눈금 시간을 원하기 때문에 Seconds(), DayOfWeek() 등을 사용하지 않습니다. 지금 = TimeCurrent(), 초 = TimeSeconds(지금); int DOW=TimeDayOfWeek(지금) ..


"당신은 테스터의 틱 시간을 원합니다."

네, 저는 이것이 전략 테스터에서 EA를 테스트할 때 정확히 제가 원하는 것이라고 믿습니다. 왜냐하면 초가 건너뛰거나 일시 중지되는 이유를 설명하는 Simon의 게시물 때문입니다.


지금 = TimeCurrent(), 초 = TimeSeconds(지금); int DOW=TimeDayOfWeek(지금) ..

다시 말해...

초 = TimeSeconds(TimeCurrent()); 및 DOW = TimeDayOfWeek(TimeCurrent());

이에 대해 뭐라고 합니까?


고맙습니다
 
WhooDoo22 :

지금 = TimeCurrent(), 초 = TimeSeconds(지금); int DOW=TimeDayOfWeek(지금) ..

다시 말해...

초 = TimeSeconds(TimeCurrent()); 및 DOW = TimeDayOfWeek(TimeCurrent());

TimeSeconds()가 제공하는 것을 살펴본 다음 TimeCurrent()가 제공하는 것을 생각하십시오. . . 어느 것이 필요하고 그 이유는 무엇입니까?
 
WhooDoo22 :

"처음부터 다시 돌아올 때까지"가 무슨 말인지 이해가 되지 않습니다. 설명해 주시겠습니까?"

테스터에서 틱이 생성되지 않습니다." 테스터에서 실제 틱이 생성되지 않는다는 뜻이 아닙니다. 테스터에서 인공 틱이 생성된다는 데 동의하지 않습니까?

  1.  int start(){
       // do something
       return ; // Return from start.
    }
     int start(){
       // do something
       // Fall off the end is a Return from start.
    }

  2. 반환할 때까지 어떤 종류의 틱도 생성되지 않으며 다음 틱을 생성하고 start()를 호출합니다. 5분 동안 계산하고 반환하면 다음 호출의 볼륨(틱 수)은 +1이 됩니다. 라이브 차트에서 5분 동안 계산하면 5분의 틱을 놓치고 M1에서 여러 개의 새로운 막대가 형성됩니다.
 
RaptorUK :
Strategy Tester에서 sleep()이 작동하는 논리적인 이유는 없습니다...

그런 말을 조심하십시오. sleep()을 실행하는 논리적인 이유가 항상 있습니다. 테스터와 지표에서도. 맞습니다. OP의 사용 사례의 경우 수면을 가지고 놀면 안되지만 모든 MQL에 대해 일반화할 수는 없습니다.

테스터에서 언제 자야 합니까? 예를 들어 테스트 중인 EA와 상호 작용하는 스크립트를 테스트하는 경우 상태를 동기화해야 할 수도 있습니다. 나는 뮤텍스에 대해 이야기하고 있습니다. 깨끗한 방법으로 뮤텍스를 획득하려면 두 부분 모두 대기 기능이 필요합니다. 수면을 사용합니다.

지표에 대해서도 마찬가지입니다. 표시기가 UI 스레드에서 실행되는 것은 중요하지 않습니다. 두 스레드가 동기화해야 하는 경우 둘 다 "잠자기" 기능이 필요합니다. 그리고 sleep()은 주어진 양의 CPU 주기를 기다려야 하는 경우 유일한 깨끗한 솔루션입니다. "for" 구문은 지식 부족을 보여줍니다.

자, 실용적인 예를 들어 보겠습니다. 내 EA는 주문 상태를 표시할 수 있습니다(자가 그린 화살표 등). 그들은 차트 개체의 텍스트 설명을 통해 "보내진" 외부 명령(1-보류 주문, 2-오픈 포지션, 3-닫힌 거래, 4-모두 함께)에 응답하여 이를 수행하므로 차트 명령이라고 부릅니다. 또는 다른 명령("시작", "중지", "재개")에 응답하여 일련의 거래를 시작/중지/재개할 수 있습니다. 명령을 읽으려면 해당 차트 개체에 대한 액세스를 동기화해야 합니다(차트 개체 생성 + 텍스트 속성 설정은 하나의 원자적 작업이 아닙니다). 물론 Tester에서 이 동작을 테스트하고 싶으므로 대기를 위해 sleep()이 필요합니다.

테스터 또는 온라인에서 실행되는 지표와 동일합니다. 그들이 비슷한 일을한다면 깨끗한 상태를 얻기 위해 UI 스레드를 "중단해야"합니다. 10밀리초는 중요하지 않습니다. btw: 깨끗한 뮤텍스 구현은 이미 대기 중인 시간을 확인하고 루프를 벗어나 몇 초 후에 동기화 잠금을 얻을 수 없는 경우 오류 신호를 보냅니다.

 int seconds;

// run until the lock is aquired
while ( true ) {
   ...
   // warn every second and cancel after 10 seconds
   duration = GetTickCount () - startTime;
   if (duration >= seconds* 1000 ) {
       if (seconds >= 10 )
         return (_false(catch( "AquireLock(5)   failed to get lock for mutex \"" + mutexName + "\" after " + DoubleToStr(duration/ 1000.0 , 3 ) + " sec., giving up" , ERR_RUNTIME_ERROR)));
      warn( StringConcatenate ( "AquireLock(6)   couldn't get lock for mutex \"" , mutexName, "\" after " , DoubleToStr(duration/ 1000.0 , 3 ), " sec., retrying..." ));
      seconds++;
   }
   //debug("AquireLock()   couldn't get lock for mutex \""+ mutexName +"\", retrying...");

   if (IsTesting() || IsIndicator()) SleepEx( 100 , true );           // expert or indicator under test
   else                                Sleep ( 100 );
}

스크립트를 작성하고 단축키를 할당하여 해당 명령을 사용합니다. 그런 다음 전문가/지표를 제어하려면 예를 들어 키를 누르기만 하면 됩니다. ALT-O는 가능한 모든 값 사이에서 순서 표시 모드를 전환합니다. 또는 즐겨찾기에 "시작" 및 "중지" 스크립트가 있고 마우스 클릭으로 시작/중지/재개합니다.

예를 들어 테스터에서. VisualMode=On이 최대 속도로 설정된 ea는 제대로 동기화되지 않으면 거의 즉시 충돌합니다.