//+------------------------------------------------------------------+
//|                                                         CCFp.mq4 |
//|                                              SemSemFX@rambler.ru |
//|              http://onix-trade.net/forum/index.php?showtopic=107 |
//+------------------------------------------------------------------+
#property copyright "SemSemFX@rambler.ru"
#property link      "http://onix-trade.net/forum/index.php?showtopic=107"
//---
#include <stderror.mqh>
#include <stdlib.mqh>
#include <WinUser32.mqh>
//----
string Indicator_Name = "CL1i: ";
//----
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_level1  0
#property indicator_levelcolor Red

#property indicator_color1  White
//---
extern int Style = DRAW_LINE; // DRAW_HISTOGRAM
extern int   History = 1440; // в минутах это сутки
extern int   MA_Method = MODE_SMA;
extern int   Price = PRICE_WEIGHTED;
extern int   Fast = 14;
extern color Color_CL1i     = White;
extern int   Line_Thickness = 1;
//----
double arrCL1i[];

//---
string CV     [8] = {"EUR","GBP","AUD","NZD","CAD","CHF","JPY","USD"};
double CV_value[8];
int CV_l_i;
int CV_r_i;
//---
string S [28]=
{
"EURUSD", // EURUSD        0    0
"GBPUSD", // GBPUSD        1    1
"AUDUSD", // AUDUSD        2    2
"NZDUSD", // NZDUSD        3    3
"USDCAD", // USDCAD        4    4
"USDCHF", // USDCHF        5    5
"USDJPY", // USDJPY        6    6

"EURGBP", // EURUSD/GBPUSD 7    0/1
"EURAUD", // EURUSD/AUDUSD 8    0/2
"EURNZD", // EURUSD/NZDUSD 9    0/3
"EURCAD", // EURUSD*USDCAD 10   0*4
"EURCHF", // EURUSD*USDCHF 11   0*5
"EURJPY", // EURUSD*USDJPY 12   0*6

"GBPAUD", // GBPUSD/AUDUSD 13   1/2
"GBPNZD", // GBPUSD/NZDUSD 14   1/3 
"GBPCAD", // GBPUSD*USDCAD 15   1*4
"GBPCHF", // GBPUSD*USDCHF 16   1*5
"GBPJPY", // GBPUSD*USDJPY 17   1*6

"AUDNZD", // AUDUSD/NZDUSD 18   2/3
"AUDCAD", // AUDUSD*USDCAD 19   2*4
"AUDCHF", // AUDUSD*USDCHF 20   2*5
"AUDJPY", // AUDUSD*USDJPY 21   2*6

"NZDCAD", // NZDUSD*USDCAD 22   3*4
"NZDCHF", // NZDUSD*USDCHF 23   3*5
"NZDJPY", // NZDUSD*USDJPY 24   3*6


"CADCHF", // USDCHF/USDCAD 25   5/4
"CADJPY", // USDJPY/USDCAD 26   6/4

"CHFJPY"  // USDJPY/USDCHF 27   6/5
};
//---
double S_curr_v[28];
double S_prev_v[28];
double S_move;
//---
int    SD[28];
double SP[28];
//---
string SL[28] =
{"EUR","GBP","AUD","NZD","USD","USD","USD","EUR","EUR","EUR","EUR","EUR","EUR","GBP","GBP","GBP","GBP","GBP",
 "AUD","AUD","AUD","AUD","NZD","NZD","NZD","CAD","CAD","CHF"};   

string SR[28] = 
{"USD","USD","USD","USD","CAD","CHF","JPY","GBP","AUD","NZD","CAD","CHF","JPY","AUD","NZD","CAD","CHF","JPY",
 "NZD","CAD","CHF","JPY","CAD","CHF","JPY","CHF","JPY","JPY"};   
