//+------------------------------------------------------------------+
//|                                            iCorrelationTable.mq4 |
//|                                                                * |
//|                                                                * |
//+------------------------------------------------------------------+
#property copyright "*"
#property link      "*"

#import "user32.dll"
   int GetWindowRect (int hwnd,int & RECT[]);
#import


#property indicator_separate_window
#property indicator_maximum 1
#property indicator_minimum -1
#property indicator_buffers 1
#property indicator_color1 Red
#property indicator_width1 2



//---- input parameters

/*
   v3
   
   Подправлен алгоритм расчета корреляции.
   
*/

/*
   v2
   
   Новые параметры:
   
      Shift - Бар с которого начинается рассчет
      Price - Цена: 0-Close, 1-Open, 2-High, 3-Low, 4-Median, 5-Typical, 6-Weighted
      Level - Значение уровня
      ColorValuesMax - Цвет значений таблицы выше Level
      ColorValuesMin - Цвет значений таблицы ниже -Level
      ChartPos - Положение графика: 1 - справа, 2 - снизу
      
   Исправлены ошибки: не удалялись надписи при снижении количества символов в таблице.
         

*/


extern int     CorPeriod            =  50;            // Период корреляции
extern int     SymbolsListVariant   =  1;             // 1 - все символы из окна обзора рынка, 2 - из файла. Список извлекается на запуске индикатора, при изменении набора символов в обзоре рынка, или в файле надо перезапустить индикатор
extern string  FileName             =  "Symbols.txt"; // Имя файла с списком символов. Используется при SymbolsListVariant=2. Файл должен находиться в каталоге experts/files. В одной строке файла один символ.
extern color   ColorOf              =  Silver;        // Цвет выключенных пунктов в списках таймфреймов и символов
extern color   ColorOn              =  SandyBrown;    // Цвет включенных пунктов в списках таймфреймов и символов
extern color   ColorCaption         =  LimeGreen;     // Цвет заголовков таблицы
extern color   ColorValues          =  Silver;        // Цвет значений таблицы
extern color   ColorMainLevels      =  White;         // Цвет уровней 0, 1, -1, графика корреляции
extern color   ColorLevels          =  Gray;          // Цвет других уровней графика корреляции
extern color   ColorLevels_2        =  Silver;        // Цвет уровней 0.5, -0.5, графика корреляции
extern color   ColorLevels_3        =  Khaki;         // Цвет уровней 0.7, -0.7, графика корреляции
extern color   ColorDot             =  Red;           // Цвет точки на графике корреляции

extern int     Shift                =  0;             // Бар с которого начинается рассчет
extern int     Price                =  0;             // Цена: 0-Close, 1-Open, 2-High, 3-Low, 4-Median, 5-Typical, 6-Weighted
extern double  Level                =  0.7;           // Значение уровня
extern color   ColorValuesMax       =  Yellow;        // Цвет значений таблицы выше Level
extern color   ColorValuesMin       =  Aqua;          // Цвет значений таблицы ниже -Level
extern int     ChartPos             =  1;             // Положение графика: 1 - справа, 2 - снизу


int SymbolWidth=50;

int TF[]={PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1,PERIOD_W1,PERIOD_MN1};
string TFN[]={"M1","M5","M15","M30","H1","H4","D1","W1","MN1"};
string SC[];
bool SS[];
string WS[];
int TFC=9;
int SN[];
int Win;
int RECT[4];
int Width;
int LastWidth=-1;
double Buf[];
string LS1="";
string LS2="";
int LTF=-1;
int LSN=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init(){

   switch(SymbolsListVariant){
      case 1:
         fSymbolsList(SC,true);
         ArrayResize(SS,ArraySize(SC));
            for(int i=0;i<MathMin(7,ArraySize(SS));i++){
               SS[i]=true;
            }
         ArrayResize(SN,ArraySize(SC));
         ArrayInitialize(SN,1);
      break;
      case 2:
         fFileLoadSymbols(SC,FileName);
         ArrayResize(SS,ArraySize(SC));
            for(i=0;i<MathMin(7,ArraySize(SS));i++){
               SS[i]=true;
            }
         ArrayResize(SN,ArraySize(SC));
         ArrayInitialize(SN,1);         
      break;
   }
   
   SetIndexBuffer(0,Buf);
   SetIndexStyle(0,DRAW_LINE);
   
   IndicatorDigits(2);

   return(0);
}



