기고글 토론 "MQL5 표준 라이브러리 확장 및 코드 재사용" - 페이지 2

 
Tango_X:


인디케이터 버퍼 배열의 인덱싱 방향이 여기에서 어떻게 설정되는지, 즉 ArraySetAsSeries와 동일하게 설정되는지 이해하도록 도와주세요. 기본 방향은 현재에서 과거로이지만 과거에서 현재로 만들어야합니다. 어제부터이 질문으로 어려움을 겪고 있습니다! 도와주세요!

표준 지그재그를 사용하므로 필요하지 않습니다.

//--- create
   m_handle=iCustom(symbol,period,"zigzag",depth,deviation_create,backstep);

지그재그에서 방향이 설정된 위치를 찾아보지만 왜 필요한지 여전히 불분명합니다. 언제든지 인덱싱 방향을 직접 변경할 수 있습니다( https://www.mql5.com/ko/docs/series).

Документация по MQL5: Доступ к таймсериям и индикаторам
Документация по MQL5: Доступ к таймсериям и индикаторам
  • www.mql5.com
Доступ к таймсериям и индикаторам - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Rashid Umarov:

표준 지그재그를 사용하므로 필요하지 않습니다.

지그재그에서 방향이 설정된 위치를 찾아보세요. 하지만 왜 필요한지는 여전히 불분명합니다. 언제든지 색인 방향을 직접 변경할 수 있습니다( https://www.mql5.com/ko/docs/series).


정보를 제공해 주셔서 감사합니다. 저희가 살펴보겠습니다!

 
Rashid Umarov:

표준 지그재그를 사용하므로 필요하지 않습니다.

지그재그에서 방향이 설정된 위치를 찾습니다. 그러나 여전히 왜 필요한지 명확하지 않습니다. 언제든지 색인 방향을 직접 변경할 수 있습니다( https://www.mql5.com/ko/docs/series).


죄송하지만, 예를 들어 지그재그 소스에 액세스할 수 없는 경우 인덱싱 방향을 변경하는 방법은 여전히 명확하지 않습니다. 인덱싱 방향은 입력 매개변수가 참조 배열인 ArraySetAsSeries()로 설정됩니다,

이지만, 이 배열은 없고 표시기 버퍼 배열에 대한 포인터만

//--- 버퍼 생성
      ((CIndicatorBuffer*)At(0)).Name("ZIGZAG");
      ((CIndicatorBuffer*)At(1)).Name("HIGH");
      ((CIndicatorBuffer*)At(2)).Name("LOW");
 
//+------------------------------------------------------------------+
//|OOO_ZIGZAG.mq5 |
//| 저작권 2017, MetaQuotes Software Corp.
//|https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#include <..\Include\Indicators\Indicator.mqh>


//--- 입력 매개변수
input ENUM_TIMEFRAMES   EAPeriod=PERIOD_CURRENT; //예약 기간
input string            CurrencyPair="EURUSD.m"; //Symbol

//+------------------------------------------------------------------+
//| 클래스 CiZigZag.|
//| 목적: 지그재그 표시기 클래스.
//| CIndicator 클래스에서 출력합니다.|
//+------------------------------------------------------------------+
class CiZigZag : public CIndicator
  {
protected:
   int               m_depth;
   int               m_deviation;
   int               m_backstep;

public:
                     CiZigZag(void);
                    ~CiZigZag(void);
   //--- 보호된 데이터에 액세스하는 방법
   int               Depth(void)          const { return(m_depth);      }
   int               Deviation(void)      const { return(m_deviation);  }
   int               Backstep(void)       const { return(m_backstep);   }
   //--- 생성 방법
   bool              Create(const string symbol,const ENUM_TIMEFRAMES period,
                            const int depth,const int deviation_create,const int backstep);
   //--- 지표 데이터에 액세스하는 방법
   double            ZigZag(const int index) const;
   double            High(const int index) const;
   double            Low(const int index) const;
   //--- 식별 방법
   virtual int       Type(void) const { return(IND_CUSTOM); }

protected:
   //--- 사용자 지정 방법
   virtual bool      Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam &params[]);
   bool              Initialize(const string symbol,const ENUM_TIMEFRAMES period,
                                const int depth,const int deviation_init,const int backstep);
  };
//+------------------------------------------------------------------+
//| 생성자|
//+------------------------------------------------------------------+
CiZigZag::CiZigZag(void) : m_depth(-1),
                         m_deviation(-1),
                         m_backstep(-1)
  {
  }
//+------------------------------------------------------------------+
//| 파괴자|
//+------------------------------------------------------------------+
CiZigZag::~CiZigZag(void)
  {
  }
//+------------------------------------------------------------------+
//|| "지그재그" 표시기 만들기|
//+------------------------------------------------------------------+
bool CiZigZag::Create(const string symbol,const ENUM_TIMEFRAMES period,
                      const int depth,const int deviation_create,const int backstep)
  {
//--- 기록 확인
   if(!SetSymbolPeriod(symbol,period))
      return(false);
//--- create
   m_handle=iCustom(symbol,period,"Examples\\ZigZag",depth,deviation_create,backstep);
//--- 결과 확인
   if(m_handle==INVALID_HANDLE)
      return(false);
//--- 표시기가 성공적으로 생성되었습니다.
   if(!Initialize(symbol,period,depth,deviation_create,backstep))
     {
      //--- 초기화 오류
      IndicatorRelease(m_handle);
      m_handle=INVALID_HANDLE;
      return(false);
     }
//--- 확인
   return(true);
  }
//+------------------------------------------------------------------+
//| 범용 파라미터로 인디케이터 초기화하기 |
//+------------------------------------------------------------------+
bool CiZigZag::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam &params[])
  {
   return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value,(int)params[2].integer_value));
  }
