/*-------------------------------------------------------------------
   Name: Xi Dashboard.mq4
   Copyright ©2010, Xaphod, http://forexwhiz.appspot.com
   
   Description: Xi Dashboard provides the following info on the chart
        Market Info: 
             Symbol, Bid, Ask and Spread.
        Fractal & Pip info with Up/Down color coding:
              PTFH - Pips to fractal high
	           PTFL - Pips to fractal low
	           PLFS - Pips of Last Fractal Swing.
	           PTO  - Pips to open	   
	           PTMA - Pips to MA
	           BSLF - Bars Since Last Fractal
	      Moving Average:
	           2 MAs for use with PTMA function above, 2 MA Modes
	           0 = Standard/Fixed MA, 1 = Time-frame variable
	      Last H1/H4 high and low with bar up/down color coding	           
	           S/R lines on chart 
	      Daily Range:
	           Calculated from 00:00 to 23:59
	           TDR - Todays Range
	           YDR - Yesterdays Range
	           ADR5 - 5 day ADR. Average Range of the last 5 days
	           ADR20 - 20 day ADR. Average Range of the last 20 days	           
	         
   Change log: 
       2010-03-28. Xaphod, v0.80 
          - First Release 
       2010-03-30. Xaphod, v0.81
          - Fixed: Previous H4 line not being erased.
          - Fixed: PLFS did not change color.
          - Added MA type. Normal and Natural Flow.
          - Made H1/H4 last high/low data and line parameters independent of each other.
          - Added BSLF - Bars Since Last Fractal.
       2010-03-31, Xaphod, v0.82
          - Added dashboard box with optional background color.
          - Improved formatting of data.          
       2010-03-31, Xaphod, v0.83
          -  Release 
          - Fixed pip values off by x100 in 2/3 digit currencies
          - Added dashboard Y-Offset Adjustment parameter
       2010-04-14, Xaphod, v0.84
          - Check for and skip sundays in adr calculation
       2010-05-16, Xaphod, v0.85
          - Added simlation mode
          - Added moving average 2
          - Changed moving average modes. 0=Fixed, 1=Time-frame variable
          - Changed High/Low text color to indicate direction of bar
          - Refactoring
          - Fixed background box resizing on different time-frames
       2010-05-18, Xaphod, v0.86
          - Fixed PTO in SimMode
       2010-05-18, Xaphod, v0.87
          - Added Dashboard X position parameter
          - Added Bar Time Left 
       2010-05-27, Xaphod, v0.88
          - Market Open time setting
          - Adr based on market open
          - ADR Alarms
       Nextup:   
          Swings
             
-----------------------------------------------------------------*/
// Indicator properties
#property copyright "Copyright © 2010, Xaphod"
#property link      "http://forexwhiz.appspot.com"
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_color1 Salmon
#property indicator_width1 2
#property indicator_color2 Salmon
#property indicator_width2 2
#property indicator_color3 White
#property indicator_width3 2
#property indicator_color4 White
#property indicator_width4 2
#property indicator_color5 Yellow
#property indicator_color6 DeepSkyBlue

#define INDICATOR_NAME "Xi-Dashboard"
#define INDICATOR_VERSION "v0.88"
#define TEXT_XPOS 5
#define TEXT_YINT 13
#define TF_M1 1
#define TF_M5 5
#define TF_M15 15
#define TF_M30 30
#define TF_H1 60
#define TF_H4 240
#define TF_D 1440
#define TF_W 10080
#define TF_M 43200

// ADR definitions
#define ADR_ERR_DATAGAP 1
#define ADR_ERR_DATAEND  2
#define ADR_TDR 0
#define ADR_YDR 1
#define ADR_ADR5 2
#define ADR_ADR20 3

// Input parameters
extern string   H1HighLow.BlankLine="###############################";
extern bool     H1HighLow.ShowLines=true; // Show last H1 High/Low lines in the chart
extern bool     H1HighLow.ShowData=true;  // Show last H1 High/Low Data in the dashboard
extern bool     H4HighLow.ShowLines=true; // Show last H4 High/Low lines in the chart
extern bool     H4HighLow.ShowData=true;  // Show last H4 High/Low Data in the dashboard

extern string   Pips.BlankLine="###############################";
extern bool     Pips.ShowData=true;       // Show Pip Range Data on Dashboard";

extern string   Adr.BlankLine="###############################";
extern bool     Adr.ShowData=true;       // Show ADR Data on Dashboard >>";
extern color    Adr.TextColor=LightBlue; // Color of the ADR text in the Dashboard
extern int      Adr.MarketOpenHour=23;   // Market open hour used to calculate adr info
extern bool     Adr.MinRangeAlert=false; // Enable minimum range exceeded alert
extern int      Adr.MinRangePips=40;     // Threshold for minimum range exceeded alert
extern bool     Adr.MaxRangeAlert=false; // Enable approching maximum range alert
extern int      Adr.MaxRangePercent=80;  // Threshold for approching maximum range alert

extern string   MA1.BlankLine="###############################";
extern string   MA1.TypeInfo="<< 0=Standard/Fixed MA, 1=TF Variable MA  >>";
extern int      MA1.Type=1;        // Type of MA. 0=Fixed MA. Same on all time frames, 1=TF Variable MA;
extern int      MA1.Period=20;     // MA1 Period. Deactivate: MA=0 
extern string   MA1.TFVPeriod="0,12,20,15,12,0,10,12,5"; // MA1 TF Variable Period. "1,5,15,60,240,1440,10080,43200";
extern int      MA1.Shift=0;       // MA1 shift
extern int      MA1.Mode=0;        // MA1 averaging mode: SMA=0, EMA=1, SMMA=2, LWMA=3
extern int      MA1.Price=0;       // Price used for calc: CLOSE=0, OPEN=1, HIGH=2, LOW=3, MEDIAN=4, TYPICAL=5, WEIGHTED=6
extern color    MA1.Color=Yellow;  // Color of the MA1 line

extern string   MA2.BlankLine="###############################";
extern string   MA2.TypeInfo="<< 0=Standard/Fixed MA, 1=TF Variable MA >>";
extern int      MA2.Type=1;           // Type of MA. 0=Fixed MA. Same on all time frames, 1=TF Variable MA;
extern int      MA2.Period=240;       // MA2 Standard Period. Deactivate: MA=0 
extern string   MA2.TFVPeriod="0,180,240,0,240,0,260,240,0"; // MA2 TF Variable Period. "1,5,15,60,240,1440,10080,43200";
extern int      MA2.Shift=0;          // MA2 shift
extern int      MA2.Mode=0;           // MA2 averaging mode: SMA=0, EMA=1, SMMA=2, LWMA=3
extern int      MA2.Price=0;          // Price used for calc: CLOSE=0, OPEN=1, HIGH=2, LOW=3, MEDIAN=4, TYPICAL=5, WEIGHTED=6
extern color    MA2.Color=DodgerBlue; // Color of the MA2 line

