9003b29674
Indicator Collection
366 lines
14 KiB
Plaintext
366 lines
14 KiB
Plaintext
//+------------------------------------------------------------------+
|
|
//| BBSqueeze.mq5 |
|
|
//| Copyright © 2005, Nick Bilak |
|
|
//| beluck[AT]gmail.com |
|
|
//+------------------------------------------------------------------+
|
|
//| Place the SmoothAlgorithms.mqh file |
|
|
//| to the terminal_data_folder\MQL5\Include |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright © 2005, Nick Bilak"
|
|
#property link "http://metatrader.50webs.com/"
|
|
//---- indicator version
|
|
#property version "1.00"
|
|
//---- drawing the indicator in a separate window
|
|
#property indicator_separate_window
|
|
//---- number of indicator buffers 4
|
|
#property indicator_buffers 4
|
|
//---- 4 plots are used
|
|
#property indicator_plots 4
|
|
//+-----------------------------------+
|
|
//| Declaration of constants |
|
|
//+-----------------------------------+
|
|
#define RESET 0 // the constant for getting the command for the indicator recalculation back to the terminal
|
|
//+-----------------------------------+
|
|
//| Indicator drawing parameters |
|
|
//+-----------------------------------+
|
|
//---- drawing the indicator as a histogram
|
|
#property indicator_type1 DRAW_HISTOGRAM
|
|
//---- teal color is used
|
|
#property indicator_color1 Teal
|
|
//---- indicator line is a solid one
|
|
#property indicator_style1 STYLE_SOLID
|
|
//---- indicator line width is equal to 2
|
|
#property indicator_width1 2
|
|
//---- displaying the indicator label
|
|
#property indicator_label1 "Uptrend"
|
|
|
|
//---- drawing the indicator as a histogram
|
|
#property indicator_type2 DRAW_HISTOGRAM
|
|
//---- magenta color is used
|
|
#property indicator_color2 Magenta
|
|
//---- indicator line is a solid one
|
|
#property indicator_style2 STYLE_SOLID
|
|
//---- indicator line width is equal to 2
|
|
#property indicator_width2 2
|
|
//---- displaying the indicator label
|
|
#property indicator_label2 "Downtrend"
|
|
//+-----------------------------------+
|
|
//| Indicator drawing parameters |
|
|
//+-----------------------------------+
|
|
//---- drawing the indicator as labels
|
|
#property indicator_type3 DRAW_ARROW
|
|
//---- blue color is used
|
|
#property indicator_color3 Blue
|
|
//---- indicator line width is equal to 2
|
|
#property indicator_width3 2
|
|
//---- displaying the indicator label
|
|
#property indicator_label3 "Strong trend"
|
|
//+-----------------------------------+
|
|
//| Indicator drawing parameters |
|
|
//+-----------------------------------+
|
|
//---- drawing the indicator as labels
|
|
#property indicator_type4 DRAW_ARROW
|
|
//---- MediumPurple color is used
|
|
#property indicator_color4 MediumPurple
|
|
//---- indicator line width is equal to 2
|
|
#property indicator_width4 2
|
|
//---- displaying the indicator label
|
|
#property indicator_label4 "Weak trend"
|
|
//+-----------------------------------+
|
|
//| Smoothings classes description |
|
|
//+-----------------------------------+
|
|
#include <SmoothAlgorithms.mqh>
|
|
//+-----------------------------------+
|
|
//---- declaration of the CXMA class variables from the SmoothAlgorithms.mqh file
|
|
CXMA XMA1;
|
|
//+-----------------------------------+
|
|
//| Declaration of enumerations |
|
|
//+-----------------------------------+
|
|
enum Applied_price_ // Type of constant
|
|
{
|
|
PRICE_CLOSE_ = 1, // Close
|
|
PRICE_OPEN_, // Open
|
|
PRICE_HIGH_, // High
|
|
PRICE_LOW_, // Low
|
|
PRICE_MEDIAN_, // Median Price (HL/2)
|
|
PRICE_TYPICAL_, // Typical Price (HLC/3)
|
|
PRICE_WEIGHTED_, // Weighted Close (HLCC/4)
|
|
PRICE_SIMPLE, // Simple Price (OC/2)
|
|
PRICE_QUARTER_, // Quarted Price (HLOC/4)
|
|
PRICE_TRENDFOLLOW0_, // TrendFollow_1 Price
|
|
PRICE_TRENDFOLLOW1_ // TrendFollow_2 Price
|
|
};
|
|
/*enum Smooth_Method - enumeration is declared in the SmoothAlgorithms.mqh file
|
|
{
|
|
MODE_SMA_, // SMA
|
|
MODE_EMA_, // EMA
|
|
MODE_SMMA_, // SMMA
|
|
MODE_LWMA_, // LWMA
|
|
MODE_JJMA, // JJMA
|
|
MODE_JurX, // JurX
|
|
MODE_ParMA, // ParMA
|
|
MODE_T3, // T3
|
|
MODE_VIDYA, // VIDYA
|
|
MODE_AMA, // AMA
|
|
}; */
|
|
//+-----------------------------------+
|
|
//| Indicator input parameters |
|
|
//+-----------------------------------+
|
|
input Smooth_Method BB_Method=MODE_EMA_; // Histogram smoothing method
|
|
input int BB_Period = 20; // Bollinger Bands period
|
|
input int BB_Phase= 100; // Bollinger Bands smoothing parameter
|
|
input double BB_Deviation=2.0; // Number of deviations
|
|
input Applied_price_ AppliedPrice=PRICE_CLOSE_; // Applied price
|
|
input double ATR_Period=20; // ATR period
|
|
input double ATR_Factor=1.5; // ATR ratio
|
|
//+-----------------------------------+
|
|
//---- declaration of the integer variables for the start of data calculation
|
|
int min_rates_total,min_rates_xma;
|
|
//---- declaration of global variables
|
|
int Count[];
|
|
double Xma[];
|
|
//---- declaration of integer variables for the indicators handles
|
|
int ATR_Handle,STD_Handle;
|
|
//---- declaration of dynamic arrays that
|
|
//---- will be used as indicator buffers
|
|
double UpHistBuffer[],DnHistBuffer[],UpArrBuffer[],DnArrBuffer[];
|
|
//+------------------------------------------------------------------+
|
|
//| Custom indicator initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
//---- initialization of variables of the start of data calculation
|
|
min_rates_xma=XMA1.GetStartBars(BB_Method,BB_Period,BB_Phase);
|
|
min_rates_total=int(MathMax(min_rates_xma,ATR_Period));
|
|
|
|
//---- getting handle of the iStdDev indicator
|
|
STD_Handle=iStdDev(NULL,0,BB_Period,0,MODE_SMA,PRICE_CLOSE);
|
|
if(STD_Handle==INVALID_HANDLE)
|
|
{
|
|
Print(" Failed to get handle of the iStdDev indicator");
|
|
return(1);
|
|
}
|
|
|
|
//---- getting handle of the ATR indicator
|
|
ATR_Handle=iATR(NULL,0,15);
|
|
if(ATR_Handle==INVALID_HANDLE)
|
|
{
|
|
Print(" Failed to get handle of the iATR indicator");
|
|
return(1);
|
|
}
|
|
|
|
//---- memory distribution for variables' arrays
|
|
if(ArrayResize(Count,BB_Period)<BB_Period) Print("Failed to distribute the memory for Count[] array");
|
|
if(ArrayResize(Xma,BB_Period)<BB_Period) Print("Failed to distribute the memory for Xma[] array");
|
|
|
|
ArrayInitialize(Count,0);
|
|
ArrayInitialize(Xma,0);
|
|
|
|
//---- set UpHistBuffer[] dynamic array as an indicator buffer
|
|
SetIndexBuffer(0,UpHistBuffer,INDICATOR_DATA);
|
|
//---- performing the shift of the beginning of the indicator drawing
|
|
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,min_rates_total);
|
|
//---- setting the indicator values that won't be visible on a chart
|
|
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
|
|
//---- indexing the elements in the buffer as timeseries
|
|
ArraySetAsSeries(UpHistBuffer,true);
|
|
|
|
//---- set DnHistBuffer[] dynamic array as an indicator buffer
|
|
SetIndexBuffer(1,DnHistBuffer,INDICATOR_DATA);
|
|
//---- performing the shift of the beginning of the indicator drawing
|
|
PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,min_rates_total);
|
|
//---- setting the indicator values that won't be visible on a chart
|
|
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,EMPTY_VALUE);
|
|
//---- indexing the elements in the buffer as timeseries
|
|
ArraySetAsSeries(DnHistBuffer,true);
|
|
|
|
//---- set UpArrBuffer[] dynamic array as an indicator buffer
|
|
SetIndexBuffer(2,UpArrBuffer,INDICATOR_DATA);
|
|
//---- performing the shift of the beginning of the indicator drawing
|
|
PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,min_rates_total);
|
|
//---- setting the indicator values that won't be visible on a chart
|
|
PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,EMPTY_VALUE);
|
|
//---- indicator symbol
|
|
PlotIndexSetInteger(2,PLOT_ARROW,159);
|
|
//---- indexing the elements in the buffer as timeseries
|
|
ArraySetAsSeries(UpArrBuffer,true);
|
|
|
|
//---- set DnArrBuffer[] dynamic array as an indicator buffer
|
|
SetIndexBuffer(3,DnArrBuffer,INDICATOR_DATA);
|
|
//---- performing the shift of the beginning of the indicator drawing
|
|
PlotIndexSetInteger(3,PLOT_DRAW_BEGIN,min_rates_total);
|
|
//---- setting the indicator values that won't be visible on a chart
|
|
PlotIndexSetDouble(3,PLOT_EMPTY_VALUE,EMPTY_VALUE);
|
|
//---- indicator symbol
|
|
PlotIndexSetInteger(3,PLOT_ARROW,159);
|
|
//---- indexing the elements in the buffer as timeseries
|
|
ArraySetAsSeries(DnArrBuffer,true);
|
|
|
|
//--- creation of the name to be displayed in a separate sub-window and in a tooltip
|
|
IndicatorSetString(INDICATOR_SHORTNAME,"BBSqueeze");
|
|
//--- determination of accuracy of displaying the indicator values
|
|
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
|
|
//---- initialization end
|
|
return(0);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Custom iteration function |
|
|
//+------------------------------------------------------------------+
|
|
int OnCalculate(const int rates_total, // number of bars in history at the current tick
|
|
const int prev_calculated,// number of bars calculated at previous call
|
|
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[])
|
|
{
|
|
//---- checking the number of bars to be enough for the calculation
|
|
if(BarsCalculated(ATR_Handle)<rates_total
|
|
|| BarsCalculated(STD_Handle)<rates_total
|
|
|| rates_total<min_rates_total) return(RESET);
|
|
|
|
//---- declarations of local variables
|
|
int to_copy,limit,bar,maxbar,maxbar1;
|
|
double STD[],ATR[],lregress,bbs,price_;
|
|
|
|
maxbar=rates_total-1;
|
|
maxbar1=maxbar-min_rates_xma-2*BB_Period;
|
|
|
|
//---- calculation of the 'limit' starting index for the bars recalculation loop
|
|
if(prev_calculated>rates_total || prev_calculated<=0)// checking for the first start of the indicator calculation
|
|
limit=rates_total-1; // starting index for calculation of all bars
|
|
else limit=rates_total-prev_calculated; // starting index for calculation of new bars
|
|
|
|
//---- calculation of the necessary amount of data to be copied
|
|
to_copy=limit+1;
|
|
//---- copy the newly appeared data into the STD[] and ATR[] arrays
|
|
if(CopyBuffer(STD_Handle,0,0,to_copy,STD)<=0) return(RESET);
|
|
if(CopyBuffer(ATR_Handle,0,0,to_copy,ATR)<=0) return(RESET);
|
|
|
|
//---- indexing elements in arrays as time series
|
|
ArraySetAsSeries(STD,true);
|
|
ArraySetAsSeries(ATR,true);
|
|
ArraySetAsSeries(high,true);
|
|
ArraySetAsSeries(low,true);
|
|
ArraySetAsSeries(open,true);
|
|
ArraySetAsSeries(close,true);
|
|
|
|
//---- main indicator calculation loop
|
|
for(bar=limit; bar>=0 && !IsStopped(); bar--)
|
|
{
|
|
price_=PriceSeries(AppliedPrice,bar,open,low,high,close);
|
|
Xma[Count[0]]=XMA1.XMASeries(maxbar,prev_calculated,rates_total,BB_Method,BB_Phase,BB_Period,price_,bar,true);
|
|
if(bar>maxbar1)
|
|
{
|
|
Recount_ArrayZeroPos(Count,BB_Period);
|
|
continue;
|
|
}
|
|
|
|
lregress=LinearRegressionValue(BB_Period,bar,open,low,high,close);
|
|
|
|
if(lregress<0)
|
|
{
|
|
UpHistBuffer[bar]=EMPTY_VALUE;
|
|
DnHistBuffer[bar]=lregress;
|
|
}
|
|
else
|
|
{
|
|
UpHistBuffer[bar]=lregress;
|
|
DnHistBuffer[bar]=EMPTY_VALUE;
|
|
}
|
|
|
|
bbs=BB_Deviation*STD[bar]/(ATR[bar]*ATR_Factor);
|
|
|
|
if(bbs<1)
|
|
{
|
|
DnArrBuffer[bar]=0;
|
|
UpArrBuffer[bar]=EMPTY_VALUE;
|
|
}
|
|
else
|
|
{
|
|
UpArrBuffer[bar]=0;
|
|
DnArrBuffer[bar]=EMPTY_VALUE;
|
|
}
|
|
|
|
if(bar) Recount_ArrayZeroPos(Count,BB_Period);
|
|
}
|
|
//----
|
|
return(rates_total);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Linear regression calculation |
|
|
//+------------------------------------------------------------------+
|
|
double LinearRegressionValue(int Len,
|
|
int index,
|
|
const double &Open[],
|
|
const double &Low[],
|
|
const double &High[],
|
|
const double &Close[])
|
|
{
|
|
//----
|
|
double SumBars,Sum1,Sum2,SumY,Slope,SumSqrBars;
|
|
double dxma,Num1,Num2,HH,LL,Intercept,LinearRegValue;
|
|
|
|
SumY=0;
|
|
Sum1=0;
|
|
//----
|
|
SumBars=Len *(Len-1)*0.5;
|
|
SumSqrBars=(Len-1)*Len *(2*Len-1)/6;
|
|
//----
|
|
for(int x=0; x<Len;x++)
|
|
{
|
|
HH=Low[index+x];
|
|
LL=High[index+x];
|
|
|
|
for(int y=x; y<x+Len; y++)
|
|
{
|
|
HH=MathMax(HH,High[index+y]);
|
|
LL=MathMin(LL,Low[index+y]);
|
|
}
|
|
|
|
dxma=Close[index+x]-((HH+LL)/2+Xma[Count[x]])/2;
|
|
Sum1+=x*dxma;
|
|
SumY+=dxma;
|
|
}
|
|
|
|
Sum2=SumBars*SumY;
|
|
Num1=Len*Sum1-Sum2;
|
|
Num2=SumBars*SumBars-Len*SumSqrBars;
|
|
//----
|
|
if(Num2!=0.0) Slope=Num1/Num2;
|
|
else Slope=0;
|
|
|
|
Intercept=(SumY-Slope*SumBars)/Len;
|
|
LinearRegValue=Intercept+Slope*(Len-1);
|
|
//----
|
|
return(LinearRegValue);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Recalculation of position of the newest element in the array |
|
|
//+------------------------------------------------------------------+
|
|
void Recount_ArrayZeroPos(int &CoArr[],// Return the current value of the price series by the link
|
|
uint Size)
|
|
{
|
|
//----
|
|
int numb,Max1,Max2;
|
|
static int count=1;
|
|
|
|
Max1=int(Size-1);
|
|
Max2=int(Size);
|
|
|
|
count--;
|
|
if(count<0) count=Max1;
|
|
|
|
for(int iii=0; iii<Max2; iii++)
|
|
{
|
|
numb=iii+count;
|
|
if(numb>Max1) numb-=Max2;
|
|
CoArr[iii]=numb;
|
|
}
|
|
//----
|
|
}
|
|
//+------------------------------------------------------------------+
|