//+-------------------------------------------------------------------------+
//|                                                     Index_pair_v22b.mq4 |
//|                                                               GrayMan77 |
//| Расчет RSI от индексов валют пары                                       |
//| Идея расчета индекса:                                                   |
//|  - Ю.Макаров                                                            |
//|    http://www.may.nnov.ru/mak/                                          |
//|  - А.Плясунов                                                           |
//|    http://www.umis.ru/clients1/study/trading_school/fc_methods?start=0  |
//| Идея применения RSI - akadex                                            |
//|    http://www.kroufr.ru/forum/index.php?topic=2692.msg6724;topicseen    |
//| Реализация - GrayMan77                                                  |
//|                                                                         |
//|        ПРИМЕНЯТЬ ТОЛЬКО ДЛЯ ПАР ВАЛЮТ USD,EUR,GBP,JPY,CHF!              |
//| ----------------------------------------------------------------------- |
//| v1 - переписан индикатор от akadex  dex_RSIndex.mq4:                    |
//|      добавлено автоопределение пары, IndicatorCounted и                 |
//|      первичное сглаживание цены (FirstEMA).                             |
//|                                                                         |
//| v2 - вычисление индексов других валют через кроссы                      |
//|                                (без весовых коэффициентов)              |
//|                                                                         |
//| v21 - индикатор переписан с целью оптимизации                           |
//|                                                                         |
//| v22 - расчет индексов - в функциях                                      |
//|                                                                         |
//| v22b - поиск баров в истории не по смещению, а по времени               |
//|    |
//+-------------------------------------------------------------------------+
#property copyright "GrayMan77"
#property link      ""

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Aqua

#property indicator_level1 30
#property indicator_level2 50
#property indicator_level3 70
//#property indicator_width1 2
//#property indicator_minimum 0
//#property indicator_maximum 100

//---- Внешние параметры

extern int RSIPeriod=12;
extern int Smooth=10;
extern int PeriodFirstEMA=3; // Первичное сглаживание - период
extern int PriceFirstEMA=6;  // Первичное сглаживание - цена:
                             //  0-Close; 1-Open; 2-High; 3-Low; 4-(H+L)/2; 5-(H+L+C)/3; 6-(H+L+C+C)/4.

//---- Буферы индикатора

double IndexBuffer[],Buffer[],RSIBuffer[];
double IndexBuffer1[],Buffer1[],RSIBuffer1[];

//---- Переменные

int BarsMin;
bool Show=false;

