//+------------------------------------------------------------------+
//|                                           FXCorrelator.mq4       |
//|                                           Copyright © 2009,      |
//|                                                                  |
//+------------------------------------------------------------------+
//
// //

#include <WinUser32.mqh> 


#property copyright "Triple Corrie"
#property link      ""

#property indicator_separate_window


// Timer
#define TIMERNAME "secsUsed_secsInBar"

#property indicator_buffers 8

#property indicator_color1 Blue
#property indicator_color2 Red
#property indicator_color3 Orange
#property indicator_color4 Gray
#property indicator_color5 Yellow
#property indicator_color6 Turquoise
#property indicator_color7 Brown
#property indicator_color8 Lime


#property indicator_level1 0.0

// index buffers for drawing
double Idx[],Idx1[],Idx2[],Idx3[],Idx4[],Idx5[],Idx6[],Idx7[];

extern int PerAvr=60,Delta=1;


extern bool ShowChart=true;
extern bool ShowEUR=true;
extern bool ShowGBP=true;
extern bool ShowAUD=true;
extern bool ShowCHF=true;
extern bool ShowJPY=true;
extern bool ShowNZD=true;
extern bool ShowCAD=true;
extern bool ShowUSD=true;

extern string SymbolSuffix="";

extern bool ShowTable=true;
extern int ShowChartLines=3;
extern int intTimePeriod_1=5;
extern int intTimePeriod_2=60;
extern int intTimePeriod_3=240;

// Timer
extern bool ShowTimer = false;
extern int TimerTextSize = 14;
extern color TimerColor = Yellow;
extern int TimerDisplayCorner = 1;   //TOP RIGHT CORNER
extern int TimerDisplayXaxis = 5;   //X-axis distance object property in pixels
extern int TimerDisplayYaxis = 20;    //Y-axis distance object property in pixels	
extern int TimerWindow = 1;

// currency rates for calculation
double EUR,GBP,AUD,CHF,JPY,NZD,CAD,USD,A1,A2,A3,A4,A5,A6,A7;

// Currency names and colors                                         
string Currencies[] = {
                        "USD1","JPY1","AUD1","CHF1","GBP1","NZD1","CAD1","EUR1",
                        "USD2","JPY2","AUD2","CHF2","GBP2","NZD2","CAD2","EUR2",
                        "USD3","JPY3","AUD3","CHF3","GBP3","NZD3","CAD3","EUR3"
                      };
                                     
int Colors[] = {
                  Lime, Yellow, Orange, Gray, Red, Turquoise, Brown, Blue,
                  Lime, Yellow, Orange, Gray, Red, Turquoise, Brown, Blue,
                  Lime, Yellow, Orange, Gray, Red, Turquoise, Brown, Blue,                               
               };

// house keeping
string ShortName;
bool ObjectsCreated = false;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{  
  
   // Set name to be displayed
   //ShortName = "FXCORR("+PerAvr+"/"+Delta+" - M"+intTimePeriod_1+", M"+intTimePeriod_2+", M"+intTimePeriod_3+")";
   //IndicatorShortName(ShortName);
   
   SetIndexBuffer(0,Idx);
   SetIndexBuffer(1,Idx1);
   SetIndexBuffer(2,Idx2);
   SetIndexBuffer(3,Idx3);
   SetIndexBuffer(4,Idx4);
   SetIndexBuffer(5,Idx5);
   SetIndexBuffer(6,Idx6);
   SetIndexBuffer(7,Idx7);
   
   SetIndexStyle(0, DRAW_LINE, EMPTY, 2);
   SetIndexStyle(1, DRAW_LINE, EMPTY, 2);
   SetIndexStyle(2, DRAW_LINE, EMPTY, 2);
   SetIndexStyle(3, DRAW_LINE, EMPTY, 2);
   SetIndexStyle(4, DRAW_LINE, EMPTY, 2);
   SetIndexStyle(5, DRAW_LINE, EMPTY, 2);
   SetIndexStyle(6, DRAW_LINE, EMPTY, 2);
   SetIndexStyle(7, DRAW_LINE, EMPTY, 2);
   
   /////////////////////////////////////////////////////////////
   // Timer
   ////////////////////////////////////////////////////////////
   ObjectDelete(TIMERNAME);   
   if (ShowTimer)
   {
	   ObjectCreate(TIMERNAME, OBJ_LABEL, TimerWindow,0,0);
	   ObjectSet(TIMERNAME,OBJPROP_CORNER,TimerDisplayCorner);	
	   ObjectSet(TIMERNAME,OBJPROP_XDISTANCE,TimerDisplayYaxis);	
	   ObjectSet(TIMERNAME,OBJPROP_YDISTANCE,TimerDisplayYaxis);	
	}
   return(0);
}

