//+------------------------------------------------------------------+
//|                                        TriangularMA centered.mq4 |
//|                                                           mladen |
//+------------------------------------------------------------------+
#property copyright "mladen"
#property link      "mladenfx@gmail.com"

#property indicator_chart_window
#property indicator_buffers 6
#property indicator_color1  DeepSkyBlue
#property indicator_color2  LimeGreen
#property indicator_color3  LimeGreen
#property indicator_color4  Red
#property indicator_color5  Red
#property indicator_color6  DimGray
#property indicator_style3  STYLE_DOT
#property indicator_style4  STYLE_DOT
#property indicator_style6  STYLE_DOT
#property indicator_width1  2

//
//
//
//
//

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

//
//
//
//
//

extern string TimeFrame               = "current time frame";
extern int    HalfLength              = 12;
extern int    Price                   = PRICE_CLOSE;
extern bool   ShowMiddleLine          = true;
extern int    DzLookBackBars          = 50;
extern double DzStartBuyProbability1  = 0.10;
extern double DzStartBuyProbability2  = 0.25;
extern double DzStartSellProbability1 = 0.10;
extern double DzStartSellProbability2 = 0.25;
extern bool   Interpolate             = true;

//
//
//
//
//

double buffer1[];
double bl1Buffer[];
double bl2Buffer[];
double sl1Buffer[];
double sl2Buffer[];
double zliBuffer[];

//
//
//
//
//

string indicatorFileName;
bool   calculateTma;
bool   returnBars;
int    timeFrame;

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

int init()
{
   HalfLength=MathMax(HalfLength,1);
      SetIndexBuffer(0,buffer1);   SetIndexDrawBegin(0,HalfLength);
      SetIndexBuffer(1,bl1Buffer); SetIndexDrawBegin(1,HalfLength);
      SetIndexBuffer(2,bl2Buffer); SetIndexDrawBegin(2,HalfLength);
      SetIndexBuffer(3,sl2Buffer); SetIndexDrawBegin(3,HalfLength);
      SetIndexBuffer(4,sl1Buffer); SetIndexDrawBegin(4,HalfLength);
      SetIndexBuffer(5,zliBuffer); SetIndexDrawBegin(5,HalfLength);

   //
   //
   //
   //
   //
         
         indicatorFileName = WindowExpertName();
         calculateTma      = (TimeFrame=="calculateTma"); if (calculateTma) return(0);
         returnBars        = (TimeFrame=="returnBars");   if (returnBars)   return(0);
         timeFrame         = stringToTimeFrame(TimeFrame);

   //
   //
   //
   //
   //
   
   return(0);
}
int deinit() { return(0); }




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