//----

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators

   IndicatorBuffers(6);
   SetIndexBuffer(0,RSIBuffer);
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(1,RSIBuffer1);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(2,IndexBuffer);
   SetIndexBuffer(3,IndexBuffer1);
   SetIndexBuffer(4,Buffer);
   SetIndexBuffer(5,Buffer1);
   IndicatorShortName("Index_pair_v22b:  "+Symbol() + "(" + Period() + "): ");
   SetIndexLabel(0, StringSubstr(Symbol(),0,3));
   SetIndexLabel(1, StringSubstr(Symbol(),3,3));

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
     int limit,i;
     string S=Symbol();
     int counted_bars=IndicatorCounted();
     
  //---- проверка на возможные ошибки
     if(counted_bars<0) return(-1);
     if(Show==false)
       {
       if(S=="GBPUSD" || S=="USDCHF" || S=="EURUSD" || S=="USDJPY" || S=="EURGBP" ||
          S=="EURCHF" || S=="EURJPY" || S=="GBPCHF" || S=="GBPJPY" || S=="CHFJPY")
          Show=true;
       }
     if(Show==false)
       {
       Alert("- ERROR! - Индикатор не работает на паре ",S," !!!");
       Print("--- ERROR ! --- Индикатор не работает на паре ",S," !!!");
       return(-1);
       }
     
  //---- вычисление минимального кол-ва баров (длины отображаемого графика)
     if(counted_bars==0)
     {
     BarsMin=iBars("GBPUSD",NULL);
     if(BarsMin>iBars("USDCHF",NULL)) BarsMin=iBars("USDCHF",NULL);
     if(BarsMin>iBars("EURUSD",NULL)) BarsMin=iBars("EURUSD",NULL);
     if(BarsMin>iBars("USDJPY",NULL)) BarsMin=iBars("USDJPY",NULL);
     if(BarsMin>iBars("EURGBP",NULL)) BarsMin=iBars("EURGBP",NULL);
     if(BarsMin>iBars("EURCHF",NULL)) BarsMin=iBars("EURCHF",NULL);
     if(BarsMin>iBars("EURJPY",NULL)) BarsMin=iBars("EURJPY",NULL);
     if(BarsMin>iBars("GBPCHF",NULL)) BarsMin=iBars("GBPCHF",NULL);
     if(BarsMin>iBars("GBPJPY",NULL)) BarsMin=iBars("GBPJPY",NULL);
     if(BarsMin>iBars("CHFJPY",NULL)) BarsMin=iBars("CHFJPY",NULL);
     }
     
  //---- последний посчитанный бар будет пересчитан
     if(counted_bars>0) counted_bars--;
     limit=Bars-counted_bars;
     if(limit>BarsMin-2) limit=BarsMin-2;
     
  //---- основной цикл

     for(i=limit;i>=0;i--)
       {
       //---- Выбор нужной пары индексов
       if (Symbol() == "EURUSD") { IndexBuffer[i]=EUR(i); IndexBuffer1[i]=USD(i); }
       if (Symbol() == "EURGBP") { IndexBuffer[i]=EUR(i); IndexBuffer1[i]=GBP(i); }
       if (Symbol() == "EURCHF") { IndexBuffer[i]=EUR(i); IndexBuffer1[i]=CHF(i); }
       if (Symbol() == "EURJPY") { IndexBuffer[i]=EUR(i); IndexBuffer1[i]=JPY(i); }
       if (Symbol() == "GBPUSD") { IndexBuffer[i]=GBP(i); IndexBuffer1[i]=USD(i); }
       if (Symbol() == "GBPCHF") { IndexBuffer[i]=GBP(i); IndexBuffer1[i]=CHF(i); }
       if (Symbol() == "GBPJPY") { IndexBuffer[i]=GBP(i); IndexBuffer1[i]=JPY(i); }
       if (Symbol() == "USDCHF") { IndexBuffer[i]=USD(i); IndexBuffer1[i]=CHF(i); }
       if (Symbol() == "USDJPY") { IndexBuffer[i]=USD(i); IndexBuffer1[i]=JPY(i); }
       if (Symbol() == "CHFJPY") { IndexBuffer[i]=CHF(i); IndexBuffer1[i]=JPY(i); }
       }

     //---- Вычисление RSI от индексов
     for(i=limit;i>=0;i--)
       {
       Buffer[i]=iRSIOnArray(IndexBuffer,0,RSIPeriod,i);
       Buffer1[i]=iRSIOnArray(IndexBuffer1,0,RSIPeriod,i);
       }
       
     //---- Сглаживание RSI  
     for(i=limit;i>=0;i--)
       {
       RSIBuffer[i]=iMAOnArray(Buffer,0,Smooth,0,MODE_EMA,i);
       RSIBuffer1[i]=iMAOnArray(Buffer1,0,Smooth,0,MODE_EMA,i);
       if(RSIBuffer[i]>100.) RSIBuffer[i]=100.;
       if(RSIBuffer1[i]>100.) RSIBuffer1[i]=100.;
       }
//----
   return(0);
  }

//+------------------------------------------------------------------+

