
//---- version
#property version   "1.00"
//---- draw indicator in a separated window
#property indicator_chart_window 
//---- one indicator buffer is used
#property indicator_buffers 5 
//---- one graphic plot is used
#property indicator_plots   1
//+-----------------------------------+
//|  Indicator plot settings          |
//+-----------------------------------+
//---- draw as a line
#property indicator_type1   DRAW_LINE
//---- line color (Red)
#property indicator_color1 clrYellow
//---- line style (solid line)
#property indicator_style1  STYLE_SOLID
//---- line width
#property indicator_width1  2
//---- line label
#property indicator_label1  "SNAKE"

 

  
  
ENUM_TIMEFRAMES TFMigrate(int tf)
  {
   switch(tf)
     {
      case 0: return(PERIOD_CURRENT);
      case 1: return(PERIOD_M1);
      case 5: return(PERIOD_M5);
      case 15: return(PERIOD_M15);
      case 30: return(PERIOD_M30);
      case 60: return(PERIOD_H1);
      case 240: return(PERIOD_H4);
      case 1440: return(PERIOD_D1);
      case 10080: return(PERIOD_W1);
      case 43200: return(PERIOD_MN1);
      
      case 2: return(PERIOD_M2);
      case 3: return(PERIOD_M3);
      case 4: return(PERIOD_M4);      
      case 6: return(PERIOD_M6);
      case 10: return(PERIOD_M10);
      case 12: return(PERIOD_M12);
      case 16385: return(PERIOD_H1);
      case 16386: return(PERIOD_H2);
      case 16387: return(PERIOD_H3);
      case 16388: return(PERIOD_H4);
      case 16390: return(PERIOD_H6);
      case 16392: return(PERIOD_H8);
      case 16396: return(PERIOD_H12);
      case 16408: return(PERIOD_D1);
      case 32769: return(PERIOD_W1);
      case 49153: return(PERIOD_MN1);      
      default: return(PERIOD_CURRENT);
     }
  }  
  
  
  
  
//---- indicator inputs
input int Snake_HalfCycle=5; // Snake_HalfCycle = 4...10 or other


double Snake_Sum, Snake_Weight, Snake_Sum_Minus, Snake_Sum_Plus;
int Snake_FullCycle;

//+-----------------------------------+
//---- indicator buffers
double Ind_Buffer[];


//--- buffers do indicador 

//----
double dPriceShift;
//+------------------------------------------------------------------+
// CT3 class, iPriceSeries(),iPriceSeriesAlert() functions are used  |
//+------------------------------------------------------------------+ 

//+------------------------------------------------------------------+
//| T3 indicator initialization function                             |
//+------------------------------------------------------------------+
void OnInit()
  {
   int    draw_begin;  
   Snake_FullCycle=Snake_HalfCycle*2+1;
   draw_begin=Snake_FullCycle+1;   
  
//---- set Ind_Buffer[] array as an indicator buffer
   SetIndexBuffer(0,Ind_Buffer,INDICATOR_DATA);
//---- set plot shift (horizontal shift in bars)
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,draw_begin);
//--- indicator label, shown in the DataWindow
   PlotIndexSetString(0,PLOT_LABEL,"SNAKE");
//---- set empty values
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
//---- variable for indicator short name
//---- set indicator short name
   IndicatorSetString(INDICATOR_SHORTNAME,"SNAKE");
//---- set precision
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
//---- initialization end




  }
