//+------------------------------------------------------------------+
//|                                Trend direction & force index.mq4 |
//|                                                           mladen |
//|                                                                  |
//|                                                                  |
//| original metastock indicator made by Piotr Wojdylo               |
//+------------------------------------------------------------------+
#property copyright "mladen"
#property link      "mladenfx@gmail.com"
#property indicator_separate_window
#property indicator_maximum  1
#property indicator_minimum  -1
#property indicator_buffers  7
#property indicator_color1   DarkSlateGray
#property indicator_color2   Lime
#property indicator_color3   Lime
#property indicator_color4   Red
#property indicator_color5   Red
#property indicator_color6   clrNONE
#property indicator_color7   clrNONE

enum   enDouble{max,mima,min};

input  enDouble mm                     = max;
extern int      TrendPeriod            = 9; //=ema36 original tdfi
extern bool     Color                  = true;
extern bool     All_zero               = true;

int length1,length2,length3,length4,tr1,tr2,tr3,tr4;
datetime time0;
double B0[],B01[],B02[],B03[],B04[],Btr1[],Btr2[], B1_0[],B1_1[],B1_2[],B1_3[], B2_0[],B2_1[],B2_2[],B2_3[], B3_0[],B3_1[],B3_2[],B3_3[], B4_0[],B4_1[],B4_2[],B4_3[];

