This script is designed as a visual trading tool that identifies price trends and provides specific "stop" levels or signal points based on price volatility. Instead of just showing a moving average, it calculates dynamic boundaries to help traders understand the current market direction.
Core Logic Overview
The script operates by analyzing price action over a specific look-back period (defined by the ChannelPeriod) to establish a "buffer zone" around the market's high and low points. Here is the step-by-step logic of how it processes data:
1. Volatility Calculation
The tool looks at a set number of previous candles to find the highest high and the lowest low. It then calculates a price range based on these extremes. By applying a specific risk multiplier (Risk), it determines a "buffer" distance. This ensures that the trend lines aren't just reacting to tiny, insignificant price flickers, but rather to meaningful movements.
2. Trend Identification The script continuously monitors whether the current closing price has broken through these calculated boundaries:
- Upward Trend: If the price closes above the calculated upper boundary, the script identifies a bullish (upward) trend.
- Downward Trend: If the price closes below the calculated lower boundary, it identifies a bearish (downward) trend.
3. Dynamic Boundary Adjustment To ensure the indicator stays relevant during a sustained move, the script includes "locking" logic:
- During an Upward Trend, the script attempts to keep the lower support level at its highest point (preventing the "floor" from dropping as the price climbs).
- During a Downward Trend, it attempts to keep the upper resistance level at its lowest point (preventing the "ceiling" from rising as the price falls).
4. Visual Signals and Lines The script translates these calculations into visual elements on your chart:
- Main Lines: These represent the active trend boundaries. They show you where the current support or resistance sits based on the established trend.
- Signals: When the script detects a transition—for example, moving from a downward trend to an upward trend—it can generate a specific signal point. This acts as a visual notification that the market momentum has shifted from one direction to another.
Summary for the User
Essentially, this tool acts as a "trend tracker." It identifies which way the market is moving by looking at price extremes, draws lines that follow those trends while filtering out minor noise, and highlights the specific moments when the trend flips from bullish to bearish (or vice versa).
//+------------------------------------------------------------------+
//| Version July 1, 2006 |
//| Editing Nikolay Kositsin 15.06.2006 farria@mail.redcom.ru |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| PriceChannel_Stop.mq4 |
//| Copyright © 2005, TrendLaboratory Ltd. |
//| E-mail: igorad2004@list.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, TrendLaboratory Ltd."
#property link "E-mail: igorad2004@list.ru"
//---- îòðèñîâêà èíäèêàòîðà â ãëàâíîì îêíå
#property indicator_chart_window
//---- êîëè÷åñòâî èíäèêàòîðíûõ áóôôåðîâ
#property indicator_buffers 6
//---- öâåòà èíäèêàòîðà
#property indicator_color1 Brown
#property indicator_color2 Magenta
#property indicator_color3 Lime
#property indicator_color4 Red
#property indicator_color5 Lime
#property indicator_color6 Red
//---- òîëùèíà èíäèêàòîðíûõ ëèíèé
#property indicator_width1 0
#property indicator_width2 0
#property indicator_width3 2
#property indicator_width4 2
#property indicator_width5 0
#property indicator_width6 0
//---- ÂÕÎÄÍÛÅ ÏÀÐÀÌÅÒÐÛ ÈÍÄÈÊÀÒÎÐÀ ----+
extern int ChannelPeriod = 5;
extern double Risk = 0.10;
extern bool Signal = true;
extern bool Line = true;
//---- ---------------------------------+
//---- èíäèêàòîðíûå áóôôåðû
double UpTrendBuffer [];
double DownTrendBuffer[];
double UpTrendSignal [];
double DownTrendSignal[];
double UpTrendLine [];
double DownTrendLine [];
//+------------------------------------------------------------------+
//| PriceChannel_Stop initialization function |
//+------------------------------------------------------------------+
int init()
{
string short_name;
//---- 6 èíäèêàòîðíûõ áóôôåðà èñïîëüçîâàíû äëÿ ñ÷¸òà
SetIndexBuffer(0, UpTrendBuffer);
SetIndexBuffer(1, DownTrendBuffer);
SetIndexBuffer(2, UpTrendSignal);
SetIndexBuffer(3, DownTrendSignal);
SetIndexBuffer(4, UpTrendLine);
SetIndexBuffer(5, DownTrendLine);
//---- Ñòèëü èñïîëíåíèÿ ãðàôèêà
SetIndexStyle(0, DRAW_ARROW);
SetIndexStyle(1, DRAW_ARROW);
SetIndexStyle(2, DRAW_ARROW);
SetIndexStyle(3, DRAW_ARROW);
SetIndexStyle(4, DRAW_LINE);
SetIndexStyle(5, DRAW_LINE);
SetIndexArrow(0, 159);
SetIndexArrow(1, 159);
SetIndexArrow(2, 108);
SetIndexArrow(3, 108);
//---- óñòàíîâêà çíà÷åíèé èíäèêàòîðà, êîòîðûå íå áóäóò âèäèìû íà ãðàôèêå
SetIndexEmptyValue(0, 0.0);
SetIndexEmptyValue(1, 0.0);
SetIndexEmptyValue(2, 0.0);
SetIndexEmptyValue(3, 0.0);
SetIndexEmptyValue(4, 0.0);
SetIndexEmptyValue(5, 0.0);
//---- èìÿ äëÿ îêîí äàííûõ è ëýéáà äëÿ ñóáúîêîí
short_name = "PriceChannel_Stop_v1("+ChannelPeriod+")";
IndicatorShortName(short_name);
SetIndexLabel(0, "UpTrend Stop");
SetIndexLabel(1, "DownTrend Stop");
SetIndexLabel(2, "UpTrend Signal");
SetIndexLabel(3, "DownTrend Signal");
SetIndexLabel(4, "UpTrend Line");
SetIndexLabel(5, "DownTrend Line");
//---- óñòàíîâêà íîìåðà áàðà, íà÷èíàÿ ñ êîòîðîãî áóäåò îòðèñîâûâàòüñÿ èíäèêàòîð
SetIndexDrawBegin(0, ChannelPeriod);
SetIndexDrawBegin(1, ChannelPeriod);
SetIndexDrawBegin(2, ChannelPeriod);
SetIndexDrawBegin(3, ChannelPeriod);
SetIndexDrawBegin(4, ChannelPeriod);
SetIndexDrawBegin(5, ChannelPeriod);
//---- Óñòàíîâêà ôîðìàòà òî÷íîñòè (êîëè÷åñòâî çíàêîâ ïîñëå äåñÿòè÷íîé òî÷êè) äëÿ âèçóàëèçàöèè çíà÷åíèé èíäèêàòîðà
IndicatorDigits(Digits);
//---- çàâåðøåíèå èíèöèàëèçàöèè
return(0);
}
//+------------------------------------------------------------------+
//| PriceChannel_Stop |
//+------------------------------------------------------------------+
int start()
{
//---- ïðîâåðêà êîëè÷åñòâà áàðîâ íà äîñòàòî÷íîñòü äëÿ ðàñ÷¸òà
if(Bars - 1 < ChannelPeriod + 1)
return(0);
//----+ Ââåäåíèå ïåðåìåííûõ ñ ïëàâàþùåé òî÷êîé
double bsmax[1], bsmin[1], high, low, price, dprice;
//---- ââåäåíèå ïåðåìåííûõ ïàìÿòè
static int time2, TREND;
static double BSMAX, BSMIN;
//----+ Ââåäåíèå öåëûõ ïåðåìåííûõ è ïîëó÷åíèå óæå ïîäñ÷èòàííûõ áàðîâ
int trend, MaxBar, bar, limit, ii, counted_bars = IndicatorCounted();
//---- ïðîâåðêà íà âîçìîæíûå îøèáêè
if(counted_bars < 0)
return(-1);
//---- ïîñëåäíèé ïîäñ÷èòàííûé áàð äîëæåí áûòü ïåðåñ÷èòàí
if(counted_bars > 0)
counted_bars--;
//---- îïðåäåëåíèå íîìåðà ñàìîãî ñòàðîãî áàðà, íà÷èíàÿ ñ êîòîðîãî áóäåò ïðîèçåä¸í ïåðåñ÷¸ò íîâûõ áàðîâ
MaxBar = Bars - 1 - ChannelPeriod - 1;
limit = Bars - counted_bars - 1;
//---- èíèöèàëèçàöèÿ íóëÿ
if(limit > MaxBar)
{
for(bar = limit; bar >= MaxBar; bar--)
{
UpTrendBuffer [bar] = 0.0;
DownTrendBuffer[bar] = 0.0;
UpTrendSignal [bar] = 0.0;
DownTrendSignal[bar] = 0.0;
UpTrendLine [bar] = 0.0;
DownTrendLine [bar] = 0.0;
}
limit=MaxBar;
}
//---- èçìåíåíèå ðàçìåðîâ âðåìåííûõ áóôôåðîâ
if(ArrayResize(bsmax, limit + 2) != limit + 2)
return(-1);
if(ArrayResize(bsmin, limit + 2) != limit + 2)
return(-1);
//---- ïðåäâàðèòåëüíûé öèêë ðàñ÷¸òà âðåìåííûõ áóôôåðîâ
for(bar = limit; bar >= 0; bar--)
{
high = High[bar];
low = Low[bar];
ii = bar - 1 + ChannelPeriod;
while(ii >= bar)
{
price = High[ii];
//----
if(high < price)
high = price;
price = Low[ii];
//----
if(low > price)
low = price;
ii--;
}
dprice = (high - low)*Risk;
bsmax[bar] = high - dprice;
bsmin[bar] = low + dprice;
}
//+--- âîññòàíîâëåíèå çíà÷åíèé ïåðåìåííûõ +======+
int Tnew = Time[limit+1];
if(limit < MaxBar)
if(Tnew == time2)
{
bsmax[limit+1] = BSMAX;
bsmin[limit+1] = BSMIN;
trend = TREND;
}
else
{
if(Tnew > time2)
Print("ERROR01");
else
Print("ERROR02");
return(-1);
}
//---- îñíîâíîé öèêë ðàñ÷¸òà èíäèêàòîðà
for(bar = limit; bar >= 0; bar--)
{
//+--- Ñîõðàíåíèå çíà÷åíèé ïåðåìåííûõ +====+
if(bar == 1)
if(((limit == 1) && (time2 == Time[2])) || (limit > 1))
{
time2 = Time [2];
BSMAX = bsmax[2];
BSMIN = bsmin[2];
TREND = trend;
}
//----
UpTrendBuffer [bar] = 0.0;
DownTrendBuffer[bar] = 0.0;
UpTrendSignal [bar] = 0.0;
DownTrendSignal[bar] = 0.0;
UpTrendLine [bar] = 0.0;
DownTrendLine [bar] = 0.0;
//----
if(Close[bar] > bsmax[bar+1])
trend = 1;
if(Close[bar] < bsmin[bar+1])
trend = -1;
//----
if(trend > 0 && bsmin[bar] < bsmin[bar+1])
bsmin[bar] = bsmin[bar+1];
if(trend < 0 && bsmax[bar] > bsmax[bar+1])
bsmax[bar] = bsmax[bar+1];
//---- +++
if(trend > 0)
{
price = bsmin[bar];
if(Signal == true && DownTrendBuffer[bar+1] > 0)
{
UpTrendSignal[bar] = price;
if(Line == true)
UpTrendLine[bar] = price;
}
else
{
UpTrendBuffer[bar] = price;
if(Line == true)
UpTrendLine[bar] = price;
}
}
//---- +++
if(trend < 0)
{
price = bsmax[bar];
if(Signal == true && UpTrendBuffer[bar+1] > 0)
{
DownTrendSignal[bar] = price;
if(Line == true)
DownTrendLine[bar] = price;
}
else
{
DownTrendBuffer[bar] = price;
if(Line == true)
DownTrendLine[bar] = price;
}
}
//---- +++
}
//----
return(0);
}
//+-----------------------------------------------------------------------------------+
Comments