//+------------------------------------------------------------------+
//|                                                       mfi MA mtf |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "www.forex-station.com"
#property link      "www.forex-station.com"

#property indicator_separate_window
#property indicator_buffers 2

#property indicator_label1  "MFI"
#property indicator_color1  clrLimeGreen
#property indicator_type1   DRAW_LINE
#property indicator_style1  STYLE_SOLID  
#property indicator_width1  2

#property indicator_label2  "MFI MA"
#property indicator_color2  clrRed
#property indicator_type2   DRAW_LINE
#property indicator_style2  STYLE_DOT
#property strict


extern ENUM_TIMEFRAMES   TimeFrame              = PERIOD_CURRENT;    // Time frame to use
input int                MfiPeriod              = 14;                // Mfi period
input int                MfiMaPeriod            = 5;                 // Mfi ma period
input ENUM_MA_METHOD     MfiMaMethod            = MODE_SMA;          // Mfi ma method
input double             OverSold               = 20;                // Over sold level
input double             OverBought             = 80;                // Over bought level
input bool               Interpolate            = true;              // Interpolate in multi time frame mode?

double mfi[],mfiMa[],count[];
string indicatorFileName;
#define _mtfCall(_buff,_ind) iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,MfiPeriod,MfiMaPeriod,MfiMaMethod,OverSold,OverBought,_buff,_ind)

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//

int OnInit()
{
   IndicatorBuffers(3);
   SetIndexBuffer(0,mfi,  INDICATOR_DATA);   
   SetIndexBuffer(1,mfiMa,INDICATOR_DATA); 
   SetIndexBuffer(2,count,INDICATOR_CALCULATIONS);
   
   indicatorFileName = WindowExpertName();
   TimeFrame         = fmax(TimeFrame,_Period);
   
   IndicatorSetDouble(INDICATOR_MINIMUM,0);
   IndicatorSetDouble(INDICATOR_MAXIMUM,100);
   
   IndicatorSetInteger(INDICATOR_LEVELS,3);
   IndicatorSetDouble( INDICATOR_LEVELVALUE,0,OverBought);
   IndicatorSetInteger(INDICATOR_LEVELSTYLE,0,STYLE_DOT);
   IndicatorSetInteger(INDICATOR_LEVELCOLOR,0,clrMediumOrchid);  
   IndicatorSetDouble( INDICATOR_LEVELVALUE,1,OverSold);
   IndicatorSetInteger(INDICATOR_LEVELSTYLE,1,STYLE_DOT);
   IndicatorSetInteger(INDICATOR_LEVELCOLOR,1,clrMediumOrchid);  
   IndicatorSetDouble( INDICATOR_LEVELVALUE,2,50);
   IndicatorSetInteger(INDICATOR_LEVELSTYLE,2,STYLE_DOT);
   IndicatorSetInteger(INDICATOR_LEVELCOLOR,2,clrMediumOrchid);  
   
   IndicatorShortName(timeFrameToString(TimeFrame)+ " Mfi + Ma("+(string)MfiPeriod+")");
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason) {   }

//+------------------------------------------------------------------
//|                                                                  
//+------------------------------------------------------------------
//
//
//
//
//

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime& time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   int i,limit=fmin(rates_total-prev_calculated+1,rates_total-1); count[0]=limit;
            if (TimeFrame!=_Period)
            {
               limit = (int)fmax(limit,fmin(rates_total-1,_mtfCall(2,0)*TimeFrame/_Period));
               for (i=limit;i>=0 && !_StopFlag; i--)
               {
                  int y = iBarShift(NULL,TimeFrame,time[i]);
                     mfi[i]   = _mtfCall(0,y);
                     mfiMa[i] = _mtfCall(1,y);
                 
                     //
                     //
                     //
                     //
                     //
                     
                     if (!Interpolate || (i>0 && y==iBarShift(NULL,TimeFrame,time[i-1]))) continue;
                        #define _interpolate(buff) buff[i+k] = buff[i]+(buff[i+n]-buff[i])*k/n
                        int n,k; datetime btime = iTime(NULL,TimeFrame,y);
                           for(n = 1; (i+n)<rates_total && time[i+n] >= btime; n++) continue;	
                           for(k = 1; k<n && (i+n)<rates_total && (i+k)<rates_total; k++) 
                           {
                              _interpolate(mfi);   
                              _interpolate(mfiMa);    
                           }                                            
              } 
   return(rates_total);
   }    
   
   //
   //
   //
   //
   //
   
   for(i=limit; i>=0; i--) mfi[i]   = iMFI(NULL,0,MfiPeriod,i);
   for(i=limit; i>=0; i--) mfiMa[i] = iMAOnArray(mfi,0,MfiMaPeriod,0,MfiMaMethod,i);
return(rates_total);
}

//+-------------------------------------------------------------------
//|                                                                  
//+-------------------------------------------------------------------
//
//
//
//
//

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("");
}


