보조지표 게시글

메타트레이더 5를 위한 커스텀 볼린저 밴드 지표

첨부파일
49464.zip (2.27 KB, 다운로드 0회)

안녕하세요, 트레이더 여러분! 오늘은 메타트레이더 5에서 사용할 수 있는 커스텀 볼린저 밴드 지표에 대해 이야기해볼까 합니다. 기존의 볼린저 밴드는 단순 이동 평균 방법만 제공하지만, 제가 개발한 이 지표는 지수 이동 평균, 스무딩 이동 평균, 선형 가중 이동 평균 등 다양한 방법을 선택할 수 있는 옵션을 제공합니다.

지표를 사용하려면, 먼저 아래의 경로에 파일을 저장해야 합니다:

C:\Users\사용자이름\AppData\Roaming\MetaQuotes\Terminal\Indicators\Examples

추가된 기능은 다음과 같습니다:

기능 스크린샷

기본값은 0으로 설정되어 있습니다:

기본값 스크린샷

여기서는 선형 가중 이동 평균을 선택하여 실행한 예시를 보여드리겠습니다:

예시 1  예시 2

다음은 지표의 코드입니다:

//+------------------------------------------------------------------+
//|                                              BBPersonalizada.mq5 |
//|                                            Lucas Vidal |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "Lucas Vidal"
#property link        "https://www.mql5.com/en/users/lucasmoura00"
#property description "Bollinger Bands Personalizada"
#include <MovingAverages.mqh>
//---
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   3
#property indicator_type1   DRAW_LINE
#property indicator_color1  LightSeaGreen
#property indicator_type2   DRAW_LINE
#property indicator_color2  LightSeaGreen
#property indicator_type3   DRAW_LINE
#property indicator_color3  LightSeaGreen
#property indicator_label1  "Bands middle"
#property indicator_label2  "Bands upper"
#property indicator_label3  "Bands lower"
//--- input parameters
enum MovingAverageMethod {
    Simple,    // 0
    Exponential,  // 1
    Smoothed,     // 2
    LinearWeighted  // 3
};
input MovingAverageMethod InpMaMethod = Simple; // 이동 평균 방법
input int     InpBandsPeriod=20;       // 기간
input int     InpBandsShift=0;         // 이동
input double  InpBandsDeviations=2.0  // 편차
//--- global variables
int           ExtBandsPeriod,ExtBandsShift;
double        ExtBandsDeviations;
int           ExtPlotBegin=0;
//--- indicator buffer
double        ExtMLBuffer[];
double        ExtTLBuffer[];
double        ExtBLBuffer[];
double        ExtStdDevBuffer[];
//+------------------------------------------------------------------+
//| 커스텀 지표 초기화 함수                                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- 입력 값 확인
   if(InpBandsPeriod<2)
     {
      ExtBandsPeriod=20;
      PrintFormat("잘못된 입력 변수 InpBandsPeriod=%d. 지표가 계산에 사용할 값=%d입니다.",InpBandsPeriod,ExtBandsPeriod);
     }
   else
      ExtBandsPeriod=InpBandsPeriod;
   if(InpBandsShift<0)
     {
      ExtBandsShift=0;
      PrintFormat("잘못된 입력 변수 InpBandsShift=%d. 지표가 계산에 사용할 값=%d입니다.",InpBandsShift,ExtBandsShift);
     }
   else
      ExtBandsShift=InpBandsShift;
   if(InpBandsDeviations==0.0)
     {
      ExtBandsDeviations=2.0;
      PrintFormat("잘못된 입력 변수 InpBandsDeviations=%f. 지표가 계산에 사용할 값=%f입니다.",InpBandsDeviations,ExtBandsDeviations);
     }
   else
      ExtBandsDeviations=InpBandsDeviations;
//--- 버퍼 정의
   SetIndexBuffer(0,ExtMLBuffer);
   SetIndexBuffer(1,ExtTLBuffer);
   SetIndexBuffer(2,ExtBLBuffer);
   SetIndexBuffer(3,ExtStdDevBuffer,INDICATOR_CALCULATIONS);
