English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
Expert Advisor 최적화 시 커스텀 조건 만들기

Expert Advisor 최적화 시 커스텀 조건 만들기

MetaTrader 5트레이딩 | 4 8월 2021, 17:28
72 0
Dmitriy Skub
Dmitriy Skub


들어가며

MetaTrader 5 클라이언트 터미널은 Expert Advisor 패러미터 최적화 용도로 여러 선택지를 제공합니다. 전략 테스터에 포함된 최적화 기준 외에도 개발자에게 자신만의 기준을 만들 수 있는 기회가 주어집니다. 이를 통해 Expert Advisor를 테스트하고 최적화할 수 있는 가능성이 무궁무진해집니다. 본 문서에서 이러한 기준을 만드는 실제 방법(복잡하고 단순한 방법 모두)을 설명할 것입니다.


1. 전략 테스터의 기능 리뷰

이 주제는 여러 번 논의되어 왔기 때문에 짧은 설명으로만 문서 목록을 작성하려고 합니다. 이 문서를 읽기 전에 아래 자료들에 친숙해지시는 것을 추천해드립니다.

  • "MetaTrader 5의 테스팅 기초". Expert Advisor 테스트의 모든 기술적 측면 - 틱 생성 모드, 오픈 매매가 및 M1 막대로 작업하는 방법에 대해 자세히 다룹니다. 테스트 중 인디케이터 사용, 환경 변수 에뮬레이션, 표준 이벤트 처리 등에 대해 설명합니다. 또한, 다중 통화 테스트의 기본 사항에 대해 설명합니다.
  • "MQL5 Expert Advisors 최적화와 테스트 가이드". Expert Advisor의 입력 패러미터 테스트 및 최적화에 대한 문제를 다룹니다. 모수의 적합 과정, 검정 결과의 해석 및 최적 모수의 선택에 대해 설명합니다.
  • "TesterWithdrawal() 함수를 통해 수익 인출 모델링하기". 이 문서에서는 전략 테스터에서 이용되는 계정에서 돈을 인출하는 모델에 활용되는TesterWithdrawal함수의 이용법에 대해 다룹니다 . 또한 이 기능이 전략 테스터의 지분하락 계산 알고리즘에 어떤 영향을 미치는지 보여줍니다.

물론 진행하기 전에 클라이언트 터미널에서 제공되는 문서에 익숙해질 필요가 있습니다.


2. Strategy Tester에 내장된 최적화 기준

이 문서를 보시면 다음과 같은 설명을 보실 수 있을 것 입니다: 최적화기준 은 테스트된 패러미터 세트의 품질을 결정하는 특정한 요인입니다. 최적화 기준의 값이 높으면 높을수록 해당 패러미터 세트를 사용한 테스트 결과가 더 나은 것으로 간주됩니다.

중요한 점을 하나 짚고 넘어가겠습니다: 최적화 기준은 최적화 유전 알고리즘 모드에서만 사용할 수 있습니다. 존재가능한 모든 패러미터 값 조합을 따져볼 때, Expert Advisor의 최적 패러미터를 선택하는 요소는 있을 수 없습니다. 또 다른 점은 테스트 결과를 저장한 후 처리하여 최적의 패러미터 조합을 찾을 수 있다는 것입니다.

해당 문서에 안내되어있는 대로, 전략 테스터에는 유전 알고리즘과 함께 쓸 최적화 기준이 포함되어 있습니다.

  • Balance max - 잔고 내 최고값;
  • Balance + max 수익 팩터 - 잔고와수익 팩터의 곱 중 최고값;
  • Balance + max Expected Payoff - 잔고와 기대 수당의 곱셈 값;
  • Balance + min Drawdown - 이 경우엔 잔고값과 사용액 수준이 고려됩니다: (100% - 사용액)*잔고;
  • Balance + max Recovery Factor - 잔고와 회수율의 곱;
  • Balance + max Sharpe Ratio - 잔고값과 샤프 지수의 곱;
  • Custom max - 최적화 커스텀 기준. 여기에서 사용되는 커스텀 기준은 Expert Advisor의 OnTester()함수의 값입니다. 이 패러미터를 사용하여 Expert Advisor의 최적화를 위한 사용자 지정 값을 사용할 수 있습니다. .

최적화 기준은 1번 그림에서 볼 수 있듯이 전략 테스터의 Settings 탭에서 선택할 수 있습니다.

Expert Advisor용으로 최적화 기준 정하기

1번 그림. Expert Advisor용으로 최적화 기준 정하기

리스트의 마지막에 있는 Custom max 기준이 가장 흥미로운데요, 이 문서에서는 이에 대해 주로 다룰 예정입니다.


