//+------------------------------------------------------------------+
//|                                                      Correl8.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_separate_window
#property indicator_buffers 13
#property indicator_color1 clrRoyalBlue
#property indicator_color2 clrSilver
#property indicator_color3 clrDarkOrange
#property indicator_color4 clrDarkViolet
#property indicator_color5 clrFireBrick
#property indicator_color6 clrMagenta
#property indicator_color7 clrYellow
#property indicator_color8 clrLimeGreen
#property indicator_color9 clrGold

#property indicator_width1  2
#property indicator_width2  2
#property indicator_width3  2
#property indicator_width4  2
#property indicator_width5  2
#property indicator_width6  2
#property indicator_width7  2
#property indicator_width8  2
#property indicator_width9  2

#property indicator_level1 0
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
enum ENUM_RANGEMODE
  {
   HIGH_LOW,
   CLOSE_CLOSE,
   HIGH_LOW_CLOSE,
  };
// Indicator parameters
extern int   iPRIPeriod=34;
input int MaxBarsBack = 300;
input ENUM_APPLIED_PRICE iPrice = PRICE_WEIGHTED;
input ENUM_RANGEMODE  RangeMode = HIGH_LOW_CLOSE;
input ENUM_TIMEFRAMES TimeFrame = 0;
input double EntryTriggerValue = 34;
input double EntryMinSDVPercent = 0;
input bool   ShowExit = false;
input double ExitTriggerValue = 30;
input bool ShowArrow = true;
input bool DailyOpenFilter=true;
input double DailyOpen_NoRange_pips=5;

input color EntryArrowColor1 = clrDodgerBlue   ;
input color EntryArrowColor2 = clrRed   ;
input int   EntryArrowWidth = 8;
input color ExitArrowColor = clrLimeGreen;
input int   ExitArrowWidth = 8;
input bool ShowAlert = true;
input bool PopupAlert = true;
input bool PushAlert = false;
input bool MailAlert = false;
input bool SoundAlert = false;
input string SoundFile = "alert.wav";
input bool ShowOnScreen = true;
// Show currencies on chart
extern bool  ShowAuto=true;
// Show all currencies
extern bool  ShowAll = false;
extern bool  ShowEUR = false;
extern bool  ShowGBP = false;
extern bool  ShowAUD = false;
extern bool  ShowNZD = false;
extern bool  ShowCHF = false;
extern bool  ShowCAD = false;
extern bool  ShowJPY = false;
extern bool  ShowUSD = false;
extern bool  ShowXAU = false;
//---index buffers for drawing
double Idx1[],Idx2[],Idx3[],Idx4[],Idx5[],Idx6[],Idx7[],Idx8[],Idx9[];
double entry[], exit[];
double exit1[], exit2[];
//---currency variables for calculation
double EUR,GBP,AUD,NZD,CHF,CAD,JPY,USD,XAU;
double EURUSD,GBPUSD,AUDUSD,NZDUSD,/*USDCHF,USDCAD,USDJPY,*/XAUUSD;
//---currency names and colors
string Currencies[9]=
  {
   "EUR","GBP","AUD","NZD",
   "CHF","CAD","JPY","USD","XAU"
  };
string ShortName;
string lbl = "Corr."+IntegerToString(iPRIPeriod)+".";
datetime lastAlert = 0;

double     myPoint;
double     myDigits;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   IndicatorBuffers(13);
   IndicatorDigits(0);

   myPoint     =  MarketInfo(Symbol(),MODE_POINT);
   myDigits    =  MarketInfo(Symbol(),MODE_DIGITS);
   if(myDigits==3 || myDigits==5)
   {
      myPoint     =  myPoint  *  10;
      myDigits    =  myDigits -1;
   } 

//---set timeframes
/*   if(TimeFrame==0)
     {
      switch(Period())
        {
         case PERIOD_M30: iPRIPeriod*=2;break;
         case PERIOD_M15: iPRIPeriod*=4;break;
         case PERIOD_M5:  iPRIPeriod*=12;break;
         case PERIOD_M1:  iPRIPeriod*=60;break;
        }
     }
   if(TimeFrame>0)
     {
      switch(TimeFrame)
        {
         case PERIOD_M30: iPRIPeriod*=2;break;
         case PERIOD_M15: iPRIPeriod*=4;break;
         case PERIOD_M5:  iPRIPeriod*=12;break;
         case PERIOD_M1:  iPRIPeriod*=60;break;
        }
     }*/
   string sTimeFrame;
   switch(TimeFrame)
     {
      case PERIOD_MN1: sTimeFrame = "MN1 ";break;
      case PERIOD_W1:  sTimeFrame = "W1 "; break;
      case PERIOD_D1:  sTimeFrame = "D1 "; break;
      case PERIOD_H4:  sTimeFrame = "H4 "; break;
      case PERIOD_H1:  sTimeFrame = "H1 "; break;
      case PERIOD_M30: sTimeFrame = "M30 ";break;
      case PERIOD_M15: sTimeFrame = "M15 ";break;
      case PERIOD_M5:  sTimeFrame = "M5 "; break;
      case PERIOD_M1:  sTimeFrame = "M1 "; break;
      default:         sTimeFrame = "";    break;
     }
   ShortName="iCorrel8 "+sTimeFrame+"("+IntegerToString(iPRIPeriod)+") ";
   IndicatorShortName(ShortName);
