//+------------------------------------------------------------------+
//|                                                       TMA+CG.mq4 |
//|                                                           mladen |
//| arrowse coded acording to idea presented by rajiv                |
//+------------------------------------------------------------------+
#property copyright   "©  rajivxxx@gmail.com, mladen  ©  Tankk,  22 мая 2020,  http://forexsystemsru.com/" 
#property link        "https://forexsystemsru.com/threads/indikatory-sobranie-sochinenij-tankk.86203/"  ////https://forexsystemsru.com/forums/indikatory-foreks.41/
#property description "Отличие Triangular Moving Average [TMA] от других скользящих средних в том," 
#property description "что ТМА берет в расчет не простые MA, а дважды сглаженные, что, с одной стороны," 
#property description "позволяет более четко определять движение рынка,"
#property description "но, с другой стороны, делает индикатор менее чувствительным."
#property description " " 
#property description "Индикатор перерисовывается если RePaint=true."
#property description " " 
#property description "Почта:  tualatine@mail.ru" 
#property version "1.65"
//#property strict
#property indicator_chart_window
#property indicator_buffers 5
//---
#property indicator_color1  clrWhite
#property indicator_color2  clrWhite
#property indicator_color3  clrWhite
#property indicator_color4  clrLime
#property indicator_color5  clrRed
//---
#property indicator_width4  0
#property indicator_width5  0
//---
#property indicator_style1  STYLE_DOT
#property indicator_style2  STYLE_DOT
#property indicator_style3  STYLE_DOT
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

extern bool             RePaint  =  true;
extern int           HalfLength  =  24;
extern ENUM_APPLIED_PRICE Price  =  PRICE_WEIGHTED;
extern double         Deviation  =  1.5;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double tmBuffer[], upBuffer[], dnBuffer[];
double wuBuffer[], wdBuffer[];
double upArrow[], dnArrow[];
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
{
   HalfLength = MathMax(HalfLength,1);
   //---
   IndicatorBuffers(7);   IndicatorDigits(Digits-Digits%2);
   //---
   SetIndexBuffer(0,tmBuffer);  SetIndexStyle(0,DRAW_LINE);   SetIndexLabel(0,"Center");
   SetIndexBuffer(1,upBuffer);  SetIndexStyle(1,DRAW_LINE);   SetIndexLabel(1,"Upper");
   SetIndexBuffer(2,dnBuffer);  SetIndexStyle(2,DRAW_LINE);   SetIndexLabel(2,"Lower");
   SetIndexBuffer(3,upArrow);   SetIndexStyle(3,DRAW_ARROW);  SetIndexArrow(3,233);       SetIndexLabel(4,"ArrowUP");
   SetIndexBuffer(4,dnArrow);   SetIndexStyle(4,DRAW_ARROW);  SetIndexArrow(4,234);       SetIndexLabel(3,"ArrowDN");
   SetIndexBuffer(5,wuBuffer);
   SetIndexBuffer(6,wdBuffer);
   //---
   IndicatorShortName("TMA ["+(string)HalfLength+"*"+DoubleToStr(Deviation,1)+"]");
//---
return(0);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int deinit() { Comment(""); return(0); }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
{
   int i, CountedBars=IndicatorCounted();
   if (CountedBars<0) return(-1);
   if (CountedBars>0) CountedBars--;
   int limit=MathMin(Bars-3-HalfLength,Bars-CountedBars-1);
   //---
   for (i=0; i<7; i++) { 
        SetIndexEmptyValue(i,0.0);  //--- значение 0 отображаться не будет 
        SetIndexDrawBegin(i,HalfLength*3); }       //--- пропуск отрисовки первых баров  
   //---
   calculateTma(limit);
   //---
  	for (i=limit; i>=0; i--)
    {
     upArrow[i]=0;   dnArrow[i]=0;            
     //---
     if (High[i+1] > upBuffer[i+1] && Close[i] < Open[i] && Close[i+1] > Open[i+1])  dnArrow[i] = High[i]+iATR(NULL,0,1,i)/2;
     if (Low[i+1]  < dnBuffer[i+1] && Close[i] > Open[i] && Close[i+1] < Open[i+1])  upArrow[i] = Low[i]-iATR(NULL,0,1,i)/2;
   } 
//---
return(0);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void calculateTma(int limit)
{
   int i, j, k;
   double FullLength = 2.0 * HalfLength + 1.0;
   //---
   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 (RePaint && j<=i)
        {
         sum  += k*iMA(NULL,0,1,0,MODE_SMA,Price,i-j);
         sumw += k;
        }
      }
     tmBuffer[i] = sum/sumw;
     //---
     //---
     double diff = iMA(NULL,0,1,0,MODE_SMA,Price,i) - tmBuffer[i];
     //---
     if (i> (Bars-HalfLength-1)) continue;
     if (i==(Bars-HalfLength-1))
      {
       upBuffer[i] = tmBuffer[i];
       dnBuffer[i] = tmBuffer[i];
       //---
       if (diff>=0)
        {
         wuBuffer[i] = MathPow(diff,2);
         wdBuffer[i] = 0;
        }
       else
        {               
         wdBuffer[i] = MathPow(diff,2);
         wuBuffer[i] = 0;
        }                  
       continue;
      }
     //---
     //---
     if (diff>=0)
      {
       wuBuffer[i] = (wuBuffer[i+1] * (FullLength-1) + MathPow(diff,2)) / FullLength;
       wdBuffer[i] =  wdBuffer[i+1] * (FullLength-1) / FullLength;
      }
     else
      {
       wdBuffer[i] = (wdBuffer[i+1] * (FullLength-1) + MathPow(diff,2)) / FullLength;
       wuBuffer[i] =  wuBuffer[i+1] * (FullLength-1) / FullLength;
      }
     //---
     upBuffer[i] = tmBuffer[i] + Deviation * MathSqrt(wuBuffer[i]);
     dnBuffer[i] = tmBuffer[i] - Deviation * MathSqrt(wdBuffer[i]);
    }
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+ 