//+------------------------------------------------------------------+
//|                                             Bol_TP_Dashboard.mq4 |
//|                                  Copyright © 2010, Kenny Hubbard |
//|                                       http://www.compu-forex.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010, Kenny Hubbard"
#property link      "http://www.compu-forex.com"

#define NO_RESULT -100

#property indicator_chart_window

extern int     Boll_Period    = 20;
extern int     Boll_Deviation = 2;
extern int     Slow_MA_Period = 365;
extern int     Fast_MA_Period = 200;

extern bool    Show_M5        = false;
extern bool    Show_M15       = true;
extern bool    Show_M30       = true;
extern bool    Show_H1        = true;
extern bool    Show_H4        = true;
extern bool    Show_D1        = true;
extern bool    Show_WK1       = true;
extern bool    Show_MN1       = false;
extern double  Min_Length     = 2;   //Length of wick from High to Low
extern double  Max_Body       = 2;    //Max body size in pips

string
   Master_List[],
   Suffix;
int
   TimeFrames[],
   Symbol_No,
   D_Factor = 1;
double
   Pip;
color
   Text_Color     = White;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   Suffix = StringSubstr(Symbol(),6);
   Print("Suffix = " + Suffix);
   Symbol_No = SymbolsList(Master_List);
string
   Master_Result[][8][3];
   ArrayResize(Master_Result,Symbol_No);

   ArrayResize(TimeFrames,0);
   if(Show_M5){
      ArrayResize(TimeFrames,ArraySize(TimeFrames)+1);
      TimeFrames[ArraySize(TimeFrames)-1] = 5;
   }
   if(Show_M15){
      ArrayResize(TimeFrames,ArraySize(TimeFrames)+1);
      TimeFrames[ArraySize(TimeFrames)-1] = 15;
   }
   if(Show_M30){
      ArrayResize(TimeFrames,ArraySize(TimeFrames)+1);
      TimeFrames[ArraySize(TimeFrames)-1] = 30;
   }
   if(Show_H1){
      ArrayResize(TimeFrames,ArraySize(TimeFrames)+1);
      TimeFrames[ArraySize(TimeFrames)-1] = 60;
   }
   if(Show_H4){
      ArrayResize(TimeFrames,ArraySize(TimeFrames)+1);
      TimeFrames[ArraySize(TimeFrames)-1] = 240;
   }
   if(Show_D1){
      ArrayResize(TimeFrames,ArraySize(TimeFrames)+1);
      TimeFrames[ArraySize(TimeFrames)-1] = 1440;
   }
   if(Show_WK1){
      ArrayResize(TimeFrames,ArraySize(TimeFrames)+1);
      TimeFrames[ArraySize(TimeFrames)-1] = 10080;
   }
   if(Show_MN1){
      ArrayResize(TimeFrames,ArraySize(TimeFrames)+1);
      TimeFrames[ArraySize(TimeFrames)-1] = 43200;
   }
      for(int i = 0;i<Symbol_No;i++){
      for(int x=0;x<ArraySize(TimeFrames);x++){
         Master_Result[i][x][0]=Get_Data(Master_List[i], TimeFrames[x]);
         Master_Result[i][x][1]=Get_Doji(Master_List[i], TimeFrames[x]);
         Master_Result[i][x][2]=Get_MA(Master_List[i], TimeFrames[x]);
      }
   }
   Display_Data(Master_Result,Master_List,TimeFrames);
   if(Digits==3||Digits==5)D_Factor = 10;
   return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
{
   ObjectsDeleteAll();
   return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{
string
   Master_Result[][8][3];
   ArrayResize(Master_Result,Symbol_No);
   for(int i = 0;i<Symbol_No;i++){
      for(int x=0;x<ArraySize(TimeFrames);x++){
         Master_Result[i][x][0]=Get_Data(Master_List[i], TimeFrames[x]);
         Master_Result[i][x][1]=Get_Doji(Master_List[i], TimeFrames[x]);
         Master_Result[i][x][2]=Get_MA(Master_List[i], TimeFrames[x]);
      }
   }
   Display_Data(Master_Result,Master_List,TimeFrames);
   return(0);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
int SymbolsList(string &M_List[])
{
bool
   In_List =false;
string 
   SymbolsFileName="symbols.sel", 
   Currency[],
   Temp_Currency[],
   Symbols[];
int 
   Offset, 
   SymbolsNumber,
   hFile = FileOpenHistory(SymbolsFileName, FILE_BIN|FILE_READ);
   if(hFile < 0) return(-1);
   SymbolsNumber = (FileSize(hFile) - 4) / 128; Offset = 116;
   ArrayResize(Symbols, SymbolsNumber);
   FileSeek(hFile, 4, SEEK_SET);
   for(int i = 0; i < SymbolsNumber; i++){  
      Symbols[i] = StringSubstr(FileReadString(hFile, 12),0,6);
      FileSeek(hFile, Offset, SEEK_CUR);
   }
   FileClose(hFile);
   int handle=FileOpen(AccountCompany() + "_My_Dashboard.csv",FILE_CSV|FILE_READ, ';');
   
   if(handle < 0){
      ArrayResize(M_List,SymbolsNumber);
      handle=FileOpen(AccountCompany() + "_My_Dashboard.csv", FILE_CSV|FILE_WRITE, ';');
      FileSeek(handle,0,SEEK_SET);
      for (i = 0;i < SymbolsNumber;i++){
         string Sfx_Symbol = StringConcatenate(Symbols[i],Suffix);
         FileWrite(handle,Sfx_Symbol);
      }
      FileClose(handle);
      Alert("New symbol file created. Please select maximum 30 Pairs from the file in \experts\files folder & restart this dashboard.");
    }
    else{
      FileSeek(handle,0,SEEK_SET);
      for(i=0;i<30;i++){
         FileReadString(handle);
         if(FileIsEnding(handle))break;
      }
      ArrayResize(M_List,i);
      FileSeek(handle,0,SEEK_SET);
      for(int x=0;x<i;x++)M_List[x] = FileReadString(handle);
      FileClose(handle);
    }
   return(ArraySize(M_List));
}
//+------------------------------------------------------------------+
string Get_Data(string l_Pair, int TF)
{
bool
   Doji;
int
   My_MA = 0;
double
   Price = MarketInfo(l_Pair,MODE_BID),
   l_Upper = iBands(l_Pair,TF,20,2,0,PRICE_CLOSE,MODE_UPPER,0),
   l_Lower = iBands(l_Pair,TF,20,2,0,PRICE_CLOSE,MODE_LOWER,0),
   My_ATR   = iATR(l_Pair,TF,14,1);

   if(iBars(l_Pair,TF)<21)return("100");
   if(My_ATR==0)return(NO_RESULT);
   if(iHigh(l_Pair,TF,0)>l_Upper){
      if(MarketInfo(l_Pair,MODE_ASK)>l_Upper)return("20");
      if(l_Upper-Price<My_ATR/2)return("15");
      else return("10");
   }
   if(iLow(l_Pair,TF,0)<l_Lower){
      if(MarketInfo(l_Pair,MODE_BID)<l_Lower)return("-20");
      if(Price-l_Lower<My_ATR/2)return("-15");
      else return("-10");
   }
   if(l_Upper-Price<My_ATR/2)return("11");
   if(l_Upper-Price<My_ATR)return("1");
   if(Price-l_Lower<My_ATR/2)return("-11");
   if(Price-l_Lower<My_ATR)return("-1");
   return("0");
}

//+------------------------------------------------------------------+
void Display_Data(string &Results[][][], string M_List[], int l_TF[])
{
int
   Size = 11,
   First_Column = StringLen(Symbol()) * 5,
   Column_Space = 70,
   Dim2_Char_Space = 35,
   Dim3_Char_Space = 20;
color
   l_Text_Color = Text_Color;
   CreateTextLable("Header","Pair",Size,"Times New Roman",Text_Color,0,0,0);
   for(int i = 0;i<ArraySize(M_List);i++){
   string
      Pair = StringConcatenate(M_List[i],i),
      H_Line = StringConcatenate("H_Line",i);
      CreateTextLable(Pair,StringConcatenate(M_List[i],"(",DoubleToStr(Get_Spread(M_List[i]),1),")"),Size,"Times New Roman",Text_Color,0,0,i+1);
   }
   for(int x=0;x<ArraySize(l_TF);x++){
   string
      Show_TF = StringConcatenate(l_TF[x],x);
      CreateTextLable(Show_TF,Period_to_Text(l_TF[x]),Size,"Times New Roman",Text_Color,0,First_Column + (x+1)*(Column_Space),0);
   }
   for(i=0;i<ArraySize(M_List);i++){
      for(x=0;x<ArraySize(l_TF);x++){
      string
         Result_Name = StringConcatenate("Result",M_List[i],l_TF[x]);
         l_Text_Color = Text_Color;
         switch(StrToInteger(Results[i][x][0])){
            case 11  : l_Text_Color = White;
                       Results[i][x][0] = 9;
                       break;
            case -11 : l_Text_Color = White;
                       Results[i][x][0] = -9;
                       break;
            case 0   : l_Text_Color = LightSlateGray;
                       break;
            default  : l_Text_Color = Text_Color;
         } 
         CreateTextLable(Result_Name,Results[i][x][0],Size,"Times New Roman",l_Text_Color,0,First_Column + (x+1)*Column_Space,i+1);
         CreateTextLable(Result_Name+"Doji",Results[i][x][1],Size,"WingDings",Aqua,0,First_Column + (x+1)* Column_Space+Dim2_Char_Space,i+1);
         int iResult_MA = StrToInteger(Results[i][x][2]);
         switch(iResult_MA){
            case 233  : l_Text_Color = LawnGreen;break;
            case -233 : l_Text_Color = Red;break;
            case 234  : l_Text_Color = LawnGreen;break;
            case -234 : l_Text_Color = Red;break;
            case 228  : 
            case -228 : 
            case 230  :
            case -230 : l_Text_Color = Orange;break;
            default   : l_Text_Color = LightSlateGray;
         }
         if(Stoch_Check(M_List[i],l_TF[x])==NO_RESULT)l_Text_Color = SlateGray;
         Results[i][x][2] = CharToStr(MathAbs(iResult_MA));
         CreateTextLable(Result_Name+"MA",Results[i][x][2],Size,"WingDings",l_Text_Color,0,First_Column + (x+1)*Column_Space+Dim3_Char_Space,i+1);  
       }
    }
}
//+------------------------------------------------------------------+
void CreateTextLable(string TextLableName,string Text,int TextSize,string FontName,color Text_Color,int Corner,int X,int Y)
{ 
   Y *= TextSize + 10;
   
   if(Text=="100"){Text="--";Text_Color = LightSlateGray;}
   if(Text=="0"){Text=CharToStr(75);Text_Color =  SlateGray;FontName = "WingDings";}
   if(Text=="-100"){Text="XX";Text_Color = Red;}
   if(Text=="10"){Text_Color = Orange;Text = "1";}
   if(Text=="-10"){Text_Color = Orange;Text = "-1";}
   if(Text=="15"){Text_Color = Orange;Text = "9";}
   if(Text=="-15"){Text_Color = Orange;Text = "-9";}
   if(Text=="20"){Text_Color = Red;Text = "10";}
   if(Text=="-20"){Text_Color = Red;Text = "-10";}

   ObjectCreate(TextLableName, OBJ_LABEL, 0, TimeCurrent(), 0);
   ObjectSet(TextLableName, OBJPROP_CORNER, Corner);
   ObjectSet(TextLableName, OBJPROP_XDISTANCE, X);
   ObjectSet(TextLableName, OBJPROP_YDISTANCE, Y);
   ObjectSetText(TextLableName,Text,TextSize,FontName,Text_Color);
}
//+------------------------------------------------------------------+
string Period_to_Text(int TF_to_Get)
{
   switch(TF_to_Get){
      case PERIOD_MN1: return("MN1");
      case PERIOD_W1:  return("W1");
      case PERIOD_D1:  return("D1");
      case PERIOD_H4:  return("H4");
      case PERIOD_H1:  return("H1");
      case PERIOD_M30: return("M30");
      case PERIOD_M15: return("M15");
      case PERIOD_M5:  return("M5");
      case PERIOD_M1:  return("M1");
   }
}
//+------------------------------------------------------------------+
string Get_Doji(string l_Pair, int TF)
{
double 
   Hi = iHigh(l_Pair,TF,1),
   Lo = iLow(l_Pair,TF,1),
   Op = iOpen(l_Pair,TF,1),
   Cl = iClose(l_Pair,TF,1),
   Upper_Last_Bar = iBands(l_Pair,TF,20,2,0,PRICE_CLOSE,MODE_UPPER,1),
   Lower_Last_Bar = iBands(l_Pair,TF,20,2,0,PRICE_CLOSE,MODE_LOWER,1),
   Shadow_Height = Hi - Lo,
   Body_Height = MathAbs(Op - Cl);
   if (Shadow_Height < Min_Length*Pip(l_Pair)) return("");
   if (Body_Height > Max_Body*Pip(l_Pair)) return("");
   if(Cl>Upper_Last_Bar)return(CharToStr(85));
   if(Cl<Lower_Last_Bar)return(CharToStr(85));
   return("");
}
//+------------------------------------------------------------------+
string Get_MA(string l_Pair, int TF)
{
double
   Slow_MA = iMA(l_Pair,TF,Slow_MA_Period,0,MODE_EMA,PRICE_CLOSE,0),
   Fast_MA = iMA(l_Pair,TF,Fast_MA_Period,0,MODE_EMA,PRICE_CLOSE,0);
   if(Fast_MA>=Slow_MA){
      if(MarketInfo(l_Pair,MODE_BID)>Fast_MA)return("233");
      if(MarketInfo(l_Pair,MODE_BID)<Slow_MA)return("-234");
      return("228");
   }
   if(Fast_MA<Slow_MA){
      if(MarketInfo(l_Pair,MODE_ASK)<Fast_MA)return("234");
      if(MarketInfo(l_Pair,MODE_ASK)>Slow_MA)return("-233");
      return("230");
   }
   return("120");
}
//+------------------------------------------------------------------+
int Stoch_Check(string l_Pair, int TF)
{
double
   Main_Stoch = iStochastic(l_Pair,TF,9,3,3,1,0,MODE_MAIN,0),
   Signal_Stoch = iStochastic(l_Pair,TF,9,3,3,1,0,MODE_SIGNAL,0);
   if(Main_Stoch>=80){
      if(Signal_Stoch>=80)return(1);
   }
   if(Main_Stoch<=20){
      if(Signal_Stoch<=20)return(-1);
   }
   return(NO_RESULT);
}
//+------------------------------------------------------------------+
double Pip(string Pair)
{
   if(Digits==3||Digits==5)return(MarketInfo(Pair,MODE_POINT)*10);
   else return(MarketInfo(Pair,MODE_POINT));
}
//+------------------------------------------------------------------+   
double Get_Spread(string lPair)
{
   return(MarketInfo(lPair,MODE_SPREAD)/D_Factor);
}
//+------------------------------------------------------------------+
bool BullishEngulfingExists(string l_Pair, int TF)
{
   if (iOpen(l_Pair,TF,1)<=iClose(l_Pair,TF,2)){
      if(iClose(l_Pair,TF,1) >= iOpen(l_Pair,TF,2)){
         if(iOpen(l_Pair,TF,2) -  iClose(l_Pair,TF,2) >= 10*Pip(l_Pair)){
            if(iClose(l_Pair,TF,1) - iOpen(l_Pair,TF,1)>=10*Pip(l_Pair))return (true);
         }
      }
   }
   return (false);
}
//+------------------------------------------------------------------+
bool BullishHaramiExists(string l_Pair, int TF)
{
   if(iClose(l_Pair,TF,2)<iOpen(l_Pair,TF,2)){
      if(iOpen(l_Pair,TF,1)<iClose(l_Pair,TF,1)){
         if(iOpen(l_Pair,TF,2)-iClose(l_Pair,TF,2)>iATR(l_Pair,TF,14,2)){
            if(iOpen(l_Pair,TF,2)-iClose(l_Pair,TF,2) > 4*(iClose(l_Pair,TF,1) - iOpen(l_Pair,TF,1)))return(true);
         }
      }
   }
   return (false);
}

//+------------------------------------------------------------------+
bool DojiAtBottomExists(string l_Pair, int TF)
{
  if (iOpen( l_Pair,  TF,3) - iClose( l_Pair,  TF,3) >= 8*Pip(l_Pair) && MathAbs(iClose( l_Pair,  TF,2) - iOpen( l_Pair,  TF,2)) <= 1*Pip(l_Pair) && iClose( l_Pair,  TF,1) - iOpen( l_Pair,  TF,1) >= 8*Pip(l_Pair)) return (true);
  return (false);
}
//+------------------------------------------------------------------+
bool DojiAtTopExists(string l_Pair, int TF)
{
  if (iClose( l_Pair,  TF,3) - iOpen( l_Pair, TF,3) >= 8*Pip(l_Pair) && MathAbs(iClose( l_Pair,  TF,2) - iOpen( l_Pair,  TF,2)) <= 1*Pip(l_Pair) && iOpen( l_Pair,  TF,1) - iClose( l_Pair,  TF,1) >= 8*Pip(l_Pair)) return (true);
  return (false);
}
//+------------------------------------------------------------------+
bool BearishHaramiExists(string l_Pair, int TF)
{
  if (iClose( l_Pair,  TF,2) > iClose( l_Pair,  TF,1) && iOpen( l_Pair,  TF,2) < iOpen( l_Pair,  TF,1) && iClose( l_Pair,  TF,2) > iOpen( l_Pair,  TF,2) && iOpen( l_Pair,  TF,1) > iClose( l_Pair,  TF,1) && iClose( l_Pair,  TF,2) -  iOpen( l_Pair,  TF,2) > iATR(NULL, 0, 14, 2) && iClose( l_Pair,  TF,2) -  iOpen( l_Pair,  TF,2) > 4*(iOpen( l_Pair,  TF,1) -  iClose( l_Pair,  TF,1))) return (true);
  return (false);
}
//+------------------------------------------------------------------+
bool LongUpCandleExists(string l_Pair, int TF)
{
  if (iOpen( l_Pair,  TF,2) < iClose( l_Pair,  TF,2) && iHigh( l_Pair,  TF,2) - iLow( l_Pair,  TF,2) >= 40*Pip(l_Pair) && iHigh( l_Pair,  TF,2) - iLow( l_Pair,  TF,2) > 2.5*iATR(NULL, 0, 14, 2) && iClose( l_Pair,  TF,1) < iOpen( l_Pair,  TF,1) && iOpen( l_Pair,  TF,1) -  iClose( l_Pair,  TF,1) > 10*Pip(l_Pair)) return (true);
  return (false);
}
//+------------------------------------------------------------------+
bool LongDownCandleExists(string l_Pair, int TF)
{
   if (iOpen(l_Pair, TF,1) > iClose( l_Pair,  TF,1) && iHigh( l_Pair,  TF,1) -iLow( l_Pair,  TF,1) >= 40*Pip(l_Pair) && iHigh( l_Pair, TF,1) - iLow( l_Pair,  TF,1) > 2.5*iATR(NULL, 0, 14, 1)) return (true);
   return (false);
}
//+------------------------------------------------------------------+
bool BearishEngulfingExists(string l_Pair, int TF)
{
  if (iOpen(l_Pair,TF,1) >= iClose( l_Pair,  TF,2) && iClose( l_Pair,  TF,1) <= iOpen( l_Pair,  TF,2) && iOpen( l_Pair,  TF,2) -iClose( l_Pair,  TF,2) >= 10*Pip(l_Pair) && iClose( l_Pair,  TF,1)- iOpen( l_Pair,  TF,1) >= 10*Pip(l_Pair))return (true);
  return (false);
}
//+------------------------------------------------------------------+
bool SpinningTopExists(string l_Pair, int TF)
{
  if (iHigh( l_Pair,  TF,1) - iLow( l_Pair,  TF,1) > 1.5*iATR(NULL, 0, 14, 1) && (iHigh( l_Pair,  TF,1) - iLow( l_Pair,  TF,1) > 30*Pip(l_Pair)) && MathAbs(iOpen( l_Pair,  TF,1) - iClose( l_Pair,  TF,1))*5 < iHigh( l_Pair,  TF,1)- iLow( l_Pair,  TF,1)) return (true);
  return (false);
}
//+------------------------------------------------------------------+