//+------------------------------------------------------------------+
//|                                      ay-MurreyMathPeriodHiLo.mq4 |
//+------------------------------------------------------------------+
#property copyright "ahmad.yani@hotmail.com"
#property link      "mailto:ahmad.yani@hotmail.com"
#property indicator_chart_window
#property indicator_buffers 7

//property copyright "Vladislav Goshkov (VG) && Alex.Piech.FinGeR && xard777@connectfree.co.uk"
//property link      "4vg@mail.ru && regnif@gmx.net && xard777@connectfree.co.uk"
// ============================================================================================
// * Line 8/8 & 0/8 (Ultimate Support and Ultimate Resistance).
// * Those lines are the most strong concerning Support and Resistance.
// ============================================================================================
//* Line 7/8  (Weak, Place to Stop and Reverse).
//* This line is weak. If suddenly the price was going too fast and too far and stops around this line 
//* it means the price will reverse down very soon. If the price did not stop near this line, this price 
//* will continue the movement to the line 8/8.
// ============================================================================================
//* Line 1/8  (Weak, Place to Stop and Reverse).
//* This line is weak. If suddenly the price was going too fast and too far and stops around this line 
//* it means the price will reverse up very soon. If the price did not stop near this line, this price
//* will continue the movement down to the line 0/8.
// ============================================================================================
//* Line 2/8 and 6/8 (Pivot, Reverse)
//* Those two lines yield the line 4/8 only to the strength to reverse the price movement.
// ============================================================================================
//* Line 5/8 (Top of Trading Range)
//* The price is spending the about 40% of the time on the movement between the lines 5/8 and 3/8. 
//* If the price is moving near line 5/8 and stopping near the line during the 10 - 12 days, so it means 
//* that it is necessary to sell in this "bonus zone" (some people are doing like this) but if the price
//* is keeping the tendency to stay above the 5/8 line, so it means that the price will be above. 
//* But if the price is droping below 5/8 line it means that the price will continue falling 
//* to the next level of resistance.
// ============================================================================================
//* Line 3/8 (Bottom of Trading Range).
//* If the price is below this line and in uptrend it means that it will be very difficult for the price
//* to break this level. 
//* If the price broke this line during the uptrend and staying above during the 10 12 days it means that
//* the price will be above this line during the 40% of its time moving between this line and 5/8 line.
// ============================================================================================
//* Line 4/8 (Major Support/Resistance Line).
//* It is the major line concerning support and resistance.
//* This level is the better for the new sell or buy. 
//* It is the strong level of support of the price is above 4/8. It is the fine resistance line
//* if the price is below this 4/8 line. 
// ============================================================================================

//-- buffer
double MMLPlus2[], MMLPlus1[], MML8[], MML7[], MML6[], MML5[];
double MML4[];
double MMLMin2[],  MMLMin1[],  MML0[], MML1[], MML2[], MML3[];

//+------------------------------------------------------------------+
//| Define the Variables to use.....                                 |
//+------------------------------------------------------------------+
extern bool      ModeUpperLevel = true;
extern string    TimeFrameInfo = " use MN1, W1, D1, H4, H1, M30, M15, M5, M1";
extern string    TimeFrame = "D1";
extern int       NumberOfBarsTF = 2;
extern int       ShiftText = 5;
//-- color vars
extern string    Clr.Info     = "Define Lines Color";
extern string    Clr.Info1    = "Lines Color for ModeUpperLevel = true";
extern color     Clr.MMLPlus2 = Red;
extern color     Clr.MMLPlus1 = Red;
extern color     Clr.MML8     = DeepSkyBlue;
extern color     Clr.MML7     = Yellow;
extern color     Clr.MML6     = Magenta;
extern color     Clr.MML5     = Lime;
extern color     Clr.MML4     = Aqua;
extern string    Clr.Info2    = "Lines Color for ModeUpperLevel = false";
extern color     Clr.MML3     = Lime;
extern color     Clr.MML2     = Magenta;
extern color     Clr.MML1     = Yellow;
extern color     Clr.MML0     = DeepSkyBlue;
extern color     Clr.MMLMin1  = Red;
extern color     Clr.MMLMin2  = Red;