//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit(){
   fObjDeleteByPrefix(WindowExpertName());
   return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start(){
   
      if(!IsDllsAllowed()){
         Alert(WindowExpertName()+": Разрешите DLL");
         return(0);
      }
      
   Win=WindowFind(WindowExpertName());
         
      if(ObjectFind(WindowExpertName()+"+Period_2")==Win){
         CorPeriod=StrToDouble(ObjectDescription(WindowExpertName()+"+Period_2"));
      }
   fObjLabel(WindowExpertName()+"+Period_1",315,4,"CorPeriod: ",0,ColorCaption,7,Win,"Arial",false);
   fObjLabel(WindowExpertName()+"+Period_2",365,4,""+CorPeriod,0,ColorOn,7,Win,"Arial",false); 
   CorPeriod=StrToDouble(ObjectDescription(WindowExpertName()+"+Period_2"));

   GetWindowRect(WindowHandle(Symbol(),Period()),RECT);
   Width=RECT[2]-RECT[0];
   if(LastWidth==-1)LastWidth=Width;

   int TimeFrame=fTFSelect();
   int LastY=fSymbolSelect();

      if(!fDataUpdateFromListSCmnt(WS,TimeFrame,1,3)){
         return(0);
      }
   
   static int Mode=0;
   static string S1;
   static string S2;
      if(Mode==0){
         Mode=1;
         S1=WS[0];
         S2=WS[1];
      }  
   
   static int LastCount=0;
      
      for(int i=ArraySize(WS);i<LastCount;i++){
         ObjectDelete(WindowExpertName()+"_Tab_Top_"+i);
         ObjectDelete(WindowExpertName()+"_Tab_Left_"+i); 
            for(int j=0;j<LastCount;j++){
               ObjectDelete(WindowExpertName()+"_Tab_Value_"+i+"_"+j); 
               ObjectDelete(WindowExpertName()+"_Tab_Value_"+j+"_"+i); 
            }
      }
   LastCount=ArraySize(WS);
   
      for(i=0;i<ArraySize(WS);i++){
            if(fGUI_PushButton(WindowExpertName()+"_Tab_Top_"+i,5+i*SymbolWidth+SymbolWidth,LastY+20,WS[i],0,ColorCaption,7,Win,"Arial",false)){
               if(LastWidth==Width){
                  SN[i]*=-1;
               }
            }
         string Sign=" ";
            if(SN[i]==-1){
               Sign="-";
            }
         fGUI_PushButton(WindowExpertName()+"_Tab_Top_"+i,5+i*SymbolWidth+SymbolWidth,LastY+20,Sign+WS[i],0,ColorCaption,7,Win,"Arial",false);
            if(fGUI_PushButton(WindowExpertName()+"_Tab_Left_"+i,5,LastY+20+i*15+15, Sign+WS[i],0,ColorCaption,7,Win,"Arial",false)){
               if(LastWidth==Width){
                  Mode=1;
                  S1=WS[i];
               }
            }         
         for(j=0;j<ArraySize(WS);j++){
            double dVal;
            string sVal;
            color CV=ColorValues;
               if(i==j){
                  sVal="  -------";
               }
               else{
                  int Shift1=Shift;
                  int Shift2=iBarShift(WS[j],TimeFrame,iTime(WS[i],TimeFrame,Shift1),false);
                  if(fPirsonPricePrice_TFS(WS[i],Shift1,WS[j],Shift2,TimeFrame,CorPeriod,Price,dVal)){
                     dVal*=SN[i];
                     dVal*=SN[j];
                        if(dVal>0){
                           sVal="  +"+DS2(dVal);
                        }
                        else if(dVal<0){
                           sVal="  "+DS2(dVal);
                        }
                        else{
                           sVal="   0.00";
                        }
                        if(dVal>=Level || dVal<=-Level){
                           CV=ColorValuesMax;
                        }   
                        if(dVal<=-Level){
                           CV=ColorValuesMin;
                        }                          
                  }
               }
               if(fGUI_PushButton(WindowExpertName()+"_Tab_Value_"+i+"_"+j,  5+i*SymbolWidth+SymbolWidth,  LastY+20+j*15+15,sVal,0,CV,7,Win,"Arial",false)){
                  if(LastWidth==Width){
                     if(i!=j){
                        Mode=2;    
                        S1=WS[i];
                        S2=WS[j];
                     }
                  }
               }
         }
      }
   
   fObjDeleteByPrefix(WindowExpertName()+"_Cor");
   
      if(Mode==1){
         int Gsh=20;
         int SN1;
            for(i=0;i<ArraySize(WS);i++){
               if(S1==WS[i]){
                  SN1=SN[i];
                  break;
               }
            }
         int l=0;   
            for(i=0;i<ArraySize(WS);i++){
               if(S1!=WS[i]){
                  if(fPirsonPricePrice_TFS(S1,Shift1,WS[i],Shift2,TimeFrame,CorPeriod,Price,dVal)){
                     dVal*=SN1;
                     dVal*=SN[i];
                     Sign=" ";
                        if(SN[i]==-1){
                           Sign="-";
                        }  
                        switch(ChartPos){
                           case 1:                   
                              X(WindowExpertName()+"_Cor_"+l,Gsh+(ArraySize(WS)+1)*SymbolWidth+40+19*l,LastY+55,0,Win,Level,dVal,Sign+WS[i]);
                           break;
                           case 2:
                              X(WindowExpertName()+"_Cor_"+l,33+19*l,LastY+65+(ArraySize(WS)+1)*15,0,Win,Level,dVal,Sign+WS[i]);
                           break;
                        }   
                     l++;    
                  }   
               }
            }
         Sign=" ";
            if(SN1==-1){
               Sign="-";
            }     
            switch(ChartPos){
               case 1:                   
                  fObjLabel(WindowExpertName()+"_Cor_N",Gsh+(ArraySize(WS)+1)*SymbolWidth+40,LastY+20,Sign+S1,0,ColorCaption,7,Win,"Arial",false); 
                  fObjLabel(WindowExpertName()+"_Cor_N1",Gsh+(ArraySize(WS)+1)*SymbolWidth+19,LastY+27,"+1.00",0,ColorMainLevels,6,Win,"Arial",false); 
                  fObjLabel(WindowExpertName()+"_Cor_N2",Gsh+(ArraySize(WS)+1)*SymbolWidth+23,LastY+28+40,"0.00",0,ColorMainLevels,6,Win,"Arial",false); 
                  fObjLabel(WindowExpertName()+"_Cor_N3",Gsh+(ArraySize(WS)+1)*SymbolWidth+20,LastY+28+80,"-1.00",0,ColorMainLevels,6,Win,"Arial",false); 
               break;
               case 2:
                  fObjLabel(WindowExpertName()+"_Cor_N",30,LastY+10+(ArraySize(WS)+1)*15+20,Sign+S1,0,ColorCaption,7,Win,"Arial",false); 
                  fObjLabel(WindowExpertName()+"_Cor_N1",10,LastY+10+(ArraySize(WS)+1)*15+27,"+1.00",0,ColorMainLevels,6,Win,"Arial",false); 
                  fObjLabel(WindowExpertName()+"_Cor_N2",10,LastY+10+(ArraySize(WS)+1)*15+28+40,"0.00",0,ColorMainLevels,6,Win,"Arial",false); 
                  fObjLabel(WindowExpertName()+"_Cor_N3",10,LastY+10+(ArraySize(WS)+1)*15+28+80,"-1.00",0,ColorMainLevels,6,Win,"Arial",false); 
               break;
            }              
      }

      if(Mode==2){
            for(i=0;i<ArraySize(WS);i++){
               if(S1==WS[i]){
                  SN1=SN[i];
                  break;
               }
            } 
         int SN2;        
            for(i=0;i<ArraySize(WS);i++){
               if(S2==WS[i]){
                  SN2=SN[i];
                  break;
               }
            }       
         Ind_PirsonPricePrice_TFS(S1,S2,TimeFrame,Buf,CorPeriod,Price,SN1,SN2);
    
      }
      else{
         ArrayInitialize(Buf,EMPTY_VALUE);
         SetLevelValue(0,2);
         SetLevelValue(1,-2);

      }

   LastWidth=Width;

   WindowRedraw();

   return(0);
}

