MetaTrader5
메타트레이더 5를 위한 커스텀 볼린저 밴드 지표
안녕하세요, 트레이더 여러분! 오늘은 메타트레이더 5에서 사용할 수 있는 커스텀 볼린저 밴드 지표에 대해 이야기해볼까 합니다. 기존의 볼린저 밴드는 단순 이동 평균 방법만 제공하지만, 제가 개발한 이 지표는 지수 이동 평균, 스무딩 이동 평균, 선형 가중 이동 평균 등 다양한 방법을 선택할 수 있는 옵션을 제공합니다.지표를 사용하려면, 먼저 아래의 경로에 파일을 저장해야 합니다:C:\Users\사용자이름\AppData\Roaming\MetaQuotes\Terminal\Indicators\Examples추가된 기능은 다음과 같습니다:기본값은 0으로 설정되어 있습니다:여기서는 선형 가중 이동 평균을 선택하여 실행한 예시를 보여드리겠습니다: 다음은 지표의 코드입니다://+------------------------------------------------------------------+
//| 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);
}
//+------------------------------------------------------------------+
2024.04.28