English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
하나의 지표를 다른 지표에 적용하기

하나의 지표를 다른 지표에 적용하기

MetaTrader 5 | 18 8월 2021, 09:24
200 0
MetaQuotes
MetaQuotes

소개

다른 지표의 값에 적용되는 지표를 개선하는 작업을 생각해 봅시다. 이 글에서는 이전 글 "MQL5: 나만의 지표 만들기"에서 생성되고 고려된 True Strength Index(TSI)로 계속 작업할 것입니다.

다른 지표 값을 기반으로 한 사용자 지정 지표

OnCalculate() 함수 호출의 짧은 형식을 사용하는 지표를 작성할 때 지표가 가격 데이터뿐만 아니라 다른 지표( 내장형이든 맞춤형이든 상관없이).

간단한 실험을 해보겠습니다. 표준 설정이 포함된 내장 RSI 지표를 차트에 첨부하고 True_Strength_Index_ver2.mq5 사용자 지정 지표를 RSI 지표 창으로 드래그합니다. 나타난 창의 매개변수 탭에서 지표가 이전 지표의 데이터(RSI(14))에 적용되어야 함을 지정합니다.

결과는 우리가 예상한 것과 상당히 다를 것입니다. TSI 표시기의 추가 줄이 RSI 표시기 창에 나타나지 않았고 데이터 창에서도 값이 불명확함을 알 수 있습니다.

RSI 값이 거의 전체 기록에 걸쳐 정의되어 있음에도 불구하고 TSI 값(RSI 데이터에 적용됨)은 완전히 없거나(처음에는) 항상 -100과 같습니다.

이러한 동작은 begin 매개변수 값이 True_Strength_Index_ver2.mq5의 OnCalculate() 어디에도 사용되지 않기 때문에 발생합니다. begin 매개변수는 price[] 입력 매개변수의 빈 값 수를 지정합니다. 이러한 빈 값은 지표 값 계산에 사용할 수 없습니다. OnCalculate() 함수 호출의 첫 번째 형식에 대한 정의를 상기해 보겠습니다.
int OnCalculate (const int rates_total,      // price[] array length
                 const int prev_calculated,  // number of bars calculated after previous call
                 const int begin,            // start index of meaningful data
                 const double& price[]       // array for calculation
   );

price constant 중 하나를 지정하는 가격 데이터에 표시기를 적용할 때 각 바에 대해 지정된 가격 유형이 있기 때문에 begin 매개변수는 0과 같습니다. 따라서 price[] 입력 배열은 항상 첫 번째 요소인 price[0]부터 올바른 데이터를 갖습니다. 그러나 다른 지표의 데이터를 계산 소스로 지정하면 더 이상 보장되지 않습니다.

OnCalculate()의 시작 매개변수