bool fFileLoadSymbols(string & aArray[],string aFileName="symbols.set"){
   ArrayResize(aArray,0);
   int th=FileOpen(aFileName,FILE_CSV|FILE_READ);
      if(th>0){
            while(!FileIsEnding(th)){
               string tStr=StringTrimLeft(StringTrimRight(FileReadString(th)));
                  if(tStr!=""){
                     ArrayResize(aArray,ArraySize(aArray)+1);
                     aArray[ArraySize(aArray)-1]=tStr;
                  }
            }
         FileClose(th);
         return(true);
      }
   Alert("Ошибка открытия файла "+aFileName+", возможно файл отсутствует");   
   return(false);      
}

void Ind_PirsonPricePrice_TFS(string aSymbol_1,string aSymbol_2, int aTimeFrame,double & aToBuf[],int aPeriod,int aPrice,int aSN1,int aSN2){

   int limit=Bars-IndicatorCounted()-1;

      if(LS1!=aSymbol_1 || LS2!=aSymbol_2 || LTF!=aTimeFrame || LSN!=aSN1*aSN2){
         limit=Bars-1;
         LS1=aSymbol_1;
         LS2=aSymbol_2;
         LTF=aTimeFrame;
         LSN=aSN1*aSN2;
         SetIndexLabel(0,iif_string(aSN1==1,"","-")+aSymbol_1+" "+iif_string(aSN2==1,"","-")+aSymbol_2);
         datetime LimitTime=MathMax(iTime(aSymbol_1,aTimeFrame,iBars(aSymbol_1,aTimeFrame)-aPeriod),iTime(aSymbol_2,aTimeFrame,iBars(aSymbol_2,aTimeFrame)-aPeriod));
         limit=MathMin(limit,iBarShift(NULL,0,LimitTime)-1);
         ArrayInitialize(Buf,EMPTY_VALUE);
         SetLevelValue(0,Level);
         SetLevelValue(1,-Level);
      }
	int NTFBarNum_1=iBarShift(aSymbol_1,aTimeFrame,Time[limit],true);
	datetime NTFTime_1=iTime(aSymbol_1,aTimeFrame,NTFBarNum_1);
	int NTFBarNum_2=iBarShift(aSymbol_2,aTimeFrame,Time[limit],true);
	datetime NTFTime_2=iTime(aSymbol_1,aTimeFrame,NTFBarNum_2);	
	limit=iBarShift(NULL,0,MathMax(NTFTime_1,NTFTime_2));	
	     for(int i=limit;i>=0;i--){
	           if(aTimeFrame>=Period()){
                  int BarNum_1=iBarShift(aSymbol_1,aTimeFrame,Time[i],false); 
                  int BarNum_2=iBarShift(aSymbol_2,aTimeFrame,Time[i],false); 
              }
              else{
                  BarNum_1=iBarShift(aSymbol_1,aTimeFrame,Time[i]+Period()*60-aTimeFrame*60,false); 
                  BarNum_2=iBarShift(aSymbol_2,aTimeFrame,Time[i]+Period()*60-aTimeFrame*60,false);               
              }
            double tValue;
               if(fPirsonPricePrice_TFS(aSymbol_1,BarNum_1,aSymbol_2,BarNum_2,aTimeFrame,aPeriod,aPrice,tValue)){
                  aToBuf[i]=tValue*aSN1*aSN2;
               }
               else{
                  aToBuf[i]=aToBuf[i+1];
               }
      }
}

