
//------------------------------------------------------------------
#property copyright "www.forex-station.com"
#property link      "www.forex-station.com"
//------------------------------------------------------------------
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1  clrDodgerBlue
#property indicator_width1  3
#property strict

extern ENUM_TIMEFRAMES   TimeFrame     = PERIOD_CURRENT; // Time frame
input int                MaPeriod      = 13;             // Average period
input ENUM_MA_METHOD     ma_method     = MODE_SMA;       // Average type
input ENUM_APPLIED_PRICE applied_price = PRICE_CLOSE;    // Price
input int                ma_shift      = 0;              // Shift
input bool               Interpolate   = true;           // Interpolate in multi time frame mode on/off?

double ma[],count[];
string indicatorFileName;
#define _mtfCall(_buff,_ind) iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,MaPeriod,ma_method,applied_price,0,_buff,_ind)

//+------------------------------------------------------------------
//|                                                                 |
//+------------------------------------------------------------------
//
//

int OnInit()
{
   IndicatorBuffers(2);
   SetIndexBuffer(0,ma,   INDICATOR_DATA); SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(1,count,INDICATOR_CALCULATIONS);
   
   
   indicatorFileName = WindowExpertName();
   TimeFrame         = fmax(TimeFrame,_Period); 
   
   for (int i=0; i<7; i++) SetIndexShift(i,ma_shift*TimeFrame/Period());
   IndicatorShortName(timeFrameToString(TimeFrame)+" Ma ("+(string)MaPeriod+")");
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason){   }

int OnCalculate (const int       rates_total,
                 const int       prev_calculated,
                 const datetime& btime[],
                 const double&   open[],
                 const double&   high[],
                 const double&   low[],
                 const double&   close[],
                 const long&     tick_volume[],
                 const long&     volume[],
                 const int&      spread[])
{
      int i,counted_bars = prev_calculated;
      if(counted_bars < 0) return(-1);
      if(counted_bars > 0) counted_bars--;
            int limit=fmin(rates_total-counted_bars,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]);
                     ma[i]   = _mtfCall(0,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 time = iTime(NULL,TimeFrame,y);
                        for(n = 1; (i+n)<rates_total && Time[i+n] >= time; n++) continue;	
                        for(k = 1; k<n && (i+n)<rates_total && (i+k)<rates_total; k++) _interpolate(ma);                       
               }          
     return(rates_total);
     }     
               
     //
     //
     //
     //
     //
     
     for(i=limit; i>=0; i--) ma[i] = iMA(NULL,0,MaPeriod,ma_shift,ma_method,applied_price,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("");
}
 
