//+------------------------------------------------------------------+
//|Saguaro.mq4                                              |
//|Programed by ME                                                   |
//+------------------------------------------------------------------+
#property copyright "Masha Inc."

#property indicator_chart_window

//---- extern inputs
//+------------------------------------------------------------------+
// extern string PairList1="AUDCAD,AUDCHF,AUDJPY,AUDNZD,AUDUSD,CADCHF,CADJPY,"+
//                         "CHFJPY,EURAUD,EURCAD,EURCHF,EURGBP,EURJPY,EURNZD";
// extern string PairList2 ="EURUSD,GBPAUD,GBPCAD,GBPCHF,GBPJPY,GBPNZD,GBPUSD";
// extern string PairList3 ="NZDCAD,NZDCHF,NZDJPY,NZDUSD,USDCAD,USDCHF,USDJPY";

extern string otherSymbol = "GBPUSD";
extern int Length_Calculation=50;
extern int Calculation_Interval = PERIOD_M30;
extern double Correlation_Limit = 90;
extern int yFirstRow=120;
extern int setCorner = 0;
extern color colorTitle         = clrSilver;
//+------------------------------------------------------------------+
extern string TimeFrameList="30, 1440";
int Price = PRICE_CLOSE;

#define IndicatorName "correlationMeter"

//---- buffers
string Pair[50];
int iTimeFrame[10];
double Corr1,Corr2;

//---- variables
string sIndicatorName;
string symbolA, symbolB;
datetime thisTime,oldTime;
string txtTFrame1, txtTFrame2, txtCalcInterval;

//---- Text parameters ----------------
int Corner_LeftUp  = 0;
int Corner_RightUp = 1;
int Corner_LeftDn  = 2;
int Corner_RightDn = 3;

//---- colors

color colorTime          = White;
color colorPlusIndi      = Green;
color colorMinusIndi     = Red;
color colorPlusSignal    = DeepSkyBlue;
color colorMinusSignal   = Magenta;
color colorNeutralSignal = SandyBrown;

color colorCorrOK  = Green;
color colorCorrNOK = Red;

//---- distances ----------------
int xText=80;
int xArrow=60;
int xValue1 = 40;
int xValue2 =  2;
// int yFirstRow=120;
int yStep=20;
int xx,yy;

int rowTextHeight=12;
int rowValueHeight=11;

//---- variables
int nTitles=50;
int NumberSymbols,NumberTimeFrames;
string SymbolSuffix;
int iWindow,iCorner;

int init()
{
    sIndicatorName=IndicatorName + " (" + symbolA + ", " + Length_Calculation + ") ";
    IndicatorShortName(sIndicatorName);
    IndicatorDigits(1);

//---- initialisations
    iWindow = 0;
    iCorner = setCorner;
   
//-- symbols
    SymbolSuffix = Get_SymbolSuffix(Symbol());
    NumberSymbols = 0;
    // Get_PairListNames(PairList1);
    // Get_PairListNames(PairList2);
    // Get_PairListNames(PairList3);
   
//-- time frames 
    NumberTimeFrames = 0;
    Get_TimeFrameListValues();
    txtTFrame1 = Get_sPeriod(iTimeFrame[1]);
    txtTFrame2 = Get_sPeriod(iTimeFrame[2]);
    txtCalcInterval = Get_sPeriod(Calculation_Interval);

   return(0);
}

int deinit()
{
    Delete_ObjectNames("corr_");
    return(0);
}

int start()
{
    int iBar = 0;
    symbolA = Symbol();
    symbolB = otherSymbol;

    thisTime = iTime(Symbol(), Calculation_Interval, 0);
    
    if (thisTime != oldTime)
    {
        oldTime = thisTime;                        
            
        double currentCorr1 = Get_Correlation(symbolA, symbolB, iBar, Length_Calculation, iTimeFrame[1]);
        double currentCorr2 = Get_Correlation(symbolA, symbolB, iBar, Length_Calculation, iTimeFrame[2]);
        
        Corr1 = currentCorr1;
        Corr2 = currentCorr2;
    
        Write_Correlations();
    }

    return(0);
}

