//+------------------------------------------------------------------+
//|                                        Tradable Correlations.mq4 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, smjones"
#property link      "sjcoinc2000@yahoo.com"

#property indicator_chart_window


extern int     CorrelationPeriods = 50;
extern int     CorrelationTimeFrame = 1440;
extern double  PositiveAbove = 75;
extern double  NegativeBelow = -75;
extern int     FontSize = 12;
extern int     Columns = 4;
extern int     X_Spacing = 245;
extern int     Y_Spacing = 20;
extern color   PositiveColor = Aqua;
extern color   NegativeColor = Red;

extern int K = 100;
extern int D = 1;
extern int S = 1;

extern string     StochTimeFrame_notes = "============  Timeframe M1=1, M5=5, M15=15, H1=60, H4=240, D1=1440 =============";

extern int     StochTimeFrame = 5;

extern bool ShowCorelation=true;
extern bool ShowStochDiff=true;



datetime cor_once = 0;
string m="";
string s[13],temp_p[676],temp_n[676];
double c[13][13];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
      m = StringSubstr(Symbol(),6,StringLen(Symbol())-6);
      s[0]="EURUSD"+m;  s[1]="USDJPY"+m;  s[2]="GBPUSD"+m;  s[3]="USDCHF"+m;  s[4]="USDCAD"+m;
      s[5]="AUDUSD"+m;  s[6]="EURJPY"+m;  s[7]="CHFJPY"+m;   s[8]="NZDUSD"+m;
       s[9]="EURCHF"+m;  s[10]="GBPCHF"+m; 
      s[11]="GBPJPY"+m;  s[12]="EURCAD"+m; s[13]="EURAUD"+m; 
     
      
       
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
      Comment("");
      DeleteObject("Corr");
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
 
      
      string name_pos,name_neg;
      
      int cnt = ArraySize(temp_p),pos=0,neg=0;
      for(int ii=0;ii<cnt;ii++)
         {
            temp_p[ii] = "";
            temp_n[ii] = "";
         }
      
   if( cor_once != iTime(Symbol(),CorrelationTimeFrame,0) )
      {         
       cor_once = iTime(Symbol(),CorrelationTimeFrame,0);
       int count = ArraySize(s);
       for(int i=0;i<count;i++)
         {
            for(int n=0;n<count;n++)
               {
                  c[i][n]= 100*cp(s[i],s[n],CorrelationTimeFrame,CorrelationPeriods);
                  
                  double stoch1 = iStochastic(s[i],StochTimeFrame,K,D,S,0,0,0,0); 
    
                  double stoch2 = iStochastic(s[n],StochTimeFrame,K,D,S,0,0,0,0); 
                                    
                  if( c[i][n] >= PositiveAbove && c[i][n] < 99.99 )
                     {
                       // temp_p[pos]= s[i]+" | "+s[n]+"  "+DoubleToStr(c[i][n],0)+"   " +DoubleToStr(MathAbs(stoch1-stoch2),0)+" ";
                       
                        temp_p[pos]= s[i]+" | "+s[n]+"  ";
                       
                        if(ShowCorelation) temp_p[pos]= temp_p[pos]+"  "+DoubleToStr(c[i][n],0);
                        
                         if(ShowStochDiff) temp_p[pos]= temp_p[pos]+"  "+DoubleToStr(MathAbs(stoch1-stoch2),0)+" ";
                           
                        pos++;
                     }
                  if( c[i][n] <= NegativeBelow )
                     {
                       // temp_n[neg]= s[i]+" | "+s[n]+"  "+DoubleToStr(c[i][n],0) + "   "+DoubleToStr(MathAbs(stoch1-stoch2),0)+" ";
                       
                       temp_n[neg]= s[i]+" | "+s[n]+"  ";
                       
                        if(ShowCorelation) temp_n[neg]= temp_n[neg]+"  "+DoubleToStr(c[i][n],0);
                        
                         if(ShowStochDiff) temp_n[neg]= temp_n[neg]+"  "+DoubleToStr(MathAbs(stoch1-stoch2),0)+" ";
                        neg++;
                     }       
               }// end for n  
                         
         }//end for i
       
       DeleteObject("Corr");  
       int pcnt = ArrayResize(temp_p,pos+1), xspace=X_Spacing,yspace=Y_Spacing,xx=0,yy=0;  
       for( i=0;i<pcnt;i++ )
         {
            ObjectCreate("CorrPos"+DoubleToStr(i,0),OBJ_LABEL,0,0,0);
            ObjectSet("CorrPos"+DoubleToStr(i,0),OBJPROP_XDISTANCE,xx*xspace);
            ObjectSet("CorrPos"+DoubleToStr(i,0),OBJPROP_YDISTANCE,yy*yspace);
            ObjectSetText("CorrPos"+DoubleToStr(i,0), temp_p[i], FontSize, "Arial", PositiveColor);
            xx++;
            if ( xx==Columns ) 
               {
                  xx = 0;
                  yy++;
               }     
         } // end for i
         
       int ncnt = ArrayResize(temp_n,neg+1); 
       xx=0;yy++;yy++;  
       for( i=0;i<ncnt;i++ )
         {
            ObjectCreate("CorrNeg"+DoubleToStr(i,0),OBJ_LABEL,0,0,0);
            ObjectSet("CorrNeg"+DoubleToStr(i,0),OBJPROP_XDISTANCE,xx*xspace);
            ObjectSet("CorrNeg"+DoubleToStr(i,0),OBJPROP_YDISTANCE,yy*yspace);
            ObjectSetText("CorrNeg"+DoubleToStr(i,0), temp_n[i], FontSize, "Arial", NegativeColor);
            xx++;
            if ( xx==Columns ) 
               {
                  xx = 0;
                  yy++;
               }     
         } // end for i

        
      }//end if cor_once
                         

      return(0);
  }
