Files
chungnh 6049dd6e40 update
2024-09-06 15:35:14 +07:00

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;
}