int i,j,k,Counted_bars;
double dv;
string sv;
int    last_error;
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
//--------------------------------------------------------------------
int start()                          
  {
//--------------------------------------------------------------------
   Counted_bars = IndicatorCounted(); // Количество просчитанных баров 
   i = Bars - Counted_bars - 1;       // Индекс первого непосчитанного
   if (i > History-1)                 // Если много баров то ..
      i = History-1;                  // ..рассчитывать заданное колич.
//***     Print("Counted_bars1= ",Counted_bars," i=",i);
//-----------------------------------------------------------------------      
   while(i >= 0)                      // Цикл по непосчитанным барам
   {
//---
//***     Print("Counted_bars2= ",Counted_bars," i=",i); ED_Kaiser_LPF iCustom(Symbol(),0,"CL1i",1440,MODE_SMA,PRICE_WEIGHTED,14,White,2,0,0);
     for (k = 0; k <= 6; k++)
     {
       last_error = 1;
       while (last_error != 0)
       {
        S_curr_v[k] = iMA(S[k],Period(),Fast,0,MA_Method,Price,i+0); last_error = GetLastError();
//***         sv = StringConcatenate("start():",i," iMA(",S[k],"= ",NormalizeDouble(S_curr_v[k],SD[k]),","," TimeFrame =",Period()," Period=",Fast," ma_metod=",MA_Method," applied_price=",Price,
//***                              " shift=",i,")"," возвратила код ошибки:", last_error,"-",ErrorDescription(last_error));
//***         Print(sv);
       } // while (last_error != 0) конец цикла 
//---       
       last_error = 1;
       while (last_error != 0)
       {
       
        S_prev_v[k] = iMA(S[k],Period(),Fast,0,MA_Method,Price,i+1); last_error = GetLastError();
//***         sv = StringConcatenate("start():",i," iMA(",S[k],"= ",NormalizeDouble(S_prev_v[k],SD[k]),","," TimeFrame =",Period()," Period=",Fast," ma_metod=",MA_Method," applied_price=",Price,
//***                              " shift=",i+1,")"," возвратила код ошибки:", last_error,"-",ErrorDescription(last_error));
//***         Print(sv);
       } // while (last_error != 0) конец цикла 
     } // for (k = 0; k <= 6; k++) конец цикла 
//***     Print("S_cross()");
     S_cross();
//---    
     ArrayInitialize(CV_value, 0);
//---
     for (k = 0; k <= 27; k++)
     {
       S_move   = NormalizeDouble(S_curr_v[k]/S_prev_v[k],SD[k]);
       S_move   = NormalizeDouble(S_move -1,SD[k]);
       S_move   = NormalizeDouble(S_move/SP[k],0);
       for (j = 0; j <= 7; j++)
       {
        if (SL[k] == CV[j]) CV_value[j] += S_move;
        if (SR[k] == CV[j]) CV_value[j] -= S_move;        
       }        
     } // конец цикла for (k = 0; k <= 27; k++)
//---     
     arrCL1i[i] = (CV_value[CV_l_i]-CV_value[CV_r_i]);        
//---           
      i--;                          // Расчёт индекса следующего бара
   }  // конец цикла while(i >= 0) 
//--------------------------------------------------------------------
   return;                          // Выход из спец. ф-ии start()
  }