//---currencies to show
   if(ShowAuto)
     {
      string Quote= StringSubstr(Symbol(),3,3);  //Quote currency name
      string Base = StringSubstr(Symbol(),0,3);  //Base currency name
      if(Quote == "EUR" || Base == "EUR")  ShowEUR = true;
      if(Quote == "GBP" || Base == "GBP")  ShowGBP = true;
      if(Quote == "AUD" || Base == "AUD")  ShowAUD = true;
      if(Quote == "NZD" || Base == "NZD")  ShowNZD = true;
      if(Quote == "CHF" || Base == "CHF")  ShowCHF = true;
      if(Quote == "CAD" || Base == "CAD")  ShowCAD = true;
      if(Quote == "JPY" || Base == "JPY")  ShowJPY = true;
      if(Quote == "USD" || Base == "USD")  ShowUSD = true;
      if(Quote == "XAU" || Base == "XAU")  ShowXAU = true;
      //ShowAll=false;
     }

   if(ShowAll)
     {
      //ShowAuto = false;
      ShowEUR = true;
      ShowGBP = true;
      ShowAUD = true;
      ShowNZD = true;
      ShowCHF = true;
      ShowCAD = true;
      ShowJPY = true;
      ShowUSD = true;
      ShowXAU = true;
     }

   int window=WindowFind(ShortName);
   int xStart=4;       //label coordinates
   int xIncrement=25;
   int yStart=16;
   string cur1 = StringSubstr(Symbol(), 0, 3);
   string cur2 = StringSubstr(Symbol(), 3, 3);
//---set buffer properties
   if(ShowEUR)
     {
      SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,indicator_width1);
      SetIndexLabel(0,Currencies[0]);
      SetIndexDrawBegin(0,iPRIPeriod);
      if (cur1==Currencies[0] || cur2==Currencies[0])
      {
        CreateLabel(lbl+Currencies[0],window,xStart,yStart,indicator_color1);
        xStart+=xIncrement;
      }
     }
   if(ShowGBP)
     {
      SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,indicator_width2);
      SetIndexLabel(1,Currencies[1]);
      SetIndexDrawBegin(1,iPRIPeriod);
      if (cur1==Currencies[1] || cur2==Currencies[1])
      {
        CreateLabel(lbl+Currencies[1],window,xStart,yStart,indicator_color2);
        xStart+=xIncrement;
      }
     }
   if(ShowAUD)
     {
      SetIndexStyle(2,DRAW_LINE,STYLE_SOLID,indicator_width3);
      SetIndexLabel(2,Currencies[2]);
      SetIndexDrawBegin(2,iPRIPeriod);
      if (cur1==Currencies[2] || cur2==Currencies[2])
      {
        CreateLabel(lbl+Currencies[2],window,xStart,yStart,indicator_color3);
        xStart+=xIncrement;
      }
     }
   if(ShowNZD)
     {
      SetIndexStyle(3,DRAW_LINE,STYLE_SOLID,indicator_width4);
      SetIndexDrawBegin(3,iPRIPeriod);
      SetIndexLabel(3,Currencies[3]);
      if (cur1==Currencies[3] || cur2==Currencies[3])
      {
        CreateLabel(lbl+Currencies[3],window,xStart,yStart,indicator_color4);
        xStart+=xIncrement;
      }
     }
   if(ShowCHF)
     {
      SetIndexStyle(4,DRAW_LINE,STYLE_SOLID,indicator_width5);
      SetIndexLabel(4,Currencies[4]);
      SetIndexDrawBegin(4,iPRIPeriod);
      if (cur1==Currencies[4] || cur2==Currencies[4])
      {
        CreateLabel(lbl+Currencies[4],window,xStart,yStart,indicator_color5);
        xStart+=xIncrement;
      }
     }
   if(ShowCAD)
     {
      SetIndexStyle(5,DRAW_LINE,STYLE_SOLID,indicator_width6);
      SetIndexLabel(5,Currencies[5]);
      SetIndexDrawBegin(5,iPRIPeriod);
      if (cur1==Currencies[5] || cur2==Currencies[5])
      {
        CreateLabel(lbl+Currencies[5],window,xStart,yStart,indicator_color6);
        xStart+=xIncrement;
      }
     }
   if(ShowJPY)
     {
      SetIndexStyle(6,DRAW_LINE,STYLE_SOLID,indicator_width7);
      SetIndexLabel(6,Currencies[6]);
      SetIndexDrawBegin(6,iPRIPeriod);
      if (cur1==Currencies[6] || cur2==Currencies[6])
      {
        CreateLabel(lbl+Currencies[6],window,xStart,yStart,indicator_color7);
        xStart+=xIncrement;
      }
     }
   if(ShowUSD)
     {
      SetIndexStyle(7,DRAW_LINE,STYLE_SOLID,indicator_width8);
      SetIndexLabel(7,Currencies[7]);
      SetIndexDrawBegin(7,iPRIPeriod);
      if (cur1==Currencies[7] || cur2==Currencies[7])
      {
        CreateLabel(lbl+Currencies[7],window,xStart,yStart,indicator_color8);
        xStart+=xIncrement;
      }
     }
   if(ShowXAU)
     {
      SetIndexStyle(8,DRAW_LINE,STYLE_SOLID,indicator_width9);
      SetIndexLabel(8,Currencies[8]);
      SetIndexDrawBegin(8,iPRIPeriod);
      if (cur1==Currencies[8] || cur2==Currencies[8])
      {
        CreateLabel(lbl+Currencies[8],window,xStart,yStart,indicator_color9);
      }
      xStart+=xIncrement;
     }
   //SetIndexStyle(9,DRAW_NONE);
   //SetIndexStyle(10,DRAW_NONE);