//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
{
   // delete all objects we created
   ObjectsDeleteAll(WindowFind(ShortName)); 
   //ObjectDelete(TIMERNAME);  
   return(0);
}


//+-------------------------------------------------------------------+
//| Create all text labels (colored names of the displayed currencies)|
//+-------------------------------------------------------------------+
void CreateObjects( int intTimePeriod_1, int intTimePeriod_2, int TimePeriod_3)
{      


   if (ShowTable)
   {
      int window = WindowFind(ShortName);
               
      if (ShowChartLines < 0 || ShowChartLines > 3)
      {
         ShowChartLines = 3;
      }
      
      //////////////////////////////////////////
      // Draw titles
      //////////////////////////////////////////

      if (ShowChartLines ==1)
      {
         // Line 1 - First column
         ObjectCreate("obj_tm1",OBJ_LABEL,window,0,0);   
         ObjectSetText("obj_tm1","M"+intTimePeriod_1,8,"Arial");
         ObjectSet("obj_tm1",OBJPROP_COLOR,White);
         ObjectSet("obj_tm1",OBJPROP_XDISTANCE,4);
         ObjectSet("obj_tm1",OBJPROP_YDISTANCE,38);
      }
      
      if (ShowChartLines==2)
      {               
         // Line 1 - First column
         ObjectCreate("obj_tm1",OBJ_LABEL,window,0,0);   
         ObjectSetText("obj_tm1","M"+intTimePeriod_1,8,"Arial");
         ObjectSet("obj_tm1",OBJPROP_COLOR,White);
         ObjectSet("obj_tm1",OBJPROP_XDISTANCE,4);
         ObjectSet("obj_tm1",OBJPROP_YDISTANCE,38);      
         
         // Line 2 - First column  
         ObjectCreate("obj_tm2",OBJ_LABEL,window,0,0);
         ObjectSetText("obj_tm2","M"+intTimePeriod_2,8,"Arial");
         ObjectSet("obj_tm2",OBJPROP_COLOR,White);
         ObjectSet("obj_tm2",OBJPROP_XDISTANCE,4);
         ObjectSet("obj_tm2",OBJPROP_YDISTANCE,58);
      }

      if (ShowChartLines ==3 )
      {           
         // Line 1 - First column
         ObjectCreate("obj_tm1",OBJ_LABEL,window,0,0);   
         ObjectSetText("obj_tm1","M"+intTimePeriod_1,8,"Arial");
         ObjectSet("obj_tm1",OBJPROP_COLOR,White);
         ObjectSet("obj_tm1",OBJPROP_XDISTANCE,4);
         ObjectSet("obj_tm1",OBJPROP_YDISTANCE,38);   
                     
         // Line 2 - First column  
         ObjectCreate("obj_tm2",OBJ_LABEL,window,0,0);
         ObjectSetText("obj_tm2","M"+intTimePeriod_2,8,"Arial");
         ObjectSet("obj_tm2",OBJPROP_COLOR,White);
         ObjectSet("obj_tm2",OBJPROP_XDISTANCE,4);
         ObjectSet("obj_tm2",OBJPROP_YDISTANCE,58);   
                
         // Line 3 - First column     
         ObjectCreate("obj_tm3",OBJ_LABEL,window,0,0);
         ObjectSetText("obj_tm3","M"+TimePeriod_3,8,"Arial");
         ObjectSet("obj_tm3",OBJPROP_COLOR,White);
         ObjectSet("obj_tm3",OBJPROP_XDISTANCE,4);
         ObjectSet("obj_tm3",OBJPROP_YDISTANCE,78);
      }   
      
      // create all labels
      string Titles[] = {"USD","JPY","AUD","CHF","GBP","NZD","CAD","EUR",};
      int xStart = 35;
      int xIncrement = 30;
      int i;
      int yStart = 20;
      int yIncrement = 0;
   
      // start and increment of Y coordinates

      yIncrement = 0;
      
      if (ShowChartLines >= 0 )
      {                 
         for(  i = 0; i < 8; i++ )
         {
               ObjectCreate("obj_"+Titles[i],OBJ_LABEL,window,0,0);
               ObjectSetText("obj_"+Titles[i],Titles[i],8);
               ObjectSet("obj_"+Titles[i],OBJPROP_COLOR,Colors[i]);
               ObjectSet("obj_"+Titles[i],OBJPROP_XDISTANCE,xStart);
               ObjectSet("obj_"+Titles[i],OBJPROP_YDISTANCE,yStart);

            xStart += xIncrement;
            yStart += yIncrement;
         }
      }
      ////////////////////////////////////////////////////////////////////////
      //   LINE-1
      ////////////////////////////////////////////////////////////////////////  
      // start and increment of X coordinates
   
      xStart = 38;
      xIncrement = 30;
   
   
      // start and increment of Y coordinates
      yStart = 35;
      yIncrement = 0;
  
      // create arrows
      for( i = 0; i < 8; i++ )
      {
            ObjectCreate("obj_arr_"+Currencies[i],OBJ_LABEL,window,0,0);
            ObjectSetText("obj_arr_"+Currencies[i],"",14,"Wingdings");
            ObjectSet("obj_arr_"+Currencies[i],OBJPROP_COLOR,Colors[i]);
            ObjectSet("obj_arr_"+Currencies[i],OBJPROP_XDISTANCE,xStart);
            ObjectSet("obj_arr_"+Currencies[i],OBJPROP_YDISTANCE,yStart);

         xStart += xIncrement;
         yStart += yIncrement;
      }

      //////////////////////////////////////////////////////////////////////////
      //   LINE-2
      //////////////////////////////////////////////////////////////////////// 
        
      xStart = 38;
      xIncrement = 30;
   
      // start and increment of Y coordinates
      yStart = 55;
      yIncrement = 0;   

      // create arrows
      for( i = 8; i < 16; i++ )
      {
            ObjectCreate("obj_arr_"+Currencies[i],OBJ_LABEL,window,0,0);
            ObjectSetText("obj_arr_"+Currencies[i],"",14,"Wingdings");
            ObjectSet("obj_arr_"+Currencies[i],OBJPROP_COLOR,Colors[i]);
            ObjectSet("obj_arr_"+Currencies[i],OBJPROP_XDISTANCE,xStart);
            ObjectSet("obj_arr_"+Currencies[i],OBJPROP_YDISTANCE,yStart);

         xStart += xIncrement;
         yStart += yIncrement;
      }

      ////////////////////////////////////////////////////////////////////////
      //   LINE-3
      //////////////////////////////////////////////////////////////////////// 
  
      xStart = 38;
      xIncrement = 30;
   
      // start and increment of Y coordinates
      yStart = 75;
      yIncrement = 0;
   
      // create arrows
      for( i = 16; i < 24; i++ )
      {
            ObjectCreate("obj_arr_"+Currencies[i],OBJ_LABEL,window,0,0);
            ObjectSetText("obj_arr_"+Currencies[i],"",14,"Wingdings");
            ObjectSet("obj_arr_"+Currencies[i],OBJPROP_COLOR,Colors[i]);
            ObjectSet("obj_arr_"+Currencies[i],OBJPROP_XDISTANCE,xStart);
            ObjectSet("obj_arr_"+Currencies[i],OBJPROP_YDISTANCE,yStart);

         xStart += xIncrement;
         yStart += yIncrement;
      }
   }
}


