Files
2021-04-28 17:27:12 +02:00

178 lines
16 KiB
Plaintext

//------------------------------------------------------------------
#property copyright "© mladen, 2018"
#property link "mladenfx@gmail.com"
#property version "1.00"
//------------------------------------------------------------------
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots 2
#property indicator_label1 "Volume average percent"
#property indicator_type1 DRAW_COLOR_HISTOGRAM
#property indicator_color1 clrDarkGray,clrYellowGreen,clrOrange,clrGreen,clrRed
#property indicator_width1 2
#property indicator_label2 "Average"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrDarkGray
#include <AZ-INVEST/CustomBarConfig.mqh>
//---
enum enMaTypes
{
ma_sma, // Simple moving average
ma_ema, // Exponential moving average
ma_smma, // Smoothed MA
ma_lwma // Linear weighted MA
};
//---
enum enVolumeType
{
vol_ticks, // Use ticks
vol_volume // Use real volume
};
//--- input parameters
input enVolumeType inpVolumeType = vol_ticks; // Volume type to use
input int inpAveragePeriod = 50; // Average period
input enMaTypes inpAverageMethod = ma_ema; // Average method
input double inpBreakoutPercent = 50; // Breakout percentage
//--- buffers
double val[],valc[],average[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//---- indicator buffers mapping
SetIndexBuffer(0,val,INDICATOR_DATA);
SetIndexBuffer(1,valc,INDICATOR_COLOR_INDEX);
SetIndexBuffer(2,average,INDICATOR_DATA);
string _avgNames[]={"SMA","EMA","SMMA","LWMA"};
IndicatorSetString(INDICATOR_SHORTNAME,"Volume "+_avgNames[inpAverageMethod]+" average percent ("+(string)inpAveragePeriod+")");
customChartIndicator.SetGetVolumesFlag();
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
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[])
{
if(Bars(_Symbol,_Period)<rates_total) return(-1);
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
return(0);
if(!customChartIndicator.BufferSynchronizationCheck(close))
return(0);
int _prev_calculated = customChartIndicator.GetPrevCalculated();
int _rates_total = customChartIndicator.GetRatesTotal();
int i=(int)MathMax(_prev_calculated-1,0);
for(; i<_rates_total && !_StopFlag; i++)
{
double _volume=double((inpVolumeType==vol_ticks) ? customChartIndicator.Tick_volume[i]: customChartIndicator.Real_volume[i]);
double _avg = iCustomMa(inpAverageMethod,_volume,inpAveragePeriod,i,_rates_total);
average[i] = 100;
val[i] = (_avg!=0) ? 100*_volume/_avg : 0;
valc[i] = 0;
if(i>0 && customChartIndicator.Close[i] > customChartIndicator.Close[i-1]) valc[i] = (_volume > _avg*(1+inpBreakoutPercent*0.01)) ? 3 : 1;
if(i>0 && customChartIndicator.Close[i] < customChartIndicator.Close[i-1]) valc[i] = (_volume > _avg*(1+inpBreakoutPercent*0.01)) ? 4 : 2;
}
return(i);
}
//+------------------------------------------------------------------+
//| Custom functions |
//+------------------------------------------------------------------+
#define _maInstances 1
#define _maWorkBufferx1 1*_maInstances
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double iCustomMa(int mode,double price,double length,int r,int bars,int instanceNo=0)
{
switch(mode)
{
case ma_sma : return(iSma(price,(int)length,r,bars,instanceNo));
case ma_ema : return(iEma(price,length,r,bars,instanceNo));
case ma_smma : return(iSmma(price,(int)length,r,bars,instanceNo));
case ma_lwma : return(iLwma(price,(int)length,r,bars,instanceNo));
default : return(price);
}
}
double workSma[][_maWorkBufferx1];
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double iSma(double price,int period,int r,int _bars,int instanceNo=0)
{
if(ArrayRange(workSma,0)!=_bars) ArrayResize(workSma,_bars);
workSma[r][instanceNo]=price;
double avg=price;
int k=1;
for(; k<period && (r-k)>=0; k++) avg+=workSma[r-k][instanceNo];
return(avg/(double)k);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double workEma[][_maWorkBufferx1];
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double iEma(double price,double period,int r,int _bars,int instanceNo=0)
{
if(ArrayRange(workEma,0)!=_bars) ArrayResize(workEma,_bars);
workEma[r][instanceNo]=price;
if(r>0 && period>1)
workEma[r][instanceNo]=workEma[r-1][instanceNo]+(2.0/(1.0+period))*(price-workEma[r-1][instanceNo]);
return(workEma[r][instanceNo]);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double workSmma[][_maWorkBufferx1];
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double iSmma(double price,double period,int r,int _bars,int instanceNo=0)
{
if(ArrayRange(workSmma,0)!=_bars) ArrayResize(workSmma,_bars);
workSmma[r][instanceNo]=price;
if(r>1 && period>1)
workSmma[r][instanceNo]=workSmma[r-1][instanceNo]+(price-workSmma[r-1][instanceNo])/period;
return(workSmma[r][instanceNo]);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double workLwma[][_maWorkBufferx1];
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double iLwma(double price,double period,int r,int _bars,int instanceNo=0)
{
if(ArrayRange(workLwma,0)!=_bars) ArrayResize(workLwma,_bars);
workLwma[r][instanceNo] = price; if(period<1) return(price);
double sumw = period;
double sum = period*price;
for(int k=1; k<period && (r-k)>=0; k++)
{
double weight=period-k;
sumw += weight;
sum += weight*workLwma[r-k][instanceNo];
}
return(sum/sumw);
}
//+------------------------------------------------------------------+