extern string   Market.BlankLine="###############################";
extern bool     Market.ShowData=true;         // Show MARKET info in Dashboard 
extern color    Market.SymbolTextColor=Gold;  // Color of the SYMBOL text in the Dashboard
extern color    Market.BidTextColor=Lime;     // Color of the BID text in the Dashboard
extern bool     Market.ShowAsk=true;          // Show Ask Data in Dashboard 
extern color    Market.AskTextColor=Maroon;   // Color of the ASK text in the Dashboard
extern bool     Market.ShowSpread=true;       // Show SPREAD Data in Dashboard
extern color    Market.SpreadTextColor=Aqua;  // Color of the SPREAD text in the Dashboard

extern string   BarTime.BlankLine="###############################";
extern bool     BarTime.Enable=true;        // Enable displaying of bar time left adjacent to current bar
extern int      BarTime.Pos=3;              // Position of the bar time relative to the latest bar
extern bool     BarTime.ShowArrow=false;    // Draw an arrow infront of the bar time left "<-15:30"
extern int      BarTime.FontSize=10;        // Font size of bar time left text
extern color    BarTime.TextColor=Aqua;     // Color size of bar time left text
extern int      BarTime.Window=0;           // Window in which to show the bar time left
extern int      BarTime.MaxTimeFrame=60;    // Maximum TF onwhich to show clock: 1,5,15,60,240,1440,10080,43200

extern string   Dashboard.BlankLine="###############################";
extern color    Dashboard.UpTextColor=Blue;   // Text Color for data moving up
extern color    Dashboard.DnTextColor=Maroon; // Text Color for data moving down
extern color    Dashboard.BkgColor=DarkGray;  // Text Color for dashboard background
extern int      Dashboard.Corner=0;           // Top Left=0, Top Right=1,Bottom left=2, Bottom Right=3
extern int      Dashboard.XPos=1;             // X position offset for dashboard in chart window
extern int      Dashboard.YPos=10;            // Y position offset for dashboard in chart window
extern bool     Dashboard.SimMode=false;      // Simlation mode for VHandsTrade & LHF Trade Simulators

// Indicator buffers
double dExtMapBuffer1[];
double dExtMapBuffer2[];
double dExtMapBuffer3[];
double dExtMapBuffer4[];
double dExtMapBuffer5[];
double dExtMapBuffer6[];

// Module variables
// Dashboard position & size
int iTextYPos = 1;
int iTextCorner = 1;
int iDashHeight=0;
// MA periods
int iMA1Period=0;
int iMA1TFPeriod[9]={0,0,0,0,0,0,0,0,0};
int iMA2Period=0;
int iMA2TFPeriod[9]={0,0,0,0,0,0,0,0,0};
// ADR
int iDataError;
double dYHigh;
double dYLow;
double dTOpenPrice;
datetime tTOpenTime;
double dADR[4];

//---- Indicator name 
string sObjId = INDICATOR_NAME;


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init() {
  // Indicator Settings
  SetIndexStyle(0,DRAW_LINE);
  SetIndexBuffer(0,dExtMapBuffer1);
  SetIndexDrawBegin(0, 60/Period());   
  SetIndexLabel(0,"H1 Last High");
  SetIndexStyle(1,DRAW_LINE);
  SetIndexBuffer(1,dExtMapBuffer2);
  SetIndexDrawBegin(1, 60/Period());
  SetIndexLabel(1,"H1 Last Low");
  SetIndexStyle(2,DRAW_LINE);
  SetIndexBuffer(2,dExtMapBuffer3);
  SetIndexDrawBegin(2, TF_H4/Period()); 
  SetIndexLabel(2,"H4 Last High");  
  SetIndexStyle(3,DRAW_LINE);
  SetIndexBuffer(3,dExtMapBuffer4);
  SetIndexDrawBegin(3, TF_H4/Period());   
  SetIndexLabel(3,"H4 Last Low");
  SetIndexStyle(4,DRAW_LINE,EMPTY, EMPTY, MA1.Color);
  SetIndexBuffer(4,dExtMapBuffer5);  
  SetIndexStyle(5,DRAW_LINE,EMPTY, EMPTY, MA2.Color);
  SetIndexBuffer(5,dExtMapBuffer6);  
  
  // Set indicator name  
  IndicatorShortName( "[" + INDICATOR_NAME + INDICATOR_VERSION + "]");
  
  // Set lower TF MA Period
  if (MA1.Type==0)
    iMA1Period = MA1.Period;
  else
    iMA1Period = GetMA1TFV(Period());
  SetIndexLabel(4,"MA"+iMA1Period);
  
  // Set Higher TF MA Period
  if (MA2.Type==0)
    iMA2Period = MA2.Period;
  else
    iMA2Period = GetMA2TFV(Period());
  SetIndexLabel(5,"MA"+iMA2Period);
  
  // Simulator settings
  if (Dashboard.SimMode==true) 
    Market.ShowAsk=false; 
  
  // Set Constant variables
  iTextCorner = Dashboard.Corner;  
  iDashHeight=DashboardBoxHeight();
  
  // Exit
  return(0);
}
  
  
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit() {
  int i;
  
  // Clear text objects
  for( i=ObjectsTotal()-1; i>-1; i--)
   if (StringFind(ObjectName(i),sObjId)>=0)  ObjectDelete(ObjectName(i));
   
  // Exit
  return(0);
}


//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()  {
  //int iNewBars;
  int iNewTick;
  int iCountedBars; 
  int i;  
  
  // Get unprocessed bars
  iCountedBars=IndicatorCounted();
  if(iCountedBars < 0) return (-1); 
  if(iCountedBars>0) iCountedBars--;
  iNewTick=Bars-iCountedBars;
  
  // Display MA
  if (iMA1Period>0)
    for(i=iNewTick-2; i>=0; i--) 
      dExtMapBuffer5[i]=iMA(NULL,0,iMA1Period,MA1.Shift,MA1.Mode,MA1.Price,i);
  if (iMA2Period>0)  
    for(i=iNewTick-2; i>=0; i--) 
      dExtMapBuffer6[i]=iMA(NULL,0,iMA2Period,MA2.Shift,MA2.Mode,MA2.Price,i);
  
  if (BarTime.Enable==true && Dashboard.SimMode==false && BarTime.MaxTimeFrame>=Period()) 
    BarTimeLeft(BarTime.Pos, BarTime.ShowArrow,BarTime.FontSize,BarTime.TextColor,BarTime.Window);       
  
  //DrawDashBkg();
  if (Dashboard.BkgColor!=CLR_NONE)
    DrawDashBox();
  
  // Display Market info on Dashboard
  iTextYPos = 1;  
  if (Market.ShowData==true) {
    DisplayMarketInfo(); 
    iTextYPos++; 
  }
  
  // Display fractal & pip data on Dashboard
  if (Pips.ShowData==true) {
    FractalPipData();
    PipsToOpen();
    PipsToMA();
    iTextYPos++;
  }
  
  // Display H1 and H4 last high/low on Dashboard and draw lines
  SetH1LastHigh();
  SetH4LastHigh();
  if ((H1HighLow.ShowData==true || H4HighLow.ShowData==true) && Period()<TF_H4)
    iTextYPos++;  
    
  // Display daily range & pip data on Dashboard
  if (Adr.ShowData==true) 
    DailyRange();
  ADRAlarm();
    
  // exit
  return(0);
}
//+------------------------------------------------------------------+