string iif_string(bool a1,string a2,string a3){
   if(a1)return(a2);
   return(a3);
}


void X(string aName,int aX,int aY,int aCorner,int aWindowNumber,double aLevelVal,double aVal,string aCapt){
   fObjLabel(aName+"_a1_"+0,aX,aY+0*5,"_",aCorner,ColorMainLevels,12,aWindowNumber,"Arial",false);   
   fObjLabel(aName+"_a3_"+0,aX+8,aY-0*5,"_",aCorner,ColorMainLevels,12,aWindowNumber,"Arial",false);      
      for(int i=1;i<5;i++){
         fObjLabel(aName+"_a1_"+i,aX,aY+i*4,"_",aCorner,ColorLevels,12,aWindowNumber,"Arial",false);   
         fObjLabel(aName+"_a2_"+i,aX,aY-i*4,"_",aCorner,ColorLevels,12,aWindowNumber,"Arial",false);     
         fObjLabel(aName+"_a3_"+i,aX+8,aY+i*4,"_",aCorner,ColorLevels,12,aWindowNumber,"Arial",false);   
         fObjLabel(aName+"_a4_"+i,aX+8,aY-i*4,"_",aCorner,ColorLevels,12,aWindowNumber,"Arial",false);        
      }
   fObjLabel(aName+"_a1_"+i,aX,aY+i*4,"_",aCorner,ColorLevels_2,12,aWindowNumber,"Arial",false);   
   fObjLabel(aName+"_a2_"+i,aX,aY-i*4,"_",aCorner,ColorLevels_2,12,aWindowNumber,"Arial",false);     
   fObjLabel(aName+"_a3_"+i,aX+8,aY+i*4,"_",aCorner,ColorLevels_2,12,aWindowNumber,"Arial",false);   
   fObjLabel(aName+"_a4_"+i,aX+8,aY-i*4,"_",aCorner,ColorLevels_2,12,aWindowNumber,"Arial",false);    
      for(i=6;i<7;i++){
         fObjLabel(aName+"_a1_"+i,aX,aY+i*4,"_",aCorner,ColorLevels,12,aWindowNumber,"Arial",false);   
         fObjLabel(aName+"_a2_"+i,aX,aY-i*4,"_",aCorner,ColorLevels,12,aWindowNumber,"Arial",false);     
         fObjLabel(aName+"_a3_"+i,aX+8,aY+i*4,"_",aCorner,ColorLevels,12,aWindowNumber,"Arial",false);   
         fObjLabel(aName+"_a4_"+i,aX+8,aY-i*4,"_",aCorner,ColorLevels,12,aWindowNumber,"Arial",false);        
      }   
   fObjLabel(aName+"_a1_"+i,aX,aY+i*4,"_",aCorner,ColorLevels,12,aWindowNumber,"Arial",false);   
   fObjLabel(aName+"_a2_"+i,aX,aY-i*4,"_",aCorner,ColorLevels,12,aWindowNumber,"Arial",false);     
   fObjLabel(aName+"_a3_"+i,aX+8,aY+i*4,"_",aCorner,ColorLevels,12,aWindowNumber,"Arial",false);   
   fObjLabel(aName+"_a4_"+i,aX+8,aY-i*4,"_",aCorner,ColorLevels,12,aWindowNumber,"Arial",false);      
      for(i=8;i<10;i++){
         fObjLabel(aName+"_a1_"+i,aX,aY+i*4,"_",aCorner,ColorLevels,12,aWindowNumber,"Arial",false);   
         fObjLabel(aName+"_a2_"+i,aX,aY-i*4,"_",aCorner,ColorLevels,12,aWindowNumber,"Arial",false);     
         fObjLabel(aName+"_a3_"+i,aX+8,aY+i*4,"_",aCorner,ColorLevels,12,aWindowNumber,"Arial",false);   
         fObjLabel(aName+"_a4_"+i,aX+8,aY-i*4,"_",aCorner,ColorLevels,12,aWindowNumber,"Arial",false);        
      }     
   fObjLabel(aName+"_a1_"+i,aX,aY+i*4,"_",aCorner,ColorMainLevels,12,aWindowNumber,"Arial",false);   
   fObjLabel(aName+"_a2_"+i,aX,aY-i*4,"_",aCorner,ColorMainLevels,12,aWindowNumber,"Arial",false);     
   fObjLabel(aName+"_a3_"+i,aX+8,aY+i*4,"_",aCorner,ColorMainLevels,12,aWindowNumber,"Arial",false);   
   fObjLabel(aName+"_a4_"+i,aX+8,aY-i*4,"_",aCorner,ColorMainLevels,12,aWindowNumber,"Arial",false);        
   
   fObjLabel(aName+"_b1",aX+5,aY-aVal*40+9,StringSetChar("",0,159),aCorner,ColorDot,12,aWindowNumber,"Wingdings",false);  

   fObjLabel(aName+"_c",aX+13,aY+60,aCapt,aCorner,ColorCaption,7,aWindowNumber,"Arial",false);  
   ObjectSet(aName+"_c",OBJPROP_ANGLE,-90);
   
   fObjLabel(aName+"_z1_",aX,  aY+aLevelVal*40,"_",aCorner,ColorLevels_3,12,aWindowNumber,"Arial",false);   
   fObjLabel(aName+"_z2_",aX,  aY-aLevelVal*40,"_",aCorner,ColorLevels_3,12,aWindowNumber,"Arial",false);     
   fObjLabel(aName+"_z3_",aX+8,aY+aLevelVal*40,"_",aCorner,ColorLevels_3,12,aWindowNumber,"Arial",false);   
   fObjLabel(aName+"_z4_",aX+8,aY-aLevelVal*40,"_",aCorner,ColorLevels_3,12,aWindowNumber,"Arial",false);     
   
}


