//+------------------------------------------------------------------+
//|                                             All Wilder's DMI.mq4 |
//+------------------------------------------------------------------+
#property copyright   "mladen"
#property link        "www.forex-tsd.com"

#property indicator_separate_window
#property  indicator_buffers 5
#property indicator_minimum  0
#property indicator_color1   Lime
#property indicator_color2   Tomato
#property indicator_color3   DeepSkyBlue
#property indicator_color4   Orange
#property indicator_color5   LimeGreen
#property indicator_width3   2 
#property indicator_width4   2 
#property indicator_style1   STYLE_DOT
#property indicator_style2   STYLE_DOT

//
//
//
//
//

#import "dynamicZone.dll"
   double dzSell(double& sourceArray[],double probabiltyValue, int lookBack, int bars, int i );
#import

//
//
//
//
//
//

extern int    DMIPeriod           = 14;
extern int    DzLookBackBars      = 35;
extern double DzStartProbability  = 0.12;
extern string __                  = "Chose timeframes";
extern string timeFrames          = "M1;M5;M15;M30;H1;H4;D1;W1;MN";
extern bool   showDMLines         = false;
extern bool   showADXR            = false;
extern int    barsPerTimeFrame    = 35;
extern bool   shiftRight          = false; 
extern bool   currentFirst        = true; 
extern color  txtColor            = Silver; 
extern color  separatorColor      = DimGray; 
extern string separatorIdentifier = "1";

//
//
//
//
//
//

double sli[];
double DIp[];
double DIm[];
double ADX[];
double ADXR[];
double averageDIp[];
double averageDIm[];
double averageTR[];

//
//
//
//
//

string shortName;
string labels[];
int    periods[];
int    Shift;
double minValue;
double maxValue;
bool   calculateValue;
string indicatorFileName;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int init()
{
   indicatorFileName = WindowExpertName();
   calculateValue    = (__=="calculateValue");
      if (shiftRight) Shift = 1;
      else            Shift = 0;
            barsPerTimeFrame = MathMax(barsPerTimeFrame,15);      
            shortName = "Dynamic zone Wilder\s DMI "+separatorIdentifier+" ("+DMIPeriod+")";
                        IndicatorShortName(shortName);
   
      //
      //
      //
      //
      //
      
         SetIndexBuffer(0,DIp);  SetIndexShift(0,Shift*(barsPerTimeFrame+1)); SetIndexLabel(0,"DI+");
         SetIndexBuffer(1,DIm);  SetIndexShift(1,Shift*(barsPerTimeFrame+1)); SetIndexLabel(1,"DI-");
         SetIndexBuffer(2,ADX);  SetIndexShift(2,Shift*(barsPerTimeFrame+1)); SetIndexLabel(2,"ADX");
         SetIndexBuffer(3,ADXR); SetIndexShift(3,Shift*(barsPerTimeFrame+1)); SetIndexLabel(3,"ADXR");
         SetIndexBuffer(4,sli);
         if (calculateValue)
         {
            IndicatorBuffers(8);
               SetIndexBuffer(5,averageDIp);
               SetIndexBuffer(6,averageDIm);
               SetIndexBuffer(7,averageTR);
               return(0);
         }
         if (!showDMLines)
         {
            SetIndexStyle(0,DRAW_NONE);
            SetIndexStyle(1,DRAW_NONE);
         }
         else
         {
            SetIndexStyle(0,DRAW_LINE);
            SetIndexStyle(1,DRAW_LINE);
         }

      //
      //
      //
      //
      //
      
      timeFrames = StringTrimLeft(StringTrimRight(timeFrames));
      if (StringSubstr(timeFrames,StringLen(timeFrames),1) != ";")
                       timeFrames = StringConcatenate(timeFrames,";");

         //
         //
         //
         //
         //                                   
            
         int s = 0;
         int i = StringFind(timeFrames,";",s);
         int time;
         string current;
            while (i > 0)
            {
               current = StringSubstr(timeFrames,s,i-s);
               time    = stringToTimeFrame(current);
               if (time > 0) {
                     ArrayResize(labels ,ArraySize(labels)+1);
                     ArrayResize(periods,ArraySize(periods)+1);
                                 labels[ArraySize(labels)-1]   = timeFrameToString(time); 
                                 periods[ArraySize(periods)-1] = time; }
                                 s = i + 1;
                                     i = StringFind(timeFrames,";",s);
            }
      
      //
      //
      //
      //
      //

      if(currentFirst)
         for (i=1;i<ArraySize(periods);i++)
         if (Period()==periods[i])
            {
               string tmpLbl = labels[i];
               int    tmpPer = periods[i];
               
               //
               //
               //
               //
               //
               
               for (int k=i ;k>0; k--)
                     {
                        labels[k]  = labels[k-1];
                        periods[k] = periods[k-1];
                     }                     
               labels[0]  = tmpLbl;
               periods[0] = tmpPer;
            }
   return(0);
}