//--------------------------------------------------------------------
void S_cross()
{
 S_curr_v[7]  = S_curr_v[0]/S_curr_v[1];
 S_curr_v[8]  = S_curr_v[0]/S_curr_v[2];
 S_curr_v[9]  = S_curr_v[0]/S_curr_v[3]; 
 S_curr_v[10] = S_curr_v[0]*S_curr_v[4];  
 S_curr_v[11] = S_curr_v[0]*S_curr_v[5];  
 S_curr_v[12] = S_curr_v[0]*S_curr_v[6]; 
 
 S_curr_v[13] = S_curr_v[1]/S_curr_v[2];  
 S_curr_v[14] = S_curr_v[1]/S_curr_v[3];
 S_curr_v[15] = S_curr_v[1]*S_curr_v[4];
 S_curr_v[16] = S_curr_v[1]*S_curr_v[5]; 
 S_curr_v[17] = S_curr_v[1]*S_curr_v[6];  
 
 S_curr_v[18] = S_curr_v[2]/S_curr_v[3];  
 S_curr_v[19] = S_curr_v[2]*S_curr_v[4]; 
 S_curr_v[20] = S_curr_v[2]*S_curr_v[5];  
 S_curr_v[21] = S_curr_v[2]*S_curr_v[6];
 
 S_curr_v[22] = S_curr_v[3]*S_curr_v[4];
 S_curr_v[23] = S_curr_v[3]*S_curr_v[5]; 
 S_curr_v[24] = S_curr_v[3]*S_curr_v[6];  
 
 S_curr_v[25] = S_curr_v[5]/S_curr_v[4];  
 S_curr_v[26] = S_curr_v[6]/S_curr_v[4]; 
 
 S_curr_v[27] = S_curr_v[6]/S_curr_v[5];  
//-------------------------------------
 S_prev_v[7]  = S_prev_v[0]/S_prev_v[1];
 S_prev_v[8]  = S_prev_v[0]/S_prev_v[2];
 S_prev_v[9]  = S_prev_v[0]/S_prev_v[3]; 
 S_prev_v[10] = S_prev_v[0]*S_prev_v[4];  
 S_prev_v[11] = S_prev_v[0]*S_prev_v[5];  
 S_prev_v[12] = S_prev_v[0]*S_prev_v[6]; 
 
 S_prev_v[13] = S_prev_v[1]/S_prev_v[2];  
 S_prev_v[14] = S_prev_v[1]/S_prev_v[3];
 S_prev_v[15] = S_prev_v[1]*S_prev_v[4];
 S_prev_v[16] = S_prev_v[1]*S_prev_v[5]; 
 S_prev_v[17] = S_prev_v[1]*S_prev_v[6];  
 
 S_prev_v[18] = S_prev_v[2]/S_prev_v[3];  
 S_prev_v[19] = S_prev_v[2]*S_prev_v[4]; 
 S_prev_v[20] = S_prev_v[2]*S_prev_v[5];  
 S_prev_v[21] = S_prev_v[2]*S_prev_v[6];
 
 S_prev_v[22] = S_prev_v[3]*S_prev_v[4];
 S_prev_v[23] = S_prev_v[3]*S_prev_v[5]; 
 S_prev_v[24] = S_prev_v[3]*S_prev_v[6];  
 
 S_prev_v[25] = S_prev_v[5]/S_prev_v[4];  
 S_prev_v[26] = S_prev_v[6]/S_prev_v[4]; 
 
 S_prev_v[27] = S_prev_v[6]/S_prev_v[5];  

//---
 return;
}
//----------------------------------------------------------------------------
double MarketInfoF(string Sym,int Mode)
{
 double MarketInfoRes;
//---
 if (Sym != "GBPNZD") {MarketInfoRes = MarketInfo(Sym,Mode);}
 else 
 {
  switch(Mode)
  {
   case MODE_DIGITS  : MarketInfoRes = 5      ; break; 
   case MODE_POINT   : MarketInfoRes = 0.00001; break;
   case MODE_BID     : MarketInfoRes = NormalizeDouble(MarketInfo("GBPUSD",MODE_BID)/MarketInfo("NZDUSD",MODE_BID),5);  break; 
  }     
 }
//--- 
 if (MarketInfoRes <= 0) 
 {
  PlaySound("alert.wav");
  sv = StringConcatenate("MarketInfo(",Sym,",",Mode,")"," возвратила ", MarketInfoRes);
  Print(sv);
 }
 return(MarketInfoRes);
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---   
   for (i = 0; i <= 7; i++)
   {
    if (StringFind(Symbol(),CV[i],0) == 0) CV_l_i = i;
    if (StringFind(Symbol(),CV[i],0) == 3) CV_r_i = i;
   }
//---- indicator
   sv = StringConcatenate(Indicator_Name,CV[CV_l_i],CV[CV_r_i]);
   IndicatorShortName(sv);
   IndicatorDigits(0);
   SetIndexStyle (0, Style, DRAW_LINE, Line_Thickness, Color_CL1i); // DRAW_HISTOGRAM
   SetIndexBuffer(0, arrCL1i);
   sv = StringConcatenate(CV[CV_l_i],CV[CV_r_i]);
   SetIndexLabel (0,sv); 

//---   
   for (i = 0; i <=27; i++)
   {
     SD[i] = MarketInfoF(S[i],MODE_DIGITS);
     SP[i] = MarketInfoF(S[i],MODE_POINT) ;
   } // end for (i = 0; i <=27; i++)
//---
   ArrayInitialize(CV_value, 0);
   
   Print("Init() ended..............");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   return(0);
  }
//----------------------------------------------------------------------------