//-----------------------------------------------------------------------------
// function: GetMA1TFV()
// Description: Get MA1 period based on the current time-frame & MA1.TFVPeriod
//-----------------------------------------------------------------------------
int GetMA1TFV(int iPeriod) {
   string sSubStr=MA1.TFVPeriod;
   int i,iTokenEnd;
   
   for (i=0;i<9;i++) {
     iTokenEnd=StringFind(sSubStr,",",0);
     if (iTokenEnd<0) {
       iMA1TFPeriod[i]=StrToInteger(sSubStr);
       break;
     }
     else {       
       iMA1TFPeriod[i]=StrToInteger(StringSubstr(sSubStr,0,iTokenEnd));
       sSubStr=StringSubstr(sSubStr,iTokenEnd+1,StringLen(sSubStr));       
     }  
   }
   
   switch(iPeriod) {
    case TF_M1: return(iMA1TFPeriod[0]);
    case TF_M5: return(iMA1TFPeriod[1]);
    case TF_M15: return(iMA1TFPeriod[2]);
    case TF_M30: return(iMA1TFPeriod[3]);
    case TF_H1: return(iMA1TFPeriod[4]);
    case TF_H4: return(iMA1TFPeriod[5]);
    case TF_D: return(iMA1TFPeriod[6]);
    case TF_W: return(iMA1TFPeriod[7]);
    case TF_M: return(iMA1TFPeriod[8]);
    default: return(0);
  }
  return(0);
}

//-----------------------------------------------------------------------------
// function: GetMA2TFV()
// Description: Get MA2 period based on the current time-frame & MA2.TFVPeriod
//-----------------------------------------------------------------------------
int GetMA2TFV(int iPeriod) {
   string sSubStr=MA2.TFVPeriod;
   int i,iTokenEnd;
   
   for (i=0;i<9;i++) {
     iTokenEnd=StringFind(sSubStr,",",0);
     if (iTokenEnd<0) {
       iMA2TFPeriod[i]=StrToInteger(sSubStr);
       break;
     }
     else {       
       iMA2TFPeriod[i]=StrToInteger(StringSubstr(sSubStr,0,iTokenEnd));
       sSubStr=StringSubstr(sSubStr,iTokenEnd+1,StringLen(sSubStr));       
     }  
   }
  
  switch(iPeriod) {
    case TF_M1: return(iMA2TFPeriod[0]);
    case TF_M5: return(iMA2TFPeriod[1]);
    case TF_M15: return(iMA2TFPeriod[2]);
    case TF_M30: return(iMA2TFPeriod[3]);
    case TF_H1: return(iMA2TFPeriod[4]);
    case TF_H4: return(iMA2TFPeriod[5]);
    case TF_D: return(iMA2TFPeriod[6]);
    case TF_W: return(iMA2TFPeriod[7]);
    case TF_M: return(iMA2TFPeriod[8]);
    default: return(0);
  }
  return(0); 
}


//-----------------------------------------------------------------------------
// function: SetH1LastHigh()
// Description: Calc and display H1 High and Low 
//-----------------------------------------------------------------------------
void SetH1LastHigh() {
  double dHigh;
  double dLow;
 
  double dBid;
  int iNrOfBars;
  int iPeriod;
  int iShift=-1;
  int i;
  color cTextColor;
  int iY;
  
  // Get and display 14 high & low and draw SR lines
  iPeriod=GetPeriod(Period());  
  if (iPeriod<TF_H1) {  
    // Get index of the end of the last 1H bar
    for (iShift=0; iShift<Bars; iShift++) 
      if (TimeMinute(Time[iShift])== 0) 
        break;
    iShift++;    
    
    // Get nr of bars for the 1H period. There can be bars missing!
    for (i=iShift; i<Bars; i++) 
      if (TimeMinute(Time[i])== 0) 
        break;
    iNrOfBars=i-iShift+1;   
    
    // Find the highest and lowest data for specified nr of bars
    dHigh=High[iHighest(NULL,0,MODE_HIGH,iNrOfBars,iShift)];
    dLow=Low[iLowest(NULL,0,MODE_LOW,iNrOfBars,iShift)];
    
    // Get bid value
    if (Dashboard.SimMode==true) 
      dBid=Close[0]; 
    else 
      dBid=Bid;
  
    // Display on dashboard    
    if (H1HighLow.ShowData==true) {      
      if (Open[iNrOfBars+iShift]>Close[iShift]) cTextColor=Dashboard.DnTextColor; else cTextColor=Dashboard.UpTextColor;
      iY=TEXT_YINT*iTextYPos+Dashboard.YPos;
      WriteText("LH(H1)  " + DoubleToStr(dHigh, Digits), sObjId+"_LH_H1", iTextCorner, TEXT_XPOS+Dashboard.XPos, iY,cTextColor);
      iTextYPos++;
      iY=TEXT_YINT*iTextYPos+Dashboard.YPos;
      WriteText("LL(H1)  " + DoubleToStr(dLow, Digits), sObjId+"_LL_H1", iTextCorner, TEXT_XPOS+Dashboard.XPos, iY,cTextColor);
      iTextYPos++;
    }
        
    // Draw H/L line
    if (H1HighLow.ShowLines==True)  {
      // Clear old lines
      for(i=iNrOfBars+iShift; i<iNrOfBars+iShift+(1200/iPeriod)+2; i++) {    
        dExtMapBuffer1[i]=EMPTY_VALUE;
        dExtMapBuffer2[i]=EMPTY_VALUE;    
      } 
      // Draw new lines
      for(i=iShift; i<iNrOfBars+iShift; i++) {    
        dExtMapBuffer1[i]=dHigh;
        dExtMapBuffer2[i]=dLow;    
      }   
    } // end if 
  } // endif
} // end funcion()