//---index buffers
   SetIndexBuffer(0,Idx1);
   SetIndexBuffer(1,Idx2);
   SetIndexBuffer(2,Idx3);
   SetIndexBuffer(3,Idx4);
   SetIndexBuffer(4,Idx5);
   SetIndexBuffer(5,Idx6);
   SetIndexBuffer(6,Idx7);
   SetIndexBuffer(7,Idx8);
   SetIndexBuffer(8,Idx9);
   SetIndexBuffer(9,entry);
   SetIndexBuffer(10,exit);
   SetIndexBuffer(11,exit1);
   SetIndexBuffer(12,exit2);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
// delete labels
//int window=WindowFind(ShortName);
   ObjectsDeleteAll(0, lbl);
   Comment("");
   for(int i=0;i<9;i++)
      ObjectDelete(Currencies[i]);
   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 shift;
   int limit=rates_total-prev_calculated;
   if (limit>MaxBarsBack) limit = MaxBarsBack;
   if(limit<2) limit=2;
   for(int i=limit-1; i>=0; i--)
     {
      shift=iBarShift(NULL,TimeFrame,time[i]);

      EUR = iPRI("EURUSD",TimeFrame,iPRIPeriod,iPrice,shift);
      GBP = iPRI("GBPUSD",TimeFrame,iPRIPeriod,iPrice,shift);
      AUD = iPRI("AUDUSD",TimeFrame,iPRIPeriod,iPrice,shift);
      NZD = iPRI("NZDUSD",TimeFrame,iPRIPeriod,iPrice,shift);
      CHF = iPRI("USDCHF",TimeFrame,iPRIPeriod,iPrice,shift);
      CAD = iPRI("USDCAD",TimeFrame,iPRIPeriod,iPrice,shift);
      JPY = iPRI("USDJPY",TimeFrame,iPRIPeriod,iPrice,shift);
      XAU = iPRI("XAUUSD",TimeFrame,iPRIPeriod,iPrice,shift);

      EURUSD = iClose("EURUSD",TimeFrame,shift);   //Get USD ratio      
      GBPUSD = iClose("GBPUSD",TimeFrame,shift);
      AUDUSD = iClose("AUDUSD",TimeFrame,shift);
      NZDUSD = iClose("NZDUSD",TimeFrame,shift);
      //USDCHF = iClose("USDCHF",TimeFrame,shift);
      //USDCAD = iClose("USDCAD",TimeFrame,shift);
      //USDJPY = iClose("USDJPY",TimeFrame,shift)/100;
      XAUUSD = iClose("XAUUSD",TimeFrame,shift)/1000;

      if(EURUSD)
         EUR*=1/EURUSD;
      if(GBPUSD)
         GBP*=1/GBPUSD;
      if(AUDUSD)
         AUD*=1/AUDUSD;
      if(NZDUSD)
         NZD*=1/NZDUSD;
      if(XAUUSD)
         XAU*=1/XAUUSD;

      CHF*=-1;
      CAD*=-1;
      JPY*=-1;
      
      USD=-(EUR+GBP+AUD+NZD+CHF+CAD+JPY+XAU)/(9-1);   //USD relative to other 
    /*EUR += -(GBP + AUD + NZD + CHF + CAD + JPY + XAU)/(indicator_buffers-2); //Currency relative to USD
      GBP += -(EUR + AUD + NZD + CHF + CAD + JPY + XAU)/(indicator_buffers-2);
      AUD += -(EUR + GBP + NZD + CHF + CAD + JPY + XAU)/(indicator_buffers-2);
      NZD += -(EUR + GBP + AUD + CHF + CAD + JPY + XAU)/(indicator_buffers-2);
      CHF += -(EUR + GBP + AUD + NZD + CAD + JPY + XAU)/(indicator_buffers-2);
      CAD += -(EUR + GBP + AUD + NZD + CHF + JPY + XAU)/(indicator_buffers-2);
      JPY += -(EUR + GBP + AUD + NZD + CHF + CAD + XAU)/(indicator_buffers-2);
    */
      if(ShowEUR)
         Idx1[i]=EUR;
      if(ShowGBP)
         Idx2[i]=GBP;
      if(ShowAUD)
         Idx3[i]=AUD;
      if(ShowNZD)
         Idx4[i]=NZD;
      if(ShowCHF)
         Idx5[i]=CHF;
      if(ShowCAD)
         Idx6[i]=CAD;
      if(ShowJPY)
         Idx7[i]=JPY;
      if(ShowUSD)
         Idx8[i]=USD;
      if(ShowXAU)
         Idx9[i]=XAU;
      //if(StringSubstr(Symbol(), 0, 3)
      
      double open0=iOpen(Symbol(),PERIOD_D1,iBarShift(Symbol(),PERIOD_D1,iTime(Symbol(),TimeFrame,i)));
      bool dailybuy=false; bool dailysell=false;
      if(DailyOpenFilter) 
      {
         double close0=iClose(Symbol(),TimeFrame,i);
         if(close0>open0+(DailyOpen_NoRange_pips*myPoint)) dailybuy=true;
         else if(close0<open0-(DailyOpen_NoRange_pips*myPoint)) dailysell=true;
      }
      else { dailybuy=true; dailysell=true; }
      
      if (i < MaxBarsBack && i > 0)
        {
         double x1 = GetValue(StringSubstr(Symbol(), 0, 3), i);
         double x2 = GetValue(StringSubstr(Symbol(), 3, 3), i);
         double x3 = GetValue(StringSubstr(Symbol(), 0, 3), i+1);
         double x4 = GetValue(StringSubstr(Symbol(), 3, 3), i+1);
         if (x1==EMPTY_VALUE || x2==EMPTY_VALUE || x3==EMPTY_VALUE || x4==EMPTY_VALUE) continue;
         //if (TimeToStr(Time[i])=="2016.07.06 19:00") Comment(x1, ", ", x2);
         if (x1-x2>=EntryTriggerValue && x3-x4<EntryTriggerValue && ((x1-x2)-(x3-x4))/MathAbs(x3-x4)>=EntryMinSDVPercent/100)
           {
            bool allow = true; int en = -1;
            for (int j = i+1; j < MaxBarsBack; j++)
              {
               if (exit1[j] != EMPTY_VALUE || exit2[j] != EMPTY_VALUE) { allow = true; en = j; break; }
               if (entry[j] != EMPTY_VALUE) { allow = false; break; }
               double x5 = GetValue(StringSubstr(Symbol(), 0, 3), j);
               double x6 = GetValue(StringSubstr(Symbol(), 3, 3), j);
               if (x5<x6) { allow = true; en = j; break; }
              }
            if (allow && dailybuy) entry[i] = Low[i];
           }
         if (x2-x1>=EntryTriggerValue && x4-x3<EntryTriggerValue && ((x2-x1)-(x4-x3))/MathAbs(x4-x3)>=EntryMinSDVPercent/100)
           {
            bool allow = true; int en = -1;
            for (int j = i+1; j < MaxBarsBack; j++)
              {
               if (exit1[j] != EMPTY_VALUE || exit2[j] != EMPTY_VALUE) { allow = true; en = j; break; }
               if (entry[j] != EMPTY_VALUE) { allow = false; break; }
               double x5 = GetValue(StringSubstr(Symbol(), 0, 3), j);
               double x6 = GetValue(StringSubstr(Symbol(), 3, 3), j);
               if (x5>x6) { allow = true; en = j; break; }
              }
            if (allow && dailysell) entry[i] = High[i];
           }
         if (ShowExit && MathAbs(x1-x2)<=ExitTriggerValue && MathAbs(x3-x4)>ExitTriggerValue)
           {
            bool allow = false; int en = -1;
            for (int j = i+1; j < MaxBarsBack; j++)
              {
               if (entry[j] != EMPTY_VALUE) { allow = true; en = j; break; }
               if (exit[j] != EMPTY_VALUE) break;
              }
            if (allow)
              {
               //if (entry[en]==Low[en]) exit[i]=High[i];
               //if (entry[en]==High[en]) exit[i]=Low[i];
              }
           }
           
           if((x3<0 && x1>=0) || (x3>0 && x1<=0))
           {
            bool allow1= false; int en1 = -1;
            for (int j1 = i+1; j1 < MaxBarsBack; j1++)
              {
               if (entry[j1] != EMPTY_VALUE) { allow1 = true; en1 = j1; break; }
               if (exit1[j1] != EMPTY_VALUE) break;
              }
            if (allow1)
              {
               if (entry[en1]==Low[en1] && x3>=0 && x1<0) exit1[i]=High[i];
               if (entry[en1]==High[en1] && x3<=0 && x1>0) exit1[i]=Low[i];
              }
           }
           
           if((x4<0 && x2>=0) || (x4>0 && x2<=0))
           {
            bool allow2= false; int en2 = -1;
            for (int j2 = i+1; j2 < MaxBarsBack; j2++)
              {
               if (entry[j2] != EMPTY_VALUE) { allow2 = true; en2 = j2; break; }
               if (exit2[j2] != EMPTY_VALUE) break;
              }
            if (allow2)
              {
               if (entry[en2]==Low[en2] && x4<=0 && x2>0) exit2[i]=High[i];
               if (entry[en2]==High[en2] && x4>=0 && x2<0) exit2[i]=Low[i];
              }
           }
           

           
         if (ShowArrow && entry[i]!=EMPTY_VALUE)
           {
            if (entry[i]==Low[i]) DrawArrow(lbl+".Entry"+IntegerToString(Time[i]), 252, Time[i], entry[i], EntryArrowColor1, EntryArrowWidth, ANCHOR_TOP);
            if (entry[i]==High[i]) DrawArrow(lbl+".Entry"+IntegerToString(Time[i]), 252, Time[i], entry[i], EntryArrowColor2, EntryArrowWidth, ANCHOR_BOTTOM);
           }
         if (ShowArrow && exit[i]!=EMPTY_VALUE)
           {
            if (exit[i]==Low[i]) DrawArrow(lbl+".Exit"+IntegerToString(Time[i]), 251, Time[i], exit[i], ExitArrowColor, ExitArrowWidth, ANCHOR_TOP);
            if (exit[i]==High[i]) DrawArrow(lbl+".Exit"+IntegerToString(Time[i]), 251, Time[i], exit[i], ExitArrowColor, ExitArrowWidth, ANCHOR_BOTTOM);
           }
        }
        
        if(exit1[i]!=EMPTY_VALUE && exit1[i]==Low[i]) DrawArrow(lbl+".Exit.1."+IntegerToString(Time[i]), 251, Time[i], exit1[i], ExitArrowColor, ExitArrowWidth, ANCHOR_TOP);
        if(exit1[i]!=EMPTY_VALUE && exit1[i]==High[i]) DrawArrow(lbl+".Exit.1."+IntegerToString(Time[i]), 251, Time[i], exit1[i], ExitArrowColor, ExitArrowWidth, ANCHOR_BOTTOM);
        if(exit2[i]!=EMPTY_VALUE && exit2[i]==Low[i]) DrawArrow(lbl+".Exit.2."+IntegerToString(Time[i]), 251, Time[i], exit2[i], ExitArrowColor, ExitArrowWidth, ANCHOR_TOP);
        if(exit2[i]!=EMPTY_VALUE && exit2[i]==High[i]) DrawArrow(lbl+".Exit.2."+IntegerToString(Time[i]), 251, Time[i], exit2[i], ExitArrowColor, ExitArrowWidth, ANCHOR_BOTTOM);
        
     }
   if (lastAlert != Time[0])
     {
      lastAlert = Time[0];
      if (entry[1] != EMPTY_VALUE)
        {
         double x1 = GetValue(StringSubstr(Symbol(), 0, 3), 1);
         double x2 = GetValue(StringSubstr(Symbol(), 3, 3), 1);
         string msg = TimeToStr(Time[0])+": "+Symbol()+"("+GetTimeFrameName(0)+") "+(entry[1]==Low[1]?"Long":"Short")+" entry alert ("+DoubleToStr(MathAbs(x1-x2), 0)+")";
         if (SoundAlert) PlaySound(SoundFile);
         if (ShowAlert && PopupAlert) Alert(msg);
         if (ShowAlert && PushAlert) SendNotification(msg);
         if (ShowAlert && MailAlert) SendMail(msg, msg);
         if (ShowOnScreen) Comment(msg);
        }
      else if (exit[1] != EMPTY_VALUE)
        {
         double x1 = GetValue(StringSubstr(Symbol(), 0, 3), 1);
         double x2 = GetValue(StringSubstr(Symbol(), 3, 3), 1);
         string msg = TimeToStr(Time[0])+": "+Symbol()+"("+GetTimeFrameName(0)+") "+(exit[1]==High[1]?"Long":"Short")+" exit alert ("+DoubleToStr(MathAbs(x1-x2), 0)+")";
         if (SoundAlert) PlaySound(SoundFile);
         if (ShowAlert && PopupAlert) Alert(msg);
         if (ShowAlert && PushAlert) SendNotification(msg);
         if (ShowAlert && MailAlert) SendMail(msg, msg);
         if (ShowOnScreen) Comment(msg);
        }
      else if (exit1[1] != EMPTY_VALUE)
        {
         double x1 = GetValue(StringSubstr(Symbol(), 0, 3), 1);
         double x2 = GetValue(StringSubstr(Symbol(), 3, 3), 1);
         string msg;
         if(exit1[1]==High[1]) msg = TimeToStr(Time[0])+": "+Symbol()+"("+GetTimeFrameName(0)+") "+(exit1[1]==High[1]?"Long":"Short")+" exit alert ("+DoubleToStr(x1, 0)+")";
         if(exit1[1]==Low[1]) msg = TimeToStr(Time[0])+": "+Symbol()+"("+GetTimeFrameName(0)+") "+(exit1[1]==Low[1]?"Long":"Short")+" exit alert ("+DoubleToStr(x1, 0)+")";
         if (SoundAlert) PlaySound(SoundFile);
         if (ShowAlert && PopupAlert) Alert(msg);
         if (ShowAlert && PushAlert) SendNotification(msg);
         if (ShowAlert && MailAlert) SendMail(msg, msg);
         if (ShowOnScreen) Comment(msg);
        }  
      else if (exit2[1] != EMPTY_VALUE)
        {
         double x1 = GetValue(StringSubstr(Symbol(), 0, 3), 1);
         double x2 = GetValue(StringSubstr(Symbol(), 3, 3), 1);
         string msg;
         if(exit2[1]==High[1]) msg = TimeToStr(Time[0])+": "+Symbol()+"("+GetTimeFrameName(0)+") "+(exit2[1]==High[1]?"Long":"Short")+" exit alert ("+DoubleToStr(x2, 0)+")";
         if(exit2[1]==Low[1]) msg = TimeToStr(Time[0])+": "+Symbol()+"("+GetTimeFrameName(0)+") "+(exit2[1]==Low[1]?"Long":"Short")+" exit alert ("+DoubleToStr(x2, 0)+")";
         if (SoundAlert) PlaySound(SoundFile);
         if (ShowAlert && PopupAlert) Alert(msg);
         if (ShowAlert && PushAlert) SendNotification(msg);
         if (ShowAlert && MailAlert) SendMail(msg, msg);
         if (ShowOnScreen) Comment(msg);
        }  
      else if (ShowOnScreen && TimeCurrent()-Time[0]<=3) Comment("");
     }
   double x1 = GetValue(StringSubstr(Symbol(), 0, 3), 1);
   double x2 = GetValue(StringSubstr(Symbol(), 3, 3), 1);
   double x3 = GetValue(StringSubstr(Symbol(), 0, 3), 2);
   double x4 = GetValue(StringSubstr(Symbol(), 3, 3), 2);
   int xStart=8, yIncrement=18, yStart=6;
   ObjectSetInteger(0, lbl+StringSubstr(Symbol(), 0, 3), OBJPROP_YDISTANCE, yStart);
   ObjectSetInteger(0, lbl+StringSubstr(Symbol(), 0, 3), OBJPROP_XDISTANCE, xStart);
   ObjectSetInteger(0, lbl+StringSubstr(Symbol(), 3, 3), OBJPROP_YDISTANCE, yStart+yIncrement);
   ObjectSetInteger(0, lbl+StringSubstr(Symbol(), 3, 3), OBJPROP_XDISTANCE, xStart);
   ObjectSetString(0, lbl+StringSubstr(Symbol(), 0, 3), OBJPROP_TEXT, StringSubstr(Symbol(), 0, 3)+" "+DoubleToStr(x1, 1));
   ObjectSetString(0, lbl+StringSubstr(Symbol(), 3, 3), OBJPROP_TEXT, StringSubstr(Symbol(), 3, 3)+" "+DoubleToStr(x2, 1));
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
double GetValue(string cur, int shift)
  {
   if (cur=="EUR") return (Idx1[shift]);
   if (cur=="GBP") return (Idx2[shift]);
   if (cur=="AUD") return (Idx3[shift]);
   if (cur=="NZD") return (Idx4[shift]);
   if (cur=="CHF") return (Idx5[shift]);
   if (cur=="CAD") return (Idx6[shift]);
   if (cur=="JPY") return (Idx7[shift]);
   if (cur=="USD") return (Idx8[shift]);
   if (cur=="XAU") return (Idx9[shift]);
   return (EMPTY_VALUE);
  }