다른 지표의 데이터를 이용하여 계산한다면 price[] 배열에 포함된 값을 확인해봅시다. 그렇게 하려면 OnCalculate() 함수에서 확인하려는 값을 출력하는 몇 가지 코드를 추가합니다. 이제 OnCalculate() 함수의 시작은 다음과 같습니다.

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate (const int rates_total,    // price[] array length;
                 const int prev_calculated,// number of available bars after previous call;
                 const int begin,          // start index of meaningful data in price[] array 
                 const double &price[])    // data array, that will be used for calculations;
  {
//--- flag for single output of price[] values
   static bool printed=false;
//--- if begin isn't zero, then there are some values that we shouldn't take into account

   if(begin>0 && !printed)
     {
      //--- let's output them
      Print("Data for calculation begin from index equal to ",begin,
            "   price[] array length =",rates_total);

      //--- let's show the values that we shouldn't take into account for calculation
      for(int i=0;i<=begin;i++)
        {
         Print("i =",i,"  value =",price[i]);
        }
      //--- set printed flag to confirm that we have already logged the values
      printed=true;
     }

다시 한번 우리 지표의 수정된 버전을 RSI(14) 창에 드래그 앤 드롭하고 계산을 위해 이전 지표의 데이터를 지정해 봅시다. 이제 우리는 RSI(14) 표시기의 값이 사용되는 계산에 표시되지 않고 고려되어서는 안 되는 값을 볼 것입니다.


표시기 버퍼 및 DBL_MAX의 빈 값

0에서 13까지의 인덱스가 있는 price[] 배열의 처음 14개 요소는 1.797693134862316e+308과 동일한 값을 갖습니다. 이 숫자는 표시기 버퍼의 빈 값을 가리키는 데 사용되는 기본 제공 EMPTY_VALUE 상수의 숫자 값이기 때문에 매우 자주 접하게 됩니다.

빈 값을 0으로 채우는 것은 보편적인 솔루션이 아닙니다. 이 값은 다른 지표에 의한 계산 결과일 수 있기 때문입니다. 이러한 이유로 클라이언트 터미널의 모든 내장 표시기는 빈 값에 대해 이 숫자를 반환합니다. 값 1.797693134862316e+308은 double 유형의 가능한 최대값이고, 편의상 MQL5에서 DBL_MAX 상수로 제시되어 있기 때문에 선택되었습니다.

특정 이중 유형 숫자 비어 있는지 확인하려면 이를 EMPTY_VALUE 또는 DBL_MAX 상수와 비교할 수 있습니다. 두 변형은 동일하지만 코드에서 EMPTY_VALUE 상수를 사용하여 명확하게 하는 것이 좋습니다.

//+------------------------------------------------------------------+
//| returns true for "empty" values                                  |
//+------------------------------------------------------------------+
bool isEmptyValue(double value_to_check)
  {
//--- if the value is equal DBL_MAX, it has an empty value
   if(value_to_check==EMPTY_VALUE) return(true);
//--- it isn't equal DBL_MAX
   return(false);
  }

DBL_MAX는 매우 큰 숫자이며 RSI 표시기는 본질적으로 이러한 값을 반환할 수 없습니다! 그리고 배열의 15번째 요소(인덱스 14)만 50과 같은 합리적인 값을 갖습니다. 따라서 계산할 데이터의 출처인 지표에 대해 전혀 알지 못하더라도 begin 매개변수를 사용하여 이러한 경우 데이터 처리를 적절하게 구성할 수 있습니다. 더 정확하게 말하면 계산에 빈 값을 사용하는 것을 피해야 합니다.

begin 매개변수와 PLOT_DRAW_BEGIN 속성 간의 관계

주의할 점은 OnCalculate() 함수로 전달되는 begin 매개변수와 그리기 없이 초기 바의 개수를 정의하는 PLOT_DRAW_BEGIN 속성 사이에 밀접한 관계가 있다는 점입니다. MetaTrader5 표준 패키지에서 RSI의 소스 코드를 살펴보면 OnInit() 함수에서 다음 코드를 볼 수 있습니다.
//--- sets first bar from what index will be drawn
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtPeriodRSI);

이것은 인덱스가 0인 그래픽 플롯이 ExtPeriodRSI(RSI 표시기의 기간을 지정하는 입력 변수임)와 인덱스가 동일한 바에서만 시작되고 이전 바의 플롯이 없음을 의미합니다.

MQL5 언어에서 표시기 B의 데이터를 기반으로 하는 일부 표시기 A의 계산은 항상 표시기 B의 제로 버퍼 값에서 수행됩니다. 표시기 B의 제로 버퍼 값은 표시기 A의 OnCalculate() 함수에 price[] 입력 매개변수로 전송됩니다. 본질적으로 제로 버퍼는 SetIndexBuffer() 함수를 사용하여 제로 그래픽 플로팅에 할당됩니다. 그러므로:

규칙PLOT_DRAW_BEGIN 속성을 begin 매개변수로 이전하는 규칙: 맞춤 표시기 계산용 A 다른 (기본) 표시기 B의 데이터를 기반으로, OnCalculate()의 begin 입력 매개변수의 값 함수는 항상 기본 표시기의 B 0 그래픽 플로팅 속성의 PLOT_DRAW_BEGIN 속성 값과 같습니다.

따라서 기간이 14인 RSI 지표(지표 B)를 생성한 다음 해당 데이터를 기반으로 맞춤형 지표 True Strength Index(지표 A)를 생성한 경우:

  • RSI(14) 표시기는 PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,14) 때문에 14번째 바부터 플롯됩니다.
  • price[] OnCalculate() 함수의 입력 배열에는 RSI 표시기의 제로 버퍼 값이 포함됩니다.
  • TSI 표시기의 OnCalculate() 함수에서 begin 입력 매개변수의 값은 RSI 표시기의 제로 그래픽 플로팅의 PLOT_DRAW_BEGIN 속성에서 얻습니다.