3. 커스텀 최적화 기준의 생성

먼저 사용자가 Expert Advisor를 실행할 때마다 전략 테스터로 계산한 패러미터(그림 1에 표시된 패러미터에 국한되지 않은 커스텀)를 자유롭게 조합할 수 있게 해주어야 합니다.

예를 들어 이 타입을 봅시다. Balance max + min Drawdown + Trades Number - 거래 수가 증가할 때 마다 결과가 더욱 안정적으로 조정됩니다. 혹은 Balance max + min Drawdown + max Profit Factor 도 있지요. 물론 전략 테스터 설정에 포함되지 않은 흥미로운 조합도 많습니다.

이러한 기준 조합을 간단 최적화 기준 이라고 명명합시다.

그러나 그러한 기준으로는 매매 시스템을 신뢰할 수 있는 수준으로 추정하기에는 모자랍니다. 최소한의 리스크로 수익을 내는 거래 개념의 관점에서 본다면, 다음과 같은 기준을 가정할 수 있습니다: 우리는 직선과 분리된 매매의 결과의 최소 편차로 매끄러운 균형 곡선을 얻기 위해 패러미터를 최적화시킵니다.

이 기준을 균형 곡선에 의한 최적화 기준이라고 명명하겠습니다.

다음 최적화 기준은 매매 시스템의 안전성에 대한 계수입니다. 이 계수는 "Be In-Phase" 문서에서 설명되어 있습니다. 이 계수가 시장에 대한 무역 시스템의 대응성을 나타내는 것 입니다. 패러미터를 최적화하는 동안 확인해보아야합니다. 이를 매매 시스템의 안전성에 대한 계수 기반 최적화 기준(CSTS) 이라고 합니다.

또한 기술된 기준을 자유롭게 결합할 수 있도록 합시다.


4. OnTester() 함수

실제 코드를 작성하기 전에 전략 테스터에서 EA 최적화 커스텀 기준의 구성을 들여다 보겠습니다.

내장 함수 OnTester()는 최적화 커스텀 기준 생성용입니다. 지정된 시간 범위 내에서 Expert Advisor의 각 테스트 통과 시 자동으로 호출됩니다. 이 함수는 OnDeinit()함수 호출 직전에 호출됩니다.

다시 한 번 강조합니다만, OnTester() 함수를 사용하려면 1번 그림에 표시된 대로 최적화에서 Fast genetic base algorithm 모드를 활성화시켜야한다는 점을 기억하셔야합니다.

이 함수는 전략 테스터 최적화에 사용되는 double 타입을 반환합니다.

설명서를 다시 한 번 봅시다:

유전 최적화에서 내림순 정렬은 한 세대 내의 결과물에 적용됩니다. 즉, 최적화 기준의 관점에서 최고의 결과가 가장 큰 값을 갖는다는 의미입니다. 이러한 정렬에서 최악의 값은 끝에 배치된 후 버려져 다음 세대의 형성에는 관여하지 않습니다.

따라서 맞춤형 최적화 기준을 만들 때 Expert Advisor의 매매 추정에 사용할 적분 값을 구해야 합니다. 가치가 클수록 Expert Advisor의 매매가 더 좋다는 것입니다.


5. 실험적 Expert Advisor 생성

다음 단계는 전략 테스터 안에서 최적화할 Expert Advisor를 만들어볼 차례입니다. 이 경우, 최적화 루틴에 많은 시간을 소모되지 않도록 간단하게 만드는 것이 중요합니다. 만약 Expert Advisor의 수익률이 그저 그럴 경우엔 특히나 중요합니다.

"MQL5으로 트렌드를 찾는 여러 방법" 문서에 설명된 Expert Advisor를 가져다가 개선시켜봅시다. 특기하자면, 세 개의 이동 평균의 "부채"에 기반된 Expert Advisor를 쓸 것입니다. 개선을 위해 인디케이터 사용을 없애 속도를 높이고 계산용 코드를 Expert Advisor 코드 안으로 옮길 것입니다. 이를 통해 테스트 속도를 몹시 높일 수 있습니다 (2년 범주 기준으로 거의 3배).

입력 패러미터 설정 파트는 꽤나 간단합니다:

input double Lots = 0.1; 
input int  MA1Period = 200; // period of the greatest moving average
input int  MA2Period = 50;  // period of the medium moving average
input int  MA3Period = 21;  // period of the smallest moving average

이동 평균의 기간을 최적화할 것입니다.

Expert Advisor의 구조와 운영은 위에서 언급한 문서에 자세히 설명되어 있으므로 여기서는 생략하겠습니다. 여기서 주목하셔야할 부분은 테스트 패스 완료 이벤트를 처리하는 핸들러 OnTester() 함수입니다. 지금은 비어서 컨트롤을 반환합니다.

