기고글 토론 "하나의 지표를 다른 지표에 적용하기"

 

새로운 기고글 하나의 지표를 다른 지표에 적용하기 가 게재되었습니다:

OnCalculate() 함수 호출의 간단한 형식을 사용하는 지시자를 작성할 때, 가격 데이터뿐만 아니라 다른 지시자의 데이터로도 지시자를 계산할 수 있다는 사실을 놓칠 수 있습니다 (내장형이든 맞춤형이든 상관없이). 다른 지표의 데이터에 대한 올바른 적용을 위해 지표를 개선하고 싶습니까? 이 글에서는 그러한 수정에 필요한 모든 단계를 검토할 것입니다.

작성자: MetaQuotes

 

또 다른 좋은 글에 감사드립니다. 전통적으로 MQL 커뮤니티 문서는 제가 고등 교육을 받을 수 있는 방법(내장된 MQL 편집자 가이드를 의미함)이 되었습니다.

요점에서 코드에서 작은 결함을 발견했습니다. 작성자의 아이디어에 따르면

가격[] 값의 일회성 출력을 위한 플래그 //---

변수

   bool printed=false;

변수를 OnCalculate() 함수 외부로 이동해야 하며, 그렇지 않으면 모든 이벤트에서 배열 인쇄가 발생합니다.

여기에도 잘못된 인쇄가 있습니다.

Правило передачи PLOT_DRAW_BEGIN в параметр begin: Значение входного параметра begin в OnCalculate(), при расчетах пользовательского индикатора A на данных другого (базового) индикатора B, всегда равно значению свойства PLOT_DRAW_BEGIN  нулевого графического построения базового индикатора B.

따라서 주기가 14인 RSI 지표(지표 A) 를 만든 다음 RSI(14) 지표 데이터에 사용자 지정 지표인 True Strength Index(지표 B) 를 만든 경우:

규칙과 논리에 따라 판단하면 지표 A는 사용자 지정 TSI이고 지표 B(기본)는 RSI입니다.

Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
Основы языка / Функции / Функции обработки событий - Документация по MQL5
 

이 문서에는 자세한 지식이 포함되어 있습니다.

감사합니다.

 

안녕하세요,

이 기사는 정말 흥미롭고 지표를 관리할 수 있는 새로운 기회를 열어줍니다.

저는 MQL5 초보자이기 때문에 하나의 지표를 다른 지표에 적용할 수 있는 기능을 구현해 보았습니다. 저는 적응 이동 평균을 복제하기 위해

적응 이동 평균을 차트의 모든 지표에 사용하기를 희망하는 작은 코드를 작성했습니다.

안타깝게도 지표를 시작할 때 표시되는 매개 변수 목록에 "적용 대상 : 이전 지표의 데이터"가 없습니다.

다른 지표에 적용할 수 있도록 코드를 어떻게 구성해야 하나요?

다음은 제 코드입니다:

#property indicator_separate_window
#property indicator_minimum             1.3
#property indicator_maximum             1.35
//#프로퍼티 인디케이터_차트_창
#property indicator_buffers 2
#property indicator_plots   1
//--- plot dMA
#property indicator_label1  "dAMA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- 입력 매개변수
input int      AMAPeriod=9;
input int      FastEMA=2;
input int      SlowEMA=20;
//--- 표시기 버퍼
double         AMABuffer[];
double         dAMABuffer[];