string DS2(double v){return(DoubleToStr(v,2));}

bool fPirsonPricePrice_TFS(string aSymbol_1,int aShift_1,string aSymbol_2,int aShift_2,int aTimeFrame,int aPeriod, int aPrice, double & aCorrelation){
   double SumXY=0;
   double SumXX=0;
   double SumYY=0;
   double SumY=0;
   double SumX=0;         
   int j;
   int xi;
   int yi;
      for(j=0,xi=aShift_1,yi=aShift_2;j<aPeriod;j++,xi++,yi++){
         double X=iMA(aSymbol_1,aTimeFrame,1,0,0,aPrice,xi);
         double Y=iMA(aSymbol_2,aTimeFrame,1,0,0,aPrice,yi);
         SumX+=X;  
         SumY+=Y;  
         SumXX+=X*X;
         SumYY+=Y*Y;         
         SumXY+=X*Y; 
      }
   double SXXYY=MathSqrt(MathAbs((aPeriod*SumXX-SumX*SumX)*(aPeriod*SumYY-SumY*SumY)));
      if(SXXYY!=0.0){
         double SXY=aPeriod*SumXY-SumY*SumX; 
         aCorrelation=SXY/SXXYY;
         return(true);
      } 
   return(false);
}


void fObjDeleteByPrefix(string aPrefix){

   for(int i=ObjectsTotal()-1;i>=0;i--){
      if(StringFind(ObjectName(i),aPrefix,0)==0){
         ObjectDelete(ObjectName(i));
      }
   }
}