//---------------------------------------------------------------------
//  The handler of the event of completion of another test pass:
//---------------------------------------------------------------------
double OnTester()
{
  return(0.0);
}

EA 파일 FanExpert.mq5은 이 문서에 첨부되어 있습니다. 이것이 FanTrendExpert.mq5 EA와 주문 처리 관점에서 봤을 때 똑같도록 만들 수 있습니다. 차트의 새 막대를 열 때 신호의 존재 및 방향 확인이 수행됩니다.

각 패스 끝에 계산된 테스트 결과를 받아오는데에 TesterStatistics()이 사용됩니다. 그 결과로 테스트 결과로 계산된, 요청된 통계값이 리턴됩니다 이 값은 OnTester()OnDeinit() 함수에서만 호출되며, 그 외에는 정의되지 않습니다.

자 이제 커스텀 최적화 기준을 추가해봅시다. 복구 팩터의 최대 값인 최대 복구 팩터를 기반으로 최적의 결과를 찾아야 한다고 가정합니다. 그러려면 max 값, 잔고 사용액과 테스트 종료 시점의 총 수익을 알아야합니다. 복구 팩터는 최대 사용액에서 수익을 나누는 것으로 계산됩니다.

복구 팩터는 이미 계산된 테스트 통계값 리스트에 포함되어있기 때문에 예시처럼 하시면 됩니다.

그리 하려면 간단한 코드를 OnTester()함수에 추가하십시오:

//---------------------------------------------------------------------
//  The handler of the event of completion of another test pass:
//---------------------------------------------------------------------
double OnTester()
{
  double  profit = TesterStatistics(STAT_PROFIT);
  double  max_dd = TesterStatistics(STAT_BALANCE_DD);
  double  rec_factor = profit/max_dd;

  return(rec_factor);
}

제로 디비전 검사는 코드를 좀 더 간결하게 하기 위해서 생략되었습니다. 최대 사용액이 0일 수도 있기 때문에 본 테스트는 실제 Expert Advisor에서 수행해야 합니다.

이제 위에 언급한 기준들을 만들어봅시다. Balance max + min Drawdown + Trades Number - Balance + Minimal Drawdown + Number of Trades.

이를 위해서 OnTester() 함수를 다음과 같이 바꿉니다.

double OnTester()
{
  double  param = 0.0;

//  Balance max + min Drawdown + Trades Number:
  double  balance = TesterStatistics(STAT_PROFIT);
  double  min_dd = TesterStatistics(STAT_BALANCE_DD);
  if(min_dd > 0.0)
  {
    min_dd = 1.0 / min_dd;
  }
  double  trades_number = TesterStatistics(STAT_TRADES);
  param = balance * min_dd * trades_number;

  return(param);
}

여기서는 다른 조건이 동일하다고 가정할 때 단점이 작을수록 상황이 좋기 때문에 단점과 반대되는 값을 취합니다. MA1Period로 생성된 최적화 기준을 이용하여 FanExpert EA의 최적화를 돌려봅시다. 패러미터는 2009.06.01 - 2011.06.03 범위와 Н1 타임프레임입니다. 이동평균의 값 범위를 100에서 2000으로 설정합니다.

최적화가 완료되면 패러미터가 좋은 순으로 정리된 값 테이블을 얻게 됩니다.

Balance max + min Drawdown + Trades Number 패러미터 기준 최적화 중 최고의 결과

2번 그림. Balance max + min Drawdown + Trades Number 패러미터 기준 최적화 중 최고의 결과

최고의 패러미터를 여기에 정리해두었습니다 (Result 열).

이번엔 가장 별로인 패러미터를 확인해봅시다.


3번 그림. Balance max + min Drawdown + Trades Number 기준 최적화 중 최악의 결과

두 표를 비교해 보면 거래 수와 함께 사용액과 이익이 고려된다는 것을 알 수 있습니다. 즉, 최적화 기준이 정상적으로 사용되고 있습니다. 덤으로 최적화 그래프(선형)를 볼 수 있습니다.

최적화 그래프

4번 그림. Balance max + min Drawdown + Trades Number 기준 최적화 그래프

수평 축에는 최적화된 패러미터가 표시되고 수직 축에는 최적화 기준이 표시됩니다. 설정된 기준의 최대값이 분명하게 표시되며 980 ~ 1200 범위의 기간에 위치합니다.

전체 검색이 아니라 패러미터의 유전적 최적화임을 이해하고 기억해야 합니다. 그렇기 때문에 그림 2와 그림 3에 표시된 표는 몇 세대에 걸쳐 자연 선택을 통과한 가장 "실현 가능한" 패러미터를 포함하고 있습니다. 몇몇 바리에이션은 치웠습니다.