double Get_Correlation(string symA,string symB,int iBar,int length,int timeFrame)
  {
//-- formula: http://en.wikipedia.org/wiki/Correlation_and_dependence
//-- Pearson correlation formula from: http://davidmlane.com/hyperstat/A51911.html
   double sumA,sumB,avgA,avgB;
   double corr2;
   int i;
   double arrayA[],arrayB[];
   ArrayResize(arrayA,Bars);
   ArrayResize(arrayB,Bars);
//###################################################################
//    SWINGMAN FORMULAS
//###################################################################
//---- initialize arrayA -----------------------------------------
   sumA=0;
   int nI=0;
   for(i=iBar; i<iBar+length; i++)
     {
      sumA+=iClose(symA,timeFrame,i);
      nI++;
     }
   avgA=sumA/length;

   if(avgA!=0)
      for(i=iBar; i<iBar+length; i++)
         arrayA[i]=(iClose(symA,timeFrame,i)-avgA);

   double X2=0;
   for(i=iBar; i<iBar+length; i++)
      X2+=arrayA[i]*arrayA[i];

//---- initialize arrayB -----------------------------------------
   sumB = 0;
   for(i=iBar; i<iBar+length; i++)
      sumB+=iClose(symB,timeFrame,i);
   avgB=sumB/length;

   if(avgB!=0)
      for(i=iBar; i<iBar+length; i++)
         arrayB[i]=(iClose(symB,timeFrame,i)-avgB);

   double Y2;
   for(i=iBar; i<iBar+length; i++)
      Y2+=arrayB[i]*arrayB[i];

//---- correlation -----------------------------------------------
   double sumXY=0;
   for(i=iBar; i<iBar+length; i++)
      sumXY+=(arrayA[i]) *(arrayB[i]);

   double val5=MathSqrt(X2*Y2);
   if(val5 != 0)
      corr2 = sumXY / val5;
//----   
   return(corr2*100);
  }
//####################################################################
//####################################################################
//####################################################################
//+------------------------------------------------------------------+
//| Get TimeFrame List Values
//+------------------------------------------------------------------+
void Get_TimeFrameListValues()
  {
   int i,j,k;
   string CurTimeFrame;
   NumberTimeFrames=0;

   for(i=0,j=0,k=1; i<nTitles && k>0;)
     {
      k=StringFind(TimeFrameList,",",j);
      if(k==0) CurTimeFrame=StringSubstr(TimeFrameList,j,0);
      else CurTimeFrame=StringSubstr(TimeFrameList,j,k-j);

      if(CurTimeFrame!="")
        {
         NumberTimeFrames++;
         iTimeFrame[NumberTimeFrames]=StrToInteger(CurTimeFrame);
        }
      i++;

      j=StringFind(TimeFrameList,",",j)+1;
      if(j==0) break;
     }
   return;
  }
//####################################################################
//+------------------------------------------------------------------+
//|      Get PairList Names
//+------------------------------------------------------------------+
void Get_PairListNames(string PairsList)
  {
   int i,j,k;
   string CurSymbol,CurSymbolSuff;
   double dClose;

   for(i=0,j=0,k=1; i<nTitles && k>0;)
     {
      k=StringFind(PairsList,",",j);
      if(k==0)
         CurSymbol=StringSubstr(PairsList,j,0);
      else CurSymbol=StringSubstr(PairsList,j,k-j);
      //---- set uppercase for the names in the extern parameter list
      CurSymbol=Set_SymbolUppercase(CurSymbol);
      if(CurSymbol!="") 
        {
         CurSymbolSuff=CurSymbol+SymbolSuffix;
         //---- 1. check if CurSymbolSuff is allowable ------------------
         //---- check suffix and current close
         if(SymbolSuffix!="")
           {
            //---- check if CurSymbol is allowable
            dClose=iClose(CurSymbolSuff,Period(),0);
            if(dClose>0.0) 
              {
               i++;
               NumberSymbols++;
               Pair[NumberSymbols]=CurSymbolSuff;
              }
            else
              {
               //---- check if CurSymbol is allowable
               dClose=iClose(CurSymbol,Period(),0);
               if(dClose>0.0) 
                 {
                  i++;
                  NumberSymbols++;
                  Pair[NumberSymbols]=CurSymbol;
                 }
              }
           }
         else
         //---- 2. check if CurSymbol is allowable ----------------------
         //---- check only current close
           {
            dClose=iClose(CurSymbol,Period(),0);
            if(dClose>0.0) 
              {
               i++;
               NumberSymbols++;
               Pair[NumberSymbols]=CurSymbol;
              }
           }
         j=StringFind(PairsList,",",j)+1;
         if(j==0) break;
        }
     }
   return;
  }