bool fDataUpdateFromListSCmnt(string aSymbol[],int aTimeFrame,int aAllFlag=0,int aMinBars=300){
   static bool tErr=false;   
   bool tRetVal=true;
   string CommentString="";   
      for(int ti=0;ti<ArraySize(aSymbol);ti++){
         if(!fDataUpdate(aSymbol[ti],aTimeFrame,aMinBars)){
            if(LS1==aSymbol[ti])LS1="";
            if(LS2==aSymbol[ti])LS2="";            
            tRetVal=false;
            tErr=true;
            CommentString=CommentString+aSymbol[ti]+" "+fTimeFrameName(aTimeFrame)+", ";
            Comment("Жду обновления данных "+StringSubstr(CommentString,0,StringLen(CommentString)-2)+"...");
               if(aAllFlag==0){
                  break;
               }            
         }
      }
      if(tErr){
         if(tRetVal){
            tErr=false;
            Comment("");
         }
      }      
   return(tRetVal);
}

bool fDataUpdate(string aSymbol,int aTimeFrame,int aMinBars=300){
   datetime daytimes[];
      if(iClose(aSymbol,aTimeFrame,0)==0){
         return(false);
      }
   ArrayCopySeries(daytimes,MODE_TIME,aSymbol,aTimeFrame);
      if(GetLastError()==4066){
         return(false);
      }
      if(iBars(aSymbol,aTimeFrame)<aMinBars){
         return(false);
      }
   return(true);      
}
string fTimeFrameName(int arg){
      if(arg==0){
         arg=Period();
      }
      switch(arg){
         case 0:
            return("0");
         case 1:
            return("M1");
         case 5:
            return("M5");                  
         case 15:
            return("M15");
         case 30:
            return("M30");             
         case 60:
            return("H1");
         case 240:
            return("H4");                  
         case 1440:
            return("D1");
         case 10080:
            return("W1");          
         case 43200:
            return("MN1");
         default:
            return("M"+arg);          
      }
}