MA1Period = 1106 기간에 대한 잔고/자기자본 커브는 다음과 같습니다

MA1Period = 1106 기간에 대한 잔고/자기자본 커브

5번 그림. MA1Period = 1106 기간에 대한 잔고/자기자본 커브


6. 커스텀 최적화 기준 클래스 생성하기

지금까지 간단한 최적화 기준을 만들고 사용하는 방법에 대해 알아봤습니다. 그럼 이제부터는 Expert Advisor들 안에서 더욱 간단하게 사용하기 위해서 클래스를 만들도록 합시다 이러한 클래스를 만들 때에 중요한 것은 사용하기에 편하면서도 실행 속도도 빨라야한다는 것입니다. 최적화 기준 계산이 빠르게 처리되지않으면 결과를 보기까지 많은 시간이 걸릴 수도 있습니다.

MetaTrader 5에서는 최적화용으로 클라우드 연산을 제공합니다. 엄청난 양의 패러미터를 처리하려면 상당한 계산력이 필요하기 때문에 큰 도움이 되는 내용입니다. 따라서, 프로그래밍의 관점에서 우아하지는 않지만 가장 간단하고 빠른 솔루션을 개발하기 위해 이 방식을 사용할 것입니다.

개발과정에서는 클라이언트 터미널과 함께 제공되는 데이터 정리 클래스를 활용할 것입니다.

먼저 테스트의 통계적 결과물을 분류합니다:

  • 테스트 결과 값과 최적화 기준 사이에 정비례하는 부동 또는 정수 유형입니다.

즉, 테스트 결과의 값이 클수록 최적화 기준의 값이 더 좋고 커집니다. 그러한 테스트 결과의 예시중 하나는 STAT_PROFIT 테스트 끝의 총 수익입니다. 이 값은 부동 형식을 가지며 음의 무한대(실제로 예금 값에 의해 제한됨)에서 양의 무한대로 변경할 수 있습니다.

이 타입의 테스팅 결과 중 비슷한 예시는 매매 횟수 STAT_TRADES입니다. 일반적으로 거래 횟수가 많을수록 최적화의 결과에 대한 신뢰도가 높아집니다. 값은 정수 형식을 가지며 0에서 양의 무한대로 변경할 수 있습니다.

  • 테스트 결과 값과 최적화 기준 사이에 역비례하는 부동 또는 정수 유형입니다.

다시 말해 테스트 결과의 값이 작을수록 최적화 기준의 값이 더 좋고 커집니다. 그런 테스트 결과의 예시는 잔고 최대 사용액 STAT_BALANCE_DD와 다른 사용액들을 들 수 있습니다.

이러한 테스트 결과를 얻기 위해 우리는 최적화 기준의 가치 계산을 위해 역값을 취할 것입니다. 물론, 우리는 해당 오류를 피하기 위해 제로 디비전 테스트를 시행해야 합니다.

TCustomCriterion의 커스텀 기준을 생성하기 위한 클래스는 매우 간단합니다. 이 클래스의 목적은 기본 기능 판단입니다. 다음과 같이 보이죠.

class TCustomCriterion : public CObject
{
protected:
  int     criterion_level;        // type of criterion

public:
  int   GetCriterionLevel();
  virtual double  GetCriterion();  // get value of the result of optimization
};

가상 메소드 TCustomCriterion::GetCriterion는 상속된 클래스로 재정의되어야합니다. 이 메소드가 각 테스트 통과 후 Expert Advisor 테스트의 필수 결과 값을 반환하는 주요 메소드입니다.

TCustomCriterion::criterion_level 클래스 멤버들은 이 클래스 인스턴스에 존재하는 커스텀 기준의 타입을 저장합니다. 이것은 오브젝트의 종류에 따라 더욱 구별하기 위해 사용될 것입니다.

이제 최적화에 필요한 모든 클래스를 상속할 수 있습니다.

TSimpleCriterion클래스는 테스트의 지정된 통계 결과에 해당하는 "간단한" 커스텀 기준을 생성하기 위한 것입니다. 다음과 같이 이루어집니다.

class TSimpleCriterion : public TCustomCriterion
{
protected:
  ENUM_STATISTICS  stat_param_type;

public:
  ENUM_STATISTICS  GetCriterionType();     // get type of optimized stat. parameter

public:
  virtual double   GetCriterion(); // receive optimization result value
  TSimpleCriterion(ENUM_STATISTICS _stat); // constructor
};

여기에서 패러미터와 생성자를 이용하는데요, 이는 다음과 같이 이루어집니다.:

//---------------------------------------------------------------------
//  Constructor:
//---------------------------------------------------------------------
TSimpleCriterion::TSimpleCriterion(ENUM_STATISTICS _stat)
:
stat_param_type( _stat )
{
  criterion_level = 0;
}

MQL5 언어의 새 기능을 활용하면 클래스 인스턴스를 만들 때에 편리합니다. 앞서 각 테스트가 패스할 때 마다 최적화 값을 받아오는 가상 메소드 TSimpleCriterion::GetCriterion를 오버라이드 했습니다. 구현은 꽤나 쉽습니다

//---------------------------------------------------------------------
//  Get the result of optimization:
//---------------------------------------------------------------------
double  TSimpleCriterion::GetCriterion()
{
  return(TesterStatistics(stat_param_type));
}

보시다시피 테스트의 해당 통계 결과를 반환합니다.

"간단한" 커스텀 최적화 기준의 다음 타입은 TSimpleDivCriterion 클래스를 이용하여 만들어집니다. 이는 테스트 결과 값과 최적화 기준 사이의 역비례 기준으로서 작용하도록 설계되었습니다.

TSimpleDivCriterion::GetCriterion 메소드는 이하와 같습니다:

//---------------------------------------------------------------------
//  Get value of the optimization result:
//---------------------------------------------------------------------
double  TSimpleDivCriterion::GetCriterion()
{
  double  temp = TesterStatistics(stat_param_type);
  if(temp>0.0)
  {
    return(1.0/temp);
  }
  return(0.0);
}

이 코드엔 더 이상의 설명이 필요 없습니다.

두 개의 다른 "간단한" 최적화 커스텀 기준은 TSimpleMinCriterionTSimpleMaxCriterion 클래스를 이용하여 만들어집니다. 이 클래스들은 각각 위쪽과 아래쪽의 제한된 테스트 통계값을 가지고 기준을 만드는 용도로 사용됩니다.

최적화 중에 의도적으로 잘못된 패러미터 값을 배제해야 하는 경우에 유용합니다. 예를 들어 최소 거래 수, 최대 인출 수 등을 제한할 수 있습니다.

TSimpleMinCriterion 클래스의 설명은 다음과 같습니다.

class TSimpleMinCriterion : public TSimpleCriterion
{
  double  min_stat_param;

public:
  virtual double  GetCriterion();    // receive optimization result value
  TSimpleMinCriterion(ENUM_STATISTICS _stat, double _min);
};

여기에서는 2개의 패러미터를 이용한 생성자를 사용합니다. _min 패러미터는 테스트 통계값의 최저 값을 세팅합니다. 다른 테스트에서 지정된 값보다 작은 값을 얻으면 결과가 삭제됩니다.

TSimpleMinCriterion ::GetCriterion 메소드의 구현은 다음과 같습니다.

//---------------------------------------------------------------------
//  Get value of the optimization result:
//---------------------------------------------------------------------
double  TSimpleMinCriterion::GetCriterion()
{
  double  temp = TesterStatistics(stat_param_type);
  if(temp<this.min_stat_param)
  {
    return(-1.0);
  }
  return(temp);
}

TSimpleMaxCriterion 클래스는 비슷한 구성을 취하기 때문에 다른 설명이 필요 없습니다. 다른 "간단한" 커스텀 기준 클래스들은 위에 설명된 것들과 비슷하게 만들어져 있으며 이 문서에 첨부된 CustomOptimisation.mqh 파일에서 찾아볼 수있습니다. 최적화에 사용할 다른 클래스를 개발하는 경우에도 동일한 원리를 사용할 수 있습니다.


위에서 설명한 클래스를 사용하기 전에 컨테이너 클래스를 만들어 기준 집합을 사용하여 작업을 보다 편리하게 수행하도록 하겠습니다. 이를 위해서 데이터 정리 표준 클래스를 사용할 것입니다. 최대한 간결한 기준 처리가 필요한데, 이에 가장 적합한 클래스는 CArrayObj입니다. 이 클래스는 CObject 클래스에서 상속된 객체로 구성된 능동 어레이를 만들도록 도와줍니다.

컨테이너 클래스 TCustomCriterionArray는 매우 간단합니다.

class TCustomCriterionArray : public CArrayObj
{
public:
  virtual double  GetCriterion( );  // get value of the optimization result
};

유일한 메소드 TCustomCriterionArray::GetCriterion는 테스트가 패스할 때 마다 그 끝에 최적화 기준의 값을 반환합니다. 다음과 같이 구현됩니다.

