//+------------------------------------------------------------------+
//|                                                  3TF HAS Bar.mq4 |
//|                                      Copyright ©                 |
//+------------------------------------------------------------------+
#property copyright "Copyright © "
#property link      ""

#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 5
#property indicator_buffers 6
#property indicator_color1 Lime
#property indicator_color2 Red
#property indicator_color3 Lime
#property indicator_color4 Red
#property indicator_color5 Lime
#property indicator_color6 Red

//---- parameters
extern int MaMethod  = 2;
extern int MaPeriod = 6;
extern int MaMethod2  = 3;
extern int MaPeriod2 = 2;
extern int BarWidth = 0;
extern color BarColorUp = Lime;
extern color BarColorDown = Red;
extern color TextColor = White;
//extern int MaxBars = 500;
extern bool AlertOn = true;
extern bool DeleteAllArrows = false;
// extern 
double Gap = 1; // Gap between the lines of bars
//---- buffers
double buf3_up[];
double buf3_down[];
double buf2_up[];
double buf2_down[];
double buf1_up[];
double buf1_down[];
double haOpen;
double haClose;
double haOpen2;
double haClose2;

// double m2, m3;
//bool mAlertDown = true, mAlertUp;

string shortname = "";

int ArrSize = 110;//159;
int UniqueNum = 2282;
int Period_1, Period_2, Period_3;

//+------------------------------------------------------------------+
//| ADR stuff                                                 begin  |
//+------------------------------------------------------------------+
bool ExcludeSundayData=true;
int ATR1_Prd=5,ATR2_Prd=25;
extern double RoomLimitRatio=0.2;
extern color TradeableColor=Lime;
extern color UntradeableColor=Red;
extern color OtherColor=Yellow;
int DisplayPosition=1;


double point;
int    LastBars0=0;
int    DisplayCorner;
int x,y;
//+------------------------------------------------------------------+
//| ADR stuff                                                  end   |
//+------------------------------------------------------------------+


int BeginTradingHour = 7;
int EndTradingHour = 17;
int DSTOffset = 0;
extern double  GMTshift = 2;
//extern bool    UsePivotGMTcorrection = false;
extern bool    DST = True;
bool OkToTrade;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   Comment(" ");
   
   if(DST) 
      DSTOffset = 1;
   BeginTradingHour = BeginTradingHour + GMTshift - DSTOffset;
   EndTradingHour = EndTradingHour + GMTshift - DSTOffset;

   SetIndexStyle(0,DRAW_ARROW,0,BarWidth,BarColorUp);
   SetIndexArrow(0,ArrSize);
   SetIndexBuffer(0,buf1_up);
   SetIndexEmptyValue(0,0.0);
   SetIndexStyle(1,DRAW_ARROW,0,BarWidth,BarColorDown);
   SetIndexArrow(1,ArrSize);
   SetIndexBuffer(1,buf1_down);
   SetIndexEmptyValue(1,0.0);
   SetIndexStyle(2,DRAW_ARROW,0,BarWidth,BarColorUp);
   SetIndexArrow(2,ArrSize);
   SetIndexBuffer(2,buf2_up);
   SetIndexEmptyValue(2,0.0);
   SetIndexStyle(3,DRAW_ARROW,0,BarWidth,BarColorDown);
   SetIndexArrow(3,ArrSize);
   SetIndexBuffer(3,buf2_down);
   SetIndexEmptyValue(3,0.0);
   SetIndexStyle(4,DRAW_ARROW,0,BarWidth,BarColorUp);
   SetIndexArrow(4,ArrSize);
   SetIndexBuffer(4,buf3_up);
   SetIndexEmptyValue(4,0.0);
   SetIndexStyle(5,DRAW_ARROW,0,BarWidth,BarColorDown);
   SetIndexArrow(5,ArrSize);
   SetIndexBuffer(5,buf3_down);
   SetIndexEmptyValue(5,0.0);
   
   SetIndexLabel(0,NULL);
   SetIndexLabel(1,NULL);
   SetIndexLabel(2,NULL);
   SetIndexLabel(3,NULL);
   SetIndexLabel(4,NULL);
   SetIndexLabel(5,NULL);
   
   IndicatorDigits(0);
   getPeriod();
   
   shortname = "INVICTUS";
   IndicatorShortName(shortname);
   