int fSymbolSelect(){   
   int y=18;
   int sx=5;
   int x=sx;
   int ly;
   int cnt=0;
      for(int i=0;i<ArraySize(SC);i++){
            if(fGUI_PushButton(WindowExpertName()+"S_List_"+i,x,y,SC[i],0,ColorOf,7,Win,"Arial",false)){
               if(LastWidth==Width){
                  if(SS[i]){
                     SS[i]=false;
                  }
                  else{
                     SS[i]=true;
                  }
               }
            }
            if(SS[i]){
               fGUI_PushButton(WindowExpertName()+"S_List_"+i,x,y,SC[i],0,ColorOn,7,Win,"Arial",false);
               cnt++;
            }
         ly=y;
         x+=SymbolWidth;
            if(x+SymbolWidth*2>=Width){
               x=sx;
               y+=10;
            }
      }
   ArrayResize(WS,cnt);
   int k=0;
      for(i=0;i<ArraySize(SC);i++){
         if(SS[i]){
            WS[k]=SC[i];
            k++;
         }
      }
   return(ly);
}

int fTFSelect(){
   static int last=-1;
      if(last==-1){
         last=0;
            for(int i=0;i<TFC;i++){
               if(TF[i]==Period()){
                  last=i;
                  break;
               }
            }
      }
   int pushed=-1;      
      for(i=0;i<TFC;i++){
         if(fGUI_PushButton(WindowExpertName()+"TF_Option_"+i,110+20*i,4,TFN[i],0,ColorOf,7,Win,"Arial",false)){
            pushed=i;
         }
      }
      if(pushed!=-1){
         last=pushed;
      }
    fGUI_PushButton(WindowExpertName()+"TF_Option_"+last,110+20*last,4,TFN[last],0,ColorOn,7,Win,"Arial",false);
    return(TF[last]);
}