double USD(int j)
  {
  double value;
  datetime TimeBar=Time[j];
  double GBP_USD=iMA("GBPUSD",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("GBPUSD",NULL,TimeBar,false));
  double USD_CHF=iMA("USDCHF",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("USDCHF",NULL,TimeBar,false));
  double EUR_USD=iMA("EURUSD",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("EURUSD",NULL,TimeBar,false));
  double USD_JPY=iMA("USDJPY",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("USDJPY",NULL,TimeBar,false));
         // Проверка для исключения деления на 0
       if(GBP_USD==0) GBP_USD=1.;
       if(EUR_USD==0) EUR_USD=1.;
  value = MathPow(USD_CHF*USD_JPY/GBP_USD/EUR_USD,0.2);
  return(value);
  }
//+------------------------------------------------------------------+
double GBP(int j)
  {
  double value;
  datetime TimeBar=Time[j];
  double GBP_USD=iMA("GBPUSD",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("GBPUSD",NULL,TimeBar,false));
  double EUR_GBP=iMA("EURGBP",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("EURGBP",NULL,TimeBar,false));
  double GBP_CHF=iMA("GBPCHF",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("GBPCHF",NULL,TimeBar,false));
  double GBP_JPY=iMA("GBPJPY",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("GBPJPY",NULL,TimeBar,false));
         // Проверка для исключения деления на 0
       if(EUR_GBP==0) EUR_GBP=1.;
  value = MathPow(GBP_USD*GBP_CHF*GBP_JPY/EUR_GBP,0.2);
  return(value);
  }
//+------------------------------------------------------------------+
double EUR(int j)
  {
  double value;
  datetime TimeBar=Time[j];
  double EUR_USD=iMA("EURUSD",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("EURUSD",NULL,TimeBar,false));
  double EUR_GBP=iMA("EURGBP",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("EURGBP",NULL,TimeBar,false));
  double EUR_CHF=iMA("EURCHF",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("EURCHF",NULL,TimeBar,false));
  double EUR_JPY=iMA("EURJPY",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("EURJPY",NULL,TimeBar,false));
  value = MathPow(EUR_USD*EUR_GBP*EUR_CHF*EUR_JPY,0.2);
  return(value);
  }
//+------------------------------------------------------------------+
double CHF(int j)
  {
  double value;
  datetime TimeBar=Time[j];
  double USD_CHF=iMA("USDCHF",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("USDCHF",NULL,TimeBar,false));
  double EUR_CHF=iMA("EURCHF",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("EURCHF",NULL,TimeBar,false));
  double GBP_CHF=iMA("GBPCHF",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("GBPCHF",NULL,TimeBar,false));
  double CHF_JPY=iMA("CHFJPY",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("CHFJPY",NULL,TimeBar,false));
         // Проверка для исключения деления на 0
       if(USD_CHF==0) USD_CHF=1.;
       if(EUR_CHF==0) EUR_CHF=1.;
       if(GBP_CHF==0) GBP_CHF=1.;
  value = MathPow(CHF_JPY/USD_CHF/EUR_CHF/GBP_CHF,0.2);
  return(value);
  }
//+------------------------------------------------------------------+
double JPY(int j)
  {
  double value;
  datetime TimeBar=Time[j];
  double USD_JPY=iMA("USDJPY",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("USDJPY",NULL,TimeBar,false));
  double EUR_JPY=iMA("EURJPY",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("EURJPY",NULL,TimeBar,false));
  double GBP_JPY=iMA("GBPJPY",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("GBPJPY",NULL,TimeBar,false));
  double CHF_JPY=iMA("CHFJPY",NULL,PeriodFirstEMA,0,1,PriceFirstEMA,iBarShift("CHFJPY",NULL,TimeBar,false));
         // Проверка для исключения деления на 0
       if(USD_JPY==0) USD_JPY=1.;
       if(EUR_JPY==0) EUR_JPY=1.;
       if(GBP_JPY==0) GBP_JPY=1.;
       if(CHF_JPY==0) CHF_JPY=1.;
  value = MathPow(1./USD_JPY/EUR_JPY/GBP_JPY/CHF_JPY,0.2);
  return(value);
  }
//+------------------------------------------------------------------+