void CheckTimerPeriod()
{
   ////////////////////////////////////////////////////
   // Input check
   ////////////////////////////////////////////////////
      
   if ( (intTimePeriod_1 != 1) && (intTimePeriod_1 != 5) && (intTimePeriod_1 != 15)&& (intTimePeriod_1 != 30)&& (intTimePeriod_1 != 60)&& (intTimePeriod_1 != 240))
   {
      Alert("ERROR, M", intTimePeriod_1, " not allowed, defaulting to M5");
      intTimePeriod_1 = 5;       
   }
   
   if ( (intTimePeriod_2 != 1) && (intTimePeriod_2 != 5) && (intTimePeriod_2 != 15)&& (intTimePeriod_2 != 30)&& (intTimePeriod_2 != 60)&& (intTimePeriod_2 != 240))
   {
      Alert("ERROR, M", intTimePeriod_2, " not allowed, defaulting to M15");
      intTimePeriod_2 = 15;        
   }
   
   if ( (intTimePeriod_3 != 1) && (intTimePeriod_3 != 5) && (intTimePeriod_3 != 15)&& (intTimePeriod_3 != 30)&& (intTimePeriod_3 != 60)&& (intTimePeriod_3 != 240))
   {
      Alert("ERROR, M", intTimePeriod_3, " not allowed, defaulting to M60");
      intTimePeriod_3 = 60;        
   }
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{  

   CheckTimerPeriod();
   
   ShortName = "Triple Corrie ("+PerAvr+"/"+Delta+" - M"+intTimePeriod_1+", M"+intTimePeriod_2+", M"+intTimePeriod_3+")";
   IndicatorShortName(ShortName);  

   // only create objects here, window handle is not valid in init()  
   if ( !ObjectsCreated )
   {
      CreateObjects(intTimePeriod_1, intTimePeriod_2, intTimePeriod_3);
      ObjectsCreated = true;
   }
   
   
   if (ShowTable)
   {
      if (ShowChartLines ==1)
      {
         DrawTable(intTimePeriod_1, 1);      
      }
      
      if (ShowChartLines==2)
      {
         DrawTable(intTimePeriod_1, 1);
         DrawTable(intTimePeriod_2, 2);      
      }

      if (ShowChartLines==3)
      {
         DrawTable(intTimePeriod_1, 1);
         DrawTable(intTimePeriod_2, 2);      
         DrawTable(intTimePeriod_3, 3);           
      }   
   }
   
   if (ShowChart)
   {
      DrawChart();
   }
   
   if (ShowTimer)
   {
      DrawTimer();
   }
     
   return(0);
}


/////////////////////////////////////////////
// Draw the Timer
////////////////////////////////////////////

void DrawTimer()
{   
   
   if (ShowTimer)
   {
      string txtTmp;
      double i;
      int m,s,k;
      m=Time[0]+Period()*60-CurTime();
      i=m/60.0;
      s=m%60;
      m=(m-m%60)/60;  
   
      string strSec = s;
      if (StringLen(strSec) == 1)   
      {
         strSec = "0" + strSec;
      }
   
      string strMin = m;
      if (StringLen(strMin) == 1)   
      {
         strMin = "0" + strMin;
      }
   
       txtTmp = StringConcatenate(strMin,":",strSec);   
         
      ObjectSetText(TIMERNAME,txtTmp,TimerTextSize,"Arial",TimerColor);	   
      //Comment( m + " minutes " + s + " seconds left to bar end");   
   }

   return(0);
}

////////////////////////////////////////////////
// Draw the main chart 
/////////////////////////////////////////////////

void DrawChart()
{

   int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
   int limit=Bars-counted_bars;
   
   for(int i=limit; i>=0; i--)    
   {
      A1=(iMA("EURUSD"+SymbolSuffix,0,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i)-iMA("EURUSD"+SymbolSuffix,0,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i+Delta))/1;      
      A2=(iMA("GBPUSD"+SymbolSuffix,0,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i)-iMA("GBPUSD"+SymbolSuffix,0,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i+Delta))/1; 
      A3=(iMA("AUDUSD"+SymbolSuffix,0,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i)-iMA("AUDUSD"+SymbolSuffix,0,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i+Delta))/1; 
      A4=(iMA("USDCHF"+SymbolSuffix,0,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i+Delta)-iMA("USDCHF"+SymbolSuffix,0,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i))/1;
      A5=(iMA("USDJPY"+SymbolSuffix,0,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i+Delta)-iMA("USDJPY"+SymbolSuffix,0,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i))/100; 
      A6=(iMA("NZDUSD"+SymbolSuffix,0,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i)-iMA("NZDUSD"+SymbolSuffix,0,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i+Delta))/1;      
      A7=(iMA("USDCAD"+SymbolSuffix,0,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i+Delta)-iMA("USDCAD"+SymbolSuffix,0,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i))/1;

      USD=-(A1+A2+A3+A4+A5+A6+A7)/7;
      EUR=A1-(A2+A3+A4+A5+A6+A7)/6;
      GBP=A2-(A1+A3+A4+A5+A6+A7)/6;
      AUD=A3-(A1+A2+A4+A5+A6+A7)/6;     
      CHF=A4-(A1+A2+A3+A5+A6+A7)/6;  
      JPY=A5-(A1+A2+A3+A4+A6+A7)/6;
      NZD=A6-(A1+A2+A3+A4+A5+A7)/6;
      CAD=A7-(A1+A2+A3+A4+A5+A6)/6;
             
      if ( ShowEUR )
         Idx[i] = EUR; 
         
      if ( ShowGBP )
         Idx1[i] = GBP;
      
      if ( ShowAUD )
         Idx2[i] = AUD;
         
      if ( ShowCHF )
         Idx3[i] = CHF;
      
      if ( ShowJPY )
         Idx4[i] = JPY;
      
      if ( ShowNZD )
         Idx5[i] = NZD;
      
      if ( ShowCAD )
         Idx6[i] = CAD;
      
      if ( ShowUSD )
         Idx7[i] = USD;
   }
   
   /////////////////////////////////
   // Shows the direction of the last chart period 
   // Can't find a use for it!
   //////////////////////////////////////////////
   /*
   string tmp = "";   
   if (Idx[0] < Idx[1]){ tmp = tmp + "EUR Down, ";} else {tmp = tmp + "EUR Up, "; }  
   if (Idx1[0] < Idx1[1]){tmp = tmp + "GBP Down, ";} else {tmp = tmp + "GBP Up, "; }
   if (Idx2[0] < Idx2[1]){tmp = tmp + "AUD Down, ";} else {tmp = tmp + "AUD Up, "; }
   if (Idx3[0] < Idx3[1]){tmp = tmp + "CHF Down, ";} else {tmp = tmp + "CHF Up, "; } 
   if (Idx4[0] < Idx4[1]){tmp = tmp + "JPY Down, ";} else {tmp = tmp + "JPY Up, "; }  
   if (Idx5[0] < Idx5[1]){tmp = tmp + "NZD Down, ";} else {tmp = tmp + "NZD Up, "; } 
   if (Idx6[0] < Idx6[1]){tmp = tmp + "CAD Down, ";} else {tmp = tmp + "CAD Up, "; } 
   if (Idx7[0] < Idx7[1]){tmp = tmp + "USD Down, ";} else {tmp = tmp + "USD Up, "; }
   Comment(tmp);
   */
   ////////////////////////////////////////
}

void DrawTable(int intTimePeriod, int x)
{
   int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
   int limit=Bars-counted_bars;

   for(int i=limit; i>=0; i--)    
   {
      A1=(iMA("EURUSD"+SymbolSuffix,intTimePeriod,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i)       -iMA("EURUSD"+SymbolSuffix,intTimePeriod,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i+Delta))/1; 
      A2=(iMA("GBPUSD"+SymbolSuffix,intTimePeriod,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i)       -iMA("GBPUSD"+SymbolSuffix,intTimePeriod,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i+Delta))/1; 
      A3=(iMA("AUDUSD"+SymbolSuffix,intTimePeriod,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i)       -iMA("AUDUSD"+SymbolSuffix,intTimePeriod,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i+Delta))/1; 
      A4=(iMA("USDCHF"+SymbolSuffix,intTimePeriod,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i+Delta) -iMA("USDCHF"+SymbolSuffix,intTimePeriod,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i))/1;
      A5=(iMA("USDJPY"+SymbolSuffix,intTimePeriod,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i+Delta) -iMA("USDJPY"+SymbolSuffix,intTimePeriod,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i))/100; 
      A6=(iMA("NZDUSD"+SymbolSuffix,intTimePeriod,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i)       -iMA("NZDUSD"+SymbolSuffix,intTimePeriod,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i+Delta))/1;
      A7=(iMA("USDCAD"+SymbolSuffix,intTimePeriod,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i+Delta) -iMA("USDCAD"+SymbolSuffix,intTimePeriod,PerAvr,0,MODE_LWMA,PRICE_CLOSE,i))/1;
   
      USD=-(A1+A2+A3+A4+A5+A6+A7)/7;
      EUR=A1-(A2+A3+A4+A5+A6+A7)/6;
      GBP=A2-(A1+A3+A4+A5+A6+A7)/6;
      AUD=A3-(A1+A2+A4+A5+A6+A7)/6;     
      CHF=A4-(A1+A2+A3+A5+A6+A7)/6;  
      JPY=A5-(A1+A2+A3+A4+A6+A7)/6;
      NZD=A6-(A1+A2+A3+A4+A5+A7)/6;
      CAD=A7-(A1+A2+A3+A4+A5+A6)/6;
          
      ArrowDirection("EUR"+x, EUR);
      ArrowDirection("GBP"+x, GBP);
      ArrowDirection("AUD"+x, AUD);
      ArrowDirection("CHF"+x, CHF);
      ArrowDirection("JPY"+x, JPY);
      ArrowDirection("NZD"+x, NZD);
      ArrowDirection("CAD"+x, CAD);
      ArrowDirection("USD"+x, USD);
   }     
}

//+-------------------------------------------------------------------+
//| Arrow Direction based on their value (using WIngdings font)       |
//+-------------------------------------------------------------------+
void ArrowDirection(string currency, double value) 
{
   if(value>0)  { ObjectSetText("obj_arr_"+currency,"á ",14,"Wingdings"); }
   
   if(value<0)  { ObjectSetText("obj_arr_"+currency,"â ",14,"Wingdings"); }
   
   if(value==0) { ObjectSetText("obj_arr_"+currency,"ô ",14,"Wingdings"); } 
}
//+------------------------------------------------------------------+ 