bool fGUI_PushButton(
                     string aObjectName,     // 1 имя
                     int aX,                 // 2 х
                     int aY,                 // 3 у
                     string aText,           // 4 текст
                     int aCorner=0,          // 5 угол   0  1
                                             //          2  3
                     color aColor=Red,       // 6 цвет
                     int aFontSize=8,        // 7 размер шрифта
                     int aWindowNumber=0,    // 8 окно
                     string aFont="Arial",   // 9 шрифт
                     bool aBack=false        // 10 фон
                  ){
      if(ObjectFind(aObjectName)==aWindowNumber){
         int tX=ObjectGet(aObjectName,OBJPROP_XDISTANCE);
         int tY=ObjectGet(aObjectName,OBJPROP_YDISTANCE);
            if(tX!=aX || tY!=aY){
               fObjLabel(aObjectName,aX,aY,aText,aCorner,aColor,aFontSize,aWindowNumber,aFont,aBack);
               tX=ObjectGet(aObjectName,OBJPROP_XDISTANCE);
               tY=ObjectGet(aObjectName,OBJPROP_YDISTANCE);
                  if(tX==aX && tY==aY){
                     ObjectDelete(aObjectName);
                     fObjLabel(aObjectName,aX,aY,aText,aCorner,aColor,aFontSize,aWindowNumber,aFont,aBack);
                     return(true);
                  }
            }
         fObjLabel(aObjectName,aX,aY,aText,aCorner,aColor,aFontSize,aWindowNumber,aFont,aBack);               
      }
      else{
         fObjLabel(aObjectName,aX,aY,aText,aCorner,aColor,aFontSize,aWindowNumber,aFont,aBack);
      }
   return(false);
}

void fObjLabel(
   string aObjectName,     // 1 имя
   int aX,                 // 2 х
   int aY,                 // 3 у
   string aText,           // 4 текст
   int aCorner=0,          // 5 угол   0  1
                           //          2  3
   color aColor=Red,       // 6 цвет
   int aFontSize=8,        // 7 размер шрифта
   int aWindowNumber=0,    // 8 окно
   string aFont="Arial",   // 9 шрифт
   bool aBack=false        // 10 фон
   ){     
      if(ObjectFind(aObjectName)!=aWindowNumber){
         ObjectCreate(aObjectName,OBJ_LABEL,aWindowNumber,0,0);
      }      
   ObjectSet(aObjectName,OBJPROP_XDISTANCE,aX);
   ObjectSet(aObjectName,OBJPROP_YDISTANCE,aY);   
   ObjectSetText(aObjectName,aText,aFontSize,aFont,aColor);
   ObjectSet(aObjectName,OBJPROP_BACK,aBack);
   ObjectSet(aObjectName,OBJPROP_CORNER,aCorner);   
}


int fSymbolsList(string & Symbols[], bool Selected){
   // Функция SymbolsList © http://www.mql4.com/ru/users/Ilnur
   string SymbolsFileName;
   int Offset, SymbolsNumber;
      if(Selected){
         SymbolsFileName="symbols.sel";
      }
      else{
         SymbolsFileName="symbols.raw";
      }
   // Открываем файл с описанием символов
   int hFile=FileOpenHistory(SymbolsFileName,FILE_BIN|FILE_READ);
   if(hFile<0)return(-1);
   // Определяем количество символов, зарегистрированных в файле
      if(Selected){
         SymbolsNumber=(FileSize(hFile)-4)/128;
         Offset=116;
      }
      else{
         SymbolsNumber=FileSize(hFile)/1936;
         Offset=1924;
      }
   ArrayResize(Symbols, SymbolsNumber);
   // Считываем символы из файла
      if(Selected){
         FileSeek(hFile, 4, SEEK_SET);
      }
      for(int i=0;i<SymbolsNumber;i++){
         Symbols[i]=FileReadString(hFile,12);
         FileSeek(hFile,Offset,SEEK_CUR);
      }
   FileClose(hFile);
   // Возвращаем количество считанных инструментов
   return(SymbolsNumber);
}

