//+------------------------------------------------------------------+
//|                                                          tst.mq4 |
//|                        Copyright 2014, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property strict

//+------------------------------------------------------------------+
#define ADX_TR          0
#define ADX_PLUS_DM1    1
#define ADX_MINUS_DM1   2
#define ADX_TR14        3
#define ADX_PLUS_DM14   4
#define ADX_MINUS_DM14  5
#define ADX_PLUS_DL14   6
#define ADX_MINUS_DL14  7
#define ADX_DL14_DIFF   8
#define ADX_DL14_SUM    9
#define ADX_DX          10
#define ADX_ADX         11

#define ADX_DEPTH       150

double ADX14(string symbol, int timeframe, int shift)
{
  double result=0, data[12,ADX_DEPTH+28], buf[3];
  MqlRates rates[];
  
  if (CopyRates(symbol,timeframe,shift,ADX_DEPTH+28,rates) != (ADX_DEPTH+28))
  {
    Print(__FUNCTION__,": Error geting rates");
    Alert(__FUNCTION__,": Error geting rates");
    return(result);
  }
  ArraySetAsSeries(rates,false);
  
  ArrayFill(data,0,12*(ADX_DEPTH+28),0);
  
  for (int i=1; i < ADX_DEPTH+28; i++)
  {
    ArrayFill(buf,0,3,0);
    buf[0]=rates[i].high-rates[i].low;
    buf[1]=MathAbs(rates[1].high-rates[i-1].close);
    buf[2]=MathAbs(rates[1].low-rates[i-1].close);
    data[ADX_TR,i]=buf[ArrayMaximum(buf)];
    ArrayFill(buf,0,3,0);
    buf[0]=rates[i].high-rates[i-1].high;
    if ((rates[i].high-rates[i-1].high) > (rates[i-1].low-rates[i].low))
      data[ADX_PLUS_DM1,i]=buf[ArrayMaximum(buf)];
    buf[0]=rates[i-1].low-rates[i].low;
    if ((rates[i-1].low-rates[i].low) > (rates[i].high-rates[i-1].high))
      data[ADX_MINUS_DM1,i]=buf[ArrayMaximum(buf)];
    
    if (i < 14)
      continue;
    else if (i == 14)  
      for (int j=0; j < 14; j++)
      {
        data[ADX_TR14,i]+=data[ADX_TR,i-j];
        data[ADX_PLUS_DM14,i]+=data[ADX_PLUS_DM1,i-j];
        data[ADX_MINUS_DM14,i]+=data[ADX_MINUS_DM1,i-j];
      }
    else
    {
      data[ADX_TR14,i]=data[ADX_TR14,i-1]-(data[ADX_TR14,i-1]/14)+data[ADX_TR,i];
      data[ADX_PLUS_DM14,i]=data[ADX_PLUS_DM14,i-1]-(data[ADX_PLUS_DM14,i-1]/14)+data[ADX_PLUS_DM1,i];
      data[ADX_MINUS_DM14,i]=data[ADX_MINUS_DM14,i-1]-(data[ADX_MINUS_DM14,i-1]/14)+data[ADX_MINUS_DM1,i];
    }
    data[ADX_PLUS_DL14,i]=data[ADX_PLUS_DM14,i]/data[ADX_TR14,i]*100;
    data[ADX_MINUS_DL14,i]=data[ADX_MINUS_DM14,i]/data[ADX_TR14,i]*100;
    data[ADX_DL14_DIFF,i]=MathAbs(data[ADX_PLUS_DL14,i]-data[ADX_MINUS_DL14,i]);
    data[ADX_DL14_SUM,i]=data[ADX_PLUS_DL14,i]+data[ADX_MINUS_DL14,i];
    data[ADX_DX,i]=data[ADX_DL14_DIFF,i]/data[ADX_DL14_SUM,i]*100;
    
    if (i < 27)
      continue;
    else if (i == 27)
    {
      for (int j=0; j < 14; j++)
        data[ADX_ADX,i]+=data[ADX_DX,i-j];
      data[ADX_ADX,i]/=14;
    }
    data[ADX_ADX,i]=(data[ADX_ADX,i-1]*13+data[ADX_DX,i])/14;
  }
  result=data[ADX_ADX,ADX_DEPTH+28-1];
  
/*  int hFile=FileOpen("123.csv",FILE_WRITE|FILE_WRITE|FILE_TXT);
  FileSeek(hFile,0,SEEK_SET);
  string s;
  for (int i=0; i < 150+28; i++)
  {
    s=DoubleToString(rates[i].high,4)+";"+DoubleToString(rates[i].low,4)+";"+DoubleToString(rates[i].close,4)+"\n";
    FileWriteString(hFile,s);
  }
  FileClose(hFile);*/
  
  return(result);
}

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
//---

  Alert(ADX14(_Symbol,PERIOD_CURRENT,0));
  //Alert(rsi[0]);
}
//+------------------------------------------------------------------+