//
//
//
//
//

int deinit()
{
   for(int l=0;l<ArraySize(periods);l++)
   {
         ObjectDelete(separatorIdentifier+l);
         ObjectDelete(separatorIdentifier+l+"label");
      }         
   return(0);
}


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int start()
{
   if (calculateValue) { calculateDMI(); return(0); }
     string separator;
     int    window=WindowFind(shortName);
     int    k=0;

     //
     //
     //
     //
     //

            minValue =  999999;
            maxValue = -999999;
            for(int p=0; p<ArraySize(periods);p++)
                  {
                     for(int i=0; i<barsPerTimeFrame;i++,k++)
                           {
                              DIp[k] =iCustom(NULL,periods[p],indicatorFileName,DMIPeriod,DzLookBackBars,DzStartProbability,"calculateValue",0,i);
                              DIm[k] =iCustom(NULL,periods[p],indicatorFileName,DMIPeriod,DzLookBackBars,DzStartProbability,"calculateValue",1,i);
                              ADX[k] =iCustom(NULL,periods[p],indicatorFileName,DMIPeriod,DzLookBackBars,DzStartProbability,"calculateValue",2,i);
                              sli[k] =iCustom(NULL,periods[p],indicatorFileName,DMIPeriod,DzLookBackBars,DzStartProbability,"calculateValue",4,i);
                              if (showADXR)
                                 ADXR[k] =iCustom(NULL,periods[p],indicatorFileName,DMIPeriod,DzLookBackBars,DzStartProbability,"calculateValue",3,i);
                                 checkMinMax(k);
                           }
                           DIp[k]  = EMPTY_VALUE;
                           DIm[k]  = EMPTY_VALUE;
                           ADX[k]  = EMPTY_VALUE;
                           ADXR[k] = EMPTY_VALUE;
                           sli[k]  = EMPTY_VALUE;
                           k += 1;
                           
                           //
                           //
                           //
                           //
                           //
                           
                           separator = separatorIdentifier+p;
                           if(ObjectFind(separator)==-1)
                              ObjectCreate(separator,OBJ_TREND,window,0,0);
                              ObjectSet(separator,OBJPROP_TIME1,barTime(k-Shift*(barsPerTimeFrame+1)-1));
                              ObjectSet(separator,OBJPROP_TIME2,barTime(k-Shift*(barsPerTimeFrame+1)-1));
                              ObjectSet(separator,OBJPROP_COLOR ,separatorColor);
                              ObjectSet(separator,OBJPROP_WIDTH ,2);
                           separator = separatorIdentifier+p+"label";
                           if(ObjectFind(separator)==-1)
                              ObjectCreate(separator,OBJ_TEXT,window,0,0);
                              ObjectSet(separator,OBJPROP_TIME1,barTime(k-Shift*(barsPerTimeFrame+1)-5));
                              ObjectSetText(separator,labels[p],9,"Arial",txtColor);
                  }

         //
         //
         //
         //
         //
         
         for(p=0; p<ArraySize(periods);p++) {
               separator = separatorIdentifier+p;
                  ObjectSet(separator,OBJPROP_PRICE1,maxValue);
                  ObjectSet(separator,OBJPROP_PRICE2,minValue);
               separator = separatorIdentifier+p+"label";
                  ObjectSet(separator,OBJPROP_PRICE1,maxValue);
            }                  

      //
      //
      //
      //
      //
      
      SetIndexDrawBegin(0,Bars-k);
      SetIndexDrawBegin(1,Bars-k);
      SetIndexDrawBegin(2,Bars-k);
      SetIndexDrawBegin(3,Bars-k);
   return(0);
}