int            h_dAMA;
int            h_AMA;
//+------------------------------------------------------------------+
//| 사용자 지정 표시기 초기화 기능 |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- 표시기 버퍼 매핑
   SetIndexBuffer(0,dAMABuffer,INDICATOR_DATA);
   SetIndexBuffer(1,AMABuffer,INDICATOR_CALCULATIONS);
   
   
   
   //PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,MAPeriod+1);
   
   h_AMA=iAMA(_Symbol,PERIOD_CURRENT,AMAPeriod,FastEMA,SlowEMA,0,PRICE_CLOSE);
   if(h_AMA == INVALID_HANDLE)
    {
      Print("AMA indicator initialization error, Code = ", GetLastError());
      return(-1);
    }
   ArraySetAsSeries(AMABuffer,true);
   ArraySetAsSeries(dAMABuffer,true);
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,MathMax(AMAPeriod,SlowEMA));
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| 사용자 지정 인디케이터 반복 함수|
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,    // 가격[] 배열의 크기
                const int prev_calculated,// 이전 호출에서 처리된 막대 수
                const int begin,          // 중요한 데이터가 시작되는 위치
                const double &price[]     // 계산용 배열
                )
  {
   
   if(BarsCalculated(h_AMA)<rates_total) return(0);
//--- 모든 데이터를 복사할 수 있는 것은 아닙니다.
   int to_copy;
   if(prev_calculated>rates_total || prev_calculated<=0) 
     {
      to_copy=rates_total;
      if(CopyBuffer(h_AMA,0,0,to_copy,AMABuffer)<=0) return(0);
      for (int i=0;i<to_copy-MathMax(AMAPeriod,SlowEMA);i++)
          {
            dAMABuffer[i]=AMABuffer[i];
          }
     }
   else
     {
      to_copy=rates_total-prev_calculated+MathMax(AMAPeriod,SlowEMA)-1;
      //--- 마지막 값은 항상 복사됩니다.
      to_copy++;
      if(CopyBuffer(h_AMA,0,0,to_copy,AMABuffer)<=0) return(0); 
      for (int i=0;i<to_copy;i++)
         {
            dAMABuffer[i]=AMABuffer[i];
         }
     }
//--- 복사 시도
   
   Print(dAMABuffer[0]); //끝까지 가는지 확인하려면
//--- 다음 호출을 위한 prev_calculated의 반환 값
//---
//--- 다음 호출을 위한 prev_calculated의 반환 값
   return(rates_total);
  }
//+------------------------------------------------------------------+
 

안녕하세요,

같은 창에 있는 하나의 지표만 다른 지표에 적용할 수 있다는 문제를 이해했습니다.

하나의 지표를 메인 창에 있는 다른 창에 적용하고 별도의 창에 표시하는 방법에 대한 아이디어가 있나요?

고마워요

Bests

 

프로그래밍 방식으로(예를 들어 iCustom을 통해) 지표를 만들고 다른 지표의 데이터를 입력으로 사용하도록 지시할 수 있나요? 또는 더 좋은 방법은 지표를 작성해야 할 데이터 배열을 직접 제공하는 것입니다.

 
ds2:

프로그래밍 방식으로(예를 들어 iCustom을 통해) 지표를 만들고 다른 지표의 데이터를 입력으로 사용하도록 지시할 수 있나요? 또는 더 좋은 방법은 지표를 작성해야 하는 데이터 배열을 직접 제공하는 것입니다.

iCustom 함수를 참조하세요:

인디케이터에서 첫 번째 형태의 호출을 사용하는 경우 "매개 변수" 탭에서 사용자 지정 인디케이터를 시작할 때 계산할 데이터를 추가로 지정할 수 있습니다. "적용 대상" 매개변수를 명시적으로 선택하지 않으면 기본적으로 계산은 "닫기" 값으로 수행됩니다.

mql5 프로그램에서 사용자 지정 지표를 호출할 때는 사용자 지정 지표에서 제공하는 모든 입력 변수 다음에 Applied_Price 매개 변수 또는 다른 지표의 핸들을 마지막에 전달해야 합니다.

 

안녕하세요,

매우 좋은 글이지만 몇 가지 질문이 있습니다.

1.OnCalculate() 함수 호출의 짧은 형식을 사용하는 지표 만 다른 지표에 적용 할 수 있는지 아니면OnCalculate() 함수 호출의형식을 사용하는 지표도 적용 할 수 있습니까? 그렇다면OnCalculate() 함수 호출의 긴 형태를 사용하는 하나의 인디케이터를 다른 인디케이터에 적용할 수 있나요????

