Overview of Logic
The AutoTrendChannel is a specialized technical analysis tool designed to automatically identify and visualize market trends by constructing dynamic "channels" on a trading chart. Unlike static moving averages, this script calculates the prevailing direction of price movement and draws three parallel lines that define the boundaries of that trend.
How the Logic Works
1. Trend Analysis and Directional Detection The script begins by analyzing a specific window of recent price history (based on a user-defined hourly timeframe). It uses mathematical regression to determine the "path" the market is currently traveling. It specifically looks for two things:
- The overall slope of the price action.
- Significant peaks and valleys within that timeframe.
2. Identifying Highs and Lows To determine how wide the trend channel should be, the script divides the data into two segments. It scans these segments to find the most significant high points and low points. This allows the tool to "understand" the volatility of the current market—essentially deciding if the price is moving in a tight, compressed range or a wide, volatile swing.
3. Dynamic Channel Construction Based on the data gathered, the script classifies the market into one of two primary states:
- Bearish Trend: If the logic detects that the downward pressure and previous lows are the dominant feature, it focuses on the lower bounds of the price action.
- Bullish Trend: If it detects upward momentum and recent highs as the primary drivers, it focuses on the upper bounds.
Once the direction is established, it calculates three distinct price levels to draw on your chart:
- The Upper Boundary: Represents the maximum reach of the current trend (colored Red for bearish contexts/resistance).
- The Median Line: Represents the "fair value" or the center point of the current price action (shown in a Sky Blue color).
- The Lower Boundary: Represents the base support level of the current trend (colored Blue for bullish contexts/support).
4. Visual Representation The script automatically draws these three lines across the chart window. Because it is "Auto," the lines adjust their slope and width in real-time as new price data enters the system, ensuring that the boundaries stay relevant to the most recent market movements.
Summary for the User
Think of this tool as an automated "envelope" for the price. It looks at where the price has been over a set period, calculates the "gravity" of the trend, and draws a three-line corridor. This helps traders visualize whether the price is currently trending, how wide that trend's "lane" is, and whether it is pushing toward a resistance level or pulling back toward a support level.
//+------------------------------------------------------------------+
//| AutoTrendChannel.mq4 |
//| Copyright © 2006, MetaQuotes Software Corp. |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net"
/*********************************************************************
* Author: Muhammad Hamizi Jaminan (hymns)
* Original Author: ANG3110@latchess.com
*
* Date: December 14, 2006
* Custom Indicator: AutoTrendChannel.mq4
* Version: 1.0.1
* Description: Trend Detector
*
* Change Logs
* Version 1.0.1
* - Rewriting Code. Multi Color.
* Other function will add next release :)
*
* Version ang_AutoCh_HL-v1
* - Release by ANG3110@latchess.com
**********************************************************************/
#property indicator_chart_window
extern int Hours = 24;
extern color col_bull = Blue;
extern color col_mid = SkyBlue;
extern color col_bear = Red;
//------------------
double lr,lr0,lrp;
double sx,sy,sxy,sx2,aa,bb;
int p,fs;
int f,f0,f1;
double dh,dl,dh_1,dl_1,dh_2,dl_2;
int ai_1,ai_2,bi_1,bi_2;
double hai,lai,dhi,dli,dhm,dlm,ha0,hap,la0,lap;
double price_p1,price_p0,price_p2,price_01,price_00,price_02;
int p1,p0,p2,fp;
string sName = "AutoTrendChannel";
//*****************************************
int init() {
p = Hours*60/Period();
if (fs==0) {
fs = 1;
}
return(0);
}
//*******************************
int deinit() {
ObjectDelete("1"+sName);
ObjectDelete("0"+sName);
ObjectDelete("2"+sName);
}
//*******************************
int start() {
int i,n;
//------------------------------------------------------------------------------
if (f==1) {
p1=iBarShift(Symbol(),Period(),ObjectGet("1"+sName,OBJPROP_TIME1));
p0=iBarShift(Symbol(),Period(),ObjectGet("0"+sName,OBJPROP_TIME1));
p2=iBarShift(Symbol(),Period(),ObjectGet("2"+sName,OBJPROP_TIME1));
if (fp==0 && p!=p1) {p=p1; fp=1;}
if (fp==0 && p!=p0) {p=p0; fp=1;}
if (fp==0 && p!=p2) {p=p2; fp=1;}
}
//====================================================
sx=0; sy=0; sxy=0; sx2=0;
for (n=0; n<=p; n++) {
sx+=n; sy+=Close[n];
sxy+=n*Close[n];
sx2+=MathPow(n,2);
}
aa=(sx*sy-(p+1)*sxy)/(MathPow(sx,2)-(p+1)*sx2);
bb=(sy-aa*sx)/(p+1);
//----------------------------------------------------
for (i=0; i<=p; i++) {
lr=bb+aa*i;
dh=High[i]-lr;
dl=Low[i]-lr;
//----------------------------------------------------
if (i<p/2) {
if (i==0) {
dh_1=0.0;
dl_1=0.0;
ai_1=i;
bi_1=i;
}
if (dh>=dh_1) {
dh_1=dh;
ai_1=i;
}
if (dl<=dl_1) {
dl_1=dl;
bi_1=i;
}
}
//----------------------------------------------------
if (i>=p/2) {
if (i==p/2) {
dh_2=0.0;
dl_2=0.0;
ai_2=i;
bi_2=i;
}
if (dh>=dh_2) {
dh_2=dh;
ai_2=i;
}
if (dl<=dl_2) {
dl_2=dl;
bi_2=i;
}
}
}
//-------------------------------------
lr0=bb;
lrp=bb+aa*(i+p);
//===================================================
if (MathAbs(ai_1-ai_2)>MathAbs(bi_1-bi_2)) f=1;
if (MathAbs(ai_1-ai_2)<MathAbs(bi_1-bi_2)) f=2;
if (MathAbs(ai_1-ai_2)==MathAbs(bi_1-bi_2)) {
if (MathAbs(dh_1-dh_2)<MathAbs(dl_1-dl_2)) f=1;
if (MathAbs(dh_1-dh_2)>=MathAbs(dl_1-dl_2)) f=2;
}
//=================================================
if (f==1) {
for (n=0; n<=20; n++) {
f1=0;
for (i=0; i<=p; i++) {
hai=High[ai_1]*(i-ai_2)/(ai_1-ai_2)+High[ai_2]*(i-ai_1)/(ai_2-ai_1);
if (i==0 || i==p/2) dhm=0.0;
if (High[i]-hai>dhm && i<p/2) {
ai_1=i;
f1=1;
}
if (High[i]-hai>dhm && i>=p/2) {
ai_2=i;
f1=1;
}
}
if (f==0) break;
}
//----------------------------
for (i=0; i<=p; i++) {
hai=High[ai_1]*(i-ai_2)/(ai_1-ai_2)+High[ai_2]*(i-ai_1)/(ai_2-ai_1);
dli=Low[i]-hai;
if (i==0) dlm=0.0;
if (dli<dlm) dlm=dli;
}
ha0=High[ai_1]*(0-ai_2)/(ai_1-ai_2)+High[ai_2]*(0-ai_1)/(ai_2-ai_1);
hap=High[ai_1]*(p-ai_2)/(ai_1-ai_2)+High[ai_2]*(p-ai_1)/(ai_2-ai_1);
//----------------------------
price_p1=hap;
price_p0=hap+dlm/2;
price_p2=hap+dlm;
price_01=ha0;
price_00=ha0+dlm/2;
price_02=ha0+dlm;
}
//=================================================
if (f==2) {
for (n=0; n<=20; n++) {
f1=0;
for (i=0; i<=p; i++) {
lai=Low[bi_1]*(i-bi_2)/(bi_1-bi_2)+Low[bi_2]*(i-bi_1)/(bi_2-bi_1);
if (i==0 || i==p/2) dlm=0.0;
if (Low[i]-lai<dlm && i<p/2) {
bi_1=i;
f1=1;
}
if (Low[i]-lai<dlm && i>=p/2) {
bi_2=i;
f1=1;
}
}
if (f==0) break;
}
//----------------------------
for (i=0; i<=p; i++) {
lai=Low[bi_1]*(i-bi_2)/(bi_1-bi_2)+Low[bi_2]*(i-bi_1)/(bi_2-bi_1);
dhi=High[i]-lai;
if (i==0) dhm=0.0;
if (dhi>dhm) dhm=dhi;
}
la0=Low[bi_1]*(0-bi_2)/(bi_1-bi_2)+Low[bi_2]*(0-bi_1)/(bi_2-bi_1);
lap=Low[bi_1]*(p-bi_2)/(bi_1-bi_2)+Low[bi_2]*(p-bi_1)/(bi_2-bi_1);
//----------------------------------------------------------------
price_p1=lap;
price_p0=lap+dhm/2;
price_p2=lap+dhm;
price_01=la0;
price_00=la0+dhm/2;
price_02=la0+dhm;
}
//===================================================================================
ObjectCreate("1"+sName,2, 0,Time[p],price_p1,Time[0],price_01);
ObjectCreate("0"+sName,2, 0,Time[p],price_p0,Time[0],price_00);
ObjectCreate("2"+sName,2, 0,Time[p],price_p2,Time[0],price_02);
//-----------------------------------------------------------------
ObjectSet("1"+sName,OBJPROP_COLOR,col_bear);
ObjectSet("0"+sName,OBJPROP_COLOR,col_mid);
ObjectSet("0"+sName,OBJPROP_STYLE,STYLE_DOT);
ObjectSet("2"+sName,OBJPROP_COLOR,col_bull);
//---------------------------------------------
ObjectSet("1"+sName,OBJPROP_TIME1,Time[p]);
ObjectSet("1"+sName,OBJPROP_PRICE1,price_p1);
ObjectSet("1"+sName,OBJPROP_TIME2,Time[0]);
ObjectSet("1"+sName,OBJPROP_PRICE2,price_01);
ObjectSet("0"+sName,OBJPROP_TIME1,Time[p]);
ObjectSet("0"+sName,OBJPROP_PRICE1,price_p0);
ObjectSet("0"+sName,OBJPROP_TIME2,Time[0]);
ObjectSet("0"+sName,OBJPROP_PRICE2,price_00);
ObjectSet("2"+sName,OBJPROP_TIME1,Time[p]);
ObjectSet("2"+sName,OBJPROP_PRICE1,price_p2);
ObjectSet("2"+sName,OBJPROP_TIME2,Time[0]);
ObjectSet("2"+sName,OBJPROP_PRICE2,price_02);
//==================================================================
f=1;
p1=p;
p0=p;
p2=p;
fp=0;
//*************************************************************************************
ObjectsRedraw();
return(0);
}
//=====================================================================================
Comments