TSI 지표는 일부 첫 번째 바에 대해 지표 값이 결정되지 않기 때문에 차트의 시작 부분에서 그려지지 않음을 기억하십시오. TSI 표시기에서 선으로 표시되는 첫 번째 바 인덱스는 r+s-1과 같습니다. 여기서:

  • r - MTMBuffer[] 및 AbsMTMBuffer[] 배열을 해당 EMA_MTMBuffer[] 및 EMA_AbsMTMBuffer[] 배열로 첫 번째 지수 평활화 기간.
  • s - EMA_MTMBuffer[] 및 EMA_AbsMTMBuffer[] 배열의 후속 평활화 기간.

인덱스가 r+s-1보다 작은 바의 경우 TSI 지표를 표시할 값이 없습니다. 따라서 TSI 표시기를 계산하는 데 사용되는 최종 MA2_MTMBuffer[] 및 EMA2_AbsMTMBuffer[] 배열의 경우 데이터에 추가 오프셋이 있고 r+s-1 인덱스에서 시작합니다. "MQL5: 나만의 지표 만들기" 문서에서 자세한 정보를 찾을 수 있습니다.

OnInit() 함수에는 첫 번째 r+s-1 바 그리기를 비활성화하는 문이 있습니다.

//--- first bar to draw
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,r+s-1);

입력 데이터의 시작이 시작 바만큼 앞으로 이동하므로 이를 고려하여 OnCalculate() 함수에서 데이터 그리기의 시작 포지션을 시작 바만큼 늘려야 합니다.

   if(prev_calculated==0)
     { 
      //--- let's increase beginning position of data by begin bars,
      //--- because we use other indicator's data for calculation
      if(begin>0)PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,begin+r+s-1);
     }
이제 begin 매개변수를 고려하여 TSI 표시기의 값을 계산합니다. 또한, 다른 표시기가 계산을 위해 TSI 값을 사용하는 경우 begin 매개변수가 올바르게 전송됩니다. beginother_indicator=beginour_indicator+r+s -1. 따라서 하나의 지표를 다른 지표의 값에 적용하는 규칙을 공식화할 수 있습니다.

지표 부과 규칙: Na 포지션(처음 Na개 값 플롯되지 않음) 포지션 Nb에서 가져온 다른 표시기 B의 데이터를 기반으로 하며 결과 표시기 A{B} Nab=Na+Nb 포지션에서 시작하여 그려집니다. 여기서 A{B}는 표시기 A는 표시기 B의 제로 버퍼 값에서 계산됩니다.

따라서 TSI(25,13){RSI(14)}TSI(25,13) 지표가 RSI(14) 표시기. 부과한 결과 이제 데이터의 시작은 (25+13-1)+14=51입니다. 즉, 표시기의 그리기는 52번째 바(바 색인은 0부터 시작)부터 시작됩니다.

지표 계산에 사용할 begin 값 추가

이제 우리는 price[] 배열의 의미 있는 값이 항상 begin 매개변수로 지정된 포지션에서 시작한다는 것을 정확히 알고 있습니다. 코드를 단계별로 수정해 보겠습니다. 먼저 MTMBuffer[] 및 AbsMTMBuffer[] 배열 값을 계산하는 코드가 나옵니다. begin 없이 매개변수 배열 채우기가 인덱스 1로 시작되었습니다.

//--- calculate values for mtm and |mtm|
   int start;
   if(prev_calculated==0) start=1;  // start filling MTMBuffer[] and AbsMTMBuffer[] arrays from 1st index 
   else start=prev_calculated-1;    // set start equal to last array index
   for(int i=start;i<rates_total;i++)
     {
      MTMBuffer[i]=price[i]-price[i-1];
      AbsMTMBuffer[i]=fabs(MTMBuffer[i]);
     }

이제 (begin+1) 포지션에서 시작하고 수정된 코드는 다음과 같습니다(코드 변경 사항은 굵게 표시됨).

//--- calculate values for mtm and |mtm|
   int start;
   if(prev_calculated==0) start=begin+1;   // start filling MTMBuffer[] and AbsMTMBuffer[] arrays from begin+1 index 
   else start=prev_calculated-1;           // set start equal to the last array index
   for(int i=start;i<rates_total;i++)
     {
      MTMBuffer[i]=price[i]-price[i-1];
      AbsMTMBuffer[i]=fabs(MTMBuffer[i]);
     }