2. 한 인디케이터를 다른 인디케이터에 적용하면(RSI에서 TSI로) 일부 표시 문제가 발생합니다(첨부 이미지 참조). RSI는 0에서 100까지 표시되지만 두 번째 지표(TSI)도 0 미만의 값을 가지며 차트에서 볼 수 없는 값입니다. 이것이 문제이며 차트가 두 지표를 모두 올바르게 표시하도록 제대로 조정되지 않는 이유입니다. 이 문제를 해결할 수 있을까요 아니면 메타트레이더 버그인가요?

파일:
RSIcTSI.png  32 kb
 
Rosh:

지표에서 지표를 만들기로 결정했는데 혼란을 겪었습니다.

두 지표 모두 베이스를 기반으로 구축됩니다.

int OnCalculate (const int rates_total,      // 가격[] 배열 크기
                 const int prev_calculated,  // 이전 호출에서 처리된 바
                 const int begin,            // 중요한 데이터가 시작되는 인덱스 в массиве price[]
                 const double& price[]       // 계산용 배열
   );

따라서 사용자는 매개 변수에서 적용된 가격 필드를 설정할 수 있습니다.

내 어려움은 적용된 가격 필드를 내부 지표 (외부 지표가 빌드되는)에 전달하는 방법입니다.

가장 간단한 해결책은 적용된 가격 입력과 적용된 가격 매개 변수가 동일해야한다고 사용자에게 경고하는 것이지만 이것은 약간 비뚤어졌습니다.

 

OnCalculate() 의 예시를 보셨나요?

Для получения значений пользовательского индикатора из других mql5-программ используется функция iCustom(), возвращающая хэндл индикатора для последующих операций. При этом также можно указать необходимый массив  price[] или хэндл другого индикатора. Этот параметр должен передаваться последним в списке  входных переменных пользовательского индикатора.
 
Пример:

void OnStart()
  {
//---
   string terminal_path=StatusInfoString(STATUS_TERMINAL_PATH);
   int handle_customMA=iCustom(Symbol(),PERIOD_CURRENT, "Custom Moving Average",13,0, MODE_EMA,PRICE_TYPICAL);
   if(handle_customMA>0)
      Print("handle_customMA = ",handle_customMA);
   else
      Print("Cannot open or not EX5 file '"+terminal_path+"\\MQL5\\Indicators\\"+"Custom Moving Average.ex5'");
  }

이 예에서 전달된 마지막 매개변수는 ( ENUM_APPLIED_PRICE 열거형에서 가져온) PRICE_TYPICAL 값으로, 이는 사용자 지정 인디케이터가 (고가+저가+종가)/3으로 얻은 일반적인 가격으로 작성됨을 나타냅니다. 매개변수를 지정하지 않으면 각 막대의 종가, 즉 PRICE_CLOSE 값으로 인디케이터가 작성됩니다.

 
Rosh:

OnCalculate() 의 예제를 살펴보셨나요?


예, 보았습니다,

int handle_customMA=iCustom(Symbol(),PERIOD_CURRENT, "Custom Moving Average",13,0, MODE_EMA,PRICE_TYPICAL);

적용된_가격은 iCustom이 호출될 때 명시적으로 지정되지만, iCustom이 호출되는 지표에서 어디에서 가져올 수 있을까요?

사용자가 입력이 아닌 매개 변수에서 설정하기 때문입니다.

int OnInit()
  {
//--- 표시기 버퍼 매핑
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
   hndl=iCustom(_Symbol,_Period,"MyInd",param_ind,???? вот тут нужно указать аплиед_прайс который будет задавать пользователь);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| 사용자 지정 표시기 반복 함수 |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
{
 //...
 return(rates_total);
}

추신 : 비결은 사용자가 적용된 가격 매개 변수를 한 번 설정하고 더 이상 신경 쓰지 않고이 값이 전체 호출 피라미드를 통과했다는 것입니다.