//-----------------------------------------------------------------------------
// function: SetH4LastHigh()
// Description: Calc and display H4 High and Low 
//-----------------------------------------------------------------------------
void SetH4LastHigh() {
  double dHigh;
  double dLow;
  double dBid;
  int iNrOfBars;
  int iPeriod;
  int iShift;
  int i;
  color cTextColor;
  int iY;
  
  // Get and display H4 high & low and draw SR lines
  iPeriod=GetPeriod(Period());  
  if (iPeriod<TF_H4) {
  
    // Get index of the end of the last 4H bar
    for (iShift=0; iShift<Bars; iShift++)
      if (TimeMinute(Time[iShift])== 0 && MathRound(MathMod(TimeHour(Time[iShift]),4))==0) 
        break;
    iShift++;
    
    // Get nr of bars for the 4H period. There can be bars missing!
    for (i=iShift; i<Bars; i++) 
      if (TimeMinute(Time[i])== 0 && MathRound(MathMod(TimeHour(Time[i]),4))==0) 
        break;
    iNrOfBars=i-iShift+1;
   
    // Calc Hih and low for specified nr of bars
    dHigh=High[iHighest(NULL,0,MODE_HIGH,iNrOfBars,iShift)];
    dLow=Low[iLowest(NULL,0,MODE_LOW,iNrOfBars,iShift)];  
    
    // Get bid value
    if (Dashboard.SimMode==true) 
      dBid=Close[0]; 
    else 
      dBid=Bid;
    
    // Display on dashboard
    if (H4HighLow.ShowData==true) {      
      if (Open[iNrOfBars+iShift]>Close[iShift]) cTextColor=Dashboard.DnTextColor; else cTextColor=Dashboard.UpTextColor ;
      iY=TEXT_YINT*iTextYPos+Dashboard.YPos;
      WriteText("LH(H4)  " + DoubleToStr(dHigh, Digits), sObjId+"_LH-H4", iTextCorner, TEXT_XPOS+Dashboard.XPos, iY,cTextColor);
      iTextYPos++;   
      iY=TEXT_YINT*iTextYPos+Dashboard.YPos;
      WriteText("LL(H4)  " + DoubleToStr(dLow, Digits), sObjId+"_LL-H4", iTextCorner, TEXT_XPOS+Dashboard.XPos, iY,cTextColor);    
      iTextYPos++;
    }  
    
    // Draw H/L line 
    if (H4HighLow.ShowLines==True)  {
      // Clear old lines
      for(i=iNrOfBars+iShift; i<iNrOfBars+iShift+(480/iPeriod)+2; i++) {    
        dExtMapBuffer3[i]=EMPTY_VALUE;
        dExtMapBuffer4[i]=EMPTY_VALUE; 
      } 
      // Draw new lines
      for(i=iShift; i<iNrOfBars+iShift; i++) {    
        dExtMapBuffer3[i]=dHigh;
        dExtMapBuffer4[i]=dLow;   
      } 
      
    } // endif
  } // endif
} //end funcion()


//-----------------------------------------------------------------------------
// function: FractalPipData()
// Description: Calc and display:
//        PLFS - Pips of Last Fractal Swing, 
//        PTFH - Pips To Fractal High, 
//        PTFL - Pips To Fractal Low 
//        PTO - Pips to open
//        PTMA - Pips to MA
//-----------------------------------------------------------------------------
void FractalPipData() {
  double dBid;
  double dFractalHigh;
  int iFractalHigh;
  double dPTFH;
  double dFractalLow;
  int iFractalLow;
  double dPTFL;
  double dFractalSwing;
  int iBSLF;
  color cTextColor;
  int iY;
  
  // Get bid value
  if (Dashboard.SimMode==true) 
    dBid=Close[0]; 
  else 
    dBid=Bid;
  
  // Calc Fractals - PLFS - Pips of Last Fractal Swing, PTFH - Pips To Fractal High, PTFL - Pips To Fractal Low 
  iFractalHigh=GetLastFractalIndex( 0, MODE_UPPER);
  iFractalLow=GetLastFractalIndex( 0, MODE_LOWER);    
  
  if (iFractalHigh>=0) 
    dPTFH=PriceToPips( dBid - High[iFractalHigh]);
  if (iFractalLow>=0) 
    dPTFL=PriceToPips( dBid - Low[iFractalLow]);
  dFractalSwing=PriceToPips(High[iFractalHigh]-Low[iFractalLow]); 
  
  // Display Fractal data
  if (dPTFH<=0) cTextColor=Dashboard.DnTextColor; else cTextColor=Dashboard.UpTextColor ;
  iY=TEXT_YINT*iTextYPos+Dashboard.YPos;
  WriteText(" PTFH  " + DoubleToStr(MathAbs(dPTFH), PipPrecision()), sObjId+"_PTFH", iTextCorner, TEXT_XPOS+Dashboard.XPos, iY,cTextColor);
  iTextYPos++;
  if (dPTFL<=0) cTextColor=Dashboard.DnTextColor; else cTextColor=Dashboard.UpTextColor ;
  iY=TEXT_YINT*iTextYPos+Dashboard.YPos;
  WriteText(" PTFL  " + DoubleToStr(MathAbs(dPTFL), PipPrecision()), sObjId+"_PTFL", iTextCorner, TEXT_XPOS+Dashboard.XPos, iY,cTextColor);
  iTextYPos++;
  
  if (iFractalHigh>iFractalLow) cTextColor=Dashboard.DnTextColor; else cTextColor=Dashboard.UpTextColor ;
  iY=TEXT_YINT*iTextYPos+Dashboard.YPos;
  WriteText(" PLFS  " + DoubleToStr(dFractalSwing, PipPrecision()), sObjId+"_PLFS", iTextCorner, TEXT_XPOS+Dashboard.XPos, iY,cTextColor);
  iTextYPos++;
  
  // Calc BSLF - Bars Since Last Fractal
  if (iFractalLow>=iFractalHigh) {
    iBSLF=iFractalHigh;
    if (dBid > High[iFractalHigh]) cTextColor=Dashboard.UpTextColor; else cTextColor=Dashboard.DnTextColor;
  }
  else {
    iBSLF=iFractalLow;
    if (dBid > Low[iFractalLow]) cTextColor=Dashboard.UpTextColor; else cTextColor=Dashboard.DnTextColor;
  }
  iY=TEXT_YINT*iTextYPos+Dashboard.YPos;
  WriteText(" BSLF  " + iBSLF,sObjId+"_BSLF", iTextCorner, TEXT_XPOS+Dashboard.XPos, iY,cTextColor);
  iTextYPos++;
} // end funcion()


//-----------------------------------------------------------------------------
// function: PipsToOpen()
// Description: Calc and display:
//        PTO - Pips to open
//-----------------------------------------------------------------------------
void PipsToOpen() {
  double dBid;
  double dPTO;
  color cTextColor;
  int iY;
  //datetime tOpenTime;
  
  // Get bid value
  if (Dashboard.SimMode==true) 
    dBid=Close[0]; 
  else 
    dBid=Bid;
    
  // Get todays open price & datetime & Calc PTO - Pips to open
  GetMarketOpen(Adr.MarketOpenHour);
  dPTO=PriceToPips(dBid-dTOpenPrice);
  
  // Display PTO  
  if (dPTO<=0) cTextColor=Dashboard.DnTextColor; else cTextColor=Dashboard.UpTextColor ;
  iY=TEXT_YINT*iTextYPos+Dashboard.YPos;
  WriteText("  PTO  " + DoubleToStr( MathAbs(dPTO) ,PipPrecision()),sObjId+"_PTO", iTextCorner, TEXT_XPOS+Dashboard.XPos, iY,cTextColor);
  iTextYPos++;
}