price[0]부터 price[begin-1]까지의 값은 계산에 사용할 수 없으므로 price[begin]부터 시작합니다. MTMBuffer[] 및 AbsMTMBuffer[] 배열에 대해 계산된 첫 번째 값은 다음과 같습니다.

      MTMBuffer[begin+1]=price[begin+1]-price[begin];
      AbsMTMBuffer[begin+1]=fabs(MTMBuffer[begin+1]);

이러한 이유로 for 주기의 start 변수는 이제 1 대신 start=begin+1 초기값을 갖습니다.

종속 배열에 대한 시작 계정

이제 MTMBuffer[] 및 AbsMTMBuffer[] 배열의 지수 평활화가 제공됩니다. 규칙도 간단합니다. 기본 배열의 초기 포지션이 시작 바만큼 증가했다면 모든 종속 배열의 초기 포지션도 시작 바만큼 증가해야 합니다.

//--- calculating the first moving average on arrays
   ExponentialMAOnBuffer(rates_total,prev_calculated,
                         1,               // index of the starting element in array 
                         r,               // period of exponential average
                         MTMBuffer,       // source buffer for average
                         EMA_MTMBuffer);  // target buffer
   ExponentialMAOnBuffer(rates_total,prev_calculated,
                         1,r,AbsMTMBuffer,EMA_AbsMTMBuffer);

여기서 MTMBuffer [] 및 AbsMTMBuffer []는 기본 배열이며 이 배열의 계산된 값은 이제 begin만큼 큰 인덱스에서 시작합니다. 따라서 이 오프셋을 ExponentialMAOnBuffer() 함수에 추가하기만 하면 됩니다.

이제 이 블록은 다음과 같습니다.

//--- calculating the first moving average on arrays
   ExponentialMAOnBuffer(rates_total,prev_calculated,
                         begin+1,         // index of the starting element in array 
                         r,               // period for exponential average
                         MTMBuffer,       // source buffer for average
                         EMA_MTMBuffer);  // target buffer
   ExponentialMAOnBuffer(rates_total,prev_calculated,
                         begin+1,r,AbsMTMBuffer,EMA_AbsMTMBuffer);

보다시피 전체 수정은 시작 데이터 포지션, 시작 으로 정의 매개변수. N복잡합니다. 같은 방식으로 변경 두 번째 스무딩 블록<s. /s28>

이전:

//--- calculating the second moving average on arrays
   ExponentialMAOnBuffer(rates_total,prev_calculated,
                         r,s,EMA_MTMBuffer,EMA2_MTMBuffer);
   ExponentialMAOnBuffer(rates_total,prev_calculated,
                         r,s,EMA_AbsMTMBuffer,EMA2_AbsMTMBuffer);

후에:

//--- calculating the second moving average on arrays
   ExponentialMAOnBuffer(rates_total,prev_calculated,
                         begin+r,s,EMA_MTMBuffer,EMA2_MTMBuffer);
   ExponentialMAOnBuffer(rates_total,prev_calculated,
                         begin+r,s,EMA_AbsMTMBuffer,EMA2_AbsMTMBuffer);

In the same way we'll change the last calculation block.

이전:

//--- calculating values of our indicator
   if(prev_calculated==0) start=r+s-1; // set initial index for input arrays
   else start=prev_calculated-1;       // set start equal to last array index
   for(int i=start;i<rates_total;i++)
     {
      TSIBuffer[i]=100*EMA2_MTMBuffer[i]/EMA2_AbsMTMBuffer[i];
     }

후에:

//--- calculating values of our indicator
   if(prev_calculated==0) start=begin+r+s-1;  // set initial index for input arrays
   else start=prev_calculated-1;              // set start equal to last array index
   for(int i=start;i<rates_total;i++)
     {
      TSIBuffer[i]=100*EMA2_MTMBuffer[i]/EMA2_AbsMTMBuffer[i];
     }

표시기의 조정이 끝났고 이제 OnCalculate()에서 price[] 입력 배열의 첫 번째 begin 빈 값을 건너뛰고 이 생략에 의해 발생하는 오프셋을 고려합니다. 그러나 일부 다른 지표는 계산에 TSI 값을 사용할 수 있음을 기억해야 합니다. 이러한 이유로 지표의 빈 값을 EMPTY_VALUE로 설정합니다.