//+------------------------------------------------------------------+
void DrawArrow(string name, int arrow, datetime time, double price, color col, int width, ENUM_ARROW_ANCHOR anchor)
{
  if (ObjectFind(0, name) == -1)
  {
    ObjectCreate(0, name, OBJ_ARROW, 0, time, price);
    ObjectSetInteger(0, name, OBJPROP_BACK, false);
    ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
    ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
  }
  if (ObjectGetInteger(0, name, OBJPROP_ANCHOR) != anchor) ObjectSetInteger(0, name, OBJPROP_ANCHOR, anchor);
  if (ObjectGetInteger(0, name, OBJPROP_ARROWCODE) != arrow) ObjectSetInteger(0, name, OBJPROP_ARROWCODE, arrow);
  if (ObjectGetInteger(0, name, OBJPROP_COLOR) != col) ObjectSetInteger(0, name, OBJPROP_COLOR, col);
  if (ObjectGetInteger(0, name, OBJPROP_WIDTH) != width) ObjectSetInteger(0, name, OBJPROP_WIDTH, width);
  if (ObjectGetInteger(0, name, OBJPROP_TIME, 0) != time) ObjectSetInteger(0, name, OBJPROP_TIME, 0, time);
  if (NormalizeDouble(ObjectGetDouble(0, name, OBJPROP_PRICE, 0), _Digits) != NormalizeDouble(price, _Digits)) ObjectSetDouble(0, name, OBJPROP_PRICE, 0, price);
}
//+------------------------------------------------------------------+
string GetTimeFrameName(int tf)
{
  switch (tf)
  {
    case PERIOD_M1: return("M1");
    case PERIOD_M5: return("M5");
    case PERIOD_M15: return("M15");
    case PERIOD_M30: return("M30");
    case PERIOD_H1: return("H1");
    case PERIOD_H4: return("H4");
    case PERIOD_D1: return("D1");
    case PERIOD_W1: return("W1");
    case PERIOD_MN1: return("MN1");
    case 0: return(GetTimeFrameName(Period()));
  }
  return ("");
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CreateLabel(string currency,
                 int window,
                 int x,
                 int y,
                 int clr)
  {
   int label=ObjectCreate(currency,OBJ_LABEL,window,0,0);
   ObjectSetText(currency,currency,8);
   ObjectSet(currency,OBJPROP_CORNER,CORNER_RIGHT_UPPER);
   ObjectSet(currency,OBJPROP_COLOR,clr);
   ObjectSet(currency,OBJPROP_XDISTANCE,x);
   ObjectSet(currency,OBJPROP_YDISTANCE,y);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool NewBar()
  {
   static datetime time_prev;
   if(iTime("EURUSD",TimeFrame,0) != time_prev &&
      iTime("GBPUSD",TimeFrame,0) != time_prev &&
      iTime("AUDUSD",TimeFrame,0) != time_prev &&
      iTime("NZDUSD",TimeFrame,0) != time_prev &&
      iTime("USDCHF",TimeFrame,0) != time_prev &&
      iTime("USDCAD",TimeFrame,0) != time_prev &&
      iTime("USDJPY",TimeFrame,0) != time_prev &&
      iTime("XAUUSD",TimeFrame,0) != time_prev)
     {
      time_prev = iTime("EURUSD",TimeFrame,0);
      time_prev = iTime("GBPUSD",TimeFrame,0);
      time_prev = iTime("AUDUSD",TimeFrame,0);
      time_prev = iTime("NZDUSD",TimeFrame,0);
      time_prev = iTime("USDCHF",TimeFrame,0);
      time_prev = iTime("USDCAD",TimeFrame,0);
      time_prev = iTime("USDJPY",TimeFrame,0);
      time_prev = iTime("XAUUSD",TimeFrame,0);
      return(true);
     }
   return(false);
  }
//+------------------------------------------------------------------+
//| Percent Range Index Function                                     |
//+------------------------------------------------------------------+
const int iPRI(string symbol,
               const ENUM_TIMEFRAMES timeframe,
               const int period,
               const ENUM_APPLIED_PRICE price,
               const int idx)
  {
   int PRI;
   double Price;
   double Range;
   double MaxHigh = 0;
   double MinLow = 0;
   double HighHigh;
   double HighClose;
   double HighLow;
   double LowHigh;
   double LowClose;
   double LowLow;
   if (StringLen(Symbol())>6) symbol = symbol+StringSubstr(Symbol(), 6);

   switch(RangeMode)
     {
      case HIGH_LOW:
        {
         MaxHigh=iHigh(symbol,timeframe,
                 iHighest(symbol,timeframe,MODE_HIGH,period,idx));
         MinLow=iLow(symbol,timeframe,
                iLowest(symbol,timeframe,MODE_LOW,period,idx));
         break;
        }
      case CLOSE_CLOSE:
        {
         MaxHigh=iClose(symbol,timeframe,
                 iHighest(symbol,timeframe,MODE_CLOSE,period,idx));
         MinLow=iClose(symbol,timeframe,
                iLowest(symbol,timeframe,MODE_CLOSE,period,idx));
         break;
        }
      case HIGH_LOW_CLOSE:
        {
         HighHigh=iHigh(symbol,timeframe,
                  iHighest(symbol,timeframe,MODE_HIGH,period,idx));
         HighClose=iClose(symbol,timeframe,
                   iHighest(symbol,timeframe,MODE_CLOSE,period,idx));
         HighLow=iLow(symbol,timeframe,
                 iHighest(symbol,timeframe,MODE_LOW,period,idx));
         LowHigh=iHigh(symbol,timeframe,
                 iLowest(symbol,timeframe,MODE_HIGH,period,idx));
         LowClose=iClose(symbol,timeframe,
                  iLowest(symbol,timeframe,MODE_CLOSE,period,idx));
         LowLow=iLow(symbol,timeframe,
                iLowest(symbol,timeframe,MODE_LOW,period,idx));
         MaxHigh=(HighHigh+HighClose+HighLow)/3;
         MinLow =(LowHigh+LowClose+LowLow)/3;
         break;
        }
     }

   switch(price)
     {
      case PRICE_CLOSE:    Price = iClose(symbol,timeframe,idx);    break;
      case PRICE_HIGH:     Price = iHigh(symbol,timeframe,idx);     break;
      case PRICE_LOW:      Price = iLow(symbol,timeframe,idx);      break;
      case PRICE_MEDIAN:   Price =(iHigh(symbol,timeframe,idx)+
                                   iLow(symbol,timeframe,idx))/2;   break;
      case PRICE_TYPICAL:  Price =(iHigh(symbol,timeframe,idx)+
                                   iLow(symbol,timeframe,idx)+
                                   iClose(symbol,timeframe,idx))/3; break;
      case PRICE_WEIGHTED: Price =(iHigh(symbol,timeframe,idx)+
                                   iLow(symbol,timeframe,idx)+
                                   iClose(symbol,timeframe,idx)+
                                   iClose(symbol,timeframe,idx))/4; break;
      default:             Price = iClose(symbol,timeframe,idx);
     }

   Range=MaxHigh-MinLow;

   if(NormalizeDouble(Range,3)!=0.0)
     {
      PRI=(int)(100*(Price-MinLow)/Range);
      PRI-=50;
     }
   else PRI=0;
//if(PRI >  50)   PRI =  50;
//if(PRI < -50)   PRI = -50;
   return(PRI);
  }
//+------------------------------------------------------------------+
