SHI_Channel_true_with_quadrants

Download script
Author: Copyright � 2004, Shurka & Kevin, quandrants added by itLogics
SHI_Channel_true_with_quadrants

This script is designed to automatically identify and project trend channels on a trading chart. Rather than relying on manual drawing, it uses mathematical logic to detect significant price structures and project them forward to help traders visualize potential support and resistance zones.

Core Logic and Workflow

1. Identifying Key Pivot Points (Fractals) The script begins by scanning the recent price history to find "fractals"—specific peaks and valleys in the market. It looks for points where the price reaches a local high or low relative to its surrounding bars. The specific distance it looks back varies automatically depending on the timeframe you are using (e.g., it looks at different scales for a 1-minute chart versus a daily chart).

2. Establishing the Trend Direction Once it identifies these peaks and valleys, it determines the direction of the trend:

  • If it finds a significant high followed by a significant low, it calculates the trajectory based on that movement.
  • If it finds a low followed by a high, it calculates the opposite trajectory.

3. Calculating the Channel Slope After identifying two primary points (the start and end of a trend segment), the script calculates a "Step." This is essentially the rate of change—how much the price moves up or down over a specific number of bars. This mathematical slope is then used to build the rest of the channel.

4. Dynamic Adjustment and Boundary Detection The logic doesn't just draw a straight line between two points; it performs a "sanity check" on the data. It scans the price history between the identified points to ensure that the projected channel lines do not cut through existing historical price action. If it detects that the price has breached certain boundaries, it adjusts the starting position of the channel to better fit the actual market behavior.

5. Visual Output Once the calculations are finalized, the script draws four distinct trend lines on your chart:

  • The Outer Boundaries: Two solid lines representing the primary upper and lower limits of the price channel.
  • The Median Line: A dashed line representing the exact middle of the channel.
  • The Inner Support/Resistance Lines: Two dotted lines that further divide the channel into smaller segments.

6. Real-Time Information To provide immediate context, the script also displays a text comment on the screen. This tells you the total size of the channel (the distance between the boundaries) and the current slope, allowing you to see how aggressive or flat the current trend is at a glance.

Miscellaneous
Implements a curve of type %1
12 Views
0 Downloads
0 Favorites
SHI_Channel_true_with_quadrants
//+------------------------------------------------------------------+
//|                                                  SHI_Channel.mq4 |
//|                                 Copyright © 2004, Shurka & Kevin |
//|                                     quandrants added by itLogics |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, Shurka & Kevin, quandrants added by itLogics"
#property link      ""

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Lime
double ExtMapBuffer1[];
//---- input parameters
extern int       AllBars=192;
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);
//----
	
	
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 
DelObj();   
//----
   return(0);
  }

void DelObj()
{
	ObjectDelete("TL1");
	ObjectDelete("TL2");
	ObjectDelete("MIDL");
	ObjectDelete("MIDTL1");
	ObjectDelete("MIDTL2");
}

//+------------------------------------------------------------------+
//| 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;
	DelObj();
	ObjectCreate("TL1",OBJ_TREND,0,T2,PP+Step*AB,T1,PP); 
		ObjectSet("TL1",OBJPROP_COLOR,Lime); 
		ObjectSet("TL1",OBJPROP_WIDTH,2); 
		ObjectSet("TL1",OBJPROP_STYLE,STYLE_SOLID); 
	ObjectCreate("TL2",OBJ_TREND,0,T2,P2,T1,P1); 
		ObjectSet("TL2",OBJPROP_COLOR,Lime); 
		ObjectSet("TL2",OBJPROP_WIDTH,2); 
		ObjectSet("TL2",OBJPROP_STYLE,STYLE_SOLID); 
	ObjectCreate("MIDL",OBJ_TREND,0,T2,(P2+PP+Step*AB)/2,T1,(P1+PP)/2);
		ObjectSet("MIDL",OBJPROP_COLOR,Lime); 
		ObjectSet("MIDL",OBJPROP_WIDTH,1); 
		ObjectSet("MIDL",OBJPROP_STYLE,STYLE_DASH);
	ObjectCreate("MIDTL1",OBJ_TREND,0,T2,((PP+Step*AB)+((P2+PP+Step*AB)/2))/2,T1,(PP+((P1+PP)/2))/2); 
		ObjectSet("MIDTL1",OBJPROP_COLOR,Lime); 
		ObjectSet("MIDTL1",OBJPROP_WIDTH,1); 
		ObjectSet("MIDTL1",OBJPROP_STYLE,STYLE_DOT); 
	ObjectCreate("MIDTL2",OBJ_TREND,0,T2,(P2+((P2+PP+Step*AB)/2))/2,T1,(P1+((P1+PP)/2))/2); 
		ObjectSet("MIDTL2",OBJPROP_COLOR,Lime); 
		ObjectSet("MIDTL2",OBJPROP_WIDTH,1); 
		ObjectSet("MIDTL2",OBJPROP_STYLE,STYLE_DOT); 
		Comment(" Channel size = ", DoubleToStr(MathAbs(PP - P1)/Point,0), " Slope = ", DoubleToStr(-Step/Point, 2));
//----

//----
   return(0);
  }
//+------------------------------------------------------------------+

Comments