//+------------------------------------------------------------------+
//|                                                        Kairi.mq4 |
//|                    Copyright(C) 2005 S.B.T. All Rights Reserved. |
//|                              http://fumito.s68.xrea.com/sb/sufx/ |
//+------------------------------------------------------------------+
#property  copyright "Copyright(C) 2005 S.B.T. All Rights Reserved."
#property  link      "http://fumito.s68.xrea.com/sb/sufx/"
//---- indicator settings
#property  indicator_separate_window
#property  indicator_buffers 1
#property  indicator_color1  DodgerBlue
//---- indicator parameters

//
//
enum enTimeFrames
{
   tf_cu  = PERIOD_CURRENT, // Current time frame
   tf_m1  = PERIOD_M1,      // 1 minute
   tf_m5  = PERIOD_M5,      // 5 minutes
   tf_m15 = PERIOD_M15,     // 15 minutes
   tf_m30 = PERIOD_M30,     // 30 minutes
   tf_h1  = PERIOD_H1,      // 1 hour
   tf_h4  = PERIOD_H4,      // 4 hours
   tf_d1  = PERIOD_D1,      // Daily
   tf_w1  = PERIOD_W1,      // Weekly
   tf_mn1 = PERIOD_MN1,     // Monthly
   tf_n1  = -1,             // First higher time frame
   tf_n2  = -2,             // Second higher time frame
   tf_n3  = -3              // Third higher time frame
};

//
extern enTimeFrames    TimeFrame          = tf_cu;   // Time frame
extern int MA_Period=21;
extern ENUM_MA_METHOD     MA_Method=0;
extern ENUM_APPLIED_PRICE Apply=0;
//---- indicator buffers
double     Kairi_buffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   string short_name1,short_name2;
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)+1);
   SetIndexBuffer(0,Kairi_buffer);
   switch(MA_Method)
     {
      case 1 : short_name1="EMA("; break;
      case 2 : short_name1="SMMA("; break;
      case 3 : short_name1="LWMA("; break;
      default :
         MA_Method=0;
         short_name1="SMA(";
     }
   switch(Apply)
     {
      case 1 : short_name2="Apply to Open price"; break;
      case 2 : short_name2="Apply to High price"; break;
      case 3 : short_name2="Apply to Low price"; break;
      case 4 : short_name2="Apply to Median price, (high+low)/2"; break;
      case 5 : short_name2="Apply to Typical price, (high+low+close)/3"; break;
      case 6 : short_name2="Apply to Weighted close price, (high+low+close+close)/4"; break;
      default :
         Apply=0;
         short_name2="Apply to Close price";
     }
     TimeFrame         = (enTimeFrames)timeFrameValue(TimeFrame);
   IndicatorShortName("Kairi("+short_name1+"("+MA_Period+")) "+short_name2);
   SetIndexLabel(0,"Kairi");
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence                           |
//+------------------------------------------------------------------+
int start()
{
   int counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
         int limit = MathMin(MathMax(Bars-counted_bars,TimeFrame/_Period),Bars-1);

   for(int i=0; i<limit; i++) 
   {
      int y = iBarShift(NULL,TimeFrame,Time[i]);
      double ma = iMA(NULL,TimeFrame,MA_Period,0,MA_Method,Apply,y);
         Kairi_buffer[i] = (ma!=0) ? (iMA(NULL,TimeFrame,1,0,MODE_SMA,Apply,y)-ma)/ma*100 : 0;
   }
   return(0);
}

//
//

string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,15,30,60,240,1440,10080,43200};

string timeFrameToString(int tf)
{
   for (int i=ArraySize(iTfTable)-1; i>=0; i--) 
         if (tf==iTfTable[i]) return(sTfTable[i]);
                              return("");
}
int timeFrameValue(int _tf)
{
   int add  = (_tf>=0) ? 0 : MathAbs(_tf);
   if (add != 0) _tf = _Period;
   int size = ArraySize(iTfTable); 
      int i =0; for (;i<size; i++) if (iTfTable[i]==_tf) break;
                                   if (i==size) return(_Period);
                                                return(iTfTable[(int)MathMin(i+add,size-1)]);
}