oscillatorsonchart

Author: Copyright 2014, MetaQuotes Software Corp.
oscillatorsonchart
Price Data Components
Series array that contains the highest prices of each barSeries array that contains the lowest prices of each barSeries array that contains close prices for each barSeries array that contains the highest prices of each barSeries array that contains the lowest prices of each bar
Indicators Used
Moving average indicatorRelative strength indexCommodity channel index
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screenIt sends emailsIt plays sound alerts
0 Views
0 Downloads
0 Favorites
oscillatorsonchart
//+------------------------------------------------------------------+
//|                                           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(Bars<BarsWindow)   return(rates_total);
   if(prev_calculated>0 && 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");
     }
  }
//+------------------------------------------------------------------+

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---