//-----------------------------------------------------------------------------
// function: GetMarketOpen()
// Description: Get the market open time & price
//-----------------------------------------------------------------------------
double GetMarketOpen(int iOpenHour) {
  static datetime tCurHour=0;
  bool bNewHour=false;
  int i;
  int iCloseHour;
  
  // Init vars
  iDataError=0;
  iCloseHour=GetCloseHour(iOpenHour);
  
  // Check for new hour & set new hour flag
  if (Dashboard.SimMode==false) {
    if (tCurHour!=iTime(NULL,TF_H1,0)){
      tCurHour=iTime(NULL,TF_H1,0);   
      bNewHour=true;
    }
  }
  else {
    // Sim mode
    if (TimeHour(Time[0])==iOpenHour && TimeMinute(Time[0])==0) {
      tCurHour=Time[0];   
      bNewHour=true;
    }
  }
    
  if (bNewHour==true) {
  if (Dashboard.SimMode==false) {
    // Move to latest close time
    for (i=0; i<iBars(NULL,TF_H1); i++) {
      if (TimeHour(iTime(NULL,TF_H1,i))==iOpenHour) {  
        // Found open time
        i++;
        break;
      }
      if (TimeHour(iTime(NULL,TF_H1,i))==iCloseHour) { 
        // Found close time
        break;    
      }
      if (i>24) { 
        // Neither open nor close time found within 24 hours
        iDataError=ADR_ERR_DATAGAP;
      break;
      }
    }
    // Get todays open price & datetime
    if (i>0) {
      dTOpenPrice=iOpen(NULL,TF_H1,i-1);
      tTOpenTime=iTime(NULL,TF_H1,i-1);
    }    
  }
  else {
    // Get nr of bars for the period. There can be bars missing!
    for (i=0; i<Bars; i++) 
      if (TimeHour(Time[i])==iOpenHour && TimeMinute(Time[i])==0)
        break;
    dTOpenPrice=Time[i];
    tTOpenTime=Open[i];
  }
  }
}


//-----------------------------------------------------------------------------
// function: PipsToMA()
// Description: Calc and display:
//        PTMA - Pips to MA
//-----------------------------------------------------------------------------
void PipsToMA() {
  double dBid;
  double dPTMA;
  double dCurMA;
  color cTextColor;
  int iY;
  
  // Get bid value
  if (Dashboard.SimMode==true) 
    dBid=Close[0]; 
  else 
    dBid=Bid;
    
  // Calc PTMA - Pips to MA
  if (iMA1Period>0) {
    dCurMA=iMA(NULL,0,iMA1Period,MA1.Shift,MA1.Mode,MA1.Price,0);
    dPTMA=PriceToPips(dBid-dCurMA);
    if (dBid<dCurMA) cTextColor=Dashboard.DnTextColor; else cTextColor=Dashboard.UpTextColor ;
    iY=TEXT_YINT*iTextYPos+Dashboard.YPos;
    WriteText("PTMA1  " + DoubleToStr(MathAbs(dPTMA) , PipPrecision()), sObjId+"_PTMA1", iTextCorner, TEXT_XPOS+Dashboard.XPos, iY,cTextColor);
    iTextYPos++;
  }
    
  if (iMA2Period>0) {
    dCurMA=iMA(NULL,0,iMA2Period,MA2.Shift,MA2.Mode,MA2.Price,0);
    dPTMA=PriceToPips(dBid-dCurMA);
    if (dBid<dCurMA) cTextColor=Dashboard.DnTextColor; else cTextColor=Dashboard.UpTextColor ;
    iY=TEXT_YINT*iTextYPos+Dashboard.YPos;
    WriteText("PTMA2  " + DoubleToStr(MathAbs(dPTMA) , PipPrecision()), sObjId+"_PTMA2", iTextCorner, TEXT_XPOS+Dashboard.XPos, iY,cTextColor);
    iTextYPos++;    
  }  
}


//-----------------------------------------------------------------------------
// function: GetLastFractalIndex()
// Description: Get the index of the latest High or Low Fractal
//-----------------------------------------------------------------------------
int GetLastFractalIndex(int iTimeFrame, int iMode) {
  
  for (int i=0; i<Bars; i++) 
    if (iFractals(NULL, iTimeFrame, iMode, i)!=NULL) return(i); 

  return(-1);
}  // end funcion()


//-----------------------------------------------------------------------------
// function: DailyRange()
// Description: Calc and display the daily range
//-----------------------------------------------------------------------------
void DailyRange() {
  static datetime tCurHour=0;
  int iY;
  

  // Calc the ADR
  if (Dashboard.SimMode==false) {
    // Calc the ADR
    dADR[ADR_TDR]=PriceToPips(CalcTDR(Adr.MarketOpenHour));
    if (tCurHour!=iTime(NULL,TF_H1,0)){
      tCurHour=iTime(NULL,TF_H1,0);   
      dADR[ADR_YDR]=PriceToPips(CalcADR(1,Adr.MarketOpenHour));
      dADR[ADR_ADR5]=PriceToPips(CalcADR(5,Adr.MarketOpenHour));
      dADR[ADR_ADR20]=PriceToPips(CalcADR(20,Adr.MarketOpenHour));
    }
  }
  else {
    dADR[ADR_TDR]=PriceToPips(CalcSimTDR(Adr.MarketOpenHour));
    if (tCurHour!=TimeHour(Time[0])) {
      tCurHour=TimeHour(Time[0]);
      dADR[ADR_YDR]=PriceToPips(CalcSimADR(1,Adr.MarketOpenHour));
      dADR[ADR_ADR5]=PriceToPips(CalcSimADR(5,Adr.MarketOpenHour));
      dADR[ADR_ADR20]=PriceToPips(CalcSimADR(20,Adr.MarketOpenHour));
    }
  }
  
  // Display ADR on dashboard
  iY=TEXT_YINT*iTextYPos+Dashboard.YPos;
  WriteText("  TDR  " + DoubleToStr(dADR[ADR_TDR], PipPrecision())+"  ", sObjId+"_TDR", iTextCorner, TEXT_XPOS+Dashboard.XPos, iY, Adr.TextColor);
  iTextYPos++;
  iY=TEXT_YINT*iTextYPos+Dashboard.YPos;
  WriteText("  YDR  " + DoubleToStr(dADR[ADR_YDR], PipPrecision())+"  ", sObjId+"_YDR", iTextCorner, TEXT_XPOS+Dashboard.XPos, iY, Adr.TextColor);
  iTextYPos++;
  iY=TEXT_YINT*iTextYPos+Dashboard.YPos;
  WriteText(" ADR5  " + DoubleToStr(dADR[ADR_ADR5], PipPrecision())+"  ", sObjId+"_ADR5", iTextCorner, TEXT_XPOS+Dashboard.XPos, iY, Adr.TextColor);
  iTextYPos++;
  iY=TEXT_YINT*iTextYPos+Dashboard.YPos;
  WriteText("ADR20  " + DoubleToStr(dADR[ADR_ADR20], PipPrecision())+"  ", sObjId+"_ADR20", iTextCorner, TEXT_XPOS+Dashboard.XPos, iY, Adr.TextColor);
  iTextYPos++;
}  // end funcion()


