
//------------------------------------------------------------------
#property copyright "mrtools"
#property link      "www.forex-station.com"
//------------------------------------------------------------------

#property indicator_separate_window
#property indicator_buffers    7
#property indicator_color1     clrLimeGreen
#property indicator_color2     clrDarkGreen
#property indicator_color3     clrRed
#property indicator_color4     clrMaroon
#property indicator_color5     clrAqua  //LightCyan
#property indicator_color6     clrGold  //Magenta
#property indicator_color7     clrNONE  //DarkSlateGray
#property indicator_width1     5
#property indicator_width2     5
#property indicator_width3     5
#property indicator_width4     5
#property indicator_width5     3
#property indicator_width6     3
#property indicator_width7     2
#property indicator_level1     0
#property indicator_levelcolor clrSlateGray
#property strict

extern ENUM_TIMEFRAMES    TimeFrame    = PERIOD_CURRENT;   // Time frame
extern int	              Force_Period	= 12;                // Force index period
extern ENUM_MA_METHOD     Force_Method	= MODE_SMA;         // Force index ma method
extern ENUM_APPLIED_PRICE Force_Price	= PRICE_CLOSE;      // Force index price

enum frcTyp { FrcOff,/*Filter OFF*/ FrcVol,/*Force + Volume*/ FrcCls/*Force + Close*/ };
extern frcTyp  ForceType  =  FrcVol;  //Force filter

extern bool               Interpolate  = false;             // Interpolate in mtf mode

double force[],fohuu[],fohud[],fohdd[],fohdu[], VOLUP[], VOLDN[], trend[],slope[],count[];
string indicatorFileName;  int TFK;
#define _mtfCall(_buff,_ind) iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,Force_Period,Force_Method,Force_Price,ForceType,_buff,_ind)

//
//
//
//
//

int init()
{
   IndicatorBuffers(10);   
   SetIndexBuffer(0,fohuu); SetIndexStyle(0, DRAW_HISTOGRAM);
   SetIndexBuffer(1,fohud); SetIndexStyle(1, DRAW_HISTOGRAM);
   SetIndexBuffer(2,fohdd); SetIndexStyle(2, DRAW_HISTOGRAM);
   SetIndexBuffer(3,fohdu); SetIndexStyle(3, DRAW_HISTOGRAM);
   SetIndexBuffer(4,VOLUP); SetIndexStyle(4, DRAW_HISTOGRAM);
   SetIndexBuffer(5,VOLDN); SetIndexStyle(5, DRAW_HISTOGRAM);
   SetIndexBuffer(6,force); SetIndexStyle(6, DRAW_LINE);
   SetIndexBuffer(7,trend);
   SetIndexBuffer(8,slope);
   SetIndexBuffer(9,count);
   
   indicatorFileName = WindowExpertName();
   TimeFrame         = fmax(TimeFrame,_Period);    TFK = Interpolate ? 1 : TimeFrame/_Period;
  
   IndicatorShortName(timeFrameToString(TimeFrame)+" Force");
return(0);
}
int deinit(){ return(0);  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//

int start()
{
   int i,counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
         int limit = fmin(Bars-counted_bars,Bars-1); count[0] = limit;
         if (TimeFrame != _Period)
         {
            limit = (int)fmax(limit,fmin(Bars-1,_mtfCall(9,0)*TimeFrame/_Period));
            for (i=limit;i>=0 && !_StopFlag; i--)
            {
                  int y = iBarShift(NULL,TimeFrame,Time[i]);
                     force[i] = _mtfCall(6,y);
   	               trend[i] = _mtfCall(7,y);
                     slope[i] = _mtfCall(8,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)<Bars && Time[i+n] >= time; n++) continue;	
                         for(k = 1; k<n && (i+n)<Bars && (i+k)<Bars; k++) _interpolate(force);
            }
            for(i=limit; i>=0; i--) 
            {
   	         fohuu[i] = (trend[i] == 1 && slope[i] == 1) ? force[i] : EMPTY_VALUE;
               fohud[i] = (trend[i] == 1 && slope[i] ==-1) ? force[i] : EMPTY_VALUE;
               fohdd[i] = (trend[i] ==-1 && slope[i] ==-1) ? force[i] : EMPTY_VALUE;
               fohdu[i] = (trend[i] ==-1 && slope[i] == 1) ? force[i] : EMPTY_VALUE;   
               //---
               VOLUP[i]=EMPTY_VALUE;  VOLDN[i]=EMPTY_VALUE;
               //---
               int y = iBarShift(NULL,TimeFrame,Time[i]);  
               //---
               if (ForceType>0 && i+1*TFK<Bars-3)    //enum frcTyp { FrcOff, FrcVol, FrcCls };
                {
                 if (ForceType==1 && force[i]>force[i+1*TFK] && iVolume(NULL,TimeFrame,y)>iVolume(NULL,TimeFrame,y+1))  VOLUP[i] = force[i]/1.5;
                 if (ForceType==1 && force[i]<force[i+1*TFK] && iVolume(NULL,TimeFrame,y)<iVolume(NULL,TimeFrame,y+1))  VOLDN[i] = force[i]/1.5; 
                 //---
                 if (ForceType==2 && force[i]>force[i+1*TFK] && iClose(NULL,TimeFrame,y)>iClose(NULL,TimeFrame,y+1))  VOLUP[i] = force[i]/1.5;
                 if (ForceType==2 && force[i]<force[i+1*TFK] && iClose(NULL,TimeFrame,y)<iClose(NULL,TimeFrame,y+1))  VOLDN[i] = force[i]/1.5; 
                }
            }
   return(0);
   }

   //
   //
   //
   //
   //
   
   for(i=limit; i>=0; i--)
   {
      force[i] = iForce(NULL,0,Force_Period,Force_Method,Force_Price,i); 
      slope[i] = (i<Bars-1) ? (force[i]>force[i+1]) ? 1 : (force[i]<force[i+1]) ? -1 :  slope[i+1] : 0;
      trend[i] = (i<Bars-1) ? (force[i]>0)          ? 1 : (force[i]<0)          ? -1 :  trend[i+1] : 0;
      fohuu[i] = (trend[i] == 1 && slope[i] == 1) ? force[i] : EMPTY_VALUE;
      fohud[i] = (trend[i] == 1 && slope[i] ==-1) ? force[i] : EMPTY_VALUE;
      fohdd[i] = (trend[i] ==-1 && slope[i] ==-1) ? force[i] : EMPTY_VALUE;
      fohdu[i] = (trend[i] ==-1 && slope[i] == 1) ? force[i] : EMPTY_VALUE;  
      //---
      VOLUP[i]=EMPTY_VALUE;  VOLDN[i]=EMPTY_VALUE;
      //---
      if (ForceType>0 && i+1<Bars-3)    //enum frcTyp { FrcOff, FrcVol, FrcCls, };
       {
        if (ForceType==1 && force[i]>force[i+1] && Volume[i]>Volume[i+1])  VOLUP[i] = force[i]/1.5;
        if (ForceType==1 && force[i]<force[i+1] && Volume[i]<Volume[i+1])  VOLDN[i] = force[i]/1.5; 
        //---
        if (ForceType==2 && force[i]>force[i+1] && Close[i]>Close[i+1])  VOLUP[i] = force[i]/1.5;
        if (ForceType==2 && force[i]<force[i+1] && Close[i]<Close[i+1])  VOLDN[i] = force[i]/1.5; 
       }
  //---            
   }    
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("");
}