//+------------------------------------------------------------------+
//| T3 iteration function                                            | 
//+------------------------------------------------------------------+ 
int OnCalculate(const int rates_total, 
                 // rates total
                const int prev_calculated,// number of bars, calculated at previous call
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[]
                )
  {
  

  
//---- bars checking
   if(rates_total<0)return(0);


//---- declaration of variables of integer type
   int first;

//---- calculation of starting bar index (first)
   if(prev_calculated>rates_total || prev_calculated<=0) // at first call
      first=0; // starting bar index
   else first=prev_calculated-1; // starting bar index for new bars



         int Pos = first;
         
         
         
         int bars=Bars(_Symbol,_Period);
         
         
         if(Pos>bars-Snake_HalfCycle-1) 
            Pos=bars-Snake_HalfCycle-1;
                     
         
         int      buffer_num=0;           // indicator buffer number 
         int      start_pos=0;            // start position 
         int      count=500;                // amount to copy 
         
        
            

            
       /*  SNAKE bar  */
       
         
       
     
         if(Pos<=Snake_HalfCycle+1)
         {
            Pos=Snake_HalfCycle+2;
                     
         }
         
         Ind_Buffer[Pos]=SnakeFirstCalc(Pos,open,high,low,close);
         Pos--;
           
         
         while(Pos>=Snake_HalfCycle)
         {
            Ind_Buffer[Pos]=SnakeNextCalc(Pos,open,high,low,close);
            Pos--;
           
         
         }
         while(Pos>0)
         {
            Ind_Buffer[Pos]=SnakeFirstCalc(Pos,open,high,low,close);
            Pos--;
 
         }
         if(Pos==0) 
            Ind_Buffer[0]=iMA(NULL,0,Snake_HalfCycle,0,MODE_LWMA,PRICE_TYPICAL);
       
     
   return(rates_total);
  }
//+------------------------------------------------------------------+


//----
double SnakePrice(int Shift,
               const double &open[],
                const double &high[],
                const double &low[],
                const double &close[])
{

  return((2*close[Shift]+high[Shift]+low[Shift])/4);
}
//----
double SnakeFirstCalc(int Shift,const double &open[],
                const double &high[],
                const double &low[],
                const double &close[])
{
   int i, j, w;
   Snake_Sum=0.0;
   Snake_Weight=0.0;
   if(Shift<Snake_HalfCycle)
   {
      i=0;
      w=Shift+Snake_HalfCycle;
      while(w>=Shift)
      {
         i++;
         Snake_Sum=Snake_Sum+i*SnakePrice(w,open,high,low,close);
         Snake_Weight=Snake_Weight+i;
         w--;
      }
      while(w>=0)
      {
         i--;
         Snake_Sum=Snake_Sum+i*SnakePrice(w,open,high,low,close);
         Snake_Weight=Snake_Weight+i;
         w--;
      }
   }
   else
   {
      Snake_Sum_Minus=0.0;
      Snake_Sum_Plus=0.0;
      for(j=Shift-Snake_HalfCycle,i=Shift+Snake_HalfCycle,w=1;
          w<= Snake_HalfCycle; 
          j++,i--,w++)
      {
         Snake_Sum=Snake_Sum+w*(SnakePrice(i,open,high,low,close)+SnakePrice(j,open,high,low,close));
         Snake_Weight=Snake_Weight+2*w;
         Snake_Sum_Minus=Snake_Sum_Minus+SnakePrice(i,open,high,low,close);
         Snake_Sum_Plus=Snake_Sum_Plus+SnakePrice(j,open,high,low,close);
      }
      Snake_Sum=Snake_Sum+( Snake_HalfCycle+1)*SnakePrice(Shift,open,high,low,close);
      Snake_Weight=Snake_Weight+ Snake_HalfCycle+1;
      Snake_Sum_Minus=Snake_Sum_Minus+SnakePrice(Shift,open,high,low,close);
   }
   return(Snake_Sum/ Snake_Weight);
}
//----
double SnakeNextCalc(int Shift,
               const double &open[],
                const double &high[],
                const double &low[],
                const double &close[])
{
   Snake_Sum_Plus=Snake_Sum_Plus+SnakePrice(Shift-Snake_HalfCycle,open,high,low,close);
   Snake_Sum=Snake_Sum-Snake_Sum_Minus+Snake_Sum_Plus;
   Snake_Sum_Minus=Snake_Sum_Minus-SnakePrice(Shift+Snake_HalfCycle+1,open,high,low,close)+SnakePrice(Shift,open,high,low,close);
   Snake_Sum_Plus=Snake_Sum_Plus-SnakePrice(Shift,open,high,low,close);
   return(Snake_Sum/Snake_Weight);
}
//----



