This technical tool is designed to identify and visualize structural boundaries in financial markets by analyzing price history. It focuses on identifying "Fractals"—specific turning points where the market creates local highs or lows—and uses these points to construct a dynamic visual channel on your chart.
Core Operational Logic
1. Identifying Structural Peaks and Troughs The script scans past price data to locate significant high and low points. It does this by comparing a specific candle's price against its neighbors on both the left and right sides. If a candle’s high is higher than all those surrounding it (based on a user-defined range), it is flagged as a structural peak. Conversely, if a candle's low is lower than its neighbors, it is flagged as a structural trough.
2. Tracking Market Extremes Once these peaks and troughs are identified, the tool maintains a continuous memory of the highest and lowest points encountered in the recent price action. Instead of just looking at one moment in time, it builds a "running record" of the market's range. It updates these records as new price data arrives, ensuring that the boundaries reflect the most significant price extremes over a specific period.
3. Dynamic Channel Construction Using the established high and low extremes, the script calculates three distinct visual lines:
- The Upper Boundary: This represents the "ceiling" of the current market range. It is calculated based on the highest recorded price point.
- The Lower Boundary: This represents the "floor" of the current market range, based on the lowest recorded price point.
- The Middle Line: The tool automatically calculates a centerline exactly halfway between the upper and lower boundaries, providing a clear visual representation of the "equilibrium" price.
4. Customizable Sensitivity The logic allows for adjustments in how these channels are rendered. You can define the "Margin," which dictates how much space is left between the calculated boundaries and the actual high/low points, and you can adjust the "Type" or range to determine how many candles must be compared to confirm a peak or trough.
Summary of Purpose
In practical terms, this script filters out "market noise" to show you the overarching structure of price movement. By highlighting the boundaries of the current trading range and providing a midline for balance, it helps traders visualize whether the market is expanding, contracting, or moving toward a significant structural limit.
//+------------------------------------------------------------------+
//| FractalChannel_v3.mq4 |
//| Copyright © 2006, TrendLaboratory |
//| http://finance.groups.yahoo.com/group/TrendLaboratory |
//| E-mail: igorad2003@yahoo.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, TrendLaboratory"
#property link "http://finance.groups.yahoo.com/group/TrendLaboratory"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Yellow
#property indicator_color2 Yellow
#property indicator_color3 Yellow
//---- input parameters
extern int ChannelType=1;
extern double Margins=0;
extern int Shift = 0;
extern int OpenClose=0;
//---- buffers
double UpBuffer[];
double DnBuffer[];
double MdBuffer[];
double smin[];
double smax[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
string short_name;
//---- indicator line
IndicatorBuffers(5);
SetIndexStyle(0,DRAW_LINE);
SetIndexStyle(1,DRAW_LINE);
SetIndexStyle(2,DRAW_LINE,2);
SetIndexBuffer(0,UpBuffer);
SetIndexBuffer(1,DnBuffer);
SetIndexBuffer(2,MdBuffer);
SetIndexBuffer(3,smin);
SetIndexBuffer(4,smax);
//---- name for DataWindow and indicator subwindow label
short_name="Fractal Channel("+ChannelType+")";
IndicatorShortName(short_name);
SetIndexLabel(0,"Up Channel");
SetIndexLabel(1,"Down Channel");
SetIndexLabel(2,"Middle Channel");
SetIndexShift(0,Shift);
SetIndexShift(1,Shift);
SetIndexShift(2,Shift);
//----
SetIndexDrawBegin(0,2*ChannelType);
SetIndexDrawBegin(1,2*ChannelType);
SetIndexDrawBegin(2,2*ChannelType);
//----
return(0);
}
//+------------------------------------------------------------------+
//| FractalChannel_v3 |
//+------------------------------------------------------------------+
int start()
{
int shift,k,counted_bars=IndicatorCounted();
double v1,v2,cond[100];
if ( counted_bars > 0 ) int limit=Bars-counted_bars-1;
if ( counted_bars < 0 ) return(0);
if ( counted_bars ==0 ) limit=Bars-2*ChannelType-1;
for(shift=limit;shift>=0;shift--)
{
k=1;
while (k<=ChannelType)
{
if (High[shift+ChannelType+k]<=High[shift+ChannelType] && High[shift+ChannelType-k]<High[shift+ChannelType])
{
cond[k]=High[shift+ChannelType];
if(k==1)
{v1=cond[k];k++;}
else
{
if(cond[k-1]==cond[k]){v1=cond[k];k++;}else {v1=0; break;}
}
}
else
{
v1=0;
break;
}
}
k=1;
while (k<=ChannelType)
{
if (Low[shift+ChannelType+k]>=Low[shift+ChannelType] && Low[shift+ChannelType-k]>Low[shift+ChannelType])
{
cond[k]=Low[shift+ChannelType];
if(k==1)
{v2=cond[k];k++;}
else
{
if(cond[k-1]==cond[k]){v2=cond[k];k++;}else {v2=0; break;}
}
}
else
{
v2=0;
break;
}
}
smax[shift]=smax[shift+1];
if ( v1>0 ) smax[shift]=v1;
if (High[shift]>smax[shift]) smax[shift]=High[shift];
smin[shift]=smin[shift+1];
if ( v2>0 ) smin[shift]=v2;
if (Low[shift]<smin[shift]) smin[shift]=Low[shift];
if (shift==Bars-1-2*ChannelType) {smin[shift]=Low[shift];smax[shift]=High[shift];}
UpBuffer[shift]=smax[shift]-(smax[shift]-smin[shift])*Margins;
DnBuffer[shift]=smin[shift]+(smax[shift]-smin[shift])*Margins;
MdBuffer[shift]=(UpBuffer[shift]+DnBuffer[shift])/2;
}
return(0);
}
//+------------------------------------------------------------------+
Comments