double  v45=0
        ,mmlm2  =0
        ,mmlm1  =0
        ,mml0   =0
        ,mml1   =0
        ,mml2   =0
        ,mml3   =0
        ,mml4   =0
        ,mml5   =0
        ,mml6   =0
        ,mml7   =0
        ,mml8   =0
        ,mmlp1  =0
        ,mmlp2  =0;
        
//double mm92=0,mm94=0,mm96=0,mm82=0,mm84=0,mm86=0,mm72=0,mm74=0,mm76=0,mm62=0,mm64=0,mm66=0,mm56=0,mm54=0,mm52=0,mm46=0,mm44=0,mm42=0,mm36=0,mm34=0,mm32=0,mm26=0,mm24=0,mm22=0,mm16=0,mm14=0,mm12s=0,mm06=0,mm04=0,mm02=0,mm106=0,mm104=0,mm102=0,mm1006=0,mm1004=0,mm1002=0;

string LvlObjNameArr[13]= { "MM-2/8ths_txt"
                           ,"MM-1/8th_txt"
                           ,"MM 0/8th_txt"
                           ,"MM 1/8th_txt"
                           ,"MM 2/8ths_txt"
                           ,"MM 3/8ths_txt"
                           ,"MM 4/8ths_txt"
                           ,"MM 5/8ths_txt"
                           ,"MM 6/8ths_txt"
                           ,"MM 7/8ths_txt"
                           ,"MM 8/8ths_txt"
                           ,"MM+1/8th_txt"
                           ,"MM+2/8ths_txt"
                          };
                          
