//+------------------------------------------------------------------+ //| VQ.mq4 | //| Volatility Quality | //| by raff1410@o2.pl | //+------------------------------------------------------------------+ // mod by Dr.EA Keiji 2020.01.07 #property strict #property indicator_separate_window #property indicator_buffers 3 #property indicator_color1 clrYellow #property indicator_color2 clrYellow #property indicator_color3 clrCyan #property indicator_width1 1 extern int Length = 5; extern int Method = 3; extern int Smoothing = 1; extern int Filter = 5; extern bool RealTime = true; extern bool Steady = false; extern bool Arrow = true; double SumVQ[]; double UpArrow[]; double DnArrow[]; double DIR[]; //+------------------------------------------------------------------+ int OnInit() { IndicatorBuffers(4); SetIndexBuffer(0, SumVQ); SetIndexBuffer(1, UpArrow); SetIndexBuffer(2, DnArrow); SetIndexBuffer(3, DIR); SetIndexStyle(0, DRAW_LINE,STYLE_SOLID); SetIndexStyle(1, DRAW_ARROW); SetIndexStyle(2, DRAW_ARROW); SetIndexArrow(1, 233); SetIndexArrow(2, 234); if (Length < 2) Length = 2; if (Method < 0) Method = 0; if (Method > 3) Method = 3; if (Smoothing < 0) Smoothing = 0; if (Filter < 0) Filter = 0; string short_name = "VQ | " + (string)Length + " , " + (string)Method + " , " + (string)Smoothing + " , " + (string)Filter + " | "; IndicatorShortName(short_name); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ 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[]) { int i, limit; if (prev_calculated == 0) { limit = rates_total - Length - 1; if (limit < 100) return(0); SumVQ[limit + 1] = Close[limit + 1]; } else { limit = rates_total - prev_calculated; if (RealTime == false && limit == 0) return(rates_total); } int ma_method; if (Steady == true) ma_method = PRICE_MEDIAN; else ma_method = PRICE_CLOSE; for (i = limit; i >= 0; i--) { // base line double ma_high = iMA(NULL, 0, Length, 0, Method, PRICE_HIGH, i); double ma_low = iMA(NULL, 0, Length, 0, Method, PRICE_LOW, i); double ma_open = iMA(NULL, 0, Length, 0, Method, PRICE_OPEN, i); double ma = iMA(NULL, 0, Length, 0, Method, ma_method, i); double ma_smooth = iMA(NULL, 0, Length, 0, Method, ma_method, i + Smoothing); double max_deviation = MathMax(ma_high - ma_smooth, ma_smooth - ma_low); if (MathMax(ma_high - ma_low, max_deviation) == 0) { SumVQ[i] = SumVQ[i + 1]; DIR[i] = DIR[i + 1]; continue; } double VQ = (ma - ma_smooth) / MathMax(ma_high - ma_low, max_deviation); VQ += (ma - ma_open) / (ma_high - ma_low); VQ *= 0.5; VQ = MathAbs(VQ) * (ma * 2 - ma_smooth - ma_open) * 0.5; SumVQ[i] = SumVQ[i + 1] + VQ; if (Filter > 0 && MathAbs(SumVQ[i] - SumVQ[i + 1]) < Filter * Point) SumVQ[i] -= VQ; // direction DIR[i] = DIR[i + 1]; if (SumVQ[i] - SumVQ[i + 1] > 0) DIR[i] = 1; if (SumVQ[i + 1] - SumVQ[i] > 0) DIR[i] = -1; // arrow if (Arrow == true) { UpArrow[i] = EMPTY_VALUE; DnArrow[i] = EMPTY_VALUE; if (DIR[i] == 1 && DIR[i + 1] == -1) UpArrow[i] = SumVQ[i + 1]; if (DIR[i] == -1 && DIR[i + 1] == 1) DnArrow[i] = SumVQ[i + 1]; } } return(rates_total); }