//+------------------------------------------------------------------+
//| 특수 매개 변수로 표시기 초기화하기 |
//+------------------------------------------------------------------+
bool CiZigZag::Initialize(const string symbol,const ENUM_TIMEFRAMES period,
                        const int depth,const int deviation_init,const int backstep)
  {
   if(CreateBuffers(symbol,period,3))
     {
      //--- 렌더링 상태 표시줄
      m_name  ="ZigZag";
      m_status="("+symbol+","+PeriodDescription()+","+
               IntegerToString(depth)+","+IntegerToString(deviation_init)+","+
               IntegerToString(backstep)+") H="+IntegerToString(m_handle);
      //--- 설정 저장
      m_depth=depth;
      m_deviation=deviation_init;
      m_backstep=backstep;       
      //--- 버퍼 생성
      ((CIndicatorBuffer*)At(0)).Name("ZIGZAG");
      ((CIndicatorBuffer*)At(1)).Name("HIGH");
      ((CIndicatorBuffer*)At(2)).Name("LOW");
      //--- 확인
      return(true);
     }
//--- 오류
   return(false);
  }
//+------------------------------------------------------------------+
//| "지그재그" 표시기의 지그재그 버퍼에 액세스 ||
//+------------------------------------------------------------------+
double CiZigZag::ZigZag(const int index) const
  {
   CIndicatorBuffer *buffer=At(0);
//--- 확인
   if(buffer==NULL)
      return(EMPTY_VALUE);
//---
   return(buffer.At(index));
  }
//+------------------------------------------------------------------+
//| "지그재그" 표시기의 높은 버퍼에 액세스합니다.
//+------------------------------------------------------------------+
double CiZigZag::High(const int index) const
  {
   CIndicatorBuffer *buffer=At(1);
   //--- 확인
   if(buffer==NULL)
      return(EMPTY_VALUE);
//---
   return(buffer.At(index));
  }
//+------------------------------------------------------------------+
//| "지그재그" 표시기의 낮은 버퍼에 액세스합니다.
//+------------------------------------------------------------------+
double CiZigZag::Low(const int index) const
  {
   CIndicatorBuffer *buffer=At(2);
//--- 확인
   if(buffer==NULL)
      return(EMPTY_VALUE);
//---
   return(buffer.At(index));
  }
//+------------------------------------------------------------------+



CiZigZag *Zig;
//+------------------------------------------------------------------+
//| 사용자 지정 표시기 초기화 기능 |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- 표시기 버퍼 매핑
   Zig=new CiZigZag;
   Zig.Create(CurrencyPair,EAPeriod,12,5,3);
//---
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   delete(Zig);
  }  
//+------------------------------------------------------------------+
//| 사용자 지정 표시기 반복 함수 |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int limit;
   if(prev_calculated==0)limit=0;
   else
     limit=prev_calculated-1; 
     
   for(int i=limit;i<rates_total && !IsStopped();i++)
      {
       Zig.Refresh();
       if (Zig.ZigZag(i)!=0) Print(Zig.ZigZag(i)," ",time[i]);  
      }
//--- 다음 호출을 위한 prev_calculated의 반환 값
   return(rates_total);
  }
//+------------------------------------------------------------------+

다음은 지표의 전체 코드이며, 지표 값의 출력은 현재에서 과거로, 그 반대의 경우도 필요합니다.

 
Tango_X:

죄송하지만, 예를 들어 소스 지그재그에 액세스할 수 없는 경우 인덱싱 방향을 변경하는 방법은 여전히 명확하지 않습니다. 인덱싱 방향은 입력 매개변수가 참조 배열인 ArraySetAsSeries()로 설정됩니다,

