지표: 슈퍼트렌드

 

슈퍼트렌드:

슈퍼트렌드 추세 표시기.

슈퍼트렌드

Author: Nikolay Kositsin

 

니콜라이! 지연이 가장 적고 잘못된 신호가 가장 적은 아이디어는 무엇입니까 (물론 이것이 전혀 결정될 수 있다면).

 
Makser:

니콜라이! 어떤 아이디어가 가장 지연이 적고 잘못된 신호가 가장 적은지 (물론 이것이 전혀 결정될 수 있다면).

여기에 질문이 있습니다. 저는 십자가와 최근에는 다른 모든 것에서 JFatlSpeed를 사용합니다. 그러나 4 시간 마커에서만. 그리고 X2MA_BBx9에서 5 분 거래에서 바운스를 잡습니다.
 

그래서 제 프로그래밍 스타일은 절대 아닙니다.

나무만 보고 숲을 보지 못한다 = 모든 주석에 대한 코드를 볼 수 없다.

또한 입력 매개 변수 'shift'는 전혀 사용되지 않습니다.

저는 이것을 제 스타일로 다시 프로그래밍했는데, 아마도 '슈퍼 프로그래머'는 제 책에서 잎을 가져갈 수 있을 것입니다.

//+------------------------------------------------------------------+
//|슈퍼트렌드.mq5 |
//| 원본 코드는 https://www.mql5.com/ko/code/527 | 
//| 제이슨 로빈슨의 원본 코드, 니콜라이 코시친이 재작성 |
//| 개선자: 오토 파우저 가명 크로넨차크라 | | 개선됨
//+------------------------------------------------------------------+ 

//--- 포함
#include <Utils.mqh>

//--- 일반 속성
#property copyright COPY 
#property link      LINK 
#property version   "1.00"

//--- 표시기 속성
#property indicator_chart_window
#property indicator_buffers 4 
#property indicator_plots   4

//--- 입력 매개변수
input int CCIPeriod  =  50;   // CCI 표시 기간 
input int ATRPeriod  =   5;   // ATR 표시 기간
input int Level      =   0;   // CCI 활성화 수준

//---- 표시기 버퍼
double   ATR[],
         CCI[];
double   TrendUp[],
         TrendDn[];
double   SignUp[],
         SignDn[];
         
//---- 전역 변수
int      min_rates_total;
int      ATR_Handle,
         CCI_Handle;

//+------------------------------------------------------------------+
//| 사용자 지정 표시기 초기화 기능 |
//+------------------------------------------------------------------+
int OnInit()
{
   min_rates_total=MathMax(CCIPeriod,ATRPeriod);

   CCI_Handle=iCCI(NULL,0,CCIPeriod,PRICE_TYPICAL);
   if(InvalidHandle(CCI_Handle,"iCCI"))
      return(INIT_FAILED);

   ATR_Handle=iATR(NULL,0,ATRPeriod);
   if(InvalidHandle(ATR_Handle,"iATR"))
      return(INIT_FAILED);

   string shortname=IndiShortName("Supertrend",CCIPeriod,ATRPeriod);
   IndicatorSetString(INDICATOR_SHORTNAME,shortname);
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);

   InitBuffer(TrendUp,DRAW_LINE ,"Supertrend Up"         ,clrLime,min_rates_total,0  ,2,true);
   InitBuffer(TrendDn,DRAW_LINE ,"Supertrend Down"       ,clrRed ,min_rates_total,0  ,2,true);
   InitBuffer(SignUp ,DRAW_ARROW,"Supertrend signal Buy" ,clrLime,min_rates_total,108,1,true);
   InitBuffer(SignDn ,DRAW_ARROW,"Supertrend signal Sell",clrRed ,min_rates_total,108,1,true);

   ArraySetAsSeries(ATR,true);
   ArraySetAsSeries(CCI,true);

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| 사용자 지정 표시기 반복 함수 |
//+------------------------------------------------------------------+
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[])
{
   if                                                    // check
      (
          BarsCalculated(CCI_Handle)<rates_total ||      // CCI 표시기 확인
          BarsCalculated(ATR_Handle)<rates_total ||      // ATR 표시기 확인
          rates_total<min_rates_total                    // 막대가 충분한지 확인
      )
          return(0);                                     // 다음 틱 시도

   int limit,to_copy,bar;

   ArraySetAsSeries(high,true);                          //를 매 틱마다 AsSeries로 설정해야 합니다.
   ArraySetAsSeries(low ,true);

   if(prev_calculated>rates_total || prev_calculated<=0) // 지표 계산의 첫 시작을 확인합니다.
      limit=rates_total-min_rates_total;                 // 모든 막대 계산을 위한 시작 인덱스
   else
      limit=rates_total-prev_calculated;                 // 새 막대 계산을 위한 시작 인덱스

   to_copy=limit+1;                                      // ATR-Data를 버퍼에 복사
   if(CopyBuffer(ATR_Handle,0,0,to_copy,ATR)<=0) return(0);

   to_copy++;                                            // CCI-Data를 버퍼에 복사
   if(CopyBuffer(CCI_Handle,0,0,to_copy,CCI)<=0) return(0);

   for(bar=limit; bar>=0; bar--)                         // 계산 메인 루프
     {
      TrendUp[bar]=NULL;                                 // 모든 버퍼 지우기
      TrendDn[bar]=NULL;
      SignUp [bar]=NULL;
      SignDn [bar]=NULL;
                                                         // 라인 계산
      if(CCI[bar]>=Level && CCI[bar+1]<Level) TrendUp[bar]=TrendDn[bar+1];
      if(CCI[bar]<=Level && CCI[bar+1]>Level) TrendDn[bar]=TrendUp[bar+1];

      if(CCI[bar]>Level)                                 
        {
         TrendUp[bar]=low[bar]-ATR[bar];
         if(TrendUp[bar]<TrendUp[bar+1] && CCI[bar+1]>=Level) TrendUp[bar]=TrendUp[bar+1];
        }

      if(CCI[bar]<Level)                                 
        {
         TrendDn[bar]=high[bar]+ATR[bar];
         if(TrendDn[bar]>TrendDn[bar+1] && CCI[bar+1]<=Level) TrendDn[bar]=TrendDn[bar+1];
        }

      if(TrendDn[bar+1]!=0.0 && TrendUp[bar]!=0.0) SignUp[bar]=TrendUp[bar];  // 신호 UP 확인
      if(TrendUp[bar+1]!=0.0 && TrendDn[bar]!=0.0) SignDn[bar]=TrendDn[bar];  // 신호 DOWN 확인
     }
    
   return(rates_total);
}
//+------------------------------------------------------------------+
//|Utils.mqh |
//| Copyright © 2018, Ing. 오토 파우저 | 
//| https://www.mql5.com/ko/users/kronenchakra | 
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| 정의|
//+------------------------------------------------------------------+

