//+------------------------------------------------------------------+
//|                                            TrendRevers Areas.mq4 |
//|                                 Copyright © 2009.06.25, SwingMan |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009.06.25, SwingMan"
#property link      ""
/*+------------------------------------------------------------------+
Source from: HourPower Signals
2009.03.16  Send Signal-Alert and -EMail
            Factor_SignalOffset
2009.03.17  Problem with appear/disappear of signals on the same bar solved
            "transparent" arrows
2009.06.25  Areas for TrendRevers / HullSlope indicator            
//+-----------------------------------------------------------------*/

#property indicator_chart_window

#property indicator_buffers 2

#property indicator_color1 DeepSkyBlue
#property indicator_color2 Magenta
#property indicator_width1 2
#property indicator_width2 2

//---- extern inputs -------------------------------------------------
extern int MaxBars = 200;
//extern double Factor_SignalOffset = 0.5;
//extern double SAR_Step = 0.05;
//extern double SAR_Max  = 0.2;
//extern double Stoch_Kperiod = 5;
//extern double Stoch_Dperiod = 3;
//extern double Stoch_Slowing = 3;
extern bool SendAlert_Signals  = true;
extern bool SendEmail_Signals  = false;
//extern bool PrintAlert_Signals = false;
extern bool ThickArrows = true;
//--------------------------------------------------------------------

bool Slope_HistogramValues = false;


//---- constants
string sTextAlert        = "TrendRevers Areas";
string subjectEmailAlert = "TrendRevers Areas";
string windowsName       = "TrendRevers Areas";

double limitOverBought = 80;
double limitOverSold   = 20;
//---- buffers
double signalUP[], signalDN[];
double hMainTrend[], hSlopeMain[], hSlopeSignal[];
int hSignalDirection[], signalTRADE[];

//---- variables
int AlertSignal, oldSignalTRADE, thisSignalTRADE;
string sPeriod;
datetime signalTime;

