DTS-SHI_Channel_MTF

Download script
Author: Copyright � 2004, Shurka & Kevin
DTS-SHI_Channel_MTF

This script is designed to automatically identify and visualize a price "channel" on your trading charts. It works by analyzing historical price movements to find significant structural points and then projects these trends forward visually.

Here is a breakdown of how the logic functions:

Structural Identification

The script begins by scanning a specific history of recent price bars (a range defined by the user). It looks for "fractals"—essentially, local peaks (highs) and valleys (lows) in the price movement.

  • It specifically searches for the most prominent high and low points within these windows to establish the boundaries of the current market trend.
  • The timeframe you are viewing (e.g., 1-hour, 4-hour, Daily) dictates how sensitive the script is; it uses different "lookback" settings automatically to ensure it finds meaningful data for each specific timeframe.

Channel Calculation

Once the script identifies these two primary structural points (a high and a low), it performs the following mathematical operations:

  1. Trend Slope: It calculates the "step" or the rate of change between the high and low point. This determines whether the market is trending upward, downward, or moving sideways.
  2. Projection: Using this slope, it projects two parallel lines forward into the future. These lines represent the upper and lower boundaries of the price channel.
  3. Midline: It automatically calculates a centerline (the "middle" of the channel) to help traders identify the equilibrium point of the current trend.

Dynamic Adjustments

The script includes logic to ensure the channel remains relevant to current price action:

  • It checks if the current price has broken out of or interacted with the projected boundaries.
  • If a price breach occurs, it can adjust the "pivot" point of the calculation to stay aligned with the most recent significant market behavior.

Visual Output

Instead of just showing numbers, the script draws actual geometric objects on your chart:

  • Trend Lines: Two solid lines representing the top and bottom boundaries of the channel.
  • Midline: A dotted line running through the center of the channel.
  • Data Labels: Each line is labeled with dynamic text that displays the current Channel Size (the width between the boundaries) and the Slope (the steepness of the trend).

In summary, this tool automates the manual task of drawing trend channels by identifying historical peaks and valleys, calculating the mathematical trajectory of the price, and projecting that path forward to help you visualize potential support and resistance zones.

Price Data Components
Series array that contains the lowest prices of each barSeries array that contains the highest prices of each bar
Miscellaneous
Implements a curve of type %1
9 Views
0 Downloads
0 Favorites
DTS-SHI_Channel_MTF
//+------------------------------------------------------------------+
//|                                                  SHI_Channel.mq4 |
//|                                 Copyright © 2004, Shurka & Kevin |
//|                                 MTF by Michel                    |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, Shurka & Kevin"
#property link      ""

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red

//---- input parameters
extern int Timeframe = 0;
extern int AllBars=240;
extern int BarsForFract=0;

double ExtMapBuffer1[];
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;
color Clr;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexArrow(0,164);
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexEmptyValue(0,0.0);
   
   if(Timeframe == 0) Timeframe = Period();
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 
   DelObj();
//----
   return(0);
  }