double  TCustomCriterionArray::GetCriterion()
{
  double  temp = 1.0;
  int     count = this.Total();
  if(count == 0)
  {
    return(0.0);
  }
  for(int i=0; i<count; i++)
  {
    temp *= ((TCustomCriterion*)(this.At(i))).GetCriterion();
    if(temp <= 0.0)
    {
      return(temp);
    }
  }

  return(temp);
}

유의해야 할 사항이 하나 있는데, 이는 기준을 처리할 때 마이너스 값을 얻게 되면 계속해서 테스팅할 이유가 사라진다는 것입니다. 또한 두 음수 값의 곱셈으로 양수 값이 나올 때의 상황을 없애줍니다.


7. 커스텀 최적화 기준 클래스 사용하기

지금까지 Expert Advisor를 최적화하는 동안 "간단한" 사용자 지정 기준을 사용할 수 있는 모든 것을 갖추었습니다. "실험적" Expert Advsisor FanExpert를 향상시키는 수순을 분석해봅시다.

  • 커스텀 정의 기준의 클래스에 대한 설명이 들어 있는 인클루드 파일을 추가합니다.
#include <CustomOptimisation.mqh>
  • 커스텀 조건을 사용하기 위해 컨테이너 클래스의 객체에 포인터를 추가합니다.
TCustomCriterionArray*  criterion_Ptr;
  • 커스텀 조건을 사용하기 위해 컨테이너 클래스의 객체에 대한 포인터를 초기화합니다.
  criterion_array = new TCustomCriterionArray();
  if(CheckPointer(criterion_array) == POINTER_INVALID)
  {
    return(-1);
  }

이는 OnInit 함수에서 처리될 것입니다. 객체를 성공적으로 생성하지 못한 경우 음수 값을 반환하십시오. 이 경우엔 Expert Advisor의 작동이 멈춥니다

  • Expert Advisor에 최적화 기준을 추가한 경우.
  criterion_Ptr.Add(new TSimpleCriterion(STAT_PROFIT));
  criterion_Ptr.Add(new TSimpleDivCriterion(STAT_BALANCE_DD));
  criterion_Ptr.Add(new TSimpleMinCriterion(STAT_TRADES, 20.0));

이 경우 최대 이익, 최소 인출, 최대 거래 수만큼 EA를 최적화하기로 했습니다. 또한 Expert Advisor의 외부 패러미터 세트를 폐기하여 20건 미만의 매매가 이루어지도록 합니다.

  • OnTester 함수를 호출하게 합니다.
  return(criterion_Ptr.GetCriterion());
  • OnDeinit 함수에서 컨테이너 객체를 지우는 코드를 추가합니다.:
  if(CheckPointer(criterion_Ptr) == POINTER_DYNAMIC)
  {
    delete(criterion_Ptr);
  }

이상이 최적화에 관련된 모든 것입니다. 최적화를 실행하고 모든 것이 의도한 대로 작동하는지 확인합니다. 그걸 위해선 아래 그림에 보이는대로 전략 테스터의 Settings 탭에서 패러미터를 세팅합니다.

전략 테스터 Settings 탭

6번 그림. 전략 테스터 Settings 탭

7번 그림과 같이 전략 테스터의 Input parameters 탭에서 입력 패러미터의 최적화 범위를 설정합니다.

최적화된 입력 패러미터

7번 그림. 최적화된 입력 패러미터

최적화 용으로 "클라우드" 에이전트를 사용하십시오. 그를 위해선 Agents 탭에서 이하의 패러미터를 세팅하십시오:

테스팅 용 에이전트 패러미터

8번 그림. 테스팅 용 에이전트 패러미터

이제 Start 버튼 (6번 그림)을 누르고 최적화가 끝나길 기다립니다. "클라우드" 연산 기술을 사용하면 최적화가 상당히 빠르게 수행됩니다. 결국 특정 기준에 의한 최적화 결과를 얻게됩니다.

최적화 결과

9번 그림. 최적화 결과

"실험적" Expert Advisor가 성공적으로 최적화되었습니다. "클라우드" 에이전트를 통해 최적화하는데에 13분이 소요되었습니다. 이 기준을 확인하는데에 쓰인 EA는 이 문서에 첨부된 FanExpertSimple.mq5파일입니다.


8. 밸런스 커브 분석을 기반으로 한 커스텀 최적화 기준 클래스 생성하기

이 클래스의 생성 기반은 "Controlling the Slope of Balance Curve During Work of an Expert Advisor" 문서에서 찾아볼 수 있습니다. 이 최적화 기준의 개념은 밸런스 선이 최대로 직선에 가깝게 되도록 하는 것입니다. 직선과의 근접도는 직선으로부터의 매매 결과의 표준 편차 값으로 추정됩니다. 직선 방정식은 전략 테스터의 거래 결과에 의해 그려진 회귀선에 대해 계산됩니다.