이지만 이 배열은 없고 다음과 같은 형태의 인디케이터 버퍼 배열에 대한 포인터만 있습니다.

CIndicator 베이스 클래스에는 인디케이터 버퍼에서 데이터를 가져오는 데 사용할 수 있는 GetData 메서드가 있습니다.

인디케이터 버퍼에서 시작 위치 및 번호별로 데이터를 가져옵니다.

int GetData(
const intstart_pos, // 위치
const intcount, // 숫자
const int buffer_num, // 버퍼 번호
double&buffer[]// 배열
) const



그 후, ArraySetAsSeries를 사용하여 배열의 원하는 인덱싱 방향을 설정합니다.

 
Rashid Umarov:

인디케이터 베이스 클래스에는 인디케이터 버퍼에서 데이터를 가져오는 데 사용할 수 있는 GetData 메서드가 있습니다.

인디케이터 버퍼에서 시작 위치 및 개수별로 데이터를 가져옵니다.

int GetData(
const intstart_pos, // 위치
const intcount, // 숫자
const int buffer_num, // 버퍼 번호
double&buffer[]// 배열
) const



그런 다음 배열의 원하는 인덱싱 방향을 설정합니다.

그래서 표시기 버퍼에 두 번 액세스하는 것으로 밝혀졌지만 다른 방식으로? 결국, 아래에서 우리는 이미 인디케이터 버퍼의 값에 액세스하고 있지 않나요? 중간 배열 더블 &buffer[] 내가 올바르게 이해했나요?

//+------------------------------------------------------------------+
//| "지그재그" 표시기의 지그재그 버퍼에 액세스 ||
//+------------------------------------------------------------------+
double CiZigZag::ZigZag(const int index) const
  {
   CIndicatorBuffer *buffer=At(0);
//--- 확인
   if(buffer==NULL)
      return(EMPTY_VALUE);
//---
   return(buffer.At(index));
  }
 
Rashid Umarov:

인디케이터 베이스 클래스에는 인디케이터 버퍼에서 데이터를 가져오는 데 사용할 수 있는 GetData 메서드가 있습니다.

인디케이터 버퍼에서 시작 위치 및 개수별로 데이터를 가져옵니다.

int GetData(
const intstart_pos, // 위치
const intcount, // 숫자
const int buffer_num, // 버퍼 번호
double&buffer[]// 배열
) const



그런 다음 ArraySetAsSeries를 사용하여 배열의 원하는 인덱싱 방향을 설정합니다.

제가 제대로 이해했나요?

CiZigZag *Zig;
double ArrZig[];
//+------------------------------------------------------------------+
//| 사용자 지정 표시기 초기화 기능 |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- 표시기 버퍼 매핑
   Zig=new CiZigZag;
   Zig.Create(CurrencyPair,EAPeriod,12,5,3);

   SetIndexBuffer(0,ArrZig,INDICATOR_CALCULATIONS);
   ArraySetAsSeries(ArrZig,false);

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   delete(Zig);
  }
//+------------------------------------------------------------------+
//| 사용자 지정 표시기 반복 함수 |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int limit;
   if(prev_calculated==0) limit=0;
   else
      limit=prev_calculated-1;

   Zig.Refresh();
   Zig.GetData(0,rates_total-1,0,ArrZig);

   for(int i=limit;i<rates_total-1 && !IsStopped();i++)
     {

      //if (Zig.ZigZag(i)!=0) Print(Zig.ZigZag(i)," ",time[i]); 
      if(ArrZig[i]!=0) Print(ArrZig[i]," ",time[i]);
     }
//--- 다음 호출을 위한 prev_calculated의 반환 값
   return(rates_total);
  }
//+------------------------------------------------------------------+
매 틱마다 전체 히스토리를 복사해야 한다고요?
 
Tango_X:

제가 제대로 이해하고 있나요?

각 틱에 전체 기록을 복사해야 한다는 것이 밝혀졌나요?

1. 새 바를 열 때 할 수 있습니다.

2. 왜 매번 모든 지표 값을 가져와야하고 동시에 인덱싱 방향을 처리해야합니까? 작업은 전혀 무엇입니까?

 

간단한 인디케이터를 나중에 차트에서 사용하거나 iCustom을 통해 사용하는데 왜 클래스로 래핑할까요?

Второе решение лучше, потому что является объектно-ориентированным

OOP를 위한 OOP, 알겠습니다.

 
Rashid Umarov:

1. 새 바를 열 수 있습니다.

2. 왜 매번 모든 지표 값을 가져와야하고 동시에 인덱싱 방향에 신경을 써야합니까? 작업은 전혀 무엇입니까?


문제는 루프 조건으로 해결되었으며 이제 모든 것이 원하는대로 작동합니다. 감사합니다!