FractalChannel_v5
Download scriptOverview
The Fractal Channel is a technical analysis tool designed to visualize price action boundaries by identifying significant structural highs and lows. Unlike standard moving averages that smooth out price data, this script focuses on "Fractals"—specific peaks and valleys that represent local turning points in the market. By identifying these structural points, the indicator creates a dynamic channel that helps traders visualize the current range and volatility of an asset.
Core Logic and Functionality
1. Structural Identification (Fractal Detection) The script scans the price history to find specific "Fractals." A fractal is identified when a price point is higher (for a high) or lower (for a low) than the candles immediately surrounding it.
- Customizable Sensitivity: Users can define the "Fractal Size," which determines how many bars to the left and right the script looks to confirm a peak or valley. A larger size captures broader market structures, while a smaller size captures more frequent, minor price fluctuations.
- Price Source Selection: The logic allows for monitoring either the High/Low prices of candles or the Open/Close prices, depending on the user's preferred analysis style.
2. Channel Construction Once the highest and lowest structural points are identified, the script calculates a three-line channel:
- Upper Band: This represents a percentage-based offset from the highest structural peak. It creates a ceiling for the price movement.
- Lower Band: This represents a corresponding offset from the lowest structural valley, creating a floor.
- Middle Line: This serves as the equilibrium point, calculated automatically as the midpoint between the Upper and Lower bands.
3. Dynamic Scaling and Margins The script features a "Narrowing Ratio" (Margins). This allows the user to control how tightly the bands hug the structural extremes. By adjusting this, traders can decide whether they want a wide safety buffer or a tight corridor that follows price action more closely.
4. Real-Time Visual Feedback The indicator is designed to be highly readable:
- Visual Tracking: It draws lines directly on the chart window to show the evolution of the price channel over time.
- Data Labeling: The script can be configured to display the exact numerical values of the Upper and Lower bands on the current candle. This provides an immediate reference for traders who need to know specific price levels without having to hover their mouse over the lines.
Summary for the Trader
Essentially, this tool acts as a "smart container" for price action. It automatically identifies where the market has historically turned around (Fractals) and builds a visual boundary around those points. It helps in identifying support and resistance levels dynamically, providing a clearer picture of the current trading range than standard static lines.
//+------------------------------------------------------------------+
//| FractalChannel_v5.mq4 |
//| Copyright © 2006-07, TrendLaboratory |
//| http://finance.groups.yahoo.com/group/TrendLaboratory |
//| E-mail: igorad2003@yahoo.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006-07, TrendLaboratory"
#property link "http://finance.groups.yahoo.com/group/TrendLaboratory"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 LightBlue
#property indicator_color2 Tomato
#property indicator_color3 Yellow
#property indicator_width1 1
#property indicator_width2 1
#property indicator_style3 2
//---- input parameters
extern int FractalSize = 1; //Fractal Size in bars (ex. 1-3 bars,2-5 bars,3-7 bars)
extern int PriceMode = 0; //Apply to : 0-High/Low,1-Open/Close
extern double Margins = 0; //Narrowing ration (ex.0.3)
extern int Shift = 0; //Displace in bars (ex. 1 or -1)
extern int Mode = 0; //Channel Mode: 0-default,1-similar to Fractal Chaos Bands
extern int DisplayText = 0; //0-off,1-on
extern color TextColor = White;
extern double TextSize = 8;
extern double TextDelta = 0; //Text deviation in pips
//---- buffers
double UpBuffer[];
double DnBuffer[];
double MdBuffer[];
double smin[];
double smax[];
double HiArray[],LoArray[];
int Length;
string short_name, ob_name1, ob_name2;
bool firstTime = true;
double prevUp, prevDn;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicator line
IndicatorBuffers(5);
SetIndexStyle(0,DRAW_LINE);
SetIndexStyle(1,DRAW_LINE);
SetIndexStyle(2,DRAW_LINE);
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("+FractalSize+")";
IndicatorShortName(short_name);
SetIndexLabel(0,"Up Band");
SetIndexLabel(1,"Down Band");
SetIndexLabel(2,"Middle");
SetIndexShift(0,Shift);
SetIndexShift(1,Shift);
SetIndexShift(2,Shift);
//----
Length = 2*FractalSize+1;
SetIndexDrawBegin(0,Length);
SetIndexDrawBegin(1,Length);
SetIndexDrawBegin(2,Length);
//----
ArrayResize(HiArray,Length);
ArrayResize(LoArray,Length);
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
ObjDel(ob_name1);
ObjDel(ob_name2);
//----
return(0);
}
//+------------------------------------------------------------------+
//| FractalChannel_v5 |
//+------------------------------------------------------------------+
int start()
{
int shift,k,counted_bars=IndicatorCounted();
double v1,v2;
if ( counted_bars > 0 ) int limit=Bars-counted_bars-1;
if ( counted_bars < 0 ) return(0);
if ( counted_bars ==0 ) limit=Bars-Length;
if ( counted_bars < 1 )
for(int i=1;i<Length;i++)
{
UpBuffer[Bars-i] = EMPTY_VALUE;
DnBuffer[Bars-i] = EMPTY_VALUE;
MdBuffer[Bars-i] = EMPTY_VALUE;
}
for(shift=limit;shift>=0;shift--)
{
for(int j = 0; j < Length; j++)
{
if(PriceMode == 0)
{HiArray[j] = High[shift+j]; LoArray[j] = Low[shift+j];}
else
if(PriceMode == 1)
{HiArray[j] = MathMax(Close[shift+j],Open[shift+j]); LoArray[j] = MathMin(Close[shift+j],Open[shift+j]);}
}
v1 = Fractals(HiArray,0,FractalSize);
v2 = Fractals(LoArray,1,FractalSize);
smax[shift]=smax[shift+1];
if ( v1>0 ) smax[shift]=v1;
if (Mode == 0)
if (HiArray[0]>smax[shift]) smax[shift]=HiArray[0];
smin[shift]=smin[shift+1];
if ( v2>0 ) smin[shift]=v2;
if (Mode == 0)
if (LoArray[0]<smin[shift]) smin[shift]=LoArray[0];
if (shift==Bars-Length) {smin[shift]=LoArray[0];smax[shift]=HiArray[0];}
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;
}
if (DisplayText==1 && (firstTime || NewBar() || UpBuffer[0] != prevUp || DnBuffer[0] != prevDn))
{
ob_name1 = short_name+" Up";
ob_name2 = short_name+" Dn";
ObjDel(ob_name1);
ObjDel(ob_name2);
int win = 0;
ObjectCreate(ob_name1,OBJ_TEXT,win,iTime(NULL,0,0)+(Time[0]-Time[1])*3,UpBuffer[0]+TextDelta*Point);
ObjectCreate(ob_name2,OBJ_TEXT,win,iTime(NULL,0,0)+(Time[0]-Time[1])*3,DnBuffer[0]+TextDelta*Point);
ObjectSetText(ob_name1,DoubleToStr(UpBuffer[0],Digits),TextSize,"Arial",TextColor);
ObjectSetText(ob_name2,DoubleToStr(DnBuffer[0],Digits),TextSize,"Arial",TextColor);
prevUp = UpBuffer[0];
prevDn = DnBuffer[0];
}
return(0);
}
double Fractals(double price[],int type,int size)
{
int k=1;
double v1, cond[100];
while (k<=size)
{
if (type==0) bool condition = price[size+k]<=price[size] && price[size-k]<price[size];
else condition = price[size+k]>=price[size] && price[size-k]>price[size];
if (condition)
{
if (type==0) cond[k]=price[size]; else cond[k]=price[size];
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;}
}
return(v1);
}
//+------------------------------------------------------------------+
bool NewBar()
{
static datetime dt = 0;
if (Time[0] != dt) {dt = Time[0]; return(true);}
return(false);
}
void ObjDel(string name)
{
int _GetLastError;
int obtotal = ObjectsTotal();
for ( int i = 0; i < obtotal; i ++ )
{
if( !ObjectDelete(name) )
{
_GetLastError = GetLastError();
//Print( "ObjectDelete Error #", _GetLastError );
}
}
}
Comments