//   m2 = MathRound(MaxBars * Period_1 / Period_2);
//   m3 = MathRound(MaxBars * Period_1 / Period_3);
   
//   if(MathMod(MaxBars, Period_2 / Period_1) > 0 ) m2 ++;
//   if(MathMod(MaxBars, Period_3 / Period_1) > 0) m3 ++;

   //+------------------------------------------------------------------+
   //| ADR stuff                                                        |
   //+------------------------------------------------------------------+
   point=Point;
   if( Digits==3 || Digits==5 ) point=point*10;
   
   if (DisplayPosition==0) {DisplayCorner=0;x=0;y=0;} else {DisplayCorner=2;x=-215;y=1;}
   ObjectCreate("xADR1", OBJ_LABEL, 0, 0, 1);
   ObjectSet("xADR1", OBJPROP_CORNER, DisplayCorner);
   ObjectSet("xADR1", OBJPROP_XDISTANCE, 215+x);
   ObjectSet("xADR1", OBJPROP_YDISTANCE, y);
   
   ObjectCreate("xADR2", OBJ_LABEL, 0, 0, 1);
   ObjectSet("xADR2", OBJPROP_CORNER, DisplayCorner);
   ObjectSet("xADR2", OBJPROP_XDISTANCE, 500+x);
   ObjectSet("xADR2", OBJPROP_YDISTANCE, y);
   
   ObjectCreate("xADR3", OBJ_LABEL, 0, 0, 1);
   ObjectSet("xADR3", OBJPROP_CORNER, DisplayCorner);
   ObjectSet("xADR3", OBJPROP_XDISTANCE, 320+x);
   ObjectSet("xADR3", OBJPROP_YDISTANCE, y);
   
   ObjectCreate("xADR4", OBJ_LABEL, 0, 0, 1);
   ObjectSet("xADR4", OBJPROP_CORNER, DisplayCorner);
   ObjectSet("xADR4", OBJPROP_XDISTANCE, 365+x);
   ObjectSet("xADR4", OBJPROP_YDISTANCE, y);
   
   ObjectCreate("xADR5", OBJ_LABEL, 0, 0, 1);
   ObjectSet("xADR5", OBJPROP_CORNER, DisplayCorner);
   ObjectSet("xADR5", OBJPROP_XDISTANCE, 410+x);
   ObjectSet("xADR5", OBJPROP_YDISTANCE, y);
   
   //+------------------------------------------------------------------+
   //| ADR stuff                                                  end   |
   //+------------------------------------------------------------------+
   
   return(0);
   
}//end init()
   
//+------------------------------------------------------------------+
int deinit()
{
   if(DeleteAllArrows)
      ObjectsDeleteAll(0, 22); // delete arrows
   
   ObjectDelete("xADR1");ObjectDelete("xADR2");ObjectDelete("xADR3");ObjectDelete("xADR4");ObjectDelete("xADR5");
   
   return(0);

}// end deinit()

//+------------------------------------------------------------------+