string LvlObjTextArr[13] = { "[-2/8]"
                            ,"[-1/8]"
                            ,"[0/8]"
                            ,"[1/8]"
                            ,"[2/8]"
                            ,"[3/8]"
                            ,"[4/8]"
                            ,"[5/8]"
                            ,"[6/8]"
                            ,"[7/8]"
                            ,"[8/8]"
                            ,"[+1/8]"
                            ,"[+2/8]"
                           };
                                                   
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
  IndicatorShortName("MurreyMath.PeriodHiLo(" + TimeFrame + ")");
  
  if (ModeUpperLevel)
  {
    SetIndexBuffer(0,MML4); 
    SetIndexBuffer(1,MML5); 
    SetIndexBuffer(2,MML6); 
    SetIndexBuffer(3,MML7); 
    SetIndexBuffer(4,MML8); 
    SetIndexBuffer(5,MMLPlus1); 
    SetIndexBuffer(6,MMLPlus2);
    
    SetIndexStyle(0,DRAW_ARROW, EMPTY, 2, Clr.MML4);
    SetIndexStyle(1,DRAW_ARROW, EMPTY, EMPTY, Clr.MML5);
    SetIndexStyle(2,DRAW_ARROW, EMPTY, EMPTY, Clr.MML6);
    SetIndexStyle(3,DRAW_ARROW, EMPTY, EMPTY, Clr.MML7);
    SetIndexStyle(4,DRAW_ARROW, EMPTY, 2, Clr.MML8);
    SetIndexStyle(5,DRAW_ARROW, EMPTY, EMPTY, Clr.MMLPlus1);
    SetIndexStyle(6,DRAW_ARROW, EMPTY, EMPTY, Clr.MMLPlus2); 
    
    SetIndexLabel(0, TimeFrame +" MML[4/8]");
    SetIndexLabel(1, TimeFrame +" MML[5/8]");
    SetIndexLabel(2, TimeFrame +" MML[6/8]");
    SetIndexLabel(3, TimeFrame +" MML[7/8]");
    SetIndexLabel(4, TimeFrame +" MML[8/8]");
    SetIndexLabel(5, TimeFrame +" MML[+1/8]");
    SetIndexLabel(6, TimeFrame +" MML[+2/8]");          
  }
  else
  {
    SetIndexBuffer(1,MML3); 
    SetIndexBuffer(2,MML2); 
    SetIndexBuffer(3,MML1); 
    SetIndexBuffer(4,MML0); 
    SetIndexBuffer(5,MMLMin1); 
    SetIndexBuffer(6,MMLMin2); 
    
    SetIndexStyle(1,DRAW_ARROW, EMPTY, EMPTY, Clr.MML3);
    SetIndexStyle(2,DRAW_ARROW, EMPTY, EMPTY, Clr.MML2);
    SetIndexStyle(3,DRAW_ARROW, EMPTY, EMPTY, Clr.MML1);
    SetIndexStyle(4,DRAW_ARROW, EMPTY, 2, Clr.MML0);
    SetIndexStyle(5,DRAW_ARROW, EMPTY, EMPTY, Clr.MMLMin1);
    SetIndexStyle(6,DRAW_ARROW, EMPTY, EMPTY, Clr.MMLMin2); 

    SetIndexLabel(1, TimeFrame +" MML[3/8]");
    SetIndexLabel(2, TimeFrame +" MML[2/8]");
    SetIndexLabel(3, TimeFrame +" MML[1/8]");
    SetIndexLabel(4, TimeFrame +" MML[0/8]");
    SetIndexLabel(5, TimeFrame +" MML[-1/8]");
    SetIndexLabel(6, TimeFrame +" MML[-2/8]");       
  }
  
  for (int i=0; i<7; i++) 
  { 
    SetIndexArrow(i,158);
    SetIndexEmptyValue(i,EMPTY_VALUE) ;
  }
  
  return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
{
  //for(int i=0;i<13;i++) ObjectDelete(TimeFrame + LvlObjNameArr[i]);
  if (ModeUpperLevel) for(int i=6;i<13;i++) ObjectDelete(TimeFrame + LvlObjNameArr[i]);
  else for(i=0;i<6;i++) ObjectDelete(TimeFrame + LvlObjNameArr[i]);
  return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+

int start()
{
  int limit, i, BarsToRecalc, DisplayBars, MinRequiredBars;
  
  int TF = getTFByName(TimeFrame);
  
  int counted_bars=IndicatorCounted(); 
  //---- check for possible errors 
  //found this on alligator code :)
  if(counted_bars<0) return(-1);        
                 
  //---- last counted bar will be recounted
  if(counted_bars>0) counted_bars--;
  BarsToRecalc = Bars-counted_bars;
     
  DisplayBars = iBarShift
    ( NULL
      , 0
      , iTime(NULL, TF, MathMax(NumberOfBarsTF-1,0) + iBarShift(NULL, TF, Time[0]) ) /*Time Of Choosed TF*/
    );
    
  //Print(TF + " iTime(NULL, TF, MathMax(NumberOfBarsTF-1,0)) ", TimeToStr(iTime(NULL, TF, MathMax(NumberOfBarsTF-1,0))));
  //Print(TF + " DisplayBars ", DisplayBars);       
  //Print(TF + " NumberOfBarsTF-1 ", NumberOfBarsTF-1);  
     

  limit = MathMin(DisplayBars, BarsToRecalc);
  
  //if (newBar() && NumberOfBars != 0) initBuffers(DisplayBars);
  
  int BarShiftTF;  
  double v1, v2;  
  for (i=0; i<limit; i++)
  {
    BarShiftTF = iBarShift(NULL, TF, Time[i]) + 1 ;
    
    if (TimeDayOfWeek(iTime(NULL, TF,BarShiftTF)) == 0 && TF==PERIOD_D1) BarShiftTF++;
    
    v1=iLow(NULL, TF,BarShiftTF);
    v2=iHigh(NULL, TF,BarShiftTF);   
    
    //==================
    calcMM(v1, v2);
    //==================       
    
    if (ModeUpperLevel)
    {
      MML4[i] = mml4; 
      MML5[i]=mml5; 
      MML6[i]=mml6; 
      MML7[i]=mml7; 
      MML8[i]=mml8; 
      MMLPlus1[i]=mmlp1; 
      MMLPlus2[i]=mmlp2;  
    }
    else
    {
      MML3[i]=mml3; 
      MML2[i]=mml2; 
      MML1[i]=mml1; 
      MML0[i]=mml0; 
      MMLMin1[i]=mmlm1; 
      MMLMin2[i]=mmlm2;      
    }
    if (i==0) drawTxtMML();
  }
  
  return(0);
}

 
/*---------------------------------
 *Do Murrey Math Calculation
 *---------------------------------
 */
double calcMM(double v1, double v2)
{
  //private vars
  int shift=0,i2=0,WorkTime=0,Periods=0;
  double sum=0,/*v1=0,v2=0,*/fractal=0;
  
  double range=0,octave=0,mn=0,mx=0,price=0;
  double finalH=0,finalL=0;
  double x1=0,x2=0,x3=0,x4=0,x5=0,x6=0,y1=0,y2=0,y3=0,y4=0,y5=0,y6=0;  
  
  //+------------------------------------------------------------------+
  //| Determine which Fractal to use.....                              |
  //+------------------------------------------------------------------+
  if(v2<=250000 && v2>25000) fractal = 100000;
  if(v2<=25000 && v2>2500) fractal = 10000;
  if(v2<=2500 && v2>250) fractal = 1000;
  if(v2<=250 && v2>25) fractal = 100;
  if(v2<=25 && v2>12.5) fractal = 12.5;
  if(v2<=12.5 && v2>6.25) fractal = 12.5;
  if(v2<=6.25 && v2>3.125) fractal = 6.25;
  if(v2<=3.125 && v2>1.5625) fractal = 3.125;
  if(v2<=1.5625 && v2>0.390625) fractal = 1.5625;
  if(v2<=0.390625 && v2>0) fractal = 0.1953125;
  // calculating our octave....      
  range=(v2-v1); sum=MathFloor(MathLog(fractal/range)/MathLog(2));
  octave=fractal*(MathPow(0.5,sum)); mn=MathFloor(v1/octave)*octave;
  if((mn+octave)>v2)mx=mn+octave; mx=mn+(2*octave);
  // calculating xx
  //x2
  if((v1>=(3*(mx-mn)/16+mn))&& (v2<=(9*(mx-mn)/16+mn))) x2=mn+(mx-mn)/2; else x2=0;
  //x1
  if((v1>=(mn-(mx-mn)/8))&& (v2<=(5*(mx-mn)/8+mn)) && (x2==0)) x1=mn+(mx-mn)/2; else x1=0;
  //x4
  if((v1>=(mn+7*(mx-mn)/16))&& (v2<=(13*(mx-mn)/16+mn))) x4=mn+3*(mx-mn)/4; else x4=0;
  //x5
  if((v1>=(mn+3*(mx-mn)/8))&& (v2<=(9*(mx-mn)/8+mn))&& (x4==0)) x5=mx; else x5=0;
  //x3
  if((v1>=(mn+(mx-mn)/8))&& (v2<=(7*(mx-mn)/8+mn))&& (x1==0) && (x2==0) && (x4==0) && (x5==0)) x3=mn+3*(mx-mn)/4; else x3=0;
  //x6 when we have no sbj, du {}
  if((x1+x2+x3+x4+x5)==0) x6=mx; else x6=0;

  finalH=x1+x2+x3+x4+x5+x6;
  // calculating yy
  //y1
  if(x1>0) y1=mn; else y1=0;
  //y2
  if(x2>0) y2=mn+(mx-mn)/4; else y2=0;
  //y3
  if(x3>0) y3=mn+(mx-mn)/4; else y3=0;
  //y4
  if(x4>0) y4=mn+(mx-mn)/2; else y4=0;
  //y5
  if(x5>0) y5=mn+(mx-mn)/2; else y5=0;
  //y6
  if((finalH>0) && ((y1+y2+y3+y4+y5)==0)) y6=mn; else y6=0;

  finalL=y1+y2+y3+y4+y5+y6;  
  
  v45=(finalH-finalL)/8;

  mmlm2=(finalL-v45*2); 
  mmlm1=(finalL-v45); 
  mml0=(finalL); 
  mml1=(finalL+v45); 
  mml2=(finalL+2*v45);
  mml3=(finalL+3*v45); 
  mml4=(finalL+4*v45); 
  mml5=(finalL+5*v45); 
  mml6=(finalL+6*v45); 
  mml7=(finalL+7*v45);
  mml8=(finalL+8*v45); 
  mmlp1=(finalL+9*v45); 
  mmlp2=(finalL+10*v45); 
  
}
/*
//----------
bool newBar()
{
   static datetime lastbar = 0;
   datetime curbar = Time[0];
   if(lastbar!=curbar)
   {
      lastbar=curbar;
      return (true);
   }
   else
   {
      return(false);
   }
} 
*/
//----------
/*
void initBuffers(int shift)
{       
      
  if (ModeUpperLevel)
  {
    MML4[shift]= EMPTY_VALUE;
    MML5[shift]= EMPTY_VALUE; 
    MML6[shift]= EMPTY_VALUE; 
    MML7[shift]= EMPTY_VALUE; 
    MML8[shift]= EMPTY_VALUE; 
    MMLPlus1[shift]= EMPTY_VALUE; 
    MMLPlus2[shift]= EMPTY_VALUE;  
  }
  else
  {
    MML3[shift]= EMPTY_VALUE;
    MML2[shift]= EMPTY_VALUE;
    MML1[shift]= EMPTY_VALUE; 
    MML0[shift]= EMPTY_VALUE;
    MMLMin1[shift]= EMPTY_VALUE; 
    MMLMin2[shift]= EMPTY_VALUE;      
  }
}
*/
//--------
void drawTxtMML()
{
  //datetime t = Time[iBarShift( NULL, 0 ,iTime(NULL, PERIOD_D1, iBarShift(NULL, PERIOD_D1,Time[0]))) + ShiftText ];
  datetime t = Time[ShiftText];                    
                        
  double adj ;//= 0.025 * (WindowPriceMax()-WindowPriceMin());
  //string prefix = TimeFrame;
  if (!ModeUpperLevel)
  {    
    drawText(TimeFrame + LvlObjNameArr[0], TimeFrame+LvlObjTextArr[0], t, mmlm2+adj,  Clr.MMLMin2);
    drawText(TimeFrame + LvlObjNameArr[1], TimeFrame+LvlObjTextArr[1], t, mmlm1+adj,  Clr.MMLMin1);
    drawText(TimeFrame + LvlObjNameArr[2], TimeFrame+LvlObjTextArr[2], t, mml0+adj,   Clr.MML0);
    drawText(TimeFrame + LvlObjNameArr[3], TimeFrame+LvlObjTextArr[3], t, mml1+adj,   Clr.MML1);
    drawText(TimeFrame + LvlObjNameArr[4], TimeFrame+LvlObjTextArr[4], t, mml2+adj,   Clr.MML2);
    drawText(TimeFrame + LvlObjNameArr[5], TimeFrame+LvlObjTextArr[5], t, mml3+adj,   Clr.MML3);
    
  }
  else
  {
    drawText(TimeFrame + LvlObjNameArr[6], TimeFrame+LvlObjTextArr[6], t, mml4+adj,   Clr.MML4);
    drawText(TimeFrame + LvlObjNameArr[7],  TimeFrame+LvlObjTextArr[7],   t, mml5+adj,  Clr.MML5);
    drawText(TimeFrame + LvlObjNameArr[8],  TimeFrame+LvlObjTextArr[8],   t, mml6+adj,  Clr.MML6);
    drawText(TimeFrame + LvlObjNameArr[9],  TimeFrame+LvlObjTextArr[9],   t, mml7+adj,  Clr.MML7);
    drawText(TimeFrame + LvlObjNameArr[10], TimeFrame+LvlObjTextArr[10],  t, mml8+adj,  Clr.MML8);
    drawText(TimeFrame + LvlObjNameArr[11], TimeFrame+LvlObjTextArr[11],  t, mmlp1+adj, Clr.MMLPlus2);
    drawText(TimeFrame + LvlObjNameArr[12], TimeFrame+LvlObjTextArr[12],  t, mmlp2+adj, Clr.MMLPlus2);  
  }

}
//--------
void drawText(string txtName, string txt, datetime t1, double v1, color txtColor)
{
   
   if(ObjectFind(txtName) != 0)
      ObjectCreate(
            txtName
            , OBJ_TEXT
            , 0
            , t1
            , v1
            );      
   else
      ObjectMove(txtName, 0, t1, v1);   

   ObjectSetText(txtName,txt,8,"Arial Narrow", txtColor);
   
}

int getTFByName(string TFName)
{
  int TF;
  if      (TFName == "MN1") TF = PERIOD_MN1;
  else if (TFName == "W1")  TF = PERIOD_W1;
  else if (TFName == "D1")  TF = PERIOD_D1;
  else if (TFName == "H4")  TF = PERIOD_H4;
  else if (TFName == "H1")  TF = PERIOD_H1;
  else if (TFName == "M30") TF = PERIOD_M30;
  else if (TFName == "M15") TF = PERIOD_M15;
  else if (TFName == "M5")  TF = PERIOD_M5;
  else if (TFName == "M1")  TF = PERIOD_M1;
  else TF = Period();
  
  
  return(TF);  

}