//--- 인덱스 레이블 설정
   PlotIndexSetString(0,PLOT_LABEL,"Bands("+string(ExtBandsPeriod)+") Middle");
   PlotIndexSetString(1,PLOT_LABEL,"Bands("+string(ExtBandsPeriod)+") Upper");
   PlotIndexSetString(2,PLOT_LABEL,"Bands("+string(ExtBandsPeriod)+") Lower");
//--- 지표 이름 설정
   IndicatorSetString(INDICATOR_SHORTNAME,"Bollinger Bands");
//--- 인덱스 그리기 시작 설정
   ExtPlotBegin=ExtBandsPeriod-1;
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtBandsPeriod);
   PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,ExtBandsPeriod);
   PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,ExtBandsPeriod);
//--- 인덱스 이동 설정
   PlotIndexSetInteger(0,PLOT_SHIFT,ExtBandsShift);
   PlotIndexSetInteger(1,PLOT_SHIFT,ExtBandsShift);
   PlotIndexSetInteger(2,PLOT_SHIFT,ExtBandsShift);
//--- 지표 값의 숫자 자리수 설정
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
  }
//+------------------------------------------------------------------+
//| 이동 평균 계산                                         |
//+------------------------------------------------------------------+
double CalculateMovingAverage(int position, int period, const double &price[]) {
    switch(InpMaMethod) {
        case Simple:
            return SimpleMA(position, period, price);
        case Exponential:
            // iMA 호출 시 올바른 매개변수 수정
            return iMA(NULL, 0, period, 0, MODE_EMA, PRICE_CLOSE);
        case Smoothed:
            // SMMA 함수를 구현하세요
            break;
        case LinearWeighted:
            return LinearWeightedMA(position, period, price);
    }
    return 0; // 정의되지 않은 방법의 기본 반환
}

//+------------------------------------------------------------------+
//| 볼린저 밴드                                                  |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
   if(rates_total<ExtPlotBegin)
      return(0);
//--- 이전 시작 시점으로 인덱스 그리기 시작 설정
   if(ExtPlotBegin!=ExtBandsPeriod+begin)
     {
      ExtPlotBegin=ExtBandsPeriod+begin;
      PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtPlotBegin);
      PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,ExtPlotBegin);
      PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,ExtPlotBegin);
     }
//--- 계산 시작
   int pos;
   if(prev_calculated>1)
      pos=prev_calculated-1;
   else
      pos=0;
//--- 메인 사이클
   for(int i=pos; i<rates_total && !IsStopped(); i++)
     {
      //--- 중간선
      ExtMLBuffer[i]=CalculateMovingAverage(i, ExtBandsPeriod, price);
      //--- 표준편차 계산 및 기록
      ExtStdDevBuffer[i]=StdDev_Func(i,price,ExtMLBuffer,ExtBandsPeriod);
      //--- 상한선
      ExtTLBuffer[i]=ExtMLBuffer[i]+ExtBandsDeviations*ExtStdDevBuffer[i];
      //--- 하한선
      ExtBLBuffer[i]=ExtMLBuffer[i]-ExtBandsDeviations*ExtStdDevBuffer[i];
     }
//--- OnCalculate 완료. 새로운 prev_calculated 반환.
  return(rates_total);
  }
//+------------------------------------------------------------------+
//| 표준 편차 계산                                     |
//+------------------------------------------------------------------+
double StdDev_Func(const int position,const double &price[],const double &ma_price[],const int period)
  {
   double std_dev=0.0;
//--- 표준편차 계산
   if(position>=period)
     {
      for(int i=0; i<period; i++)
         std_dev+=MathPow(price[position-i]-ma_price[position],2.0);
      std_dev=MathSqrt(std_dev/period);
     }
//--- 계산된 값 반환
   return(std_dev);
  }
//+------------------------------------------------------------------+




연관 포스트

댓글 (0)