MetaTrader5
Bollinger Bands Tersuai untuk MetaTrader 5: Panduan Lengkap
Saya telah membangunkan indikator ini sebagai alternatif kepada kaedah purata bergerak yang standard dalam indikator Bollinger Bands MetaTrader 5, yang hanya menawarkan kaedah 'simple'. Dengan indikator saya ini, pengguna mempunyai pilihan untuk memilih daripada kaedah tambahan termasuk Exponential, Smoothed, dan Linear Weighted. Untuk menggunakan indikator ini, anda perlu meletakkannya dalam direktori (pada Windows) yang menyerupai laluan berikut: C:\Users\[NamaPengguna]\AppData\Roaming\MetaQuotes\Terminal\Indicators\Examples Ciri tambahan: Indikator ini ditetapkan kepada sifar secara lalai: Contoh pelaksanaan memilih purata Linear Weighted: KOD: //+------------------------------------------------------------------+
//| 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 parametrs
enum MovingAverageMethod {
Simple, // 0
Exponential, // 1
Smoothed, // 2
LinearWeighted // 3
};
input MovingAverageMethod InpMaMethod = Simple; // Método da Média Móvel
input int InpBandsPeriod=20; // Period
input int InpBandsShift=0; // Shift
input double InpBandsDeviations=2.0 // Deviation
//--- global variables
int ExtBandsPeriod,ExtBandsShift;
double ExtBandsDeviations;
int ExtPlotBegin=0;
//--- indicator buffer
double ExtMLBuffer[];
double ExtTLBuffer[];
double ExtBLBuffer[];
double ExtStdDevBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- check for input values
if(InpBandsPeriod<2)
{
ExtBandsPeriod=20;
PrintFormat("Incorrect value for input variable InpBandsPeriod=%d. Indicator will use value=%d for calculations.",InpBandsPeriod,ExtBandsPeriod);
}
else
ExtBandsPeriod=InpBandsPeriod;
if(InpBandsShift<0)
{
ExtBandsShift=0;
PrintFormat("Incorrect value for input variable InpBandsShift=%d. Indicator will use value=%d for calculations.",InpBandsShift,ExtBandsShift);
}
else
ExtBandsShift=InpBandsShift;
if(InpBandsDeviations==0.0)
{
ExtBandsDeviations=2.0;
PrintFormat("Incorrect value for input variable InpBandsDeviations=%f. Indicator will use value=%f for calculations.",InpBandsDeviations,ExtBandsDeviations);
}
else
ExtBandsDeviations=InpBandsDeviations;
//--- define buffers
SetIndexBuffer(0,ExtMLBuffer);
SetIndexBuffer(1,ExtTLBuffer);
SetIndexBuffer(2,ExtBLBuffer);
SetIndexBuffer(3,ExtStdDevBuffer,INDICATOR_CALCULATIONS);
//--- set index labels
PlotIndexSetString(0,PLOT_LABEL,"Bands("+string(ExtBandsPeriod)+") Middle");
PlotIndexSetString(1,PLOT_LABEL,"Bands("+string(ExtBandsPeriod)+") Upper");
PlotIndexSetString(2,PLOT_LABEL,"Bands("+string(ExtBandsPeriod)+") Lower");
//--- indicator name
IndicatorSetString(INDICATOR_SHORTNAME,"Bollinger Bands");
//--- indexes draw begin settings
ExtPlotBegin=ExtBandsPeriod-1;
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtBandsPeriod);
PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,ExtBandsPeriod);
PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,ExtBandsPeriod);
//--- indexes shift settings
PlotIndexSetInteger(0,PLOT_SHIFT,ExtBandsShift);
PlotIndexSetInteger(1,PLOT_SHIFT,ExtBandsShift);
PlotIndexSetInteger(2,PLOT_SHIFT,ExtBandsShift);
//--- number of digits of indicator value
IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
}
//+------------------------------------------------------------------+
//| Calculate Moving Average |
//+------------------------------------------------------------------+
double CalculateMovingAverage(int position, int period, const double &price[]) {
switch(InpMaMethod) {
case Simple:
return SimpleMA(position, period, price);
case Exponential:
// Corrigindo a chamada da função iMA com os parâmetros corretos
return iMA(NULL, 0, period, 0, MODE_EMA, PRICE_CLOSE);
case Smoothed:
// Implemente sua função SMMA aqui
break;
case LinearWeighted:
return LinearWeightedMA(position, period, price);
}
return 0; // Retorno padrão em caso de método indefinido
}
//+------------------------------------------------------------------+
//| Bollinger Bands |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double &price[])
{
if(rates_total<ExtPlotBegin)
return(0);
//--- indexes draw begin settings, when we've recieved previous begin
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);
}
//--- starting calculation
int pos;
if(prev_calculated>1)
pos=prev_calculated-1;
else
pos=0;
//--- main cycle
for(int i=pos; i<rates_total && !IsStopped(); i++)
{
//--- middle line
ExtMLBuffer[i]=CalculateMovingAverage(i, ExtBandsPeriod, price);
//--- calculate and write down StdDev
ExtStdDevBuffer[i]=StdDev_Func(i,price,ExtMLBuffer,ExtBandsPeriod);
//--- upper line
ExtTLBuffer[i]=ExtMLBuffer[i]+ExtBandsDeviations*ExtStdDevBuffer[i];
//--- lower line
ExtBLBuffer[i]=ExtMLBuffer[i]-ExtBandsDeviations*ExtStdDevBuffer[i];
}
//--- OnCalculate done. Return new prev_calculated.
return(rates_total);
}
//+------------------------------------------------------------------+
//| Calculate Standard Deviation |
//+------------------------------------------------------------------+
double StdDev_Func(const int position,const double &price[],const double &ma_price[],const int period)
{
double std_dev=0.0;
//--- calcualte StdDev
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 calculated value
return(std_dev);
}
//+------------------------------------------------------------------+
2024.04.28