144 lines
4.9 KiB
Plaintext
144 lines
4.9 KiB
Plaintext
|
|
#property copyright "Darwinex & Trade Like A Machine Ltd"
|
||
|
|
#property link "http://www.darwinex.com"
|
||
|
|
#property strict
|
||
|
|
|
||
|
|
//Indicator settings
|
||
|
|
#property indicator_separate_window
|
||
|
|
#property indicator_buffers 2
|
||
|
|
#property indicator_plots 1
|
||
|
|
#property indicator_type1 DRAW_COLOR_HISTOGRAM
|
||
|
|
#property indicator_color1 clrGreen, clrOrange, clrRed
|
||
|
|
#property indicator_style1 0
|
||
|
|
#property indicator_width1 3
|
||
|
|
|
||
|
|
//Level of above average (1.25) and below average (0.8) volume (for time of day) - (ratio of 1.0 indicates current volume is the same as average)
|
||
|
|
#property indicator_level1 1.25 //Above Average Volume Level
|
||
|
|
#property indicator_level2 0.8 //Below Average Volume Level
|
||
|
|
|
||
|
|
//Input Parmans
|
||
|
|
input int InpAveragingDays = 5; //Number of Days for Comparison
|
||
|
|
input ENUM_APPLIED_VOLUME InpVolumeType = VOLUME_TICK; //Volume Type
|
||
|
|
|
||
|
|
//Indicator Buffers
|
||
|
|
double ExtRelVolumesBuffer[];
|
||
|
|
double ExtColorsBuffer[];
|
||
|
|
int BarsIn24Hours = 0;
|
||
|
|
int AveragingDays;
|
||
|
|
|
||
|
|
void OnInit()
|
||
|
|
{
|
||
|
|
//Set Buffers
|
||
|
|
SetIndexBuffer(0,ExtRelVolumesBuffer, INDICATOR_DATA);
|
||
|
|
SetIndexBuffer(1,ExtColorsBuffer, INDICATOR_COLOR_INDEX);
|
||
|
|
|
||
|
|
//Define how many bars required to begin drawing
|
||
|
|
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 100);
|
||
|
|
PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, 100);
|
||
|
|
|
||
|
|
//Set indicator digits
|
||
|
|
IndicatorSetInteger(INDICATOR_DIGITS, 2);
|
||
|
|
|
||
|
|
//Ensure valid InpAveragingDays
|
||
|
|
if(InpAveragingDays >= 1)
|
||
|
|
AveragingDays = InpAveragingDays;
|
||
|
|
else
|
||
|
|
AveragingDays = 5;
|
||
|
|
|
||
|
|
//Set name of indicator
|
||
|
|
string short_name = StringFormat("RVOL (Relative Volume) (%d)", AveragingDays);
|
||
|
|
IndicatorSetString(INDICATOR_SHORTNAME, short_name);
|
||
|
|
|
||
|
|
//Mean Level
|
||
|
|
IndicatorSetInteger(INDICATOR_LEVELCOLOR, 0, clrWhite);
|
||
|
|
IndicatorSetString(INDICATOR_LEVELTEXT, 0, "Above Average Volume");
|
||
|
|
IndicatorSetInteger(INDICATOR_LEVELCOLOR, 1, clrWhite);
|
||
|
|
IndicatorSetString(INDICATOR_LEVELTEXT, 1, "Below Average Volume");
|
||
|
|
}
|
||
|
|
|
||
|
|
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[])
|
||
|
|
{
|
||
|
|
//rates_total is the number of bars available for calculations
|
||
|
|
if(rates_total < 1)
|
||
|
|
return(0);
|
||
|
|
|
||
|
|
if(BarsIn24Hours == 0) //Set to 0 by default above
|
||
|
|
{
|
||
|
|
SetBarsIn24Hours();
|
||
|
|
if(BarsIn24Hours == 0) //Bars not yet available in chart for calculation to succeed
|
||
|
|
return(0);
|
||
|
|
}
|
||
|
|
//Set starting point for the processing
|
||
|
|
int startBar = prev_calculated - 1;
|
||
|
|
|
||
|
|
//Adjust Start position
|
||
|
|
if(startBar < 1)
|
||
|
|
{
|
||
|
|
ExtRelVolumesBuffer[0] = 0;
|
||
|
|
startBar = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
//Main cycle
|
||
|
|
if(InpVolumeType==VOLUME_TICK)
|
||
|
|
CalculateRelVolume(startBar, rates_total, tick_volume);
|
||
|
|
else
|
||
|
|
CalculateRelVolume(startBar, rates_total, volume);
|
||
|
|
|
||
|
|
//OnCalculate done. Return new prev_calculated.
|
||
|
|
return(rates_total);
|
||
|
|
}
|
||
|
|
|
||
|
|
void CalculateRelVolume(const int startBar, const int rates_total, const long& volume[])
|
||
|
|
{
|
||
|
|
ExtRelVolumesBuffer[0] = (double)volume[0];
|
||
|
|
ExtColorsBuffer[0] = 0.0;
|
||
|
|
|
||
|
|
for(int i = startBar; i < rates_total && !IsStopped(); i++)
|
||
|
|
{
|
||
|
|
if(i > AveragingDays * BarsIn24Hours)
|
||
|
|
{
|
||
|
|
double curr_volume = (double)volume[i];
|
||
|
|
|
||
|
|
double mean_volume = 0.0;
|
||
|
|
|
||
|
|
for(int j = 1; j <= AveragingDays; j++)
|
||
|
|
mean_volume += (double)volume[i - (j * BarsIn24Hours)];
|
||
|
|
|
||
|
|
mean_volume /= (double)AveragingDays;
|
||
|
|
|
||
|
|
ExtRelVolumesBuffer[i] = curr_volume / mean_volume; //N.B. Value of 1.0 represents current vol is equal to average volume, 0.0-1.0 is below average, >1.0 is above average
|
||
|
|
|
||
|
|
if(ExtRelVolumesBuffer[i] > indicator_level1) //If current vol higher than average
|
||
|
|
ExtColorsBuffer[i] = 0.0;
|
||
|
|
else if (ExtRelVolumesBuffer[i] > indicator_level2) //If current vol lower than average
|
||
|
|
ExtColorsBuffer[i] = 1.0;
|
||
|
|
else
|
||
|
|
ExtColorsBuffer[i] = 2.0;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
ExtRelVolumesBuffer[i] = 0.0;
|
||
|
|
ExtColorsBuffer[i] = 0.0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
int SetBarsIn24Hours()
|
||
|
|
{
|
||
|
|
datetime prevDateTime = iTime(NULL, PERIOD_CURRENT, 0) - (86400 * 7); //Need to base calculation on 7 days so that weekends don't interfere
|
||
|
|
|
||
|
|
int numBarsIn7Days = iBarShift(NULL, PERIOD_CURRENT, prevDateTime, false);
|
||
|
|
|
||
|
|
//Num bars in 7 days actually represents 5 trading days. N.B. This Indicator only works for assets that trade 5 days per week. It will not work with 24x7 Crypto for example
|
||
|
|
BarsIn24Hours = numBarsIn7Days / 5;
|
||
|
|
|
||
|
|
return BarsIn24Hours;
|
||
|
|
}
|