//+------------------------------------------------------------------+
//+                                                                  +
//+------------------------------------------------------------------+
//
//
//
//
//

void calculateDMI()
{
   double sf         = 1.0/DMIPeriod;
   int counted_bars  = IndicatorCounted();
   int i,limit;


   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
      limit=Bars-counted_bars;

   //
   //
   //
   //
   //
   
   for (i=limit;i>=0;i--)
   {
         double currTR  = MathMax(High[i],Close[i+1])-MathMin(Low[i],Close[i+1]);
         double DeltaHi = High[i] - High[i+1];
	      double DeltaLo = Low[i+1] - Low[i];
         double plusDM  = 0.00;
         double minusDM = 0.00;
         
            if ((DeltaHi > DeltaLo) && (DeltaHi > 0)) plusDM  = DeltaHi;
            if ((DeltaLo > DeltaHi) && (DeltaLo > 0)) minusDM = DeltaLo;      
         
         //
         //
         //
         //
         //
         
            averageDIp[i] = averageDIp[i+1] + sf*(plusDM  - averageDIp[i+1]);
            averageDIm[i] = averageDIm[i+1] + sf*(minusDM - averageDIm[i+1]);
            averageTR[i]  = averageTR[i+1]  + sf*(currTR  - averageTR[i+1]);

         //
         //
         //
         //
         //
                  
            DIp[i] = 0.00;                   
            DIm[i] = 0.00;                   
            if (averageTR[i] > 0)
               {              
                  DIp[i] = 100.00 * averageDIp[i]/averageTR[i];
                  DIm[i] = 100.00 * averageDIm[i]/averageTR[i];
               }            

               double DX;
               if((DIp[i] + DIm[i])>0) 
                    DX = 100*MathAbs(DIp[i] - DIm[i])/(DIp[i] + DIm[i]); 
               else DX = 0.00;
               ADX[i]  = ADX[i+1] + sf*(DX - ADX[i+1]); 
               ADXR[i] = 0.5*(ADX[i] + ADX[i+DMIPeriod]);
         sli[i] = dzSell(ADX,DzStartProbability, DzLookBackBars, Bars, i);
   }   
}


//+------------------------------------------------------------------+
//+                                                                  +
//+------------------------------------------------------------------+
//
//
//
//
//

void checkMinMax(int shift)
{
   double tmpMin;
   double tmpMax;
   
   tmpMin = MathMin(DIp[shift],DIm[shift]);
   tmpMin = MathMin(ADX[shift],tmpMin);
   tmpMax = MathMax(DIp[shift],DIm[shift]);
   tmpMax = MathMax(ADX[shift],tmpMax);
            minValue = MathMin(tmpMin,minValue);
            maxValue = MathMax(tmpMax,maxValue);
}

//
//
//
//
//

int barTime(int a)
{
   if(a<0)
         return(Time[0]+Period()*60*MathAbs(a));
   else  return(Time[a]);   
}

//+-------------------------------------------------------------------
//|                                                                  
//+-------------------------------------------------------------------
//
//
//
//
//

string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,15,30,60,240,1440,10080,43200};

//
//
//
//
//

int stringToTimeFrame(string tfs)
{
   tfs = StringUpperCase(tfs);
   for (int i=ArraySize(iTfTable)-1; i>=0; i--)
         if (tfs==sTfTable[i] || tfs==""+iTfTable[i]) return(iTfTable[i]);
                                                      return(Period());
}
string timeFrameToString(int tf)
{
   for (int i=ArraySize(iTfTable)-1; i>=0; i--) 
         if (tf==iTfTable[i]) return(sTfTable[i]);
                              return("");
}

//
//
//
//
//

string StringUpperCase(string str)
{
   string   s = str;

   for (int length=StringLen(str)-1; length>=0; length--)
   {
      int char1 = StringGetChar(s, length);
         if((char1 > 96 && char1 < 123) || (char1 > 223 && char1 < 256))
                     s = StringSetChar(s, length, char1 - 32);
         else if(char1 > -33 && char1 < 0)
                     s = StringSetChar(s, length, char1 + 224);
   }
   return(s);
}