354 行
24 KiB
MQL5
354 行
24 KiB
MQL5
#property copyright "4kk4"
|
|
#property link "https://www.mql5.com/en/users/4kk4"
|
|
#property description "KG Bollinger Bands"
|
|
//#include <MovingAverages.mqh>
|
|
//---
|
|
#property indicator_chart_window
|
|
#property indicator_buffers 6
|
|
#property indicator_plots 5
|
|
#property indicator_type1 DRAW_LINE
|
|
#property indicator_color1 Red
|
|
#property indicator_width1 2
|
|
#property indicator_type2 DRAW_LINE
|
|
#property indicator_color2 Red
|
|
#property indicator_type3 DRAW_LINE
|
|
#property indicator_color3 Red
|
|
#property indicator_type4 DRAW_LINE
|
|
#property indicator_color4 Red
|
|
#property indicator_style4 STYLE_DOT
|
|
#property indicator_type5 DRAW_LINE
|
|
#property indicator_color5 Red
|
|
#property indicator_style5 STYLE_DOT
|
|
|
|
#property indicator_label1 "Bands middle"
|
|
#property indicator_label2 "Bands upper 1"
|
|
#property indicator_label3 "Bands lower 1"
|
|
#property indicator_label4 "Bands upper 2"
|
|
#property indicator_label5 "Bands lower 2"
|
|
|
|
//--- input parametrs
|
|
input ENUM_MA_METHOD InpMaMethod = MODE_EMA; // Mode
|
|
input int InpBandsPeriod=60; // Periode MA (Total Menit)
|
|
input int InpBandsShift=0; // Shift
|
|
input double InpBandsDeviations=1.0; // Deviation 1
|
|
input double InpBandsDeviation2=2.0; // Deviation 2
|
|
//--- global variables
|
|
int ExtBandsPeriod,ExtBandsShift;
|
|
double ExtBandsDeviations;
|
|
double ExtBandsDeviation2;
|
|
int ExtPlotBegin=0;
|
|
//--- indicator buffer
|
|
double ExtMLBuffer[];
|
|
double ExtTLBuffer[];
|
|
double ExtBLBuffer[];
|
|
double ExtTL2Buffer[];
|
|
double ExtBL2Buffer[];
|
|
double ExtStdDevBuffer[];
|
|
string short_name = "Bands ";
|
|
//+------------------------------------------------------------------+
|
|
//| simple moving average |
|
|
//+------------------------------------------------------------------+
|
|
void CalculateSimpleMA(int rates_total,int prev_calculated,int begin,const double &price[])
|
|
{
|
|
int i,limit;
|
|
//--- first calculation or number of bars was changed
|
|
if(prev_calculated==0)// first calculation
|
|
{
|
|
limit=ExtBandsPeriod+begin;
|
|
//--- set empty value for first limit bars
|
|
for(i=0;i<limit-1;i++)
|
|
ExtMLBuffer[i]=0.0;
|
|
//--- calculate first visible value
|
|
double firstValue=0;
|
|
for(i=begin;i<limit;i++)
|
|
firstValue+=price[i];
|
|
firstValue/=ExtBandsPeriod;
|
|
ExtMLBuffer[limit-1]=firstValue;
|
|
}
|
|
else
|
|
limit=prev_calculated-1;
|
|
//--- main loop
|
|
for(i=limit;i<rates_total && !IsStopped();i++)
|
|
ExtMLBuffer[i]=ExtMLBuffer[i-1]+(price[i]-price[i-ExtBandsPeriod])/ExtBandsPeriod;
|
|
//---
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| exponential moving average |
|
|
//+------------------------------------------------------------------+
|
|
void CalculateEMA(int rates_total,int prev_calculated,int begin,const double &price[])
|
|
{
|
|
int i,limit;
|
|
double SmoothFactor=2.0/(1.0+ExtBandsPeriod);
|
|
//--- first calculation or number of bars was changed
|
|
if(prev_calculated==0)
|
|
{
|
|
limit=ExtBandsPeriod+begin;
|
|
ExtMLBuffer[begin]=price[begin];
|
|
for(i=begin+1;i<limit;i++)
|
|
ExtMLBuffer[i]=price[i]*SmoothFactor+ExtMLBuffer[i-1]*(1.0-SmoothFactor);
|
|
}
|
|
else
|
|
limit=prev_calculated-1;
|
|
//--- main loop
|
|
for(i=limit;i<rates_total && !IsStopped();i++)
|
|
ExtMLBuffer[i]=price[i]*SmoothFactor+ExtMLBuffer[i-1]*(1.0-SmoothFactor);
|
|
//---
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| linear weighted moving average |
|
|
//+------------------------------------------------------------------+
|
|
void CalculateLWMA(int rates_total,int prev_calculated,int begin,const double &price[])
|
|
{
|
|
int i,limit;
|
|
static int weightsum;
|
|
double sum;
|
|
//--- first calculation or number of bars was changed
|
|
if(prev_calculated==0)
|
|
{
|
|
weightsum=0;
|
|
limit=ExtBandsPeriod+begin;
|
|
//--- set empty value for first limit bars
|
|
for(i=0;i<limit;i++)
|
|
ExtMLBuffer[i]=0.0;
|
|
//--- calculate first visible value
|
|
double firstValue=0;
|
|
for(i=begin;i<limit;i++)
|
|
{
|
|
int k=i-begin+1;
|
|
weightsum+=k;
|
|
firstValue+=k*price[i];
|
|
}
|
|
firstValue/=(double)weightsum;
|
|
ExtMLBuffer[limit-1]=firstValue;
|
|
}
|
|
else
|
|
limit=prev_calculated-1;
|
|
//--- main loop
|
|
for(i=limit;i<rates_total && !IsStopped();i++)
|
|
{
|
|
sum=0;
|
|
for(int j=0;j<ExtBandsPeriod;j++)
|
|
sum+=(ExtBandsPeriod-j)*price[i-j];
|
|
ExtMLBuffer[i]=sum/weightsum;
|
|
}
|
|
//---
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| smoothed moving average |
|
|
//+------------------------------------------------------------------+
|
|
void CalculateSmoothedMA(int rates_total,int prev_calculated,int begin,const double &price[])
|
|
{
|
|
int i,limit;
|
|
//--- first calculation or number of bars was changed
|
|
if(prev_calculated==0)
|
|
{
|
|
limit=ExtBandsPeriod+begin;
|
|
//--- set empty value for first limit bars
|
|
for(i=0;i<limit-1;i++)
|
|
ExtMLBuffer[i]=0.0;
|
|
//--- calculate first visible value
|
|
double firstValue=0;
|
|
for(i=begin;i<limit;i++)
|
|
firstValue+=price[i];
|
|
firstValue/=ExtBandsPeriod;
|
|
ExtMLBuffer[limit-1]=firstValue;
|
|
}
|
|
else
|
|
limit=prev_calculated-1;
|
|
//--- main loop
|
|
for(i=limit;i<rates_total && !IsStopped();i++)
|
|
ExtMLBuffer[i]=(ExtMLBuffer[i-1]*(ExtBandsPeriod-1)+price[i])/ExtBandsPeriod;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 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);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Custom indicator initialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnInit()
|
|
{
|
|
//--- check for input values
|
|
if(InpBandsPeriod<2)
|
|
{
|
|
ExtBandsPeriod=60;
|
|
PrintFormat("Incorrect value for input variable InpBandsPeriod=%d. Indicator will use value=%d for calculations.",InpBandsPeriod,ExtBandsPeriod);
|
|
}
|
|
else
|
|
{
|
|
|
|
switch(InpMaMethod)
|
|
{
|
|
case MODE_EMA :
|
|
short_name +="EMA";
|
|
break;
|
|
case MODE_LWMA :
|
|
short_name +="LWMA";
|
|
break;
|
|
case MODE_SMA :
|
|
short_name +="SMA";
|
|
break;
|
|
case MODE_SMMA :
|
|
short_name +="SMMA";
|
|
break;
|
|
}
|
|
int period = PeriodSeconds()/60;
|
|
//daily 1440 minutes
|
|
if(period == 10080)
|
|
period = 7200; //mingguan
|
|
if(period == 40320)
|
|
period = 28800; //bulanan
|
|
if(period == 161280)
|
|
period = 115200;//4 bulanan
|
|
if(period == 483840)
|
|
period = 345600;//tahunan
|
|
ExtBandsPeriod = (InpBandsPeriod) / period; // Period
|
|
//--- indicator name
|
|
IndicatorSetString(INDICATOR_SHORTNAME,short_name+"("+string(ExtBandsPeriod)+")");
|
|
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
ExtBandsDeviations=InpBandsDeviations;
|
|
ExtBandsDeviation2=InpBandsDeviation2;
|
|
|
|
//--- define buffers
|
|
SetIndexBuffer(0,ExtMLBuffer);
|
|
SetIndexBuffer(1,ExtTLBuffer);
|
|
SetIndexBuffer(2,ExtBLBuffer);
|
|
SetIndexBuffer(3,ExtTL2Buffer);
|
|
SetIndexBuffer(4,ExtBL2Buffer);
|
|
SetIndexBuffer(5,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");
|
|
PlotIndexSetString(3,PLOT_LABEL,"Bands("+string(ExtBandsPeriod)+") Upper2");
|
|
PlotIndexSetString(4,PLOT_LABEL,"Bands("+string(ExtBandsPeriod)+") Lower2");
|
|
//--- 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);
|
|
PlotIndexSetInteger(3,PLOT_DRAW_BEGIN,ExtBandsPeriod);
|
|
PlotIndexSetInteger(4,PLOT_DRAW_BEGIN,ExtBandsPeriod);
|
|
//--- indexes shift settings
|
|
PlotIndexSetInteger(0,PLOT_SHIFT,ExtBandsShift);
|
|
PlotIndexSetInteger(1,PLOT_SHIFT,ExtBandsShift);
|
|
PlotIndexSetInteger(2,PLOT_SHIFT,ExtBandsShift);
|
|
PlotIndexSetInteger(3,PLOT_SHIFT,ExtBandsShift);
|
|
PlotIndexSetInteger(4,PLOT_SHIFT,ExtBandsShift);
|
|
//--- number of digits of indicator value
|
|
IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 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);
|
|
PlotIndexSetInteger(3,PLOT_DRAW_BEGIN,ExtPlotBegin);
|
|
PlotIndexSetInteger(4,PLOT_DRAW_BEGIN,ExtPlotBegin);
|
|
}
|
|
//--- starting calculation
|
|
int pos;
|
|
if(prev_calculated>1)
|
|
pos=prev_calculated-1;
|
|
else
|
|
pos=0;
|
|
//--- main cycle
|
|
|
|
switch(InpMaMethod)
|
|
{
|
|
case MODE_EMA:
|
|
CalculateEMA(rates_total,prev_calculated,begin,price);
|
|
break;
|
|
case MODE_LWMA:
|
|
CalculateLWMA(rates_total,prev_calculated,begin,price);
|
|
break;
|
|
case MODE_SMMA:
|
|
CalculateSmoothedMA(rates_total,prev_calculated,begin,price);
|
|
break;
|
|
case MODE_SMA:
|
|
CalculateSimpleMA(rates_total,prev_calculated,begin,price);
|
|
break;
|
|
}
|
|
|
|
for(int i=pos; i<rates_total && !IsStopped(); i++)
|
|
{
|
|
//--- middle line
|
|
//ExtMLBuffer[i]=CalculateMovingAverage(i, ExtBandsPeriod,prev_calculated, price);
|
|
//--- calculate and write down StdDev
|
|
ExtStdDevBuffer[i]=StdDev_Func(i,price,ExtMLBuffer,ExtBandsPeriod);
|
|
|
|
if(ExtBandsDeviations > 0)
|
|
{
|
|
//--- upper line
|
|
ExtTLBuffer[i]=ExtMLBuffer[i]+ExtBandsDeviations*ExtStdDevBuffer[i];
|
|
//--- lower line
|
|
ExtBLBuffer[i]=ExtMLBuffer[i]-ExtBandsDeviations*ExtStdDevBuffer[i];
|
|
}
|
|
else
|
|
{
|
|
//--- upper line
|
|
ExtTLBuffer[i]=0;
|
|
//--- lower line
|
|
ExtBLBuffer[i]=0;
|
|
|
|
}
|
|
if(ExtBandsDeviation2>0)
|
|
{
|
|
//--- upper line
|
|
ExtTL2Buffer[i]=ExtMLBuffer[i]+ExtBandsDeviation2*ExtStdDevBuffer[i];
|
|
//--- lower line
|
|
ExtBL2Buffer[i]=ExtMLBuffer[i]-ExtBandsDeviation2*ExtStdDevBuffer[i];
|
|
}
|
|
else
|
|
{
|
|
//--- upper line
|
|
ExtTL2Buffer[i]=0;
|
|
//--- lower line
|
|
ExtBL2Buffer[i]=0;
|
|
}
|
|
|
|
}
|
|
|
|
//--- OnCalculate done. Return new prev_calculated.
|
|
return(rates_total);
|
|
}
|
|
//+------------------------------------------------------------------+
|