//+------------------------------------------------------------------+

double   cp(string Symbol1,string Symbol2,int TimeFrame, int periods)
{
	//Comment( Symbol1,"  ",Symbol2,"  ",TimeFrame,"  ",periods);
	datetime closeTime1	= iTime(Symbol1,TimeFrame,0),
				closeTime2	= iTime(Symbol2,TimeFrame,0),
				closeTime	= MathMin(closeTime1,closeTime2);
	int		shift1		= iBarShift(Symbol1,TimeFrame,closeTime),
				shift2		= iBarShift(Symbol2,TimeFrame,closeTime);
	double	Co,
	         close1[],
				close2[];

	ArrayCopySeries(close1,MODE_CLOSE,Symbol1,TimeFrame);
	ArrayCopySeries(close2,MODE_CLOSE,Symbol2,TimeFrame);

	int bars = MathMin(ArraySize(close1)-shift1,ArraySize(close2)-shift2);
	if ( periods > 0 )
	     bars = periods;
   Co = Correlation(close1,close2,shift1,shift2,bars);
   
   return(Co);
}



//+------------------------------------------------------------------+
//| Correlation Coefficient R														|
//+------------------------------------------------------------------+
double Correlation(double x[], double y[], int x_shift = 0, int y_shift = 0, int count = -1)
{
	int n = MathMin(ArraySize(x)-x_shift,ArraySize(y)-y_shift);
	if(n>count && count>0)
		n=count;
	if(n<2)
		return(-2);

	double	sum_sq_x,
				sum_sq_y,
				sum_coproduct,
				mean_x = x[x_shift],
				mean_y = y[y_shift];

	for(int i = 0; i < n; i++)
	{
		double	sweep = i / (i+1.0),
					delta_x = x[i+x_shift] - mean_x,
					delta_y = y[i+y_shift] - mean_y;

		sum_sq_x += delta_x*delta_x * sweep;
		sum_sq_y += delta_y*delta_y * sweep;
    	sum_coproduct += delta_x*delta_y * sweep;
    	mean_x += delta_x / (i+1.0);
    	mean_y += delta_y / (i+1.0);
	}

	double	pop_sd_x = MathSqrt(sum_sq_x/n),
				pop_sd_y = MathSqrt(sum_sq_y/n),
				cov_x_y = sum_coproduct / n;

	if(pop_sd_x*pop_sd_y != 0.0)
		return(cov_x_y / (pop_sd_x*pop_sd_y));

	return(-3);
}

void DeleteObject(string char4)
   {
      string name;      
      int obj = ObjectsTotal();
      for ( int n=obj;n > 0 ;n--)
         {
            name = ObjectName(n);
            char4 = StringSubstr(name,0,4);
            if ( char4 == "Corr" )
               ObjectDelete(name);   
         }
      return;
   }           
         