int start()
{
   double precision = Point*100.0;
   int counted_bars=IndicatorCounted();
   int i,j,k,limit;

   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
           limit=MathMin(Bars-1,Bars-counted_bars+HalfLength);
           if (returnBars) { buffer1[0] = limit+1; return(0); }

   //
   //
   //
   //
   //

   if (calculateTma || timeFrame == Period())
   {
      for (i=limit; i>=0; i--)
      {
         double sum  = (HalfLength+1)*iMA(NULL,0,1,0,MODE_SMA,Price,i);
         double sumw = (HalfLength+1);
         for(j=1, k=HalfLength; j<=HalfLength; j++, k--)
         {
            sum  += k*iMA(NULL,0,1,0,MODE_SMA,Price,i+j);
            sumw += k;

            if (j<=i)
            {
               sum  += k*iMA(NULL,0,1,0,MODE_SMA,Price,i-j);
               sumw += k;
            }
         }
         buffer1[i] = sum/sumw;
         if (DzStartBuyProbability1 >0) bl1Buffer[i] = dzBuyP (buffer1, DzStartBuyProbability1,  DzLookBackBars, Bars, i, precision);
         if (DzStartBuyProbability2 >0) bl2Buffer[i] = dzBuyP (buffer1, DzStartBuyProbability2,  DzLookBackBars, Bars, i, precision);
         if (DzStartSellProbability1>0) sl1Buffer[i] = dzSellP(buffer1, DzStartSellProbability1, DzLookBackBars, Bars, i, precision);
         if (DzStartSellProbability2>0) sl2Buffer[i] = dzSellP(buffer1, DzStartSellProbability2, DzLookBackBars, Bars, i, precision);
         if (ShowMiddleLine)            zliBuffer[i] = dzSellP(buffer1, 0.5                    , DzLookBackBars, Bars, i, precision);
      }
      return(0);
   }      
   
   //
   //
   //
   //
   //
   
   limit = MathMax(limit,MathMin(Bars-1,iCustom(NULL,timeFrame,indicatorFileName,"returnBars",0,0)*timeFrame/Period()));
   for (i=limit; i>=0; i--)
   {
      int y = iBarShift(NULL,timeFrame,Time[i]);
         buffer1[i]   = iCustom(NULL,timeFrame,indicatorFileName,"calculateTma",HalfLength,Price,ShowMiddleLine,DzLookBackBars,DzStartBuyProbability1,DzStartBuyProbability2,DzStartSellProbability1,DzStartSellProbability2,0,y);
         if (DzStartBuyProbability1  > 0) bl1Buffer[i] = iCustom(NULL,timeFrame,indicatorFileName,"calculateTma",HalfLength,Price,ShowMiddleLine,DzLookBackBars,DzStartBuyProbability1,DzStartBuyProbability2,DzStartSellProbability1,DzStartSellProbability2,1,y);
         if (DzStartBuyProbability2  > 0) bl2Buffer[i] = iCustom(NULL,timeFrame,indicatorFileName,"calculateTma",HalfLength,Price,ShowMiddleLine,DzLookBackBars,DzStartBuyProbability1,DzStartBuyProbability2,DzStartSellProbability1,DzStartSellProbability2,2,y);
         if (DzStartSellProbability2 > 0) sl2Buffer[i] = iCustom(NULL,timeFrame,indicatorFileName,"calculateTma",HalfLength,Price,ShowMiddleLine,DzLookBackBars,DzStartBuyProbability1,DzStartBuyProbability2,DzStartSellProbability1,DzStartSellProbability2,3,y);
         if (DzStartSellProbability1 > 0) sl1Buffer[i] = iCustom(NULL,timeFrame,indicatorFileName,"calculateTma",HalfLength,Price,ShowMiddleLine,DzLookBackBars,DzStartBuyProbability1,DzStartBuyProbability2,DzStartSellProbability1,DzStartSellProbability2,4,y);
         if (ShowMiddleLine)              zliBuffer[i] = iCustom(NULL,timeFrame,indicatorFileName,"calculateTma",HalfLength,Price,ShowMiddleLine,DzLookBackBars,DzStartBuyProbability1,DzStartBuyProbability2,DzStartSellProbability1,DzStartSellProbability2,5,y);

         //
         //
         //
         //
         //
      
         if (timeFrame <= Period() || y==iBarShift(NULL,timeFrame,Time[i-1])) continue;
         if (!Interpolate) continue;

         //
         //
         //
         //
         //

         datetime time = iTime(NULL,timeFrame,y);
            for(int n = 1; i+n < Bars && Time[i+n] >= time; n++) continue;	
            double factor = 1.0 / n;
            for(k = 1; k < n; k++)
            {
               buffer1[i+k]   = k*factor*buffer1[i+n] + (1.0-k*factor)*buffer1[i];
               bl1Buffer[i+k] = k*factor*bl1Buffer[i+n] + (1.0-k*factor)*bl1Buffer[i];
               bl2Buffer[i+k] = k*factor*bl2Buffer[i+n] + (1.0-k*factor)*bl2Buffer[i];
               sl1Buffer[i+k] = k*factor*sl1Buffer[i+n] + (1.0-k*factor)*sl1Buffer[i];
               sl2Buffer[i+k] = k*factor*sl2Buffer[i+n] + (1.0-k*factor)*sl2Buffer[i];
               zliBuffer[i+k] = k*factor*zliBuffer[i+n] + (1.0-k*factor)*zliBuffer[i];
            }
   }
   return(0);
}

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

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(MathMax(iTfTable[i],Period()));
                                                      return(Period());
}

//
//
//
//
//

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);
}