int start()
{

   //---- exit if period is greater than M15 charts
   if(Period() > 15)
      return(-1); // then exit
   
//   OkToTrade = false;
//   if(TimeHour(Time[0]) >= BeginTradingHour && TimeHour(Time[0]) < EndTradingHour)
      OkToTrade = true;
   
   int counted_bars = IndicatorCounted();
   //---- check for possible errors
   if(counted_bars < 0) return(-1);
   //---- the last counted bar will be recounted
   if(counted_bars > 0) counted_bars--;
   int limit = Bars - counted_bars;
   int i,tf;
   
   //-------------------------------1----------------------------------------   
   double dif = Time[0] - Time[1];
   for(i = ObjectsTotal()-1; i > -1; i--)
   {
      if (StringFind(ObjectName(i),"FF_"+UniqueNum+"_") >= 0)  ObjectDelete(ObjectName(i));
   }// end for(i = ObjectsTotal()-1; i > -1; i--)
   
   double shift = 0.5;
   for(tf = 1; tf <= 3; tf++)
   { 
      string txt = "??";
      double gp;
      switch (tf)
      {
         case 1: txt = tf2txt(Period_1);  gp = 1 + shift; break;
         case 2: txt = tf2txt(Period_2);  gp = 1 + Gap + shift; break;
         case 3: txt = tf2txt(Period_3);  gp = 1 + Gap*2 + shift; break;
      }
      string name = "FF_"+UniqueNum+"_"+tf+"_"+txt;
      ObjectCreate(name, OBJ_TEXT, WindowFind(shortname), iTime(NULL,0,0)+dif*3, gp);
      ObjectSetText(name, txt,8,"Arial", TextColor);
   }// end for(tf = 1; tf <= 3; tf++)
   
   
   
   //-------------------------------2----------------------------------------
   datetime TimeArray_3[], TimeArray_2[], TimeArray_1[];
   ArrayCopySeries(TimeArray_1,MODE_TIME,Symbol(),Period_1);
   ArrayCopySeries(TimeArray_2,MODE_TIME,Symbol(),Period_2);
   ArrayCopySeries(TimeArray_3,MODE_TIME,Symbol(),Period_3); 
   
//   int i1 = MaxBars, i2, i3, yy;
   int  i1=0, i2=0, i3=0, yy;
   
//   for(i = MaxBars, i1 = MaxBars, i2= m2, i3 = m3; i >= 0; i--)
   for(i=0, i1=0,  i2=0,  i3=0; i < limit; i++)
   {
   if(TimeHour(Time[i]) >= BeginTradingHour && TimeHour(Time[i]) < EndTradingHour)
      OkToTrade = true;
//      if (Time[i] > TimeArray_1[i1]) i1--;
//      if (Time[i] >= TimeArray_2[i2] + (Period_2 ) * 60) i2--;
//      if (Time[i] >= TimeArray_3[i3] + (Period_3 ) * 60) i3--;
      if (Time[i]<TimeArray_1[i1]) i1++;
      if (Time[i]<TimeArray_2[i2]) i2++;
      if (Time[i]<TimeArray_3[i3]) i3++;
      
      for(tf = 1; tf <= 3; tf++)
      {
         int prd;
         switch (tf)
         {
            case 1: prd = Period_1; yy = i1;  break;
            case 2: prd = Period_2; yy = i2;  break;
            case 3: prd = Period_3; yy = i3;  break;
         }// end switch (tf)
         
         haOpen =  iCustom(NULL, prd, "Heiken Ashi", MaMethod, MaPeriod, MaMethod2, MaPeriod2, 2, yy);
         haClose = iCustom(NULL, prd, "Heiken Ashi", MaMethod, MaPeriod, MaMethod2, MaPeriod2, 3, yy);
         
         switch(tf)
         {  
            case 1: buf1_down[i]=0; buf1_up[i]=0;  
                    if (haOpen >= haClose) 
                       buf1_down[i] = 1;
                    else 
                       buf1_up[i] = 1;           
                    break;
            case 2: buf2_down[i]=0; buf2_up[i]=0; 
                    if (haOpen >= haClose)
                       buf2_down[i] = 1 + Gap * 1;
                    else 
                       buf2_up[i] = 1 + Gap * 1;
                    break;
            case 3: buf3_down[i]=0; buf3_up[i]=0; 
                    if (haOpen >= haClose)
                       buf3_down[i] = 1 + Gap * 2;
                    else 
                       buf3_up[i] = 1 + Gap * 2; 
                    break;
         }// end switch(tf)
      }// end for(tf = 1; tf <= 3; tf++)
      
      //+------------------------------------------------------------------+
      //| ADR stuff                                                        |
      //+------------------------------------------------------------------+
      
      string text; color Color;
      int Bars0=Bars;
      if(Bars0>LastBars0)
      {
         //ATR Part==========================================================
         int atr1,atr2;
//         atr1=MathRound(iATR(NULL,0,ATR1_Prd,1)/point);
         atr1=MathRound(iATR(NULL,0,ATR1_Prd,i+1)/point);
//         atr2=MathRound(iATR(NULL,0,ATR2_Prd,1)/point);
         atr2=MathRound(iATR(NULL,0,ATR2_Prd,i+1)/point);
         text="ATR" + ATR1_Prd + "=" + atr1 + "  ATR" + ATR2_Prd + "=" + atr2;
         if (atr1 > atr2) 
            Color=TradeableColor; 
         else 
            Color=UntradeableColor; 
         ObjectSetText("xADR1",text,8, "Arial Narrow", Color);
         
         //ADR Part==========================================================
         int n=1;  
         static int adr1,adr5,adr10,adr20,adr;
         double s=0.0;    
         for(int rng=1;rng<=20;rng++)
         {
            while(ExcludeSundayData && TimeDayOfWeek(iTime(NULL,PERIOD_D1,n))==0) 
               n++;
//            s=s + (iHigh(NULL,PERIOD_D1,n) - iLow(NULL,PERIOD_D1,n))/point;
            s=s + (iHigh(NULL,PERIOD_D1,i+n) - iLow(NULL,PERIOD_D1,i+n))/point;
            if(rng==1) 
               adr1=MathRound(s);
            if(rng==5) 
               adr5=MathRound(s/5);
            if(rng==10) 
               adr10=MathRound(s/10);
            if(rng==20) 
               adr20=MathRound(s/20);
            n++;  
         }// end for(int rng=1;rng<=20;rng++)
         
         adr = MathRound((adr1+adr5+adr10+adr20)/4.0);
         text="ADR="+adr+"  1d="+adr1+"  5d="+adr5+"  10d="+adr10+"  20d="+adr20;
         ObjectSetText("xADR2",text,8, "Arial Narrow", OtherColor);
         LastBars0=Bars0;
      }// end if(Bars0>LastBars0)
      
      //Today's Range and Room============================================  
      int t, RmUp, RmDn, RmLmt;
//      double low0 = iLow(NULL,PERIOD_D1,0);
//      double high0 = iHigh(NULL,PERIOD_D1,0);
      int StartOfDay = iBarShift(NULL, 0, iTime(NULL, PERIOD_D1, iBarShift(NULL, PERIOD_D1, Time[i], false)), false);
      double low0 = iLow(NULL, 0, iLowest(NULL, 0, MODE_LOW, StartOfDay, 0));
      double high0 = iHigh(NULL, 0, iHighest(NULL, 0, MODE_HIGH, StartOfDay, 0));
      t = MathRound((high0 - low0)/point);  
//      RmUp =  MathRound(adr - (Close[0] - low0)/point);
//      RmDn =  MathRound(adr - (high0 - Close[0])/point);
      RmUp =  MathRound(adr - (Close[i] - low0)/point);
      RmDn =  MathRound(adr - (high0 - Close[i])/point);
      RmLmt = MathRound(adr * RoomLimitRatio);
      
      text="RmUp:"+RmUp;
      if (RmUp > RmLmt) Color=TradeableColor; else Color=UntradeableColor;
      ObjectSetText("xADR3",text,8, "Arial Narrow", Color);
      
      text="RmDn:"+RmDn;
      if (RmDn > RmLmt) Color=TradeableColor; else Color=UntradeableColor;
      ObjectSetText("xADR4",text,8, "Arial Narrow", Color);
      
      text="Todays range="+t;
      ObjectSetText("xADR5",text,8, "Arial Narrow", OtherColor);
      
      //+------------------------------------------------------------------+
      //| ADR stuff                                                  end   |
      //+------------------------------------------------------------------+
      if(OkToTrade)
         mDrawArrows(i, RmUp, RmDn, RmLmt, atr1, atr2);
   }// end for(i = MaxBars, i1 = MaxBars, i2= m2, i3 = m3; i >= 0; i--)
   
   return(0);
   
}// end start()
 
  
//+------------------------------------------------------------------+
void getPeriod()
{
   switch(Period()) 
   {
      case 1: 
         Period_1=1; Period_2=5; Period_3=15;
         break;
      case 5: 
         Period_1=5; Period_2=15; Period_3=60;
         break;
      case 15: 
         Period_1=15; Period_2=60; Period_3=240;
         break;
   }// end switch(Period()) 
}// end void getPeriod()