지시자 버퍼의 초기화가 필요합니까?

MQL5에서 어레이는 기본적으로 일부 정의된 값으로 초기화되지 않습니다. SetIndexBuffer() 함수에 의해 표시기 버퍼에 지정된 배열에도 동일하게 적용됩니다. 배열이 표시기 버퍼인 경우 크기는 OnCalculate() 함수의 rates_total 매개변수 값에 따라 달라집니다.

예를 들어 OnCalculate() 시작 부분에서 한 번에 ArrayInitialize() 함수를 사용하여 EMPTY_VALUE 값으로 모든 표시기 버퍼를 초기화하고 싶을 수 있습니다.

//--- if it is the first call of OnCalculate() 
   if(prev_calculated==0)
     {
      ArrayInitialize(TSIBuffer,EMPTY_VALUE);
     }

그러나 다음과 같은 이유로 권장하지 않습니다. 클라이언트 터미널이 작동하는 동안 표시기를 계산하는 데 데이터가 사용되는 기호에 대해 새 따옴표가 수신됩니다. 잠시 후 바의 수가 증가하므로 클라이언트 터미널은 표시기 버퍼를 위한 추가 메모리를 예약합니다.

그러나 새("연결된") 배열 요소의 값은 임의의 값을 가질 수 있습니다. 모든 배열에 대한 메모리 재할당 중에는 초기화가 수행되지 않기 때문입니다. 초기 초기화는 명시적으로 정의되지 않은 모든 배열 요소가 초기화 중에 지정된 값으로 채워질 것이라는 잘못된 확신을 줄 수 있습니다. 물론 그것은 사실이 아니며 변수나 일부 배열 요소의 숫자 값이 우리에게 필요한 값으로 초기화될 것이라고 생각해서는 안 됩니다.

표시기 버퍼의 각 요소에 대한 값을 설정해야 합니다. 일부 바의 값이 표시기 알고리즘에 의해 정의되지 않은 경우 빈 값으로 명시적으로 설정해야 합니다. 예를 들어 표시기 버퍼의 일부 값이 나누기 연산으로 계산되는 경우 제수가 0이 될 수 있는 경우가 있습니다.

0으로 나누는 것은 MQL5에서 심각한 런타임 오류이며 mql5 프로그램의 즉각적인 종료로 이어진다는 것을 알고 있습니다. 코드에서 이 특별한 경우를 처리하여 0으로 나누는 것을 피하는 대신 이 버퍼 요소의 값을 설정해야 합니다. 어쩌면 이 그림 스타일에 대해 비어 있는 것으로 할당한 값을 사용하는 것이 더 나을 수도 있습니다.

예를 들어, 일부 그리기 스타일의 경우 PlotIndexSetDouble() 함수를 사용하여 0을 빈 값으로 정의했습니다.

   PlotIndexSetDouble(plotting_style_index,PLOT_EMPTY_VALUE,0);   

그런 다음 이 도면에서 표시기 버퍼의 모든 빈 값에 대해 명시적으로 0 값을 정의해야 합니다.

   if(divider==0)
      IndicatorBuffer[i]=0;
   else
      IndicatorBuffer[i]=... 

또한 일부 도면에 대해 DRAW_BEGIN이 지정된 경우 인덱스가 0에서 DRAW_BEGIN인 표시기 버퍼의 모든 요소가 자동으로 0으로 채워집니다.

결론

