PriceChannel_Stop_v6i
Download scriptThis script functions as a technical analysis tool designed to help traders identify market trends and potential "stop" levels based on price volatility. Rather than simply showing where the price is, it focuses on calculating boundaries that define the current market direction.
Core Logic and Functionality
The logic operates through three primary stages: boundary calculation, trend detection, and visual signaling.
1. Establishing Price Boundaries The tool first looks at a specific period of historical data (the "Channel Period") to identify the highest and lowest prices reached. Using these extremes, it calculates a dynamic "channel." Instead of just marking the outer limits, it uses a narrowing factor (Risk) to create internal boundaries. This helps determine how much price movement is considered "normal" volatility versus a significant trend shift.
2. Trend Identification & Filtering The script identifies the market direction by monitoring whether the current price closes outside of these calculated boundaries:
- Upward Trend: Triggered when the price breaks above the upper boundary.
- Downward Trend: Triggered when the price drops below the lower boundary.
To prevent "false starts" or erratic flickering during minor fluctuations, the script includes a correction mechanism. Once a trend is established, the boundaries are adjusted so they do not retreat in the direction of the trend; they only move forward as new extremes are formed. This ensures the trend remains "locked" until a significant reversal occurs.
3. Visual Output and Alerts The script translates these calculations into various visual elements on your chart:
- Trend Lines: It draws continuous lines representing the current active stop level (the boundary the price must stay above or below to maintain the trend).
- Signals: It generates specific markers or icons at the exact moment the trend flips.
- Color Bars: Depending on user settings, it can highlight price bars that are moving in favor of the current trend, providing a quick visual cue of momentum.
- Audio Alerts: The script is capable of sending a real-time notification (sound alert) the moment the market switches from an upward to a downward trend (or vice versa).
Summary for the User
Essentially, this tool acts as a "trend guard." It maps out the volatile territory of the market and draws a line in the sand. If the price stays on your side of that line, the trend is active. If the price crosses that line, the script signals a potential change in market direction, allowing you to see where the "danger zone" for your current position lies.
//+------------------------------------------------------------------+
//| PriceChannel_Stop_v6.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 8
#property indicator_color1 Blue
#property indicator_color2 Red
#property indicator_color3 Blue
#property indicator_color4 Red
#property indicator_color5 Blue
#property indicator_color6 Red
#property indicator_color7 Blue
#property indicator_color8 Red
//---- input parameters
extern int ChannelPeriod=9; //Price Channel Period
extern double Risk=0.30; //channel narrowing factor (0...0,5)
extern int Signal=1; //Display signals mode: 1-Signals & Stops; 0-only Stops; 2-only Signals;
extern int Line=1; //Display line mode: 0-no,1-yes
extern int ColorBar=1; //Display color bars mode: 0-no,1-yes
extern int TimeFrame=0; //TimeFrame in min
extern int Nbars=1000;
//---- indicator buffers
double UpTrendBuffer[];
double DownTrendBuffer[];
double UpTrendSignal[];
double DownTrendSignal[];
double UpTrendLine[];
double DownTrendLine[];
double UpTrendBar[];
double DownTrendBar[];
extern bool SoundON=true;
bool TurnedUp = false;
bool TurnedDown = false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
string short_name;
//---- indicator line
SetIndexBuffer(0,UpTrendBuffer);
SetIndexBuffer(1,DownTrendBuffer);
SetIndexBuffer(2,UpTrendSignal);
SetIndexBuffer(3,DownTrendSignal);
SetIndexBuffer(4,UpTrendLine);
SetIndexBuffer(5,DownTrendLine);
SetIndexBuffer(6,UpTrendBar);
SetIndexBuffer(7,DownTrendBar);
SetIndexStyle(0,DRAW_ARROW);
SetIndexStyle(1,DRAW_ARROW);
SetIndexStyle(2,DRAW_ARROW);
SetIndexStyle(3,DRAW_ARROW);
SetIndexStyle(4,DRAW_LINE);
SetIndexStyle(5,DRAW_LINE);
SetIndexStyle(6,DRAW_HISTOGRAM,STYLE_SOLID,1);
SetIndexStyle(7,DRAW_HISTOGRAM,STYLE_SOLID,1);
SetIndexArrow(0,159);
SetIndexArrow(1,159);
SetIndexArrow(2,241);
SetIndexArrow(3,242);
//---- name for DataWindow and indicator subwindow label
short_name="PriceChannel_Stop("+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");
SetIndexLabel(6,"UpTrend Bar");
SetIndexLabel(7,"DownTrend Bar");
//----
SetIndexDrawBegin(0,ChannelPeriod);
SetIndexDrawBegin(1,ChannelPeriod);
SetIndexDrawBegin(2,ChannelPeriod);
SetIndexDrawBegin(3,ChannelPeriod);
SetIndexDrawBegin(4,ChannelPeriod);
SetIndexDrawBegin(5,ChannelPeriod);
SetIndexDrawBegin(6,ChannelPeriod);
SetIndexDrawBegin(7,ChannelPeriod);
//----
return(0);
}
//+------------------------------------------------------------------+
//| PriceChannel_Stop_v6 |
//+------------------------------------------------------------------+
int start()
{
datetime TimeArray[];
int i,shift,trend,y=0;
double high, low, price, sum, VolAverage,UpBar,DnBar;
double smax[25000],smin[25000],bsmax[25000],bsmin[25000],Mid[25000],Vol[25000];
double LowArray[],HighArray[];
for (shift=Nbars-1;shift>=0;shift--)
{
UpTrendBuffer[shift]=0.0;
DownTrendBuffer[shift]=0.0;
UpTrendSignal[shift]=0.0;
DownTrendSignal[shift]=0.0;
UpTrendLine[shift]=EMPTY_VALUE;
DownTrendLine[shift]=EMPTY_VALUE;
UpTrendBar[shift]=0.0;
DownTrendBar[shift]=0.0;
}
// Draw price channel boards + calculation : Channel middle, half channel width,
ArrayCopySeries(TimeArray,MODE_TIME,Symbol(),TimeFrame);
ArrayCopySeries(LowArray,MODE_LOW,Symbol(),TimeFrame);
ArrayCopySeries(HighArray,MODE_HIGH,Symbol(),TimeFrame);
for(i=0,y=0;i<Nbars;i++)
{
if (Time[i]<TimeArray[y]) y++;
smin[i]=LowArray[Lowest(NULL,TimeFrame,MODE_LOW,ChannelPeriod,y)];
smax[i]=HighArray[Highest(NULL,TimeFrame,MODE_HIGH,ChannelPeriod,y)];
Mid[i]=0.5*(smin[i]+smax[i]);
}
//
for (shift=Nbars-ChannelPeriod-1;shift>=0;shift--)
{
// Calculation channel stop values
bsmax[shift]=smax[shift]-(smax[shift]-smin[shift])*Risk;
bsmin[shift]=smin[shift]+(smax[shift]-smin[shift])*Risk;
// Signal area : any conditions to trend determination:
// 1. Price Channel breakout
if(Risk>0)
{
if(Close[shift]>bsmax[shift]) trend=1;
if(Close[shift]<bsmin[shift]) trend=-1;
}
else
{
if(Close[shift]>bsmax[shift+1]) trend=1;
if(Close[shift]<bsmin[shift+1]) trend=-1;
}
// Correction boards values with existing trend
if(trend>0 && bsmin[shift]<bsmin[shift+1]) bsmin[shift]=bsmin[shift+1];
if(trend<0 && bsmax[shift]>bsmax[shift+1]) bsmax[shift]=bsmax[shift+1];
// Drawing area
UpBar=bsmax[shift];
DnBar=bsmin[shift];
if ( Risk == 0 ){UpBar=Mid[shift];DnBar=Mid[shift];}
if (trend>0)
{
if (Signal>0 && UpTrendBuffer[shift+1]==-1.0)
{
//bsmin[shift]=smin[shift];
UpTrendSignal[shift]=bsmin[shift];
if(Line>0) UpTrendLine[shift]=bsmin[shift];
if (SoundON==true && shift==0 && !TurnedUp)
{
Alert("Price Up ",Symbol(),"-",Period());
TurnedUp = true;
TurnedDown = false;
}
}
else
{
UpTrendBuffer[shift]=bsmin[shift];
if(Line>0) UpTrendLine[shift]=bsmin[shift];
UpTrendSignal[shift]=-1;
}
if(ColorBar>0)
{
if(Close[shift]>UpBar)
{
UpTrendBar[shift]=High[shift];
DownTrendBar[shift]=Low[shift];
}
else
{
UpTrendBar[shift]=EMPTY_VALUE;
DownTrendBar[shift]=EMPTY_VALUE;
}
}
if (Signal==2) UpTrendBuffer[shift]=0;
DownTrendBuffer[shift]=-1.0;
DownTrendLine[shift]=EMPTY_VALUE;
}
if (trend<0)
{
if (Signal>0 && DownTrendBuffer[shift+1]==-1.0)
{
//bsmax[shift]=smax[shift];
DownTrendSignal[shift]=bsmax[shift];
if(Line>0) DownTrendLine[shift]=bsmax[shift];
if (SoundON==true && shift==0 && !TurnedDown)
{
Alert("Price Down",Symbol(),"-",Period());
TurnedDown = true;
TurnedUp = false;
}
}
else
{
DownTrendBuffer[shift]=bsmax[shift];
if(Line>0)DownTrendLine[shift]=bsmax[shift];
DownTrendSignal[shift]=-1;
}
if(ColorBar>0)
{
if(Close[shift]<DnBar)
{
UpTrendBar[shift]=Low[shift];
DownTrendBar[shift]=High[shift];
}
else
{
UpTrendBar[shift]=EMPTY_VALUE;
DownTrendBar[shift]=EMPTY_VALUE;
}
}
if (Signal==2) DownTrendBuffer[shift]=0;
UpTrendBuffer[shift]=-1.0;
UpTrendLine[shift]=EMPTY_VALUE;
}
}
return(0);
}
//+------------------------------------------------------------------+
Comments