//---- areas
int areaNumber;
datetime beginArea, endArea;
double highArea, lowArea;
color colorUpArea = Olive;//C'98,98,255'; //Blue; Green
color colorDnArea = LightSalmon;//C'255,128,79'; //OrangeRed;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   areaNumber = 0;
   beginArea = 0; 
   endArea = 0;
   highArea = 0;
   lowArea = 0;
   //Comment(windowsName);
   
   ArraySetAsSeries(hMainTrend, true);
   ArraySetAsSeries(hSlopeMain, true);
   ArraySetAsSeries(hSlopeSignal, true);     
   ArraySetAsSeries(hSignalDirection, true);   
   ArraySetAsSeries(signalTRADE, true);
   int iArrowUP, iArrowDN;
   if (ThickArrows == false) {
      iArrowUP = 241;
      iArrowDN = 242;
   } 
   else {
      iArrowUP = 233;
      iArrowDN = 234;
   }
   SetIndexBuffer(0, signalUP);  SetIndexStyle(0, DRAW_ARROW, EMPTY, 2); 
   SetIndexArrow(0,iArrowUP); SetIndexLabel(0, "Buy");
   SetIndexBuffer(1, signalDN);  SetIndexStyle(1, DRAW_ARROW, EMPTY, 2); 
   SetIndexArrow(1,iArrowDN); SetIndexLabel(1, "Sell");
   
   sPeriod = Get_sPeriod(Period());

   return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
{   
   ObjectsDeleteAll();
   return(0);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{
//   Comment(windowsName + "  " + TimeToStr(TimeCurrent(),TIME_MINUTES|TIME_SECONDS));
   int counted_bars, limit, i;

   ArrayResize(hMainTrend, Bars);
   ArrayResize(hSlopeMain, Bars);
   ArrayResize(hSlopeSignal, Bars);   
   ArrayResize(hSignalDirection, Bars);   
   ArrayResize(signalTRADE, Bars);
   
   counted_bars = IndicatorCounted();
   if (counted_bars < 0) return(-1);
   if (counted_bars > 0) counted_bars--;

   if (Bars > MaxBars) 
        limit = MaxBars - counted_bars; 
   else limit = Bars - counted_bars;   

   //---- calculate indicators ======================================
   for (i = limit+1; i >= 0; i--) {   
      //---- Main trend / Hull(27) ..................................
      int Hull_period27 = 27;
      /*double iTrend;
      double HullValue;
      Get_HullTrend(Symbol(), Period(), Hull_period27, iTrend, HullValue, i);
      hMainTrend[i] = iTrend;*/

      //---- slope Hull(27) .................................      
      int smooth_period = 5;
      double treshold = 10.0;
      double slopeH27, slopeH8;
      Get_HullSlope(Symbol(), Period(), Hull_period27, smooth_period, treshold, slopeH27, i);
      hSlopeMain[i] = slopeH27;
      //---- slope Hull(8) .................................      
      /*int Hull_period8 = 8;
      Get_HullSlope(Symbol(), Period(), Hull_period8, smooth_period, treshold, slopeH8, i);      
      hSlopeSignal[i]  = slopeH8;*/
//if (i==0)
//Comment("MainTrend=",iTrend, "  SlopeMain=",slopeH27,"  SlopeSignal=",slopeH8);
   }
   

   //---- draw areas ======================================   
   string sName;
   for (i = limit; i >= 0; i--) {
      double slope0 = hSlopeMain[i];
      double slope1 = hSlopeMain[i+1];
//if (i==16)
//Comment("slope0=",slope0,"  slope1=",slope1);      
      //--- color is changed
      if (slope0 != slope1) {
         //-- first area
         //if (beginArea == 0) {
            areaNumber++;
            sName = "ar_" + areaNumber;
            
            beginArea = Time[i];
            double dATR2  = iATR(Symbol(),Period(),34,1) / 2.0;
            double middle = (High[i]+Low[i])/2.0;
            highArea  = NormalizeDouble(middle+dATR2, Digits);
            lowArea   = NormalizeDouble(middle-dATR2, Digits);
            
            endArea = 0;
            
            //---- signal arrows
            if (slope0 > 0) signalUP[i] = Low[i] - dATR2 * 0.80; else
            if (slope0 < 0) signalDN[i] = High[i] + dATR2 * 0.80;
            
            //---- send alerts
            if (i == 0) {
               if (slope0 > 0) AlertSignal = 1; else
               if (slope0 < 0) AlertSignal = -1;
               SendAlerts();
            }
         /*}
         else
         if (endArea == 0 && beginArea != Time[i]) {
            endArea = Time[i];            
         }*/
      }
      else
      //--- color is not changed
      if (slope0 == slope1) {
         if (endArea == 0 && beginArea != Time[i]) {
            endArea = Time[i];
            if (slope0 > 0) color dColor = colorUpArea; else dColor = colorDnArea;
            Draw_Area(sName, dColor, beginArea, highArea, endArea, lowArea);            
         }
         else
         if (endArea != 0 && endArea != Time[i]) {
            endArea = Time[i];
            Change_Area(sName, 1, endArea, lowArea);
         }
      }
   }
   
   
/*   //---- calculate signals =========================================
   for (i = limit; i >= 0; i--) {
      //---- Trend and Slope signals -----------------------------------------
      hSignalDirection[i] = 0;
      if (hMainTrend[i] > 0 && hSlopeMain[i] > 0 && hSlopeSignal[i] > 0) hSignalDirection[i] =  1; else
      if (hMainTrend[i] < 0 && hSlopeMain[i] < 0 && hSlopeSignal[i] < 0) hSignalDirection[i] =  -1;
   }
   
   //---- TRADE signals =============================================
   for (i = limit; i >= 0; i--) {
      signalTRADE[i] = hSignalDirection[i];

      //---- signals for the last bar / avoid repainting !! ---------
      if (i == 0)
      {
         //---- delete signal 
         if (signalTRADE[i] == 0 && thisSignalTRADE != 0) {
            Delete_Signal(i, thisSignalTRADE);
            thisSignalTRADE = 0;
         }
         else
         //---- new signal
         if (signalTRADE[i] != 0 && thisSignalTRADE == 0) {
            Set_NewSignal(i);
            thisSignalTRADE = signalTRADE[i];
            oldSignalTRADE  = signalTRADE[i];
         }       
      }      
      else
      
      //---- signals for history bars -------------------------------
      if (i > 0 && iTime(Symbol(),Period(),i) == signalTime)
      {
         if (signalTRADE[i] != 0 && 
             signalTRADE[i] != signalTRADE[i+1])
         {            
            Set_NewSignal(i);
            oldSignalTRADE  = signalTRADE[i];
         }      
      }
      else
      
      //---- signal on a new bar ....................................
      if (i > 0 && iTime(Symbol(),Period(),i) != signalTime)
      {
         signalTime = iTime(Symbol(),Period(),i);
      
         if (signalTRADE[i] != 0 && 
             signalTRADE[i] != signalTRADE[i+1])
         {            
            Set_NewSignal(i);
            oldSignalTRADE  = signalTRADE[i];
         }
      }
   }*/
   return(0);
}
//+------------------------------------------------------------------+


void Draw_Area(string sName, color dColor, datetime time1, double price1, datetime time2, double price2)
{
   ObjectCreate(sName,OBJ_RECTANGLE,0,time1,price1,time2,price2);
   ObjectSet(sName, OBJPROP_COLOR, dColor);
}   

void Change_Area(string sName, int point, datetime time1, double price1)
{
   ObjectMove(sName,point,time1,price1);
}   

          
//+------------------------------------------------------------------+
//    Set New Signal
//+------------------------------------------------------------------+
void Set_NewSignal(int iBar)
{
/*   double dOffset = iATR(Symbol(), Period(), 13, 1) * Factor_SignalOffset;
   if (signalTRADE[iBar] ==  1) signalUP[iBar] = Low[iBar] - dOffset; else
   if (signalTRADE[iBar] == -1) signalDN[iBar] = High[iBar]+ dOffset;
   if (iBar == 0) {
      AlertSignal = signalTRADE[iBar];
      SendAlerts();
   }*/
}

//####################################################################
//+------------------------------------------------------------------+
//    function SendAlerts
//+------------------------------------------------------------------+
void SendAlerts()
{   
   if (SendAlert_Signals == false && SendEmail_Signals == false) return;
   //if (SendAlert_Signals == false && SendEmail_Signals == false && PrintAlert_Signals == false) return;
   if (AlertSignal == 0) return;
   
   string st;
   string sSymbol = Symbol();
   
   int iOrderType = AlertSignal;
   string sPrice = DoubleToStr(iClose(sSymbol,Period(),0), Digits);
   string sTime  = TimeToStr(TimeCurrent(),TIME_MINUTES|TIME_SECONDS);
   
   switch (iOrderType) {
      case  1: st = "Buy "; break;
      case -1: st = "Sell "; break;
   }
   st = st + sSymbol + "  " + sPrice + "   (" + sPeriod + ")  " + sTextAlert + "  " + sTime;

   if (SendAlert_Signals == true) Alert(st);   
   if (SendEmail_Signals == true) SendMail(subjectEmailAlert, st);
   //if (PrintAlert_Signals== true) Print("##" + st);
   AlertSignal = 0;

   return;
}

//+------------------------------------------------------------------+
//    Delete Signal
//+------------------------------------------------------------------+
void Delete_Signal(int iBar, int oldSignalTRADE)
{
   signalUP[iBar] = EMPTY_VALUE;
   signalDN[iBar] = EMPTY_VALUE;
   
   if (SendAlert_Signals == false && SendEmail_Signals == false) return;   
   //if (SendAlert_Signals == false && SendEmail_Signals == false && PrintAlert_Signals == false) return;   
   
   string st;
   string sSymbol = Symbol();
   string sPrice = DoubleToStr(iClose(sSymbol,Period(),0), Digits);
   string sTime  = TimeToStr(TimeCurrent(),TIME_MINUTES|TIME_SECONDS);
   
   switch (oldSignalTRADE) {
      case  1: st = "Delete Buy "; break;
      case -1: st = "Delete Sell "; break;
   }
   st = st + sSymbol + "  " + sPrice + "   (" + sPeriod + ")  " + sTextAlert + "  " + sTime;

   if (SendAlert_Signals == true) Alert(st);   
   if (SendEmail_Signals == true) SendMail(subjectEmailAlert, st);
   //if (PrintAlert_Signals== true) Print("##" + st);

   return;   
}  


//####################################################################
//+------------------------------------------------------------------+
//    Get sPeriod
//+------------------------------------------------------------------+
string Get_sPeriod(int timeframe)
{
   if (timeframe == PERIOD_M1) return("M1");
   if (timeframe == PERIOD_M5) return("M5");
   if (timeframe == PERIOD_M15) return("M15");
   if (timeframe == PERIOD_M30) return("M30");
   if (timeframe == PERIOD_H1) return("H1");
   if (timeframe == PERIOD_H4) return("H4");
   if (timeframe == PERIOD_D1) return("D1");
   if (timeframe == PERIOD_W1) return("W1");
   if (timeframe == PERIOD_MN1) return("MN1");
}

//+------------------------------------------------------------------+
//    Set Label Object
//+------------------------------------------------------------------+
void SetLabelObject(string sName, string sText, color dColor, int xx, int yy)
{
   int iWindow = 0;
   int iCorner = 1;
   ObjectCreate(sName, OBJ_LABEL, iWindow, 0, 0);
        ObjectSetText(sName,sText,10, "Arial Bold", dColor);
        ObjectSet(sName, OBJPROP_CORNER, iCorner);
        ObjectSet(sName, OBJPROP_XDISTANCE, xx);
        ObjectSet(sName, OBJPROP_YDISTANCE, yy);
}


//####################################################################
//####################################################################
//####################################################################
//+------------------------------------------------------------------+
//    Get Hull Slope
//+------------------------------------------------------------------+
void Get_HullSlope(string sSymbol, int iTF, int Hull_period, int smooth_period, double treshold,
         double& iTrend, int iBar)
{
   if (Slope_HistogramValues == true) {
      //---- values
      double trendUP = iCustom(sSymbol, iTF,"smHullSlope v2", Hull_period,smooth_period,treshold, 4,iBar);
      double trendDN = iCustom(sSymbol, iTF,"smHullSlope v2", Hull_period,smooth_period,treshold, 5,iBar);   
      //---- signals
      iTrend = 0;      
      if (trendUP > 0 && trendDN == EMPTY_VALUE) iTrend = 1;  else 
      if (trendUP == EMPTY_VALUE && trendDN < 0) iTrend = -1;
   }
   else
   {
      //---- values
      trendUP = iCustom(sSymbol, iTF,"smHullSlope v2", Hull_period,smooth_period,treshold, 2,iBar);
      trendDN = iCustom(sSymbol, iTF,"smHullSlope v2", Hull_period,smooth_period,treshold, 3,iBar);   
      //---- signals
      iTrend = 0;      
      if (trendUP == 0 && trendDN == EMPTY_VALUE) iTrend = 1;  else 
      if (trendUP == EMPTY_VALUE && trendDN == 0) iTrend = -1;
   }
   
//if (iBar==0 && Hull_period == 8)
//Comment("trendUP=",trendUP, "  trendDN=",trendDN);
   
   return;
}

//####################################################################
//+------------------------------------------------------------------+
//    Get Hull Trend
//+------------------------------------------------------------------+
void Get_HullTrend(string sSymbol, int iTF, int Hull_period,
         double& iTrend, double& HullValue, int iBar)
{
double Hull_periodDivisor = 1.5;
int Hull_method = 3;
int Hull_price  = 0;
/*double trend, trend1, dUpTrend, dDnTrend, dExtHullBuffer;

   Internal_HullMAvg(sSymbol, iTF, iBar, 
                     trend, trend1, dUpTrend, dDnTrend, dExtHullBuffer,
                     Hull_period, Hull_periodDivisor, Hull_method, Hull_price);
   if (trend ==  1) {iTrend= 1; HullValue = dUpTrend;} else
   if (trend == -1) {iTrend=-1; HullValue = dDnTrend;}*/
   

   //---- Hull trend H1
   double UpTrend0 = iCustom(sSymbol, iTF,"smHull Mavg",
                   Hull_period,Hull_periodDivisor,Hull_method,Hull_price,
                   0,iBar);
   double DnTrend0 = iCustom(sSymbol, iTF,"smHull Mavg",
                   Hull_period,Hull_periodDivisor,Hull_method,Hull_price,
                   1,iBar);
                   
   double UpTrend1 = iCustom(sSymbol, iTF,"smHull Mavg",
                   Hull_period,Hull_periodDivisor,Hull_method,Hull_price,
                   0,iBar+1);
   double DnTrend1 = iCustom(sSymbol, iTF,"smHull Mavg",
                   Hull_period,Hull_periodDivisor,Hull_method,Hull_price,
                   1,iBar+1);
                                      
   //---- signals
   if (UpTrend0 != DnTrend0) {
      if (UpTrend0 != EMPTY_VALUE) {iTrend=1; HullValue=UpTrend0;}
      else
      if (DnTrend0 != EMPTY_VALUE) {iTrend=-1; HullValue=DnTrend0;}
   }
   else {
      if (UpTrend1 != EMPTY_VALUE) {iTrend=1; HullValue=UpTrend1;}
      else
      if (DnTrend1 != EMPTY_VALUE) {iTrend=-1; HullValue=DnTrend1;}
   }
   return;
}

/*
//###################################################################
//###################################################################
//###################################################################
//+------------------------------------------------------------------+ 
//|      Internal HullMAvg
//+------------------------------------------------------------------+ 
void Internal_HullMAvg(string sSymbol, int iTF, int iBar, 
                       double& trend, double& trend1, double& dUpTrend, double& dDnTrend, double& dExtHullBuffer,
                       int Hull_period, double Hull_periodDivisor, int Hull_method, int Hull_price)
{
int i, e = 200; // nBars
double vect[];
static double dExtHullBuffer1;
ArraySetAsSeries(vect, true); ArrayResize(vect, e);    
  
   int p = MathFloor(MathSqrt(Hull_period));
   int perVector = MathFloor(Hull_period/Hull_periodDivisor);   
   
   //---- first Hull vector / 200 bars
   for(i = 0; i < e; i++) 
      vect[i] = 2*WMA(sSymbol, iTF, iBar+i, perVector, Hull_method, Hull_price) -
                  WMA(sSymbol, iTF, iBar+i, Hull_period, Hull_method, Hull_price);
  
   dExtHullBuffer  = iMAOnArray(vect, 0, p, 0, Hull_method, 0);
   dExtHullBuffer1 = iMAOnArray(vect, 0, p, 0, Hull_method, 1);

   trend1 = trend;
   if (dExtHullBuffer > dExtHullBuffer1) trend=1;
   if (dExtHullBuffer < dExtHullBuffer1) trend=-1;   

   if (trend > 0) {
      dUpTrend = dExtHullBuffer;
      dDnTrend = EMPTY_VALUE;
   }
   else
   if (trend < 0) {
      dDnTrend = dExtHullBuffer;
      dUpTrend = EMPTY_VALUE;
   }
   return;
}

//+------------------------------------------------------------------+ 
//|      WMA
//+------------------------------------------------------------------+ 
double WMA(string sSymbol, int iTF, int iBar, 
           int iPeriodAvg, int Hull_method, int Hull_price) 
{ 
   return(iMA(sSymbol, iTF, iPeriodAvg, 0, Hull_method, Hull_price, iBar));
} */