//-----------------------------------------------------------------------------
// function: CalcADR()
// Description: Calc the average daily range for a give number of days
//-----------------------------------------------------------------------------
double CalcADR(int iNrOfDays, int iOpenHour) {
  int i,j;
  int iShiftBeg=0;
  int iNrOfBars=0;
  int iHoursCnt;
  int iCloseHour;
  double dHigh;
  double dLow;
  double dADR=0;
  
  // Init vars
  iDataError=0;
  iCloseHour=GetCloseHour(iOpenHour);
    
  // Move to latest close time
  for (i=0; i<iBars(NULL,TF_H1); i++) {
    if (TimeHour(iTime(NULL,TF_H1,i))==iOpenHour) {  
      // Found open time
      i++;
      break;
    }
    if (TimeHour(iTime(NULL,TF_H1,i))==iCloseHour) { 
      // Found close time
      break;    
    }
    if (i>24) { 
     // Neither open nor close time found within 24 hours
     iDataError=ADR_ERR_DATAGAP;
     break;
    }
  }
  
  // Get todays open price & datetime
  if (i>0) {
    dTOpenPrice=iOpen(NULL,TF_H1,i-1);
    tTOpenTime=iTime(NULL,TF_H1,i-1);
  }
  
  // Sum data for given amount of days
  iShiftBeg=i;  
  for (i=1; i<=iNrOfDays; i++) {    
    iHoursCnt=0;
    // Find next open to close period, starting with close time
    for (j=iShiftBeg; j<iBars(NULL,TF_H1); j++) {      
      if (TimeHour(iTime(NULL,TF_H1,j))==iOpenHour)
        // Found open time
        break;
      if (TimeHour(iTime(NULL,TF_H1,j))==iCloseHour && iHoursCnt>1) {
        // Open time was missing! Close time found
        j=j-1;
        break;    
      } 
      if (iHoursCnt>24) 
        // Neither open nor close time found within 24 hours
        iDataError=ADR_ERR_DATAGAP;
         
      iHoursCnt++;
    }
    // Calc number of bars/hours between opne & close
    iNrOfBars=j-iShiftBeg+1;    

    // Calc High and low for specified nr of bars    
    if (iNrOfBars>12) { // Check that we have at least half a day of bars (no sundays!)      
      dHigh=iHigh(NULL,TF_H1,iHighest(NULL,TF_H1,MODE_HIGH,iNrOfBars,iShiftBeg));
      dLow=iLow(NULL,TF_H1,iLowest(NULL,TF_H1,MODE_LOW,iNrOfBars,iShiftBeg));  
      dADR=dADR+ (dHigh-dLow);
    }
    
    // Get yesterdays high and Low
    if (i==1) {
      dYHigh=dHigh;
      dYLow=dLow;
    }
    
    // Continue with next period, starting with the close
    iShiftBeg=iShiftBeg+iNrOfBars;
  }
  
  // Check if not enough data was available
  if (i<iNrOfDays)
    iDataError=ADR_ERR_DATAEND;
  
  // Calc Average & exit  
  return(dADR/(i-1));
}


//-----------------------------------------------------------------------------
// function: CalcTDR()
// Description: Calc todays daily range. For sim
//-----------------------------------------------------------------------------
double CalcTDR(int iOpenHour) {
  int i;
  int iShift=0;
  int iNrOfBars=0;
  double dHigh;
  double dLow;
  datetime iCloseHour;

  // Init vars
  iDataError=0;
  iCloseHour=GetCloseHour(iOpenHour);

  // Move to latest close time
  for (i=0; i<iBars(NULL,TF_H1); i++) {
    if (TimeHour(iTime(NULL,TF_H1,i))==iOpenHour )
      break;
      
    if (TimeHour(iTime(NULL,TF_H1,i))==iCloseHour && i>0) { 
      // Found close time
      i++;
      break;    
    }
    
    if (i>24) { 
     // Neither open nor close time found within 24 hours
     iDataError=ADR_ERR_DATAGAP;
     break;
    }
  }
         
  // Calc High and low for specified nr of bars
  dHigh=iHigh(NULL,TF_H1,iHighest(NULL,TF_H1,MODE_HIGH,i+1,0));
  dLow=iLow(NULL,TF_H1,iLowest(NULL,TF_H1,MODE_LOW,i+1,0));  
    
  return(dHigh-dLow);
}


//-----------------------------------------------------------------------------
// function: ADRAlarm()
// Description: Calc todays daily range. For sim
//-----------------------------------------------------------------------------
double ADRAlarm() {
  static datetime tToday=0;
  static bool bMinAlarm=false;
  static bool bMaxAlarm=false;
  int i;

  // Check if a new day has started and reset vars
  if (tTOpenTime!=tToday) {
    tToday=tTOpenTime;
    bMinAlarm=false;
    bMaxAlarm=false;    
  }
  
  // Minumim range exceeded alert
  if (bMinAlarm==false) {
    if (dADR[ADR_TDR]>=Adr.MinRangePips) {
      bMinAlarm=true;
      if (Adr.MinRangeAlert==true)
        Alert(Symbol()," - Minimum Range Exceeded. ",INDICATOR_NAME);
    }
  }
  
  // Maximun range within reach alert
  if (bMaxAlarm==false) {      
    if (dADR[ADR_TDR]*(Adr.MaxRangePercent/100)>=dADR[ADR_YDR] ) {
      bMaxAlarm=true;
      if (Adr.MaxRangeAlert==true)
        Alert(Symbol()," - Maximum Range Warning. ",INDICATOR_NAME);
    }
  }  
}


//-----------------------------------------------------------------------------
// function: GetCloseHour()
// Description: Return the market close hour
//-----------------------------------------------------------------------------
int GetCloseHour(int iOpenHour) {
  if (iOpenHour==0) 
    return(23);
  else
    return(iOpenHour-1);
}


//-----------------------------------------------------------------------------
// function: CalcSimTDR()
// Description: Calc todays daily range. For sim
//-----------------------------------------------------------------------------
double CalcSimTDR(int iOpenHour) {
  int i;
  int iShift=0;
  int iNrOfBars=0;
  double dHigh;
  double dLow;

  // Get nr of bars for the period. There can be bars missing!
  for (i=0; i<Bars; i++) 
    if (TimeHour(Time[i])==iOpenHour && TimeMinute(Time[i])==0)
      break;
       
  // Calc Hih and low for specified nr of bars
  dHigh=High[iHighest(NULL,0,MODE_HIGH,i+1,0)];
  dLow=Low[iLowest(NULL,0,MODE_LOW,i+1,0)];  
    
  return(dHigh-dLow);
}