void Write_Correlations()
  {
   string name0,name1,name2;
   string text0,text1,text2;
   color  colr0,colr1,colr2;
//---- Titles ----------------------------------------------------
//--
   yy = yFirstRow;
   xx = xValue2;
   name0 = "corr_" + yy + "_" + xx;
   text0 = "Correlations " + symbolA;
   colr0 = colorTitle;
   SetLabelObject(name0,text0,colr0,xx,yy);
//--
/*
   yy=yy+yStep;
   name0 = "corr_" + yy + "_" + xx;
   text0 = Length_Calculation + "  Bars" + "; every " + txtCalcInterval;
   SetLabelObject(name0,text0,colr0,xx,yy);
//--
   yy=yy+yStep;
   name0 = "corr_" + yy + "_" + xx;
   text0 = "Last calc. bar: " + TimeToStr(thisTime,TIME_MINUTES);
   SetLabelObject(name0,text0,colr0,xx,yy);
*/
//--
   yy=yy+yStep;
   name1 = "corr_" + yy + "_" + xValue1;
   text1 = "["+txtTFrame1+"]";
   name2 = "corr_" + yy + "_" + xValue2;
   text2 = "["+txtTFrame2+"]";
//colr0 = Maroon;
   SetLabelObject(name1,text1,colr0,xValue1,yy);
   SetLabelObject(name2,text2,colr0,xValue2,yy);
   yy=yy+2;

//---- Correlations ----------------------------------------------
   
      yy=yy+yStep;
      //--      
      name0 = "corr_" + yy + "_" + xText;
      text0 = otherSymbol;
      colr0 = colorTitle;

      //-- correlation 1 ............................................
      name1="corr_"+yy+"_"+xValue1;
      if(Corr1>=99.999) 
        {
         text1 = "...  ";
         colr1 = colorTitle;
        }
      else
        {
         text1=DoubleToStr(Corr1,1);
         if(MathAbs(Corr1)<=Correlation_Limit)
            colr1 = colorCorrOK;
         else colr1 = colorCorrNOK;
        }
      //-- correlation 2 ............................................
      name2="corr_"+yy+"_"+xValue2;
      if(Corr2>=99.999) 
        {
         text2 = "...  ";
         colr2 = colorTitle;
        }
      else
        {
         text2=DoubleToStr(Corr2,1);
         if(MathAbs(Corr2)<=Correlation_Limit)
            colr2 = colorCorrOK;
         else colr2 = colorCorrNOK;
        }

      //-- write correlations .......................................
      //SetLabelObject(name0, text0, colr0, xText, yy);
      SetLabel_PairNamen(name0,text0,colr0,xText,yy-2);
      SetLabelObject(name1,text1,colr1,xValue1,yy);
      SetLabelObject(name2,text2,colr2,xValue2,yy);

   return;
  }