자, 간단히 요약해 보겠습니다. 다른 지표의 데이터를 기반으로 지표가 올바르게 계산되고 다른 mql5-프로그램에서 사용하기에 적합하도록 하기 위해 몇 가지 필요한 조건이 있습니다.):

  1. 기본 제공 표시기의 빈 값은 EMPTY_VALUE 상수 값으로 채워지며, 이는 double 유형(DBL_MAX)의 최대값과 정확히 동일합니다.
  2. 지표의 의미 있는 값의 시작 인덱스에 대한 자세한 내용은 OnCalculate()의 약식begin 입력 매개변수를 분석해야 합니다.
  3. 지정된 그림 스타일에 대해 처음 N개의 값을 그리는 것을 금지하려면 다음 코드를 사용하여 DRAW_BEGIN 매개변수를 설정합니다.
    PlotIndexSetInteger(plotting_style_index,PLOT_DRAW_BEGIN,N);
  4. 일부 도면에 DRAW_BEGIN이 지정되면 인덱스가 0에서 DRAW_BEGIN인 모든 표시기 버퍼 요소가 자동으로 빈 값으로 채워집니다(기본값은 EMPTY_VALUE).
  5. OnCalculate() 함수에서 자신의 표시기에서 다른 표시기 데이터를 올바르게 사용하기 위해 시작 바만큼 추가 오프셋을 추가합니다.
    //--- if it's the first call 
       if(prev_calculated==0)
         { 
          //--- increase position of data beginning by begin bars, 
          //--- because of other indicator's data use      
          if(begin>0)PlotIndexSetInteger(plotting_style_index,PLOT_DRAW_BEGIN,begin+N);
         }
    
  6. 다음 코드를 사용하여 OnInit() 함수에서 EMPTY_VALUE와 다른 고유한 빈 값을 지정할 수 있습니다.
    PlotIndexSetDouble(plotting_style_index,PLOT_EMPTY_VALUE,your_empty_value);
  7. 다음 코드를 사용하여 표시기 버퍼의 일회성 초기화에 의존하지 마십시오.
    ArrayInitialize(buffer_number,value);
        
    빈 값을 포함하여 OnCalculate() 함수에 대한 표시기 버퍼의 모든 값을 명시적이고 일관되게 설정해야 합니다.

물론 앞으로 지표를 작성해 본 경험이 있을 때 이 글의 범위를 벗어나는 경우가 있을 수 있겠지만 그 때 MQL5에 대한 지식을 통해 이를 해결할 수 있기를 바랍니다.

MetaQuotes Software Corp.에서 러시아어를 번역했습니다.

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

Expert Advisor의 한계 및 검증 Expert Advisor의 한계 및 검증
월요일에 이 기호를 거래할 수 있습니까? 포지션을 열 수 있는 충분한 자금이 있습니까? 손절매가 발동되면 손실이 얼마나 됩니까? 보류 중인 주문 수를 제한하는 방법은 무엇입니까? 거래 작업이 현재 바에서 실행되었습니까 아니면 이전 바에서 실행되었습니까? 거래 로봇이 이러한 종류의 검증을 수행할 수 없다면 모든 거래 전략이 패배할 수 있습니다. 이 문서는 모든 Expert Advisor에서 유용한 검증의 예를 보여줍니다.
최후의 성전 최후의 성전
터미널을 한번 확인해 보세요. 가격이 어떤 형태로 나타나 있나요? 바, 캔들 그리고 여러 선이 있죠. 가격을 통해서만 이익이 창출되는데 시간과 가격 모두를 추적하고 있네요. 가격만을 이용한 시장 분석을 해보면 어떨까요? 이번 글은 P&F 차트 알고리즘과 스크립트를 다루고 있습니다. 본문에 언급된 가격 패턴에 대한 설명은 다음의 링크를 참조하세요.
자신만의 추적 손절매 만드는 법 자신만의 추적 손절매 만드는 법
트레이더의 기본 원칙 - 이익을 늘리고 손실을 줄이십시오! 이 글에서는 포지션 이익을 증가시킨 후 보수적인 중지 수준(손절매 수준)을 이동하는 이 규칙을 따를 수 있는 기본 기술 중 하나를 다뤄보도록 하겠습니다. 즉 - 추적 손절매 수준. SAR 및 NRTR 표시기에서 추적 손절매를 위한 클래스를 만드는 단계별 절차를 찾을 수 있습니다. 모든 사람은 이 추적 손절매를 expert에 삽입하거나 독립적으로 계정의 포지션을 ​​제어하는 ​​데 사용할 수 있습니다.
가장 활동적인 MQL5. 커뮤니티 구성원에게 iPhone이 수여되었습니다! 가장 활동적인 MQL5. 커뮤니티 구성원에게 iPhone이 수여되었습니다!
가장 뛰어난 MQL5.com 참가자에게 보상을 하기로 결정한 후, 커뮤니티 개발에 대한 각 참가자의 기여도를 결정하기 위한 핵심 기준을 선정했습니다. 그 결과 홈페이지에 가장 많은 양의 기사를 게재한 investeo (11개 기사)와 victorg (10개 기사)와 Code Base에 그들의 프로그램을 제출하신 분 - GODZILLA(340개 프로그램), Integer(61개 프로그램), abolk(21개 프로그램), 등의 챔피언이 탄생했습니다.