#define  COPY   "저작권 © 2018, 오토 파우저"
#define  LINK   "https://www.mql5.com/ko/users/kronenchakra"
#define  SPACER "---------------------" 

//+------------------------------------------------------------------+
//| 약어|
//+------------------------------------------------------------------+

#define  PRICE ENUM_APPLIED_PRICE
#define  TIMEF ENUM_TIMEFRAMES

//+------------------------------------------------------------------+
//| 보조 기능|
//+------------------------------------------------------------------+

void InitBuffer(double &_buffer[], ENUM_DRAW_TYPE _type, string _label, color _color, int _begin, int _arrow=159, int _width=1, bool _series=false)
{
   static int idx=0;                                  // 버퍼 인덱스를 0으로 초기화
   SetIndexBuffer     (idx,_buffer);                  // 버퍼 초기화
   ArrayInitialize    (_buffer ,NULL);                // 버퍼 초기화
   ArraySetAsSeries   (_buffer ,_series);             // AsSeries 설정
                                                      // 속성 설정
   PlotIndexSetInteger(idx,PLOT_DRAW_TYPE  ,_type );
   PlotIndexSetInteger(idx,PLOT_LINE_COLOR ,_color);
   PlotIndexSetInteger(idx,PLOT_LINE_WIDTH ,_width);
   PlotIndexSetInteger(idx,PLOT_DRAW_BEGIN ,_begin);
   PlotIndexSetInteger(idx,PLOT_ARROW      ,_arrow);
   PlotIndexSetString (idx,PLOT_LABEL      ,_label);
   PlotIndexSetDouble (idx,PLOT_EMPTY_VALUE,NULL  );
   idx++;                                             // 다음 호출을 위한 버퍼 인덱스 증가
}

bool InvalidHandle(int _handle, string _msg)
{
   if(_handle==INVALID_HANDLE)                     // 핸들 확인
      Alert("*ERROR* creating "+_msg+" handle.");  // 정보
   return(_handle==INVALID_HANDLE);                // 유효하지 않으면 참을 반환합니다.
}

string IndiShortName(string _name, int val_1, int val_2=NULL, int val_3=NULL)
{
   string result=_name+"("+IntegerToString(val_1);
   if(val_2!=NULL)
      result=result+","+IntegerToString(val_2);
   if(val_3!=NULL)
      result=result+","+IntegerToString(val_3);
   return(result+")");
}

//+------------------------------------------------------------------+
//| 계산 함수|
//+------------------------------------------------------------------+
double StdDeviation(int position,const double &price[],const double &MAprice[],int period)
{
   int i;
   double StdDev_dTmp=0.0;

   if(position<period) return(StdDev_dTmp);        // 위치 확인

   for(i=0;i<period;i++)                           // 계산된 StdDev
      StdDev_dTmp+=MathPow(price[position-i]-MAprice[position],2);

   StdDev_dTmp=MathSqrt(StdDev_dTmp/period);

   return(StdDev_dTmp);                            // 계산된 값 반환
}

바로 명확해 보입니다.

예를 들어 한 줄로 플롯 버퍼를 정의하는 방법과 같이 MetaQutes도 무언가를 배울 수 있을 것입니다.

파일:
supertrend.mq5  11 kb
Utils.mqh  7 kb
 

Otto,

그거

      TrendUp[bar]=NULL;                                 // 모든 버퍼 지우기
      TrendDn[bar]=NULL;
      SignUp [bar]=NULL;
      SignDn [bar]=NULL;

는 위험합니다. NULL은'void' 유형입니다. 나중에 MT5를 더 빠르게 만들기 위해 실제로 아무것도 할당되지 않거나(그러면 이전 값이 남게 됨) 메모리 위치가 변경될 때 임의의 값이 생성될 수도 있습니다.

심볼에는 _symbol을 사용하고 값에는 EMPTY_VALUE 또는 0을 직접 사용하는 것이 더 나을 것 같습니다. 그렇게 하면 무(無)에 존재감을 부여할 수 있습니다.

 
어떻게 받을 수 있나요?
 
이 표시기를 사용하고 싶습니다.
 
ka03ht8096:
어떻게 받을 수 있나요?

1단계

2단계

 
승수와 ATR 값은 어떤 입력인가요?
 

MT4용이 있나요?