#property indicator_separate_window #property indicator_buffers 3 #property indicator_color1 White #property indicator_color2 Red #property indicator_color3 Blue #define STRING_ID "MACD_DivergenceLine" extern int Fast = 9; extern int Slow = 21; extern int Signal = 5; extern int Depth = 1; extern int ShowHidden = 0; extern int DrawGraphics = 1; double Value[]; double Sell[]; double Buy[]; int Tops[]; int Bottoms[]; double Prices[]; string IndicatorName; datetime LastTime; int init() { SetIndexBuffer(0, Value); SetIndexBuffer(1, Sell); SetIndexBuffer(2, Buy); SetIndexStyle(1, DRAW_HISTOGRAM); SetIndexStyle(2, DRAW_HISTOGRAM); IndicatorName = "Divergence(" + Fast + ", " + Slow + ", " + Signal + ")"; IndicatorShortName(IndicatorName); LastTime = 0; ArrayResize(Tops, Depth + 1); ArrayResize(Bottoms, Depth + 1); ArrayResize(Prices, Depth + 1); return(0); } int deinit() { for(int i = ObjectsTotal() - 1; i >= 0; i--) { string label = ObjectName(i); if(StringFind(label, STRING_ID) != -1) { ObjectDelete(label); } } return(0); } int start() { if (LastTime == Time[0]) return (0); LastTime = Time[0]; int toCount = Bars - IndicatorCounted(); for(int i = toCount - 1; i >= 0; i--) { Value[i] = iMACD(NULL, 0, Fast, Slow, Signal, PRICE_CLOSE, 1, i); } for(i = toCount - 1; i >= 0; i--) { if (Sell[i + 2] != EMPTY_VALUE) { Sell[i + 1] = Value[i + 1]; } if (Buy[i + 2] != EMPTY_VALUE) { Buy[i + 1] = Value[i + 1]; } CatchBullishDivergence(i + 2); CatchBearishDivergence(i + 2); } return(0); } void CatchBullishDivergence(int shift) { if(!IsBottom(shift)) return; Sell[shift - 1] = EMPTY_VALUE; Bottoms[0] = shift; Prices[0] = Low[shift]; for (int i = 1; i <= Depth; i++) { Bottoms[i] = GetLastBottom(Bottoms[i - 1]); Prices[i] = Low[Bottoms[i]]; } bool gotSignal = false; for (i = 1; i <= Depth; i++) { if (Bottoms[i] == -1) return; if (Prices[i] == 0 || Prices[i] == EMPTY_VALUE) return; if(Value[Bottoms[0]] < Value[Bottoms[i]] && Prices[0] > Prices[i]) { gotSignal = true; } if(Value[Bottoms[0]] > Value[Bottoms[i]] && Prices[0] < Prices[i] && ShowHidden == 1) { gotSignal = true; } if (gotSignal) { DrawPriceTrendLine( Time[Bottoms[0]], Time[Bottoms[i]], Prices[0], Prices[i], Blue, STYLE_SOLID); DrawIndicatorTrendLine( Time[Bottoms[0]], Time[Bottoms[i]], Value[Bottoms[0]], Value[Bottoms[i]], Blue, STYLE_SOLID); Buy[shift - 1] = Value[shift - 1]; return; } } } void CatchBearishDivergence(int shift) { if(!IsTop(shift)) return; Buy[shift - 1] = EMPTY_VALUE; Tops[0] = shift; Prices[0] = High[shift]; for (int i = 1; i <= Depth; i++) { Tops[i] = GetLastTop(Tops[i - 1]); Prices[i] = High[Tops[i]]; } bool gotSignal = false; for (i = 1; i <= Depth; i++) { if (Tops[i] == -1) return; if (Prices[i] == 0 || Tops[i] == EMPTY_VALUE) return; if(Value[Tops[0]] > Value[Tops[i]] && Prices[0] < Prices[i]) { gotSignal = true; } if(Value[Tops[0]] < Value[Tops[i]] && Prices[0] > Prices[i] && ShowHidden == 1) { gotSignal = true; } if (gotSignal) { DrawPriceTrendLine( Time[Tops[0]], Time[Tops[i]], Prices[0], Prices[i], Red, STYLE_SOLID); DrawIndicatorTrendLine( Time[Tops[0]], Time[Tops[i]], Value[Tops[0]], Value[Tops[i]], Red, STYLE_SOLID); Sell[shift - 1] = Value[shift - 1]; return; } } } bool IsTop(int i) { return ( Value[i - 1] != EMPTY_VALUE && Value[i ] != EMPTY_VALUE && Value[i + 1] != EMPTY_VALUE && Value[i + 1] < Value[i] && Value[i - 1] < Value[i]); } bool IsBottom(int i) { return ( Value[i - 1] != EMPTY_VALUE && Value[i ] != EMPTY_VALUE && Value[i + 1] != EMPTY_VALUE && Value[i + 1] > Value[i] && Value[i - 1] > Value[i]); } int GetLastTop(int shift) { for(int i = shift + 1; i < Bars; i++) { if (IsTop(i)) return (i); } return(-1); } int GetLastBottom(int shift) { for(int i = shift + 1; i < Bars; i++) { if (IsBottom(i)) return (i); } return(-1); } void DrawPriceTrendLine(datetime x1, datetime x2, double y1, double y2, color lineColor, double style) { if (DrawGraphics == 0) return; string label = STRING_ID + "_Price" + DoubleToStr(x1, 0) + DoubleToStr(x2, 0); ObjectDelete(label); ObjectCreate(label, OBJ_TREND, 0, x1, y1, x2, y2, 0, 0); ObjectSet(label, OBJPROP_RAY, 0); ObjectSet(label, OBJPROP_COLOR, lineColor); ObjectSet(label, OBJPROP_STYLE, style); ObjectSet(label, OBJPROP_WIDTH, 2); } void DrawIndicatorTrendLine(datetime x1, datetime x2, double y1, double y2, color lineColor, double style) { if (DrawGraphics == 0) return; int indicatorWindow = WindowFind(IndicatorName); if (indicatorWindow < 0) return; string label = STRING_ID + "_Value" + DoubleToStr(x1, 0) + DoubleToStr(x2, 0); ObjectDelete(label); ObjectCreate(label, OBJ_TREND, indicatorWindow, x1, y1, x2, y2, 0, 0); ObjectSet(label, OBJPROP_RAY, 0); ObjectSet(label, OBJPROP_COLOR, lineColor); ObjectSet(label, OBJPROP_STYLE, style); ObjectSet(label, OBJPROP_WIDTH, 2); }