//+------------------------------------------------------------------+ //| BrokerCheck_RSI_Divergence | //| RSI (close prices, Wilder smoothing) with divergences confirmed | //| on closed swing pivots. Regular divergences by default; hidden | //| divergences only when ShowHidden = true. | //| Native MQL only: no DLL imports, no WebRequest, no order or | //| account functions, no alerts, no chart objects. | //| Descriptive tool: it marks past price/RSI patterns and does not | //| forecast prices or trade. | //+------------------------------------------------------------------+ #property copyright "BrokerCheck" #property version "1.00" #property description "RSI with regular (optional hidden) divergences, reported when the second swing pivot is confirmed by closed bars." #property strict #property indicator_separate_window #property indicator_minimum 0 #property indicator_maximum 100 #property indicator_level1 30 #property indicator_level2 70 #property indicator_buffers 15 #property indicator_plots 9 #property indicator_label1 "RSI" #property indicator_type1 DRAW_LINE #property indicator_color1 clrDodgerBlue #property indicator_width1 2 #property indicator_label2 "Regular bearish divergence" #property indicator_type2 DRAW_LINE #property indicator_color2 clrOrangeRed #property indicator_width2 2 #property indicator_label3 "Regular bullish divergence" #property indicator_type3 DRAW_LINE #property indicator_color3 clrMediumSeaGreen #property indicator_width3 2 #property indicator_label4 "Regular bearish confirmed" #property indicator_type4 DRAW_ARROW #property indicator_color4 clrOrangeRed #property indicator_label5 "Regular bullish confirmed" #property indicator_type5 DRAW_ARROW #property indicator_color5 clrMediumSeaGreen #property indicator_label6 "Hidden bearish divergence" #property indicator_type6 DRAW_LINE #property indicator_style6 STYLE_DOT #property indicator_color6 clrOrange #property indicator_label7 "Hidden bullish divergence" #property indicator_type7 DRAW_LINE #property indicator_style7 STYLE_DOT #property indicator_color7 clrTurquoise #property indicator_label8 "Hidden bearish confirmed" #property indicator_type8 DRAW_ARROW #property indicator_color8 clrOrange #property indicator_label9 "Hidden bullish confirmed" #property indicator_type9 DRAW_ARROW #property indicator_color9 clrTurquoise input int RsiPeriod = 14; // RSI period (close prices, Wilder smoothing) input int PivotLeftBars = 5; // Pivot: bars on the left that must be strictly lower (high) / higher (low) input int PivotRightBars = 5; // Pivot: closed bars on the right = confirmation lag input int MinPivotDistance = 5; // Pair: minimum bars between the two pivots input int MaxPivotDistance = 60; // Pair: maximum bars between the two pivots input bool ShowHidden = false; // Also mark hidden divergences double RsiBuffer[]; // 0 RSI line double BearLineBuffer[]; // 1 regular bearish: RSI line from pivot 1 to pivot 2 double BullLineBuffer[]; // 2 regular bullish: RSI line from pivot 1 to pivot 2 double BearArrowBuffer[]; // 3 regular bearish: arrow at the confirming bar double BullArrowBuffer[]; // 4 regular bullish: arrow at the confirming bar double HiddenBearLineBuffer[]; // 5 hidden bearish line (ShowHidden only) double HiddenBullLineBuffer[]; // 6 hidden bullish line (ShowHidden only) double HiddenBearArrowBuffer[]; // 7 hidden bearish arrow (ShowHidden only) double HiddenBullArrowBuffer[]; // 8 hidden bullish arrow (ShowHidden only) double AvgGainBuffer[]; // 9 Wilder average gain (calculation) double AvgLossBuffer[]; // 10 Wilder average loss (calculation) double PivotHighBuffer[]; // 11 1.0 at confirmed pivot highs (calculation) double PivotLowBuffer[]; // 12 1.0 at confirmed pivot lows (calculation) double HighPairStartBuffer[]; // 13 at a confirming bar: index of pivot 1 of a high-side detection (calculation) double LowPairStartBuffer[]; // 14 at a confirming bar: index of pivot 1 of a low-side detection (calculation) int OnInit() { if(RsiPeriod<1 || PivotLeftBars<1 || PivotRightBars<1 || MinPivotDistance<1 || MaxPivotDistance=high[bar]) return(false); for(int j=bar+1; j<=bar+PivotRightBars; ++j) if(high[j]>high[bar]) return(false); return(true); } // Pivot low: mirror image of the pivot-high rule. bool BcIsPivotLow(const int bar,const double &low[]) { for(int j=bar-PivotLeftBars; j=oldest; --j) if(flags[j]!=0.0) return(j); return(-1); } // Straight line on the RSI panel from RSI at pivot 1 to RSI at pivot 2. Both end points hold the exact RSI // values, so a later segment that starts at this pivot 2 writes the same value there and nothing drawn changes. void BcDrawSegment(double &line[],const int from,const int to) { const double span=(double)(to-from); for(int k=from; k=RsiPeriod && p-q>=MinPivotDistance) { if(high[p]>high[q] && RsiBuffer[p]RsiBuffer[q]) { HiddenBearArrowBuffer[c]=RsiBuffer[c]; HighPairStartBuffer[c]=(double)q; BcDrawSegment(HiddenBearLineBuffer,q,p); } } } if(BcIsPivotLow(p,low)) { const int q=BcPreviousPivot(PivotLowBuffer,p); PivotLowBuffer[p]=1.0; if(q>=RsiPeriod && p-q>=MinPivotDistance) { if(low[p]RsiBuffer[q]) { BullArrowBuffer[c]=RsiBuffer[c]; LowPairStartBuffer[c]=(double)q; BcDrawSegment(BullLineBuffer,q,p); } else if(ShowHidden && low[p]>low[q] && RsiBuffer[p]rates_total) { // Full calculation: first call, reloaded history, or the seed bar was still the newest bar. BcClearRsiBars(0,rates_total); BcClearDivergenceBars(0,rates_total); double sumGain=0.0; double sumLoss=0.0; for(int i=1; i<=RsiPeriod; ++i) { const double change=close[i]-close[i-1]; if(change>0.0) sumGain+=change; else sumLoss-=change; } // Seed: simple mean of the first RsiPeriod price changes, stored at index RsiPeriod. AvgGainBuffer[RsiPeriod]=sumGain/(double)RsiPeriod; AvgLossBuffer[RsiPeriod]=sumLoss/(double)RsiPeriod; RsiBuffer[RsiPeriod]=BcRsiFromAverages(AvgGainBuffer[RsiPeriod],AvgLossBuffer[RsiPeriod]); rsiFrom=RsiPeriod+1; confirmFrom=0; } else { // Incremental: the previous newest bar and every new bar are recalculated. BcClearDivergenceBars(prev_calculated-1,rates_total); rsiFrom=prev_calculated-1; confirmFrom=prev_calculated-1; } // Wilder smoothing: new average = (previous average * (period - 1) + current value) / period. for(int i=rsiFrom; i0.0 ? change : 0.0))/(double)RsiPeriod; AvgLossBuffer[i]=(AvgLossBuffer[i-1]*(double)(RsiPeriod-1)+(change<0.0 ? -change : 0.0))/(double)RsiPeriod; RsiBuffer[i]=BcRsiFromAverages(AvgGainBuffer[i],AvgLossBuffer[i]); } // Only closed bars (index <= rates_total - 2) can confirm a pivot. for(int c=confirmFrom; c<=rates_total-2 && !IsStopped(); ++c) BcConfirm(c,high,low); return(rates_total); }