//-----------------------------------------------------------------------------
// function: CalcSimTDR()
// Description: Calc todays daily range. For sim
//-----------------------------------------------------------------------------
double CalcSimADR(int iNrOfDays,int iOpenHour) {
  int i,j;
  int iShiftBeg=0;
  int iShiftEnd=0;
  int iNrOfBars=0;
  double dHigh;
  double dLow;
  double dADR=0;

  // Get nr of bars form the last 00:000 hours
  for (i=0; i<Bars; i++) 
    if (TimeHour(Time[i])==iOpenHour && TimeMinute(Time[i])==0)
      break;
  
  // start from end of day, 23:59
  iShiftBeg=i+1;
  for (i=1; i<=iNrOfDays; i++) {    
    for (j=iShiftBeg; j<Bars; j++) {
      if (TimeHour(Time[j])==iOpenHour && TimeMinute(Time[j])==0)
        break;
    }
    iNrOfBars=j-iShiftBeg+1;    
    // Calc Hih and low for specified nr of bars    
    if (iNrOfBars>(12*(60.0/Period()))) { // Check that we have at least half a day of bars (no sundays!)
      dHigh=High[iHighest(NULL,0,MODE_HIGH,iNrOfBars,iShiftBeg)];
      dLow=Low[iLowest(NULL,0,MODE_LOW,iNrOfBars,iShiftBeg)];  
      dADR=dADR+ (dHigh-dLow);
    }
    iShiftBeg=iShiftBeg+iNrOfBars;
  }
  return(dADR/(i-1));
}


//-----------------------------------------------------------------------------
// function: DisplayMarketInfo()
// Description: Calc the average daily range over a number of days
//-----------------------------------------------------------------------------
void DisplayMarketInfo() {
  int iX,iY;
  double dBid;
  
  // Get bid value
  if (Dashboard.SimMode==true) 
    dBid=Close[0]; 
  else 
    dBid=Bid;
  
  // Instrument  
  if (Dashboard.Corner==1 || Dashboard.Corner==3) iX=90+Dashboard.XPos; else iX=10+Dashboard.XPos;  // Set display positions depending the corner
  if (Dashboard.Corner==2 || Dashboard.Corner==3) iY=TEXT_YINT*iTextYPos+14+Dashboard.YPos; else iY=TEXT_YINT*iTextYPos-3+Dashboard.YPos;
  WriteText(GetShortSymbol(Symbol()), sObjId+"_Symbol", iTextCorner, iX, iY,Market.SymbolTextColor,24);
  //iTextYPos++;
  
  // Price
  if (Dashboard.Corner==0 || Dashboard.Corner==2) iX=50+Dashboard.XPos; else iX=10+Dashboard.XPos; // Set display positions depending the corner
  iY=TEXT_YINT*iTextYPos+Dashboard.YPos;
  WriteText(DoubleToStr( dBid, Digits), sObjId+"_Bid", iTextCorner, iX, iY,Market.BidTextColor, 14);
  iTextYPos++;  
  
  if (Market.ShowAsk==True) {
    if (Dashboard.Corner==0 || Dashboard.Corner==2) iX=52+Dashboard.XPos; else iX=35+Dashboard.XPos; // Set display positions depending the corner
    iY=TEXT_YINT*iTextYPos+Dashboard.YPos;
    WriteText( DoubleToStr(Ask, Digits), sObjId+"_Ask", iTextCorner, iX, iY,Market.AskTextColor,9);
    iTextYPos++;
  }
  
  if (Market.ShowSpread==True) {
    if (Market.ShowAsk==False) 
      if (Dashboard.Corner==0 || Dashboard.Corner==2) iX=50+Dashboard.XPos; else iX=35+Dashboard.XPos;
    else
      if (Dashboard.Corner==0 || Dashboard.Corner==2) iX=50+Dashboard.XPos; else iX=33+Dashboard.XPos;
    iY=TEXT_YINT*iTextYPos+Dashboard.YPos;  
    WriteText("SP  "+ DoubleToStr( PriceToPips(Ask-Bid) , PipPrecision()), sObjId+"_Spread", iTextCorner, iX, iY,Market.SpreadTextColor,9);      
  iTextYPos++;
  }
  
}  // end funcion()
 
 
//-----------------------------------------------------------------------------
// function: WriteText()
// Description: Write text strings to window
//-----------------------------------------------------------------------------
void WriteText(string sText, string sTextId, int iCorner, int iXPos, int iYPos, color cTxtColor=LightBlue, int iTxtSize=9) {
  int i;      
  int iMaxStrLen=14+PipPrecision();
  int iBoxHeight=(iDashHeight)*TEXT_YINT;

  // Delete text object if it already exists      
  if (ObjectFind(sTextId)>0 ) ObjectDelete(sTextId); 
  
  // Adjust text positioning
  if ((iCorner==1 || iCorner==3) ) {
    if (StringLen(sText)<iMaxStrLen && (iYPos-Dashboard.YPos)/TEXT_YINT>3) sText=sText+PadStr(iMaxStrLen-StringLen(sText)-1); // Pad on right side
  }
  else {
    if (StringLen(sText)<iMaxStrLen && (iYPos-Dashboard.YPos)/TEXT_YINT>3) sText=" "+sText; // Pad on left side
  }
  
  if (iCorner==2 || iCorner==3) {
    iYPos=iBoxHeight+Dashboard.YPos-iYPos;    // Flip coordinates if corner=bottom
    iYPos=Dashboard.YPos+iYPos;
  }
  
  // Print Text
  ObjectCreate(sTextId, OBJ_LABEL, 0, 0, 0, 0, 0);
  ObjectSet(sTextId, OBJPROP_CORNER, iCorner);
  ObjectSet(sTextId, OBJPROP_WIDTH, 3);
  ObjectSet(sTextId, OBJPROP_XDISTANCE, iXPos);
  ObjectSet(sTextId, OBJPROP_YDISTANCE, iYPos);
  ObjectSet(sTextId, OBJPROP_BACK, false);
  ObjectSetText(sTextId, sText, iTxtSize, "Courier New", cTxtColor);
}  // end funcion()