결과 잔액이 음수인 곡선을 폐기하려면 추가 한계를 설정합니다. 결과 이익은 지정된 값보다 커야 하며 거래 수는 지정된 값보다 적을 수 없습니다.

따라서, 우리의 최적화 기준은 결과 이익의 한계와 매매 수를 고려할 때 직선으로부터의 매매 결과의 표준 편차 값에 반비례할 것입니다.

밸런스 커브에 기반을 둔 최적화 기준을 구현하기 위해서는 위에서 언급한 문서에서 나오는 TBalanceSlope 클래스가 필요합니다. 패러미터가 있는 생성자를 사용하고(편의상) 선형 회귀 계산에 표준 편차 계산을 추가합니다. 이 코드는 문서에 첨부된 BalanceSlope.mqh파일에서 찾아보실 수 있습니다.

이 최적화 기준을 Expert Advisor에 추가하는 단계는 위에서 설명한 것과 동일합니다. 이제 최적화 기준은 다음처럼 보입니다.

criterion_Ptr.Add(new TBalanceSlopeCriterion(Symbol( ), 10000.0));

밸런스 곡선 기준 외에 우리가 개발한 다른 기준도 추가할 수 있습니다. 독자들을 위해, 저는 다른 통계적 패러미터들을 실험할 수 있는 가능성을 남겨두었습니다.

설정된 기준에 따라 최적화를 수행하겠습니다. 이것보다 더 많은 매매들을 대상으로 하려면 H4 기간, 2010.01.01~2011.01.01 기간 및 EURUSD 기호를 사용하여 최적화를 수행합니다. 이하의 결과를 얻습니다.

밸런스 커브 기반 최적화 결과

10번 그림. 밸런스 커브 기반 최적화 결과

이제 최적화의 질을 측정해야 합니다. 제 생각에는 주요 기준은 최적화 기간 이외의 Expert Advisor 의 작업이라고 생각합니다. 이를 확인하려면 2010.01.01~2011.06.14 기간 내에 단일 테스트를 실행하십시오.

최적의 모수 집합에서 얻은 두 결과(중간에서 얻은 결과와 함께 얻은 최상의 결과)를 비교합니다. 최적화 기간을 벗어난 결과는 빨간색 선으로 구분됩니다.

최적화의 최고의 결과

11번 그림. 최적화의 최고의 결과

일반적으로, 곡선의 행동은 나빠지지 않았습니다. 수익성이 1.60에서 1.56으로 소폭 감소했네요.

테스트 중간 결과

12번 그림. 테스트 중간 결과

Expert Advisor는 최적화 기간 밖에서는 딱히 수익성이 좋지 않았습니다. 수익성이 2.17에서 1.75로 크게 감소했습니다.

따라서 최적화된 모수의 작업 기간과 밸런스 커브 간의 상관관계 가설이 존재할 권리가 있다는 결론을 내릴 수 있습니다. 물론 Expert Advisor가 이 기준을 사용하여 수용할 수 있는 결과를 얻을 수 없는 경우 이 변형을 제외할 수 없습니다. 그 경우엔 약간의 분석과 실험을 할 필요가 있습니다.

이 기준 용으로는 아마 가능한 최대한 긴(그러나 적당하게 긴) 기간을 사용해야 할 것입니다 이 기준을 체크하는 Expert Advisor는 이 문서에 첨부된 FanExpertBalance.mq5 파일에서 찾아볼 수 있습니다.


9. 안전매매시스템계수(Coefficient of the Safe Trade System, CSST) 기초한 맞춤형 최적화 기준 클래스 만들기

"Be in-Phase" 문서에서 설명한대로, 안전매매시스템계수(coefficient of safe trade system, CSTS)는 다음의 공식으로 계산됩니다.

CSTS = Avg.Win / Avg.Loss ((110% - %Win) / (%Win-10%) + 1)

각 지표 해설

  • Avg.Win - 이득 매매에서의 평균 값
  • Avg.Loss - 손실 매매에서의 평균 값
  • %Win - 이득 매매의 비율.

CSTS가치가 1 미만일 경우 거래 시스템은 높은 매매위험의 영역에 있게 됩니다. 심지어 값이 작을수록 수익성이 없는 매매의 영역을 나타냅니다. CSTS의 가치가 클수록, 이 매매시스템이 시장에 더 적합하고 수익성이 더 높다고 할 수 있습니다.