//+------------------------------------------------------------------+

string tf2txt(int tf)
{
   if (tf == PERIOD_M1)
      return("M1");
   if (tf == PERIOD_M5)    
      return("M5");
   if (tf == PERIOD_M15)   
      return("M15");
   if (tf == PERIOD_H1)    
      return("H1");
   if (tf == PERIOD_H4)    
      return("H4");
   
   return("??");
}// end string tf2txt(int tf)

//+------------------------------------------------------------------+

void mDrawArrows(int j, int RmUp, int RmDn, int RmLmt, int atr1, int atr2)
{
   int mLineDown      = buf1_down[j+1] + buf2_down[j+1] + buf3_down[j+1];
   int PriormLineDown = buf1_down[j+2] + buf2_down[j+2] + buf3_down[j+2];
   int mLineUp        = buf1_up[j+1] + buf2_up[j+1] + buf3_up[j+1];
   int PriormLineUp   = buf1_up[j+2] + buf2_up[j+2] + buf3_up[j+2];
   
   if(j==0)
   {
      if(mLineDown == 6 && PriormLineDown != 6 && RmDn > RmLmt && atr1 > atr2)
//      if(mLineDown == 6 && PriormLineDown != 6)
      {
         ObjectCreate("mSell" + Time[j], OBJ_ARROW, 0, 0, 0, 0, 0);    //Draw Down arrow
         ObjectSet("mSell" + Time[j], OBJPROP_PRICE1, High[j+1] + 60 * Point);
         ObjectSet("mSell" + Time[j], OBJPROP_TIME1, Time[j+1]);
         ObjectSet("mSell" + Time[j], OBJPROP_COLOR, Red);
         ObjectSet("mSell" + Time[j], OBJPROP_WIDTH, 2);
         ObjectSet("mSell" + Time[j], OBJPROP_ARROWCODE, 234);
//         mAlertUp = true;
//         if(mAlertDown && mAlert)
//         {
//            mAlertDown = false;
         if(AlertOn)
            Alert("#MTF ", Symbol(), " Down");
//         }// end if(mAlertDown && mAlert)
      }// end if(mLineDown == 6 && RmDn > RmLmt)
   
      if(mLineUp == 6 && PriormLineUp != 6 && RmUp > RmLmt && atr1 > atr2)
//      if(mLineUp == 6 && PriormLineUp != 6)
      {
         ObjectCreate("mBuy" + Time[j], OBJ_ARROW, 0, 0, 0, 0, 0);    //Draw Up arrow
         ObjectSet("mBuy" + Time[j], OBJPROP_PRICE1, Low[j+1] - 30 * Point);
         ObjectSet("mBuy" + Time[j], OBJPROP_TIME1, Time[j+1]);
         ObjectSet("mBuy" + Time[j], OBJPROP_COLOR, Lime);
         ObjectSet("mBuy" + Time[j], OBJPROP_WIDTH, 2);
         ObjectSet("mBuy" + Time[j], OBJPROP_ARROWCODE, 233);
//         mAlertDown = true;
//         if(mAlertUp && mAlert)
//         {
//            mAlertUp = false;
         if(AlertOn)
            Alert("#MTF ", Symbol(), " Up");
//         }// end if(mAlertUp && mAlert)
      }// end if(mLineUp == 6 && RmUp > RmLmt)
      WindowRedraw();
   }// end if(j==0)
   return(0);
}// end void mDrawArrows(int j, int RmUp, int RmDn, int RmLmt)

//----------------------------------------------------------------------------------

