SHI Channel11_v2
Download scriptThis script is a technical analysis tool designed to identify and project specific price channels on a trading chart. It focuses on recognizing structural trends by identifying significant market "fractals" (high or low points) and using them to build a geometric framework for the price action.
Here is a breakdown of how the logic functions:
Core Identification Logic
The script begins by scanning the recent history of price bars (specifically looking back over a set number of bars, such as 240). It searches for two distinct "fractal" points:
- High Points: Significant peaks in price movement.
- Low Points: Significant troughs in price movement.
The tool looks for these points automatically based on the timeframe you are using (e.g., it adjusts its sensitivity whether you are looking at a 1-minute chart or a daily chart). Once it identifies two consecutive significant points (a high and a low), it establishes the "anchor" for the trend.
Trend Calculation
Once these two points are found, the script calculates the Slope and the Step.
- By measuring the distance between the high and low price points and dividing it by the time elapsed between them, it determines the rate at which the price is moving (the angle of the trend).
- It then mathematically projects these lines forward to create a linear channel.
Dynamic Adjustments
The script contains logic to ensure the channel remains relevant to current market conditions:
- Boundary Detection: It checks if the current price is breaking outside of the established boundaries. If it detects a breach, it identifies the new "price floor" or "ceiling" to keep the channel updated.
- Automatic Directionality: The script automatically calculates whether the trend is ascending or descending. Based on this, it draws two parallel lines (an upper and lower boundary) and a center line.
Visual Output
For the user, the script provides several visual and informative components:
- The Channel: It draws three primary lines—an upper boundary, a middle median line, and a lower boundary—providing a clear visual "tunnel" for price action.
- Visual Cues: It uses specific colors (Blue, Green, and Red) to differentiate between the boundaries and the median.
- Real-time Data: It displays a text comment on the chart that provides the exact numerical values for the Channel Size (the width of the tunnel) and the Slope (the speed/steepness of the trend).
In summary, this tool acts as an automated trend mapper. It identifies historical price extremes to draw a mathematical "path" of least resistance, helping traders visualize whether the market is currently contained within a specific range or moving at a specific rate of incline.
/*-----------------------------+
| |
| Shared by www.Aptrafx.com |
| |
+------------------------------*/
//+------------------------------------------------------------------+
//| SHI_Channel11.mq4 |
//| Copyright © 2004, Shurka & Kevin |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, Shurka & Kevin"
#property link ""
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Blue
#property indicator_color2 Green
#property indicator_color3 Red
#property indicator_color4 Red
double ExtMapBuffer1[];
double midBuffer1[];
double ABuffer1[];
double BBuffer1[];
//---- input parameters
extern int AllBars=240;
extern int BarsForFract=0;
int CurrentBar=0;
double Step=0;
int B1=-1,B2=-1;
int UpDown=0;
double P1=0,P2=0,PP=0;
int i=0,AB=300,BFF=0;
int ishift=0;
double iprice=0;
datetime T1,T2;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0,164);
SetIndexBuffer(0,ExtMapBuffer1);
SetIndexEmptyValue(0,0.0);
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1,midBuffer1);
SetIndexEmptyValue(1,0.0);
SetIndexStyle(2,DRAW_LINE);
SetIndexBuffer(2,ABuffer1);
SetIndexStyle(3,DRAW_LINE);
SetIndexBuffer(3,BBuffer1);
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
void DelObj()
{
ObjectDelete("TL1");
ObjectDelete("TL2");
ObjectDelete("MIDL");
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
//----
if ((AllBars==0) || (Bars<AllBars)) AB=Bars; else AB=AllBars; //AB-êîëè÷åñòâî îáñ÷èòûâàåìûõ áàðîâ
if (BarsForFract>0)
BFF=BarsForFract;
else
{
switch (Period())
{
case 1: BFF=12; break;
case 5: BFF=48; break;
case 15: BFF=24; break;
case 30: BFF=24; break;
case 60: BFF=12; break;
case 240: BFF=15; break;
case 1440: BFF=10; break;
case 10080: BFF=6; break;
default: DelObj(); return(-1); break;
}
}
CurrentBar=2; //ñ÷èòàåì ñ òðåòüåãî áàðà, ÷òîáû ôðàêòàë "çàêðåïèëñÿ
B1=-1; B2=-1; UpDown=0;
while(((B1==-1) || (B2==-1)) && (CurrentBar<AB))
{
//UpDown=1 çíà÷èò ïåðâûé ôðàêòàë íàéäåí ñâåðõó, UpDown=-1 çíà÷èò ïåðâûé ôðàêòàë
//íàéäåí ñíèçó, UpDown=0 çíà÷èò ôðàêòàë åù¸ íå íàéäåí.
//Â1 è Â2 - íîìåðà áàðîâ ñ ôðàêòàëàìè, ÷åðåç íèõ ñòðîèì îïîðíóþ ëèíèþ.
//Ð1 è Ð2 - ñîîòâåòñòâåííî öåíû ÷åðåç êîòîðûå áóäåì ëèíèþ ïðîâîäèòü
if((UpDown<1) && (CurrentBar==Lowest(Symbol(),Period(),MODE_LOW,BFF*2+1,CurrentBar-BFF)))
{
if(UpDown==0) { UpDown=-1; B1=CurrentBar; P1=Low[B1]; }
else { B2=CurrentBar; P2=Low[B2];}
}
if((UpDown>-1) && (CurrentBar==Highest(Symbol(),Period(),MODE_HIGH,BFF*2+1,CurrentBar-BFF)))
{
if(UpDown==0) { UpDown=1; B1=CurrentBar; P1=High[B1]; }
else { B2=CurrentBar; P2=High[B2]; }
}
CurrentBar++;
}
if((B1==-1) || (B2==-1)) {DelObj(); return(-1);} // Çíà÷èò íå íàøëè ôðàêòàëîâ ñðåäè 300 áàðîâ 8-)
Step=(P2-P1)/(B2-B1);//Âû÷èñëèëè øàã, åñëè îí ïîëîæèòåëüíûé, òî êàíàë íèñõîäÿùèé
P1=P1-B1*Step; B1=0;//ïåðåñòàâëÿåì öåíó è ïåðâûé áàð ê íóëþ
//À òåïåðü îïîðíóþ òî÷êó ïðîòèâîïîëîæíîé ëèíèè êàíàëà.
ishift=0; iprice=0;
if(UpDown==1)
{
PP=Low[2]-2*Step;
for(i=3;i<=B2;i++)
{
if(Low[i]<PP+Step*i) { PP=Low[i]-i*Step; }
}
if(Low[0]<PP) {ishift=0; iprice=PP;}
if(Low[1]<PP+Step) {ishift=1; iprice=PP+Step;}
if(High[0]>P1) {ishift=0; iprice=P1;}
if(High[1]>P1+Step) {ishift=1; iprice=P1+Step;}
}
else
{
PP=High[2]-2*Step;
for(i=3;i<=B2;i++)
{
if(High[i]>PP+Step*i) { PP=High[i]-i*Step;}
}
if(Low[0]<P1) {ishift=0; iprice=P1;}
if(Low[1]<P1+Step) {ishift=1; iprice=P1+Step;}
if(High[0]>PP) {ishift=0; iprice=PP;}
if(High[1]>PP+Step) {ishift=1; iprice=PP+Step;}
}
//Òåïåðü ïåðåñòàâèì êîíå÷íóþ öåíó è áàð íà ÀÂ, ÷òîáû ëèíèè êàíàëà ðèñîâàëèñü ïîäëèííåå
P2=P1+AB*Step;
T1=Time[B1]; T2=Time[AB];
//Åñëè íå áûëî ïåðåñå÷åíèÿ êàíàëà, òî 0, èíà÷å ñòàâèì ïñèñó.
if(iprice!=0) ExtMapBuffer1[ishift]=iprice;
for(i=0;i<=240;i++)
{
if (Step<=0)
{
midBuffer1[i]=(P1+PP)/2-MathAbs(Step*i);
ABuffer1[i]=(P1+PP)/2-MathAbs(Step*i)+MathAbs(PP - P1)/2;
BBuffer1[i]=(P1+PP)/2-MathAbs(Step*i)-MathAbs(PP - P1)/2;
}
else
{
midBuffer1[i]=(P1+PP)/2+MathAbs(Step*i);
ABuffer1[i]=(P1+PP)/2+MathAbs(Step*i)+MathAbs(PP - P1)/2;
BBuffer1[i]=(P1+PP)/2+MathAbs(Step*i)-MathAbs(PP - P1)/2;
}
}
DelObj();
Comment(" Channel size = ", DoubleToStr(MathAbs(PP - P1)/Point,0), " Slope = ", DoubleToStr(-Step/Point, 2));
//----
return(0);
}
//+------------------------------------------------------------------+
Comments