CSTS 계산에 필요한 모든 통계 값은 각 테스트를 통과한 후 전략 테스트에서 계산됩니다. TCustomCriterion에서 상속된 TTSSFCriterion 클래스를 만들고 그 안에 GetCriterion() 메소드를 구현하는 일이 남았습니다. 코드 내에서 이 메소드는 다음과 같이 구현됩니다:

double  TTSSFCriterion::GetCriterion()
{
  double  avg_win = TesterStatistics(STAT_GROSS_PROFIT) / TesterStatistics(STAT_PROFIT_TRADES);
  double  avg_loss = -TesterStatistics(STAT_GROSS_LOSS) / TesterStatistics(STAT_LOSS_TRADES);
  double  win_perc = 100.0 * TesterStatistics(STAT_PROFIT_TRADES) / TesterStatistics(STAT_TRADES);

//  Calculated safe ratio for this percentage of profitable deals:
  double  teor = (110.0 - win_perc) / (win_perc - 10.0) + 1.0;

//  Calculate real ratio:
  double  real = avg_win / avg_loss;

//  CSTS:
  double  tssf = real / teor;

  return(tssf);
}

이러한 최적화 기준에는 짧은 기간이 적합하다고 생각합니다. 그러나 맞춤을 피하려면 최적화 결과의 중간에 있는 결과를 취하는 것이 좋습니다.

독자들이 스스로 최적화를 수행할 수 있는 기회를 드리겠습니다. 이 기준을 체크하는 Expert Advisor는 이 문서에 첨부된 FanExpertTSSF.mq5파일 입니다.


마치며

어쨌든 커스텀 최적화 기준(단일 적분율 사용)을 생성할 수 있는 가능성에 대한 이러한 간단한 솔루션이 다른 변형에 비해 거의 완벽하다는 사실을 인정해야 합니다. 이를 통해 강력한 매매시스템의 개발 기준을 더 높은 수준으로 끌어올릴 수 있게 해줍니다. "클라우드" 기술을 사용하면 수행되는 최적화의 한계를 크게 줄일 수 있습니다.

진화의 추가 방법은 서로 다른 정보 출처에서 기술된 수학적 및 통계적으로 입증된 기준과 연결될 수 있다. 그를 위한 준비는 끝났으니까요.


MetaQuotes 소프트웨어 사를 통해 러시아어가 번역됨.
원본 기고글: https://www.mql5.com/ru/articles/286

천재반을 위한 MQL5 Wizard 천재반을 위한 MQL5 Wizard
2011년 초에 MQL Wizard의 첫 버전을 릴리즈했습니다. 이 새로운 애플리케이션은 매매 봇을 자동으로 생성할 수 있는 간단하고 편리한 도구를 제공합니다. MetaTrader 5 사용자라면 MQL5 프로그래밍하는 방법을 알지 못해도 커스텀 Expert Advisor를 만들 수 있습니다.
MetaTrader 5에서 자동 정리 기능 맵 (코호넨 맵) 이용하기 MetaTrader 5에서 자동 정리 기능 맵 (코호넨 맵) 이용하기
자체 구성 기능 맵(코호넨 맵)의 가장 흥미로운 측면 중 하나는 사람이 관리하지 않아도 스스로 데이터를 분류하는 법을 배운다는 것입니다. 기본적인 형태로 입력 데이터의 유사성 맵(클러스터링)을 생성합니다. SOM 맵은 고차원 데이터의 분류 및 시각화에 사용할 수 있습니다. In this article we will consider several simple applications of Kohonen maps.
MQL5에서의 진보된 적응형 인디케이터 이론 및 구현 MQL5에서의 진보된 적응형 인디케이터 이론 및 구현
이 문서에서는 MQL5으로 적응형 Cyber Cycle, 적응형 Center of Gravity 및 적응형 RVI를 비롯한 진보된 적응형 인디케이터와 구현법에 대해 다루어볼 것입니다. 이들 인디케이터는 원래 John F. Ehlers의 "Cybernetic Analysis for Stocks and Futures"에서 제시되었습니다.
통계적 추정 통계적 추정
대부분의 수학적 모델과 방법은 서로 다른 가정을 기반으로 하기 때문에 시퀀스의 통계적 모수 추정은 매우 중요합니다. 예를 들어 분포 법칙의 정규성이나 분산 값 또는 기타 모수가 있습니다. 따라서 시계열 분석 및 예측 시 주요 통계 모수를 빠르고 명확하게 추정할 수 있는 간단하고 편리한 도구가 필요합니다. 이 문서는 랜덤 시퀀스의 가장 간단한 통계적 모수와 시각적 분석의 여러 메소드에 대해 설명할 것입니다. MQL5에서는 이러한 방법의 구현과 Gnuplot 애플리케이션을 사용한 계산 결과의 시각화 메소드를 제공합니다.