//-----------------------------------------------------------------------------
// function: DrawDashBox()
// Description: Draw the dashboard box
//-----------------------------------------------------------------------------
void DrawDashBox() {
  string sTextId;
  int iTextSize=10;
  int iXOffset=Dashboard.XPos;
  int iYOffset=Dashboard.YPos;
  
  for (int i=0; i<=iDashHeight; i++) {  
    sTextId=sObjId+"_1BoxLine_"+i;    
    if (ObjectFind(sTextId)>0 ) ObjectDelete(sTextId);    
    ObjectCreate(sTextId, OBJ_LABEL, 0, 0, 0, 0, 0);
    ObjectSet(sTextId, OBJPROP_CORNER, iTextCorner);
    ObjectSet(sTextId, OBJPROP_WIDTH, 3);
    //ObjectSet(sTextId, OBJPROP_XDISTANCE, TEXT_XPOS-iXOffset);
    ObjectSet(sTextId, OBJPROP_XDISTANCE, Dashboard.XPos);
    ObjectSet(sTextId, OBJPROP_YDISTANCE, TEXT_YINT*i+iYOffset);
    //ObjectSet(sTextId, OBJPROP_YDISTANCE, TEXT_YINT*i+1);
    ObjectSet(sTextId, OBJPROP_BACK, false);
    ObjectSetText(sTextId, "gggggggggg", iTextSize, "Webdings", Dashboard.BkgColor);  
    } // end for
} // end funcion()


//-----------------------------------------------------------------------------
// function: DashboardBoxHeight()
// Description: Calculate the height of the dashboard box
//-----------------------------------------------------------------------------
int DashboardBoxHeight() {
  int iSize=0;
  
  // Market Info
  if (Market.ShowData==true) {    
    if (Market.ShowSpread==true && Market.ShowAsk==true)
      iSize=iSize+4;
    else if (Market.ShowSpread==false && Market.ShowAsk==true)
      iSize=iSize+3;
    else if (Market.ShowSpread==true && Market.ShowAsk==false)
      iSize=iSize+3;  
    else
      iSize=iSize+2;
  }  

  // Fractal & Pip data
  if (Pips.ShowData==true && iMA1Period>0 && iMA2Period>0)
      iSize=iSize+8; 
  else if (Pips.ShowData==true && (iMA1Period>0 || iMA2Period>0))
      iSize=iSize+7;
  else if (Pips.ShowData==true)
      iSize=iSize+6;
  
  // H1 & H4 high and low data
  if (H1HighLow.ShowData==true && H4HighLow.ShowData==true && Period()<TF_H1)
    iSize=iSize+5;
  else if (H1HighLow.ShowData==true && H4HighLow.ShowData==true && Period()<TF_H4)    
    iSize=iSize+3;
  else if (H1HighLow.ShowData==true && H4HighLow.ShowData==false)    
    iSize=iSize+3;
  else if (H1HighLow.ShowData==false && H4HighLow.ShowData==true)    
    iSize=iSize+3;
  
  // ADR data
  if (Adr.ShowData==true)
    iSize=iSize+4;
  
  if (iSize>4)
    iSize=iSize+1;

  return(iSize);
} // end funcion()


//-----------------------------------------------------------------------------
// function: BarTimeLeft()
// Description: Displays the bar time left next to the current bar.
//-----------------------------------------------------------------------------
int BarTimeLeft(int iBarTime.Pos=3, bool bShowArrow=False, int iFontSize=8, color cTextColor=Black ,color iWindow=0) {
  datetime tTimeLeft,tTextPos;
  double dPrice;
  string sBarTimeLeft;
  string sObjTextName=INDICATOR_NAME+"_BarTime_Text";
  string sArrow=CharToStr(60)+CharToStr(150);
  
  // Calc time left and display position
  tTimeLeft=Time[0]+Period()*60-TimeCurrent();
  tTextPos=Time[0]+Period()*60*iBarTime.Pos;
  if (iWindow==0)
    dPrice=Bid;
  else
    dPrice=iStochastic(NULL,0,8,3,3,MODE_SMA,0,MODE_MAIN,0)+6;
  
  // Show hours if period > 60 min 
  if (Period()>60) {
    sBarTimeLeft=TimeToStr(tTimeLeft,TIME_SECONDS );
    }
  else {
    sBarTimeLeft=StringSubstr(TimeToStr(tTimeLeft,TIME_SECONDS),3);
  }  

  // Exit if time is not available  
  if (sBarTimeLeft=="alid time")
    return(0);
  
  // Add Arrow infront of time
  if (bShowArrow==true) {
   sBarTimeLeft=sArrow+sBarTimeLeft;
  }  
  
  // Display time left    
  if (iWindow>=0 && iWindow<WindowsTotal()) {
    if (ObjectFind(sObjTextName)>=0 ) ObjectDelete(sObjTextName);      
    ObjectCreate(sObjTextName, OBJ_TEXT, iWindow, tTextPos, dPrice);
    ObjectSet(sObjTextName, OBJPROP_BACK, false);
    ObjectSetText(sObjTextName, sBarTimeLeft , iFontSize, "Arial", cTextColor);
  }
  
  return(0);
}


//-----------------------------------------------------------------------------
// function: GetPeriod()
// Description: Get the current period. Translate vHandsTrade simulator periods
//              to standard  periods.
//-----------------------------------------------------------------------------
int GetPeriod(int iCurPeriod)  {
  int iResult;
  
  if (iCurPeriod==0) iCurPeriod=Period();
  
  switch (iCurPeriod) {
    case 2: iResult=TF_M1; break;   
    case 6: iResult=TF_M5; break;   
    case 16: iResult=TF_M15; break;
    case 31: iResult=TF_M30; break;
    case 61: iResult=TF_H1; break;
    case 241: iResult=TF_H4; break;
    case 1441: iResult=TF_D; break;
    case 10081: iResult=TF_W; break;
    case 43201: iResult=TF_M; break;
    default: iResult=iCurPeriod; 
  }
  return(iResult);
} // end funcion()


//-----------------------------------------------------------------------------
// function: PriceToPips()
// Description: Convert a proce difference to pips.
//-----------------------------------------------------------------------------
double PriceToPips(double dPrice) {

  if (Digits==2 || Digits==3) 
    return(dPrice/0.01); 
  else if (Digits==4 || Digits==5) 
    return(dPrice/0.0001); 
  else
    return(dPrice);            
} // end funcion()


//-----------------------------------------------------------------------------
// function: PipPrecision()
// Description: Digits of the pips
//-----------------------------------------------------------------------------
double PipPrecision() {

 if (Digits==3 || Digits==5) 
    return(1); 
  else if (Digits==2 || Digits==4) 
    return(0); 
  else
    return(0);            
} // end funcion()
  

//-----------------------------------------------------------------------------
// function: GetShortSymbol()
// Description: Shorten a symbol name. Tex. EURUSD = EU, GBPUSD = GU
//-----------------------------------------------------------------------------
string GetShortSymbol(string sSymbol) {
  string sResult="";
  
  if (StringLen(sSymbol)>5)
    sResult=StringSubstr( sSymbol, 0, 1)+ StringSubstr( sSymbol, 3, 1);
  else
    sResult="sSymbol";
 
  return(sResult);
} // end funcion()

//-----------------------------------------------------------------------------
// function: PadStr()
// Description: Create a blank string N chars long
//-----------------------------------------------------------------------------
string PadStr(int iSize) {
  string sReturn ="";
  
  for (int i=0; i<iSize; i++)
    sReturn=sReturn+" ";
  return(sReturn);
} // end funcion()