void DelObj()
{
	ObjectDelete("TL1-"+Timeframe);
	ObjectDelete("TL2-"+Timeframe);
	ObjectDelete("MIDL-"+Timeframe);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
//---- 
	if ((AllBars==0) || (iBars(Symbol(),Timeframe)<AllBars)) AB=iBars(Symbol(),Timeframe); else AB=AllBars; //AB-êîëè÷åñòâî îáñ÷èòûâàåìûõ áàðîâ
	if (BarsForFract>0) 
		BFF=BarsForFract; 
	else
	{
		switch (Timeframe)
		{
			case 1: BFF=12; Clr=Turquoise ;break;
			case 5: BFF=48; Clr=SteelBlue ;break;
			case 15: BFF=24; Clr=Lime  ;break;
			case 30: BFF=24; Clr=Silver  ;break;
			case 60: BFF=12; Clr=Magenta  ;break;
			case 240: BFF=15; Clr=Yellow  ;break;
			case 1440: BFF=10; Clr=DarkOrange ;break;
			case 10080: BFF=6; Clr=Red  ;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==iLowest(Symbol(),Timeframe,MODE_LOW,BFF*2+1,CurrentBar-BFF))) 
		{
			if(UpDown==0) { UpDown=-1; B1=CurrentBar; P1=iLow(Symbol(),Timeframe,B1); }
			else { B2=CurrentBar; P2=iLow(Symbol(),Timeframe,B2);}
		}
		if((UpDown>-1) && (CurrentBar==iHighest(Symbol(),Timeframe,MODE_HIGH,BFF*2+1,CurrentBar-BFF))) 
		{
			if(UpDown==0) { UpDown=1; B1=CurrentBar; P1=iHigh(Symbol(),Timeframe,B1); }
			else { B2=CurrentBar; P2=iHigh(Symbol(),Timeframe,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=iLow(Symbol(),Timeframe,2)-2*Step;
		for(i=3;i<=B2;i++) 
		{
			if(iLow(Symbol(),Timeframe,i)<PP+Step*i) { PP=iLow(Symbol(),Timeframe,i)-Step*i; }
		}
		if(iLow(Symbol(),Timeframe,0)<PP) {ishift=0; iprice=PP;}
		if(iLow(Symbol(),Timeframe,1)<PP+Step) {ishift=1; iprice=PP+Step;}
		if(iHigh(Symbol(),Timeframe,0)>P1) {ishift=0; iprice=P1;}
		if(iHigh(Symbol(),Timeframe,1)>P1+Step) {ishift=1; iprice=P1+Step;}
	} 
	else
	{ 
		PP=iHigh(Symbol(),Timeframe,2)-2*Step;
		for(i=3;i<=B2;i++) 
		{
			if(iHigh(Symbol(),Timeframe,i)>PP+Step*i) { PP=iHigh(Symbol(),Timeframe,i)-i*Step;}
		}
		if(iLow(Symbol(),Timeframe,0)<P1) {ishift=0; iprice=P1;}
		if(iLow(Symbol(),Timeframe,1)<P1+Step) {ishift=1; iprice=P1+Step;}
		if(iHigh(Symbol(),Timeframe,0)>PP) {ishift=0; iprice=PP;}
		if(iHigh(Symbol(),Timeframe,1)>PP+Step) {ishift=1; iprice=PP+Step;}
	}
	//Òåïåðü ïåðåñòàâèì êîíå÷íóþ öåíó è áàð íà ÀÂ, ÷òîáû ëèíèè êàíàëà ðèñîâàëèñü ïîäëèííåå
	P2=P1+AB*Step;
	T1=iTime(Symbol(),Timeframe,B1);
   T2=iTime(Symbol(),Timeframe,AB);

	//Åñëè íå áûëî ïåðåñå÷åíèÿ êàíàëà, òî 0, èíà÷å ñòàâèì ïñèñó.
	if(iprice!=0) ExtMapBuffer1[ishift]=iprice;
	DelObj();
	//Comment (PP,P1);
	
	string Text = " Channel size = "+DoubleToStr(MathAbs(PP - P1)/Point,0)+" Slope = "+DoubleToStr(-Step/Point, 2);

	if (PP<P1)
	{
	ObjectCreate("TL1-"+Timeframe,OBJ_TREND,0,T2,PP+Step*AB,T1,PP); 
		ObjectSet("TL1-"+Timeframe,OBJPROP_COLOR,Clr); 
		ObjectSet("TL1-"+Timeframe,OBJPROP_WIDTH,1); 
		ObjectSet("TL1-"+Timeframe,OBJPROP_STYLE,STYLE_SOLID); 
		ObjectSetText("TL1-"+Timeframe,Text);
	ObjectCreate("TL2-"+Timeframe,OBJ_TREND,0,T2,P2,T1,P1); 
		ObjectSet("TL2-"+Timeframe,OBJPROP_COLOR,Clr); 
		ObjectSet("TL2-"+Timeframe,OBJPROP_WIDTH,1); 
		ObjectSet("TL2-"+Timeframe,OBJPROP_STYLE,STYLE_SOLID);
		ObjectSetText("TL2-"+Timeframe,Text); 
	ObjectCreate("MIDL-"+Timeframe,OBJ_TREND,0,T2,(P2+PP+Step*AB)/2,T1,(P1+PP)/2);
		ObjectSet("MIDL-"+Timeframe,OBJPROP_COLOR,Clr); 
		ObjectSet("MIDL-"+Timeframe,OBJPROP_WIDTH,1); 
		ObjectSet("MIDL-"+Timeframe,OBJPROP_STYLE,STYLE_DOT);
		ObjectSetText("MIDL-"+Timeframe,Text);
		}
		if (PP>P1)
	{
	ObjectCreate("TL2-"+Timeframe,OBJ_TREND,0,T2,PP+Step*AB,T1,PP); 
		ObjectSet("TL2-"+Timeframe,OBJPROP_COLOR,Clr); 
		ObjectSet("TL2-"+Timeframe,OBJPROP_WIDTH,1); 
		ObjectSet("TL2-"+Timeframe,OBJPROP_STYLE,STYLE_SOLID); 
		ObjectSetText("TL2-"+Timeframe,Text);
	ObjectCreate("TL1-"+Timeframe,OBJ_TREND,0,T2,P2,T1,P1); 
		ObjectSet("TL1-"+Timeframe,OBJPROP_COLOR,Clr); 
		ObjectSet("TL1-"+Timeframe,OBJPROP_WIDTH,1); 
		ObjectSet("TL1-"+Timeframe,OBJPROP_STYLE,STYLE_SOLID); 
		ObjectSetText("TL1-"+Timeframe,Text);
	ObjectCreate("MIDL-"+Timeframe,OBJ_TREND,0,T2,(P2+PP+Step*AB)/2,T1,(P1+PP)/2);
		ObjectSet("MIDL-"+Timeframe,OBJPROP_COLOR,Clr); 
		ObjectSet("MIDL-"+Timeframe,OBJPROP_WIDTH,1); 
		ObjectSet("MIDL-"+Timeframe,OBJPROP_STYLE,STYLE_DOT);
		ObjectSetText("MIDL-"+Timeframe,Text);
		}
//----

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

Comments