int init(){
   IndicatorBuffers(27);
   SetIndexBuffer(0,B0);
   SetIndexBuffer(1,B01);   SetIndexLabel(1,NULL);
   SetIndexBuffer(2,B02);   SetIndexLabel(2,NULL);
   SetIndexBuffer(3,B03);   SetIndexLabel(3,NULL);
   SetIndexBuffer(4,B04);   SetIndexLabel(4,NULL);
   SetIndexBuffer(5,Btr1);  SetIndexLabel(5,NULL);
   SetIndexBuffer(6,Btr2);  SetIndexLabel(6,NULL);
   SetIndexBuffer(11,B1_0); SetIndexBuffer(12,B1_1); SetIndexBuffer(13,B1_2); SetIndexBuffer(14,B1_3);
   SetIndexBuffer(15,B2_0); SetIndexBuffer(16,B2_1); SetIndexBuffer(17,B2_2); SetIndexBuffer(18,B2_3);
   SetIndexBuffer(19,B3_0); SetIndexBuffer(20,B3_1); SetIndexBuffer(21,B3_2); SetIndexBuffer(22,B3_3);
   SetIndexBuffer(23,B4_0); SetIndexBuffer(24,B4_1); SetIndexBuffer(25,B4_2); SetIndexBuffer(26,B4_3);
   IndicatorShortName(NULL);
   tr1=TrendPeriod*2; tr2=TrendPeriod*3; tr3=TrendPeriod*4; tr4=TrendPeriod*5;
   length1=tr1*3; length2=tr2*3; length3=tr3*3; length4=tr4*3;
   return(0);
}
int start(){int i,limit=Bars-IndicatorCounted()-1; double b12,b3,b4;
   for(i=limit;i>=0;i--){B1_1[i]=iMA(NULL,0,tr1,0,2,0,i); B2_1[i]=iMA(NULL,0,tr2,0,0,0,i); B3_1[i]=iMA(NULL,0,tr3,0,1,0,i); B4_1[i]=iMA(NULL,0,tr4,0,3,0,i); }
   for(i=limit;i>=0;i--){double ma=-1, mi=1;
                         B1_2[i]=iMAOnArray(B1_1,0,tr1,0,2,i); b12=MathAbs(B1_1[i]-B1_2[i])/Point; b3=(B1_1[i]-B1_1[i+1]+B1_2[i]-B1_2[i+1])/(2*Point); B1_3[i]=b12*MathPow(b3,3);
                         b4=absHighest(B1_3,i); if(b4>0){B1_0[i]=B1_3[i]/b4;} else{B1_0[i]=0;} if(mm!=mima){if(ma<B1_0[i]){ma=B1_0[i];} if(mi>B1_0[i]){mi=B1_0[i];}}
                         B2_2[i]=iMAOnArray(B2_1,0,tr2,0,0,i); b12=MathAbs(B2_1[i]-B2_2[i])/Point; b3=(B2_1[i]-B2_1[i+1]+B2_2[i]-B2_2[i+1])/(2*Point); B2_3[i]=b12*MathPow(b3,3);
                         b4=absHighest(B2_3,i); if(b4>0){B2_0[i]=B2_3[i]/b4;} else{B2_0[i]=0;} if(mm!=mima){if(ma<B2_0[i]){ma=B2_0[i];} if(mi>B2_0[i]){mi=B2_0[i];}}
                         B3_2[i]=iMAOnArray(B3_1,0,tr3,0,1,i); b12=MathAbs(B3_1[i]-B3_2[i])/Point; b3=(B3_1[i]-B3_1[i+1]+B3_2[i]-B3_2[i+1])/(2*Point); B3_3[i]=b12*MathPow(b3,3);
                         b4=absHighest(B3_3,i); if(b4>0){B3_0[i]=B3_3[i]/b4;} else{B3_0[i]=0;} if(mm!=mima){if(ma<B3_0[i]){ma=B3_0[i];} if(mi>B3_0[i]){mi=B3_0[i];}}
                         B4_2[i]=iMAOnArray(B4_1,0,tr4,0,3,i); b12=MathAbs(B4_1[i]-B4_2[i])/Point; b3=(B4_1[i]-B4_1[i+1]+B4_2[i]-B4_2[i+1])/(2*Point); B4_3[i]=b12*MathPow(b3,3);
                         b4=absHighest(B4_3,i); if(b4>0){B4_0[i]=B4_3[i]/b4;} else{B4_0[i]=0;} if(mm!=mima){if(ma<B4_0[i]){ma=B4_0[i];} if(mi>B4_0[i]){mi=B4_0[i];}}
    if(mm==max){if(MathAbs(ma)>MathAbs(mi)){B0[i]=ma;}else if(MathAbs(ma)<MathAbs(mi)){B0[i]=mi;}else{B0[i]=(ma+mi)/2;}}else{
    if(mm==min){if(MathAbs(ma)<MathAbs(mi)){B0[i]=ma;}else if(MathAbs(ma)>MathAbs(mi)){B0[i]=mi;}else{B0[i]=(ma+mi)/2;}}else{
    if(mm==mima){B0[i]=(B1_0[i]+B2_0[i]+B3_0[i]+B4_0[i])/4;}}}
    if(All_zero==false){if(B0[i]>0){Btr2[i]= 1;}else{if(B0[i]<0){Btr2[i]=-1;}else{Btr2[i]= 0;}}}
    if(All_zero==true){if(B1_0[i]>0 && B2_0[i]>0 && B3_0[i]>0 && B4_0[i]>0){Btr1[i]= 1;    Btr2[i]= 1;}else
                       if(B1_0[i]<0 && B2_0[i]<0 && B3_0[i]<0 && B4_0[i]<0){Btr1[i]=-1;    Btr2[i]=-1;}else
                         {B0[i]=(B1_0[i]+B2_0[i]+B3_0[i]+B4_0[i])*0.25; Btr1[i]=Btr1[i+1]; Btr2[i]= 0;}}}
    if(Color==false){return(0);}
    for(i=limit;i>=0;i--){if(Btr2[i]== 1){B03[i]=EMPTY_VALUE; B04[i]=EMPTY_VALUE;
                                          if(Btr2[i+1]== 1)                                                                                             {B01[i+1]=B0[i+1]; B01[i]=B0[i];}else
                                          if(Btr2[i+1]<  1){if((B02[i+2]!=EMPTY_VALUE && B02[i+3]!=EMPTY_VALUE) || (Btr2[i+2]< 1)){B01[i+2]=EMPTY_VALUE; B01[i+1]=B0[i+1]; B01[i]=B0[i];}else
                                                             if(B01[i+2]!=EMPTY_VALUE && B01[i+3]!=EMPTY_VALUE)                   {B02[i+2]=EMPTY_VALUE; B02[i+1]=B0[i+1]; B02[i]=B0[i];}}}else
                          if(Btr2[i]== 0){B01[i]=EMPTY_VALUE; B02[i]=EMPTY_VALUE; B03[i]=EMPTY_VALUE; B04[i]=EMPTY_VALUE;}else
                          if(Btr2[i]==-1){B01[i]=EMPTY_VALUE; B02[i]=EMPTY_VALUE;
                                          if(Btr2[i+1]==-1)                                                                                             {B03[i+1]=B0[i+1]; B03[i]=B0[i];}else
                                          if(Btr2[i+1]> -1){if((B04[i+2]!=EMPTY_VALUE && B04[i+3]!=EMPTY_VALUE) || (Btr2[i+2]>-1)){B03[i+2]=EMPTY_VALUE; B03[i+1]=B0[i+1]; B03[i]=B0[i];}else
                                                             if(B03[i+2]!=EMPTY_VALUE && B03[i+3]!=EMPTY_VALUE)                   {B04[i+2]=EMPTY_VALUE; B04[i+1]=B0[i+1]; B04[i]=B0[i];}}}}
   return(0);
}
double absHighest(double array[], int i2){double result=0;
   for(int i=length1-1;i>=0;i--){if(result<MathAbs(array[i2+i])){result=MathAbs(array[i2+i]);}}
   return(result);
}