snake_001
Download scriptThe "Snake" indicator is a specialized technical analysis tool designed to smooth out price movements on a trading chart. Its primary goal is to provide a clearer picture of market trends by filtering out minor noise while maintaining a responsive visual flow.
Core Logic and Methodology
The script operates by calculating a dynamic weighted average. Rather than looking at the current price in isolation, it analyzes a specific window of historical data (determined by the "Snake_HalfCycle" setting) to determine where the price is likely heading.
1. Price Input Calculation Before processing the trend, the script first establishes a base price for every candle. Instead of using just the closing price, it takes into account the High and Low points of each period, giving extra importance to the Close. This creates a more comprehensive "typical" value for each moment in time.
2. The Weighted Distribution The unique "Snake" behavior comes from how it weights these prices:
- Center Focus: The logic places the highest mathematical weight on the most recent and relevant data points in its cycle.
- Symmetrical Balancing: As the script moves back into history, the influence of those price points gradually decreases. This creates a "weighted" effect where the current trend is heavily influenced by recent action but still smoothed by the context of the preceding bars.
3. Dynamic Smoothing To ensure the indicator remains fluid, the script uses two different calculation methods depending on where it is on the chart:
- Initialization: When starting a new calculation segment, it performs a full sum of all surrounding weights to establish a solid foundation.
- Continuous Flow: As the indicator moves forward, it utilizes a rolling calculation. It "drops" the oldest data point and "adds" the newest one into its existing sum. This allows the indicator to update smoothly without having to recalculate every historical bar every time the price moves, ensuring efficiency.
Visual Behavior
For the user, this logic manifests as a smooth, flowing line on the chart. Because it balances both past and present data using varying weights, the resulting line avoids the jagged spikes typical of standard moving averages while reacting more naturally to significant price shifts than a simple linear average would.
//+------------------------------------------------------------------+
//| Snake.mq4 |
//| "ÈÍÄÈÊÀÒÎÐÛ ÄËß ÑÀÌÎÎÁÌÀÍÀ" |
//| Bookkeeper, 2006, yuzefovich@gmail.com |
//+------------------------------------------------------------------+
#property copyright ""
#property link ""
//---- indicator settings
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Blue
//----
extern int Snake_HalfCycle=5; // Snake_HalfCycle = 4...10 or other
//----
double Snake_Buffer[];
double Snake_Sum, Snake_Weight, Snake_Sum_Minus, Snake_Sum_Plus;
int Snake_FullCycle;
//----
int init()
{
int draw_begin;
Snake_FullCycle=Snake_HalfCycle*2+1;
draw_begin=Snake_FullCycle+1;
SetIndexDrawBegin(0,draw_begin);
SetIndexBuffer(0,Snake_Buffer);
SetIndexStyle(0,DRAW_LINE);
return(0);
}
//----
int start()
{
int FirstPos, ExtCountedBars=0;
if(Bars<=150) return(0);
if(Snake_HalfCycle<3) Snake_HalfCycle=3;
ExtCountedBars=IndicatorCounted();
if (ExtCountedBars<0) return(-1);
if (ExtCountedBars>0) ExtCountedBars--;
FirstPos=Bars-ExtCountedBars-1;
if(FirstPos>Bars-Snake_HalfCycle-1) FirstPos=Bars-Snake_HalfCycle-1;
Snake(FirstPos);
return(0);
}
//----
void Snake(int Pos)
{
int i;
if(Pos<=Snake_HalfCycle+1) Pos=Snake_HalfCycle+2;
Snake_Buffer[Pos]=SnakeFirstCalc(Pos);
Pos--;
while(Pos>=Snake_HalfCycle)
{
Snake_Buffer[Pos]=SnakeNextCalc(Pos);
Pos--;
}
while(Pos>0)
{
Snake_Buffer[Pos]=SnakeFirstCalc(Pos);
Pos--;
}
if(Pos==0)
Snake_Buffer[0]=iMA(NULL,0,Snake_HalfCycle,0,MODE_LWMA,PRICE_TYPICAL,0);
return;
}
//----
double SnakePrice(int Shift)
{
return((2*Close[Shift]+High[Shift]+Low[Shift])/4);
}
//----
double SnakeFirstCalc(int Shift)
{
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);
Snake_Weight=Snake_Weight+i;
w--;
}
while(w>=0)
{
i--;
Snake_Sum=Snake_Sum+i*SnakePrice(w);
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)+SnakePrice(j));
Snake_Weight=Snake_Weight+2*w;
Snake_Sum_Minus=Snake_Sum_Minus+SnakePrice(i);
Snake_Sum_Plus=Snake_Sum_Plus+SnakePrice(j);
}
Snake_Sum=Snake_Sum+( Snake_HalfCycle+1)*SnakePrice(Shift);
Snake_Weight=Snake_Weight+ Snake_HalfCycle+1;
Snake_Sum_Minus=Snake_Sum_Minus+SnakePrice(Shift);
}
return(Snake_Sum/ Snake_Weight);
}
//----
double SnakeNextCalc(int Shift)
{
Snake_Sum_Plus=Snake_Sum_Plus+SnakePrice(Shift-Snake_HalfCycle);
Snake_Sum=Snake_Sum-Snake_Sum_Minus+Snake_Sum_Plus;
Snake_Sum_Minus=Snake_Sum_Minus-SnakePrice(Shift+Snake_HalfCycle+1)+SnakePrice(Shift);
Snake_Sum_Plus=Snake_Sum_Plus-SnakePrice(Shift);
return(Snake_Sum/Snake_Weight);
}
//----
Comments