This script, titled "SnakeInBorders," is designed to visualize market dynamics by creating a dynamic "corridor" that tracks price movements. Instead of following the raw market price directly—which can be volatile and noisy—the logic uses a smoothed internal path to determine boundaries and signals.
Core Concept: The Corridor
The primary goal of the script is to define a fluctuating range (a corridor) bounded by two lines: a Top Border and a Bottom Border.
- The Internal Path (Axis): The logic first calculates a central "Axis." This is based on a weighted average of price data, giving more importance to recent movements.
- Dynamic Boundaries: The script identifies the highest and lowest points of this Axis over a specific period (the Filter Period). It then uses these extremes to project the Top and Bottom borders.
- The Signal Line (Mart): Within this corridor, a third line—the "Mart"—acts as a primary signal.
Behavioral Logic
The relationship between the price, the boundaries, and the signal line changes based on market momentum:
- Trend Movement: When the market moves strongly in one direction (up or down), the corridor tends to expand. The Signal Line will stay "pinned" to the corresponding boundary. For example, in a strong uptrend, the Signal Line will move toward the upper border; in a downtree, it stays near the lower border.
- Consolidation and Volatility: When the market begins to oscillate or lose momentum, the corridor starts to shrink (narrow). As it narrows, the Signal Line may shift from one side of the corridor to the other. Once it hits the opposite boundary during this contraction, the corridor typically begins to expand again.
Operational Modes
The script includes a toggle for how calculations are handled:
- Continuous Recalculation: In one mode, the script constantly updates the values of its components based on the most recent history.
- Fixed Calculation: In the alternative mode (often used for creating other types of technical indicators), the script locks in certain historical values to provide a more stable, less reactive path.
Practical Application
For traders, this logic serves two main purposes:
- Visualizing Trends: It clearly defines the "playing field" of the market, showing where the price is currently contained and how much room it has to move.
- Filtering Noise: By using the Signal Line instead of raw price data, the script helps identify the underlying direction of the market while ignoring minor, insignificant price fluctuations. It can be used independently as a signal or as a foundation to build other complex analytical tools.
//+------------+-----------------------------------------------------+
//| v.11.09.06 | SnakeInBorders.mq4 |
//+------------+ "ÔÈËÜÒÐÓÉ ÁÀÇÀÐ!" |
//| Êîìïëåêò | Bookkeeper, 2006, yuzefovich@gmail.com |
//+------------------------------------------------------------------+
//| Snake ðàññ÷èòûâàåò êîðèäîð îòôèëüòðîâàííîãî ðûíêà, îãðàíè÷åííûé |
//| äâóìÿ áîðäþðàìè BorderTop[] è BorderBot[], è ñèãíàëüíóþ Mart[]. |
//| |
//| Âíåøíèå ïåðåìåííûå: |
//| SnakeRange - ïîëóïåðèîä ðàñ÷åòà îñè Snake'à Axis[] - îïòèìàëüíî |
//| = 4; |
//| FilterPeriod - ïåðèîä ôèëüòðàöèè. ( îïòèìàëüíî áîëüøå 13); |
//| MartFiltr - êîýôôèöèåíò ôèëüòðàöèè ðûíêà. ×åì MartFiltr áîëüøå, |
//| òåì óæå êîðèäîð îòôèëüòðîâàííîãî ðûíêà. Êîýôôèöèåíò íàäî |
//| ïîäáèðàòü, ïî óìîë÷àíèþ = 2; |
//| Ó Snake'à äâà ðåæèìà: HardCalc = true - íå ïåðåñ÷èòûâàòü, è |
//| = false - ïåðåñ÷èòûâàòü çíà÷åíèÿ Axis[Pos]...[Pos+SnakeRange+1].|
//| Ïîâåäåíèå ñèãíàëüíîé Mart[] âíóòðè êîðèäîðà: |
//| Ïðè äâèæåíèè ðûíêà ââåðõ - ñèãíàëüíàÿ îòõîäèò îò íèæíåãî |
//| áîðäþðà, ïåðåñåêàåò êîðèäîð è ñëèâàåòñÿ ñ âåðõíèì áîðäþðîì. |
//| Àíàëîãè÷íî, ñ òî÷íîñòüþ äî íàîáîðîò, - ïðè äâèæåíèè ðûíêà âíèç. |
//| Äî òåõ ïîð, ïîêà ðûíîê áóäåò äâèãàòüñÿ íàïðàâëåííî, ñèãíàëüíàÿ |
//| áóäåò "äåðæàòüñÿ" ñîîòâåòñòâóþùåé ãðàíèöû êîðèäîðà. Ïðè ýòîì |
//| óâåëè÷åíèå øèðèíû êîðèäîðà îçíà÷àåò íàïðàâëåííîå äâèæåíèå. Ïðè |
//| êîëåáàíèÿõ ðûíêà êîðèäîð íà÷èíàåò ñóæàòüñÿ. Ñóæåíèåì êîðèäîðà |
//| ñîïðîâîæäàåòñÿ äâèæåíèåì ñèãíàëüíîé îò îäíîé ãðàíèöû ê äðóãîé |
//| âíóòðè êîðèäîðà, ïîñëå äîñòèæåíèÿ ïðîòèâîïîëîæíîé ãðàíèöû - |
//| êîðèäîð íà÷íåò ðàñøèðÿòüñÿ. |
//| Snake ìîæíî èñïîëüçîâàòü êàê ñàìîñòîÿòåëüíî, ñðàâíèâàÿ äâèæåíèå |
//| ñèãíàëüíîé íà ðàçíûõ ÒÔ îäíîâðåìåííî, òàê è äëÿ ïîñòðîåíèÿ |
//| äðóãèõ èíäèêàòîðîâ, èñïîëüçóÿ Mart[] âìåñòî öåíû áàðà. Äëÿ |
//| èíäèêàòîðîâ òèïà MA, OA, AC,.. èñïîëüçîâàòü HardCalc = true, à |
//| äëÿ èíäèêàòîðîâ òèïà ZigZag, Channel,.. - HardCalc = false, à |
//| çíà÷åíèå MartFiltr ïîäáèðàòü îò 3...5. Ïðè ýòîì ìîæíî îòñåèâàòü |
//| èñòèííûå è ëîæíûå âåðøèíû: åñëè âåðøèíà ïðîìåæóòî÷íàÿ, |
//| ñèãíàëüíàÿ Mart[] íå áóäåò ñîâïàäàòü ñ áîðäþðîì. |
//+------------------------------------------------------------------+
#property copyright ""
#property link "yuzefovich@gmail.com"
//----
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Red
#property indicator_color2 Red
#property indicator_color3 Blue
//----
extern int SnakeRange = 2;
extern int FilterPeriod = 24;
extern double MartFiltr = 2;
extern bool HardCalc = true;
//----
double BorderTop[];
double BorderBot[];
double Mart[];
double Axis[];
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void deinit()
{
Comment("");
return;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int init()
{
int draw_begin;
draw_begin = FilterPeriod + SnakeRange + 2;
IndicatorBuffers (4);
SetIndexBuffer (0, BorderTop);
SetIndexBuffer (1, BorderBot);
SetIndexBuffer (2, Mart);
SetIndexBuffer (3, Axis);
SetIndexStyle (0, DRAW_LINE);
SetIndexStyle (1, DRAW_LINE);
SetIndexStyle (2, DRAW_LINE, 0, 2);
SetIndexDrawBegin (0, draw_begin);
SetIndexDrawBegin (1, draw_begin);
SetIndexDrawBegin (2, draw_begin);
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start()
{
int counted_bars = IndicatorCounted();
int limit, i;
if(counted_bars < 0)
return(-1);
if(Bars <= (FilterPeriod + SnakeRange+2))
return(0);
if(SnakeRange < 4)
SnakeRange = 4;
if(counted_bars > 0)
counted_bars--;
limit = Bars - counted_bars;
for(i = limit; i >= 0; i--)
MainCalculation(i);
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void MainCalculation(int Pos)
{
int v;
MartAxis(Pos);
if(HardCalc == true)
SmoothOverMart2(Pos);
else
SmoothOverMart(Pos);
//----
return;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void MartAxis(int Pos)
{
int SnakeWeight, i, w, ww, Shift;
double SnakeSum;
Axis[Pos] = iMA(NULL, 0, SnakeRange + 1, 0, MODE_LWMA, PRICE_WEIGHTED, Pos);
for(Shift = Pos + SnakeRange + 2; Shift > Pos; Shift--)
{
SnakeSum = 0.0;
SnakeWeight = 0;
i = 0;
w = Shift + SnakeRange;
ww = Shift - SnakeRange;
if(ww < Pos)
ww = Pos;
while(w >= Shift)
{
i++;
SnakeSum = SnakeSum + i*SnakePrice(w);
SnakeWeight = SnakeWeight + i;
w--;
}
while(w >= ww)
{
i--;
SnakeSum = SnakeSum + i*SnakePrice(w);
SnakeWeight = SnakeWeight + i;
w--;
}
Axis[Shift] = SnakeSum / SnakeWeight;
}
return;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double SnakePrice(int Shift)
{
return((2*Close[Shift] + High[Shift] + Low[Shift]) / 4);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void SmoothOverMart(int Pos)
{ // Ïðàâèì èñòîðèþ íà ïîñëåäíèõ Pos...(Pos+SnakeRange+2) áàðàõ
int Shift;
double a, t, b;
for(Shift = Pos + SnakeRange + 2; Shift >= Pos; Shift--)
{
t = Axis[ArrayMaximum(Axis, FilterPeriod, Shift)];
b = Axis[ArrayMinimum(Axis, FilterPeriod, Shift)];
a = Axis[Shift];
BorderTop[Shift] = (2*(1 + MartFiltr)*a + (t - b)) / 2 / (1 + MartFiltr);
BorderBot[Shift] = (2*(1 + MartFiltr)*a - (t - b)) / 2 / (1 + MartFiltr);
Mart[Shift] = (2*(2 + MartFiltr)*a - (t + b)) / 2 / (1 + MartFiltr);
}
return;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void SmoothOverMart2(int Shift)
{ // Íå ïîäïðàâëÿåì èñòîðèþ íà ïîñëåäíèõ áàðàõ
double a, t, b;
t = Axis[ArrayMaximum(Axis, FilterPeriod, Shift)];
b = Axis[ArrayMinimum(Axis, FilterPeriod, Shift)];
a = Axis[Shift];
BorderTop[Shift] = (2*(1 + MartFiltr)*a + (t - b))/2/(1 + MartFiltr);
BorderBot[Shift] = (2*(1 + MartFiltr)*a - (t - b))/2/(1 + MartFiltr);
Mart[Shift] = (2*(2 + MartFiltr)*a - (t + b)) / 2 / (1 + MartFiltr);
return;
}
//---------------------------------------------------------------------
Comments