//+------------------------------------------------------------------+ //| OscillatorsOnChart.mq4 | //| Copyright 2014, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2014, MetaQuotes Software Corp." #property link "http://www.mql5.com" #property version "1.00" #property strict #property indicator_chart_window #property indicator_buffers 10 #property indicator_color1 clrAqua #property indicator_color2 clrMagenta #property indicator_color3 clrAqua #property indicator_color4 clrMagenta #property indicator_color5 clrMagenta #property indicator_color6 clrAqua #property indicator_color7 clrMagenta #property indicator_color8 clrFireBrick #property indicator_color9 clrYellow #property indicator_color10 clrRoyalBlue #property indicator_style1 STYLE_SOLID #property indicator_style2 STYLE_DOT #property indicator_style3 STYLE_DOT #property indicator_style4 STYLE_DOT #property indicator_style5 STYLE_DOT #property indicator_style6 STYLE_DOT #property indicator_style7 STYLE_DOT #property indicator_style8 STYLE_SOLID #property indicator_style9 STYLE_SOLID #property indicator_style10 STYLE_SOLID #property indicator_width1 2 #property indicator_width8 2 #property indicator_width9 2 #property indicator_width10 2 #define LEVELS 7 #define sRSI "RSI " #define sCCI "CCI " #define sPRI "PRI " #define ALRT_BUY " up" #define ALRT_SELL " down" #define OP_NONE -1 #define HIGH_LOW 0 #define CLOSE_CLOSE 1 #define HIGH_LOW_CLOSE 2 #define MODE_MEDIAN 1 #define MODE_RANGE 2 //---- input parameters input bool ShowRSI = true; input int iRSIPeriod = 14; input string _ = "0=Close 4=Median 5=Typical 6=Weighted"; input int iRSIPrice = PRICE_CLOSE; input bool ShowCCI = true; input int iCCIPeriod = 14; input string __ = "0=Close 4=Median 5=Typical 6=Weighted"; input int iCCIPrice = PRICE_CLOSE; input bool ShowPRI = true; input int iPRIPeriod = 14; input string ___ = "0=Close 4=Median 5=Typical 6=Weighted"; input int iPRIPrice = PRICE_CLOSE; input int TimeFrame = 0; input int iRangePeriod = 50; input string ____ = "0=High/Low 1=Close/Close 2=High/Low/Close"; input int RangeMode = HIGH_LOW; input bool AverageMedian = false; input string _____ = "0=SMA 1=EMA 2=SMMA 3=LWMA"; input int MAMode = MODE_SMA; input string ______ = "0=Close 4=Median 5=Typical 6=Weighted"; input int MAPrice = PRICE_MEDIAN; input bool AlertsOn = true, AlertsMessage = true, AlertsEmail = false, AlertsSound = false; //---- buffers double Level_0[], Level_1[], Level_2[], Level_3[], Level_4[], Level_5[], Level_6[]; double RSI_Buffer[]; double CCI_Buffer[]; double PRI_Buffer[]; //---- levels double Level[LEVELS] = {-0.50,-0.26,-0.12, 0.0, 0.12, 0.26, 0.50}; int p_digits; //double p_point; int BarsWindow; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- set points & digits if(Digits==2 || Digits==3) p_digits = 2; else p_digits = 4; if(Symbol() == "XAUUSD") p_digits = 1; if(Symbol() == "XAGUSD") p_digits = 3; //if(Digits==2 || Digits==4) p_point=Point; //else p_point=Point*10; IndicatorDigits(p_digits); BarsWindow=WindowBarsPerChart()+iRangePeriod; //---- indicator buffer mapping SetIndexBuffer(0,Level_0); SetIndexBuffer(1,Level_1); SetIndexBuffer(2,Level_2); SetIndexBuffer(3,Level_3); SetIndexBuffer(4,Level_4); SetIndexBuffer(5,Level_5); SetIndexBuffer(6,Level_6); //---- indicator properties SetIndexStyle(0,DRAW_LINE,indicator_style1,indicator_width1); SetIndexStyle(1,DRAW_LINE,indicator_style2); SetIndexStyle(2,DRAW_LINE,indicator_style3); SetIndexStyle(3,DRAW_LINE,indicator_style4); SetIndexStyle(4,DRAW_LINE,indicator_style5); SetIndexStyle(5,DRAW_LINE,indicator_style6); SetIndexStyle(6,DRAW_LINE,indicator_style7); //---- name for DataWindow and indicator subwindow label string ShortName; ShortName="OscillatorsOnChart("+IntegerToString(iRangePeriod)+")"; IndicatorShortName(ShortName); SetIndexLabel(0," "+(string)(Level[3]*100+50)+"% "); SetIndexLabel(1," "+(string)(Level[4]*100+50)+"% "); SetIndexLabel(2," "+(string)(Level[5]*100+50)+"% "); SetIndexLabel(3," "+(string)(Level[6]*100+50)+"% "); SetIndexLabel(4," "+(string)(Level[2]*100+50)+"% "); SetIndexLabel(5," "+(string)(Level[1]*100+50)+"% "); SetIndexLabel(6," "+(string)(Level[0]*100+50)+"% "); //---- first values aren't drawn SetIndexDrawBegin(0,Bars-BarsWindow); SetIndexDrawBegin(1,Bars-BarsWindow); SetIndexDrawBegin(2,Bars-BarsWindow); SetIndexDrawBegin(3,Bars-BarsWindow); SetIndexDrawBegin(4,Bars-BarsWindow); SetIndexDrawBegin(5,Bars-BarsWindow); SetIndexDrawBegin(6,Bars-BarsWindow); int xStart=6; int yStart=70; int yIncrement=14; if(ShowRSI) { SetIndexBuffer(7,RSI_Buffer); SetIndexStyle(7,DRAW_LINE,indicator_style8,indicator_width8); SetIndexLabel(7,sRSI); SetIndexDrawBegin(7,Bars-BarsWindow); CreateLabel(sRSI+"("+IntegerToString(iRSIPeriod)+")",0,xStart,yStart,indicator_color8); yStart += yIncrement; } if(ShowCCI) { SetIndexBuffer(8,CCI_Buffer); SetIndexStyle(8,DRAW_LINE,indicator_style9,indicator_width9); SetIndexLabel(8,sCCI); SetIndexDrawBegin(8,Bars-BarsWindow); CreateLabel(sCCI+"("+IntegerToString(iCCIPeriod)+")",0,xStart,yStart,indicator_color9); yStart += yIncrement; } if(ShowPRI) { SetIndexBuffer(9,PRI_Buffer); SetIndexStyle(9,DRAW_LINE,indicator_style10,indicator_width10); SetIndexLabel(9,sPRI); SetIndexDrawBegin(9,Bars-BarsWindow); CreateLabel(sPRI+"("+IntegerToString(iPRIPeriod)+")",0,xStart,yStart,indicator_color10); } //---- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //---- check & delete labels if(ObjectFind(0,sRSI+"("+IntegerToString(iRSIPeriod)+")")!=-1) ObjectDelete(0,sRSI+"("+IntegerToString(iRSIPeriod)+")"); if(ObjectFind(0,sCCI+"("+IntegerToString(iCCIPeriod)+")")!=-1) ObjectDelete(0,sCCI+"("+IntegerToString(iCCIPeriod)+")"); if(ObjectFind(0,sPRI+"("+IntegerToString(iPRIPeriod)+")")!=-1) ObjectDelete(0,sPRI+"("+IntegerToString(iPRIPeriod)+")"); return; } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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 tick=TickIn(close[0]); if(Bars0 && tick==OP_NONE) return(rates_total); //---skip useless ticks bool newbar = NewBar(time[0]); int i,limit; static double dMedian, dRange; //---- limit = (rates_total-prev_calculated); if(prev_calculated==0) limit = BarsWindow; if(prev_calculated>0 && newbar) limit = 1; //---- for(i=limit;i>=0;i--) { int shift=iBarShift(NULL,TimeFrame,time[i]); if(prev_calculated==0 || newbar) { if(!AverageMedian) dMedian=Range(MODE_MEDIAN,TimeFrame,iRangePeriod,shift); else dMedian=iMA(NULL,TimeFrame,iRangePeriod,0,MAMode,MAPrice,shift+1); dRange=Range(MODE_RANGE,TimeFrame,iRangePeriod,shift); Level_0[i] = dMedian; Level_1[i] = dMedian + (dRange * Level[4]); Level_2[i] = dMedian + (dRange * Level[5]); Level_3[i] = dMedian + (dRange * Level[6]); Level_4[i] = dMedian + (dRange * Level[2]); Level_5[i] = dMedian + (dRange * Level[1]); Level_6[i] = dMedian + (dRange * Level[0]); } if(ShowRSI) { RSI_Buffer[i] = RSI(TimeFrame,iRSIPeriod,iRSIPrice,shift); RSI_Buffer[i] *= dRange; RSI_Buffer[i] += dMedian; if(AlertsOn && prev_calculated>0) { if(tick==OP_BUY) { if(RSI_Buffer[0] > Level_0[0] && RSI_Buffer[1] <=Level_0[1]) AlertsHandle(sRSI,Level[3],ALRT_BUY,close[0]); if(RSI_Buffer[0] > Level_1[0] && RSI_Buffer[1] <=Level_1[1]) AlertsHandle(sRSI,Level[4],ALRT_BUY,close[0]); if(RSI_Buffer[0] > Level_2[0] && RSI_Buffer[1] <=Level_2[1]) AlertsHandle(sRSI,Level[5],ALRT_BUY,close[0]); if(RSI_Buffer[0] > Level_4[0] && RSI_Buffer[1] <=Level_4[1]) AlertsHandle(sRSI,Level[2],ALRT_BUY,close[0]); if(RSI_Buffer[0] > Level_5[0] && RSI_Buffer[1] <=Level_5[1]) AlertsHandle(sRSI,Level[3],ALRT_BUY,close[0]); } if(tick==OP_SELL) { if(RSI_Buffer[0] < Level_0[0] && RSI_Buffer[1] >=Level_0[1]) AlertsHandle(sRSI,Level[3],ALRT_SELL,close[0]); if(RSI_Buffer[0] < Level_1[0] && RSI_Buffer[1] >=Level_1[1]) AlertsHandle(sRSI,Level[4],ALRT_SELL,close[0]); if(RSI_Buffer[0] < Level_2[0] && RSI_Buffer[1] >=Level_2[1]) AlertsHandle(sRSI,Level[5],ALRT_SELL,close[0]); if(RSI_Buffer[0] < Level_4[0] && RSI_Buffer[1] >=Level_4[1]) AlertsHandle(sRSI,Level[2],ALRT_SELL,close[0]); if(RSI_Buffer[0] < Level_5[0] && RSI_Buffer[1] >=Level_5[1]) AlertsHandle(sRSI,Level[3],ALRT_SELL,close[0]); } } } if(ShowCCI) { CCI_Buffer[i] = CCI(TimeFrame,iCCIPeriod,iCCIPrice,shift); CCI_Buffer[i] *= dRange; CCI_Buffer[i] += dMedian; if(AlertsOn && prev_calculated>0) { if(tick==OP_BUY) { if(CCI_Buffer[0] > Level_0[0] && CCI_Buffer[1] <=Level_0[1]) AlertsHandle(sCCI,Level[3],ALRT_BUY,close[0]); if(CCI_Buffer[0] > Level_1[0] && CCI_Buffer[1] <=Level_1[1]) AlertsHandle(sCCI,Level[4],ALRT_BUY,close[0]); if(CCI_Buffer[0] > Level_2[0] && CCI_Buffer[1] <=Level_2[1]) AlertsHandle(sCCI,Level[5],ALRT_BUY,close[0]); if(CCI_Buffer[0] > Level_4[0] && CCI_Buffer[1] <=Level_4[1]) AlertsHandle(sCCI,Level[2],ALRT_BUY,close[0]); if(CCI_Buffer[0] > Level_5[0] && CCI_Buffer[1] <=Level_5[1]) AlertsHandle(sCCI,Level[3],ALRT_BUY,close[0]); } if(tick==OP_SELL) { if(CCI_Buffer[0] < Level_0[0] && CCI_Buffer[1] >=Level_0[1]) AlertsHandle(sCCI,Level[3],ALRT_SELL,close[0]); if(CCI_Buffer[0] < Level_1[0] && CCI_Buffer[1] >=Level_1[1]) AlertsHandle(sCCI,Level[4],ALRT_SELL,close[0]); if(CCI_Buffer[0] < Level_2[0] && CCI_Buffer[1] >=Level_2[1]) AlertsHandle(sCCI,Level[5],ALRT_SELL,close[0]); if(CCI_Buffer[0] < Level_4[0] && CCI_Buffer[1] >=Level_4[1]) AlertsHandle(sCCI,Level[2],ALRT_SELL,close[0]); if(CCI_Buffer[0] < Level_5[0] && CCI_Buffer[1] >=Level_5[1]) AlertsHandle(sCCI,Level[3],ALRT_SELL,close[0]); } } } if(ShowPRI) { PRI_Buffer[i] = PRI(TimeFrame,iPRIPeriod,iPRIPrice,shift); PRI_Buffer[i] *= dRange; PRI_Buffer[i] += dMedian; if(AlertsOn && prev_calculated>0) { if(tick==OP_BUY) { if(PRI_Buffer[0] > Level_0[0] && PRI_Buffer[1] <=Level_0[1]) AlertsHandle(sPRI,Level[3],ALRT_BUY,close[0]); if(PRI_Buffer[0] > Level_1[0] && PRI_Buffer[1] <=Level_1[1]) AlertsHandle(sPRI,Level[4],ALRT_BUY,close[0]); if(PRI_Buffer[0] > Level_2[0] && PRI_Buffer[1] <=Level_2[1]) AlertsHandle(sPRI,Level[5],ALRT_BUY,close[0]); if(PRI_Buffer[0] > Level_4[0] && PRI_Buffer[1] <=Level_4[1]) AlertsHandle(sPRI,Level[2],ALRT_BUY,close[0]); if(PRI_Buffer[0] > Level_5[0] && PRI_Buffer[1] <=Level_5[1]) AlertsHandle(sPRI,Level[3],ALRT_BUY,close[0]); } if(tick==OP_SELL) { if(PRI_Buffer[0] < Level_0[0] && PRI_Buffer[1] >=Level_0[1]) AlertsHandle(sPRI,Level[3],ALRT_SELL,close[0]); if(PRI_Buffer[0] < Level_1[0] && PRI_Buffer[1] >=Level_1[1]) AlertsHandle(sPRI,Level[4],ALRT_SELL,close[0]); if(PRI_Buffer[0] < Level_2[0] && PRI_Buffer[1] >=Level_2[1]) AlertsHandle(sPRI,Level[5],ALRT_SELL,close[0]); if(PRI_Buffer[0] < Level_4[0] && PRI_Buffer[1] >=Level_4[1]) AlertsHandle(sPRI,Level[2],ALRT_SELL,close[0]); if(PRI_Buffer[0] < Level_5[0] && PRI_Buffer[1] >=Level_5[1]) AlertsHandle(sPRI,Level[3],ALRT_SELL,close[0]); } } } } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CreateLabel(string oscillator,int window,int x,int y,int clr) { int label=ObjectCreate(oscillator,OBJ_LABEL,window,0,0); ObjectSetText(oscillator,oscillator,10,"Arial Bold"); ObjectSet(oscillator,OBJPROP_COLOR,clr); ObjectSet(oscillator,OBJPROP_XDISTANCE,x); ObjectSet(oscillator,OBJPROP_YDISTANCE,y); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool NewBar(datetime time) { static datetime time_prev=0; if(time_prev!=time) { time_prev=time; return(true); } return(false); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int TickIn(double price) { int tick_in=OP_NONE; static double tick_price[3]; tick_price[2] = tick_price[1]; tick_price[1] = tick_price[0]; tick_price[0] = NormalizeDouble(price,p_digits); if(tick_price[0] > tick_price[2]) tick_in = OP_BUY; if(tick_price[0] < tick_price[2]) tick_in = OP_SELL; return(tick_in); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double RSI(int timeframe,int period,int price,int idx) { double RSI; RSI = iRSI(NULL,timeframe,period,price,idx); RSI -= 50; RSI /= 100; return(RSI); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CCI(int timeframe,int period,int price,int idx) { double CCI; double Mul=0.015/period; CCI = iCCI(NULL,timeframe,period,price,idx); CCI *= Mul; return(CCI); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double PRI(int timeframe,int period,int price,int idx) { double PRI; double Price; double MaxHigh; double MinLow; double PRIRange; MaxHigh = iHigh(NULL,timeframe, iHighest(NULL,timeframe,MODE_HIGH,period,idx)); MinLow = iLow(NULL,timeframe, iLowest(NULL,timeframe,MODE_LOW,period,idx)); PRIRange = MaxHigh-MinLow; switch(price) { case PRICE_CLOSE: Price = iClose(NULL,timeframe,idx); break; case PRICE_HIGH: Price = iHigh(NULL,timeframe,idx); break; case PRICE_LOW: Price = iLow(NULL,timeframe,idx); break; case PRICE_MEDIAN: Price = (iHigh(NULL,timeframe,idx)+ iLow(NULL,timeframe,idx))/2; break; case PRICE_TYPICAL: Price = (iHigh(NULL,timeframe,idx)+ iLow(NULL,timeframe,idx)+ iClose(NULL,timeframe,idx))/3; break; case PRICE_WEIGHTED: Price = (iHigh(NULL,timeframe,idx)+ iLow(NULL,timeframe,idx)+ iClose(NULL,timeframe,idx)+ iClose(NULL,timeframe,idx))/4; break; default: Price = iClose(NULL,timeframe,idx); break; } if(NormalizeDouble(PRIRange,Digits)!=0.0) { PRI = (Price-MinLow) / PRIRange; PRI -= 0.50; } else PRI = 0.0; //if(PRI > 0.50) PRI = 0.50; //if(PRI < -0.50) PRI = -0.50; return(PRI); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double Range(int mode,int timeframe,int period,int idx) { double MaxHigh=0, MinLow=0, Range; double HighHigh, HighClose, HighLow; double LowHigh, LowClose, LowLow; switch(RangeMode) { case HIGH_LOW: { MaxHigh = iHigh(NULL,timeframe, iHighest(NULL,timeframe,MODE_HIGH,period-1,idx+1)); MinLow = iLow(NULL,timeframe, iLowest(NULL,timeframe,MODE_LOW,period-1,idx+1)); break; } case CLOSE_CLOSE: { MaxHigh = iClose(NULL,timeframe, iHighest(NULL,timeframe,MODE_CLOSE,period-1,idx+1)); MinLow = iClose(NULL,timeframe, iLowest(NULL,timeframe,MODE_CLOSE,period-1,idx+1)); break; } case HIGH_LOW_CLOSE: { HighHigh = iHigh(NULL,timeframe, iHighest(NULL,timeframe,MODE_HIGH,period-1,idx+1)); HighLow = iLow(NULL,timeframe, iHighest(NULL,timeframe,MODE_LOW,period-1,idx+1)); HighClose = iClose(NULL,timeframe, iHighest(NULL,timeframe,MODE_CLOSE,period-1,idx+1)); LowHigh = iHigh(NULL,timeframe, iLowest(NULL,timeframe,MODE_HIGH,period-1,idx+1)); LowLow = iLow(NULL,timeframe, iLowest(NULL,timeframe,MODE_LOW,period-1,idx+1)); LowClose = iClose(NULL,timeframe, iLowest(NULL,timeframe,MODE_CLOSE,period-1,idx+1)); MaxHigh = (HighHigh+HighLow+HighClose)/3; MinLow = (LowHigh+LowLow+LowClose)/3; break; } } if(mode==MODE_MEDIAN) Range = (MaxHigh+MinLow)/2; else Range = (MaxHigh-MinLow); return(Range); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void AlertsHandle(string oscillator,double level,string alert_type,double price) { static datetime time_prev; static string type_prev; string alert_Message; if(time_prev != iTime(NULL,TimeFrame,0) /*|| osc_prev != oscillator*/ || type_prev != alert_type) { time_prev = iTime(NULL,TimeFrame,0); //osc_prev = oscillator; type_prev = alert_type; alert_Message = StringConcatenate(Symbol()," @ ",TimeToStr(TimeLocal(),TIME_SECONDS), " ",oscillator,"crossed ",level*100+50,"% level", alert_type," @ ",NormalizeDouble(price,p_digits)); if(AlertsMessage) Alert(alert_Message); if(AlertsEmail) SendMail(StringConcatenate(Symbol(),"OscOnChart Alert "),alert_Message); if(AlertsSound) PlaySound("alert2.wav"); } } //+------------------------------------------------------------------+