//#####################################################
//             OBJECTS
//#####################################################
//+------------------------------------------------------------------+
//| Set Label Object
//+------------------------------------------------------------------+
void SetLabelObject(string sName,string sText,color dColor,int x,int y)
  {
   ObjectDelete(sName);
   ObjectCreate(sName,OBJ_LABEL,iWindow,0,0);
//ObjectSetText(sName,sText,rowTextHeight, "Courier New", dColor);
   ObjectSetText(sName,sText,rowTextHeight,"Tahoma",dColor);
   ObjectSet(sName,OBJPROP_CORNER,iCorner);
   ObjectSet(sName,OBJPROP_XDISTANCE,x);
   ObjectSet(sName,OBJPROP_YDISTANCE,y);
   return;
  }
//+------------------------------------------------------------------+
//| Set Label Object Values
//+------------------------------------------------------------------+
void SetLabel_PairNamen(string sName,string sText,color dColor,int x,int y)
  {
   ObjectDelete(sName);
   ObjectCreate(sName,OBJ_LABEL,iWindow,0,0);
   ObjectSetText(sName,sText,rowValueHeight,"Tahoma",dColor);
//ObjectSetText(sName,sText,rowTextHeight, "Arial Bold", dColor);
   ObjectSet(sName,OBJPROP_CORNER,iCorner);
   ObjectSet(sName,OBJPROP_XDISTANCE,x);
   ObjectSet(sName,OBJPROP_YDISTANCE,y);
   return;
  }
//+------------------------------------------------------------------+
//| Set Arrow Object
//+------------------------------------------------------------------+
void SetArrowObject(string sName,int ArrowCode,int iHeight,color dColor,int x,int y)
  {
   ObjectDelete(sName);
   ObjectCreate(sName,OBJ_LABEL,iWindow,0,0);
   ObjectSetText(sName,CharToStr(ArrowCode),iHeight,"Wingdings",dColor);
   ObjectSet(sName,OBJPROP_CORNER,iCorner);
   ObjectSet(sName,OBJPROP_XDISTANCE,x);
   ObjectSet(sName,OBJPROP_YDISTANCE,y);
   return;
  }
//+------------------------------------------------------------------+
//| Delete Object Names
//+------------------------------------------------------------------+
void Delete_ObjectNames(string sName)
  {
   int nObjects=ObjectsTotal();
   for(int i=nObjects; i>=0; i--)
     {
      string sObjectName=ObjectName(i);
      if(StringFind(sObjectName,sName,0)!=-1)
         ObjectDelete(sObjectName);
     }
   return;
  }
//+------------------------------------------------------------------+
//    Get sPeriod
//+------------------------------------------------------------------+
string Get_sPeriod(int timeframe)
  {
   if(timeframe == PERIOD_M1) return("M1");
   if(timeframe == PERIOD_M5) return("M5");
   if(timeframe == PERIOD_M15) return("M15");
   if(timeframe == PERIOD_M30) return("M30");
   if(timeframe == PERIOD_H1) return("H1");
   if(timeframe == PERIOD_H4) return("H4");
   if(timeframe == PERIOD_D1) return("D1");
   if(timeframe == PERIOD_W1) return("W1");
   if(timeframe == PERIOD_MN1) return("MN1");
  }
//+------------------------------------------------------------------+
//    Get Symbol Suffix
//+------------------------------------------------------------------+
string Get_SymbolSuffix(string sSymbol)
  {
   int Len = StringLen(sSymbol);
   if(Len <= 6) return("");

   int iChar=StringGetChar(sSymbol,Len-1);

   string sChar="x";
   sChar=StringSetChar(sChar,0,iChar);

   string sSuffix=StringSubstr(sSymbol,6,Len-5);
   return(sSuffix);
  }
//+------------------------------------------------------------------+
//    Set Symbol Uppercase
//+------------------------------------------------------------------+
string Set_SymbolUppercase(string sText)
  {
   int Len=StringLen(sText);
   for(int i=0; i<Len; i++) 
     {
      if(i<6)
        {
         int iChar = StringGetChar(sText, i);
         if(iChar >= 97 && iChar <=122)
            sText=StringSetChar(sText,i,iChar-32);
        }
     }
   return(sText);
  }
//+------------------------------------------------------------------+
