MQL debugging을 위한 Break Point 구현


일반적으로 프로그램 개발 툴은 디버깅을 위해 Break Point 기능이 있습니다.

하지만 MQL4는 Break Point가 없습니다.

그것은 실시간 디버깅이 어렵다는 것을 의미합니다.

 

MQL4에서 디버깅이 필요한 경우는 2가지가 있습니다.

 

1. 전략테스트의 Visual Mode에서의 디버깅

2. 실시간 차트에서의 디버깅

 

아래 내용은 "BreakPoint.mqh" 라는 파일에 저장하였습니다.

Kyobo MetaTrader 4expertsinclude 안에 저장하고

선언부에 #include 를 추가하시고 사용하면 됩니다.

파일 첨부하였습니다.

 

1. 전략테스트의 Visual Mode에서의 디버깅

아래 싸이트를 참조하였습니다.

http://cafe.naver.com/mt4ea/86

 

아래 프로그램을 테스트해본 결과 동작이 될때도 않될 때도 있습니다.

이유는 직접적으로 Break point를 동작 시키는 것이 아니라

가상key를 이용하여 버튼을 누르는 것이라

버튼 클릭이 작동하지 않을 때도 있는 것같습니다.

윈도우즈방식이 좀... 그러네요 ㅋ

 

#include

 

//1. Visual mode Break Point
bool breakV(string str="Break Point")
{  
  if(Bars<102)return(0); // Visual mode는 101번째 봉부터 시뮬레이션을 시작한다.

                                 // 101번째 봉은 Break Point가 발생해도 무시하도록 한다. 이유는 가끔 오작동이 나는듯...   

  if(!IsVisualMode())return(0);

 

  Print(str);
  keybd_event(19,0,0,0);
  Sleep(20);
  keybd_event(19,0,2,0);

 

  return(1);
}

 

사용예)

#include

...

...

breakV("Break Point Result" + time[0]);

 

Visual mode는 아래 그림의 빨간색 안의 체크박스에 체크가 되어있어야합니다.

가상키( keybd_event(19...)은 파란색 안의 버튼에 대한 클릭 이벤트입니다.

 

 

2. 실시간 차트에서 디버깅

우리는 EA나 Indicator를 개발하고 실시간의 디버깅을 해야할 때도 있을 것입니다.

(일반적으로 Print, Alert, comment로 해결되지만)

 

EA이나 Indicator에서 Break Point에서 실행을 멈출 수 있는 방법은 없습니다.

아이디어를 낸다면 Break Point 위치에서 return함수를 호출하여 강제 종료하는 것입니다.

하지만, 한가지 문제가 더 남아 있습니다. start()함수의 경우 return을 시켜도

새로운 시세가 들어오면 start()함수를 다시 호출합니다.

이럴때는 start()를 정지시킬 수 있는 방법이 없으므로 start()함수가 호출 되자마자 return 시켜야합니다.

Break Point 함수는 BreakR() 함수를 사용하고, start()가 호출되자마자 리턴 시키는 함수는 Blocking()함수입니다.

이들 함수의 구현은 아래와 같습니다.

 

bool bBlocking_init = false;
bool bBreakR = false; // Break Point On 상태인가

//2. RealTime mode Break Point
// Break Point 초기화
bool Blocking()
{
  bBlocking_init = true;
  return(bBreakR);
}

 

bool breakR(string str="Break Point")
{
  if(!bBlocking_init)return(false);
 
  bBreakR = true;
  Print(str);
 
  return(true);  
}

 

이것은 EA나 Indicator의 Start()함수에서만 사용해야, 예상되는 Break Point의 동작을 수행할 것이라고 생각됩니다.

 

사용예)

#include

...

...

int start()
{

  //----각종 선언부

  int i = 0, Period = 120;

  ...

  if(Blocking())return(1); //BreakR()함수가 실행됐다면, true를 반환한다.

  //----메인 코드
  ...

  ...

 

  if(cnt == 10)

  {  //조건 만족시 breakR을 실행한다.

     //breakR() 함수는 사용자의 String을 출력하고, Blocking이 true를 반환하도록 한다.

     breakR("Break Point"+Close[0]);

     return(1);

  }

  ...

  ...


  //----
  return(0);

}

 

위 예제를 보면 코드가 원시적이지만 꼭 필요한 사람은 사용해보기 바랍니다^^

 

start()함수가 최초에 실행되면 Blocking함수는 기본적으로 false 값을 반환하므로

일반적으로는 return(1)을 수행하지 않습니다.

 

breakR이 실행되면 현상태에서 return(1) 되고,

다시 시세가 들어와서 start()함수에 진입하면 이번에는 Blocking()함수가 true를 반환하여

start에 들어올때마다 return(1)을 수행하여

Break Point 를 흉내냅니다.  ㅋ

 

만들고 보니 별로 필요가 없을 것 같다라는 생각이 들지만

혹시  필요할 것 같다면 사용해보세요^^;

 

첨부파일

코멘트 (1)

배고픈딜러

수고하십니다.