Regression_Channel_V2
Download scriptThis script is designed to automatically calculate and draw a "Regression Channel" on your trading chart. Instead of you having to manually guess where a trend begins or ends, the tool uses mathematical logic to identify significant price movements and project a visual corridor around them.
Here is a breakdown of how the logic works in plain English:
1. Identifying the Trend Boundaries
The first thing the script does is scan back through historical price data to find the "starting" and "ending" points of a major market move. It looks for specific price actions relative to a Moving Average (a line that shows the average price over a set period).
Specifically, it identifies:
- High Points: Where the price pushes significantly above the average.
- Low Points: Where the price drops significantly below the average.
By finding these extremes, the script determines the most relevant section of the chart to analyze, essentially "zooming in" on the current trend.
2. Calculating the Regression Line (The Middle)
Once the start and end points are identified, the script performs a mathematical calculation to find the "best fit" line. This is known as Linear Regression. Imagine trying to draw a perfectly straight line through a cloud of messy data points; the script calculates exactly where that line should sit to represent the core direction of the trend. This becomes your Middle Line.
3. Calculating the Price Deviation (The Width)
A trend isn't just a single line; it has "noise" or volatility. To account for this, the script measures how much the price typically wanders away from that middle regression line. It calculates the standard deviation—a measure of how far prices usually stray from the norm.
4. Drawing the Channels (The Boundaries)
Finally, the script uses that deviation measurement to draw three distinct sets of boundaries:
- The Outside Channel: These are wide boundaries based on a larger deviation setting. They represent the "extreme" limits of the price action. If the price breaks out beyond these lines, it may signal a significant change in market sentiment or a major trend reversal.
- The Inside Channel: These are tighter boundaries based on a smaller deviation. They represent the "normal" zone where the price is expected to trade. When the price stays within these lines, it confirms that the current trend is stable.
Summary for the User
In short, this tool automatically detects the "skeleton" of a market trend. It draws a central path (the Regression Line) and two sets of corridors (Inside and Outside channels). This allows you to see at a glance whether the current price is behaving normally within the trend or if it is reaching an extreme point that might require a change in your trading strategy.
//+------------------------------------------------------------------+
//| Regression_Channel.mq4 |
//| Converted to MT4 by KimIV |
//| Modified bt MrPip to place lines at 2 different Standard Devs |
//| Also makes StDev level an input, with some Stache mods |
//+------------------------------------------------------------------+
/*[[
Name := Regression_Channel
Author := Copyright © 2004, MetaQuotes Software Corp.
Link := http://www.metaquotes.net/
]]*/
#property copyright "KimIV"
#property link "http://www.kimiv.ru"
#property indicator_chart_window
//------- Âíåøíèå ïàðàìåòðû èíäèêàòîðà -------------------------------
extern int NumberName = 1;
extern int iPeriod = 56;
extern double MAShoot = 50;
extern int LineWeight = 1;
extern color LineColor = Magenta;
extern double StDevOutside = 1.618;
extern color Outside = SteelBlue;
extern int OutsideWeight=1;
extern double StDevInside = 0.809;
extern color Inside = Goldenrod;
extern int InsideWeight=1;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void init() {
ObjectCreate("Regression_middle"+NumberName, OBJ_TREND, 0, 0,0, 0,0);
ObjectSet("Regression_middle"+NumberName, OBJPROP_COLOR, LineColor);
ObjectSet("Regression_middle"+NumberName, OBJPROP_STYLE, STYLE_SOLID);
ObjectSet("Regression_middle"+NumberName, OBJPROP_WIDTH, LineWeight);
ObjectCreate("Regression_Outside_upper" +NumberName, OBJ_TREND, 0, 0,0, 0,0);
ObjectSet("Regression_Outside_upper"+NumberName, OBJPROP_COLOR, Outside);
ObjectSet("Regression_Outside_upper"+NumberName, OBJPROP_STYLE, STYLE_SOLID);
ObjectSet("Regression_Outside_upper"+NumberName, OBJPROP_WIDTH, OutsideWeight);
ObjectCreate("Regression_Outside_lower" +NumberName, OBJ_TREND, 0, 0,0, 0,0);
ObjectSet("Regression_Outside_lower"+NumberName, OBJPROP_COLOR, Outside);
ObjectSet("Regression_Outside_lower"+NumberName, OBJPROP_STYLE, STYLE_SOLID);
ObjectSet("Regression_Outside_lower"+NumberName, OBJPROP_WIDTH, OutsideWeight);
ObjectCreate("Regression_Inside_upper" +NumberName, OBJ_TREND, 0, 0,0, 0,0);
ObjectSet("Regression_Inside_upper"+NumberName, OBJPROP_COLOR, Inside);
ObjectSet("Regression_Inside_upper"+NumberName, OBJPROP_STYLE, STYLE_SOLID);
ObjectSet("Regression_Inside_upper"+NumberName, OBJPROP_WIDTH, InsideWeight);
ObjectCreate("Regression_Inside_lower" +NumberName, OBJ_TREND, 0, 0,0, 0,0);
ObjectSet("Regression_Inside_lower"+NumberName, OBJPROP_COLOR, Inside);
ObjectSet("Regression_Inside_lower"+NumberName, OBJPROP_STYLE, STYLE_SOLID);
ObjectSet("Regression_Inside_lower"+NumberName, OBJPROP_WIDTH, InsideWeight);
Comment("Auto Regression channel");
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
void deinit() {
ObjectDelete("Regression_middle"+NumberName);
ObjectDelete("Regression_Outside_upper" +NumberName);
ObjectDelete("Regression_Outside_lower" +NumberName);
ObjectDelete("Regression_Inside_upper" +NumberName);
ObjectDelete("Regression_Inside_lower" +NumberName);
Comment("");
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
void start() {
bool check_low, check_high;
bool check_upper_chanel;
double save_low, save_high;
double MA, a1, a2, a3, b1, a_, b_, y1, y2, price;
double stddiv_low, stddiv_high, tmp_div;
double x_n_upOut, x_1_upOut, x_n_downOut, x_1_downOut;
double x_n_upIn, x_1_upIn, x_n_downIn, x_1_downIn;
double ratio_currency;
int shift;
int n, n_begin, n_end;
int MAType, MAPrice;
int save_shift_low, save_shift_high;
save_low = -1;
save_high = -1;
save_shift_low = -1;
save_shift_high = -1;
check_low = false;
check_high = false;
MAType = MODE_SMA;
MAPrice = PRICE_CLOSE;
if (Close[1]>80) ratio_currency = 100;
else ratio_currency = 10000;
// Ïîèñê òî÷åê ïåðåñå÷åíèÿ ñ ÌÀ
for (shift=Bars-1; shift>=0; shift--) {
MA = iMA(NULL, 0, iPeriod, 0, MAType, MAPrice, shift);
if (MA-MAShoot/ratio_currency>Close[shift]) {
if (Close[shift]<save_low || save_low==-1) {
check_low = true;
save_low = Close[shift];
save_shift_low = shift;
}
}
if (MA+MAShoot/ratio_currency<Close[shift]) {
if (save_high<Close[shift] || save_high==-1) {
check_high = true;
save_high = Close[shift];
save_shift_high = shift;
}
}
if (check_low) {
if (MA+MAShoot/ratio_currency<Close[shift]) {
check_low = false;
save_low = -1;
}
}
if (check_high) {
if (MA-MAShoot/ratio_currency>Close[shift]) {
check_high = false;
save_high = -1;
}
}
}
//Îïðåäåëåíèå ãðàíèö ïîñòðîåíèÿ êàíàëëà
if (save_shift_low>save_shift_high) {
n_begin = save_shift_low;
n_end = save_shift_high;
} else {
n_begin = save_shift_high;
n_end = save_shift_low;
}
if (n_end==0) n_end = 1; // Íóëåâîé áàð íå èñïîëüçîâàòü
n = n_begin - n_end + 1; // äëèíà êàíàëà
a1 = 0;
a2 = 0;
a3 = 0;
b1 = 0;
a_ = 0;
b_ = 0;
y1 = 0;
y2 = 0;
tmp_div = 0;
if (Close[n_begin]<Close[n_end]) check_upper_chanel = true;
else check_upper_chanel = false;
for (shift=n_begin; shift>=n_end; shift--) {
if (check_upper_chanel) price = Low[shift];
else price = High[shift];
a1 = a1 + shift*price;
a2 = a2 + shift;
a3 = a3 + price;
b1 = b1 + shift*shift;
}
b_ = (n*a1 - a2*a3)/(n*b1 - a2*a2);
a_ = (a3 - b_*a2)/n;
y1 = a_ + b_*n_begin;
y2 = a_ + b_*n_end;
ObjectSet("Regression_middle"+NumberName, OBJPROP_TIME1, Time[n_begin]);
ObjectSet("Regression_middle"+NumberName, OBJPROP_TIME2, Time[n_end]);
ObjectSet("Regression_middle"+NumberName, OBJPROP_PRICE1, y1);
ObjectSet("Regression_middle"+NumberName, OBJPROP_PRICE2, y2);
for (shift=n_begin; shift>=n_end; shift--) {
if (check_upper_chanel) price = Low[shift];
else price = High[shift];
tmp_div = tmp_div + (price - (a_ + b_*shift))*(price - (a_ + b_*shift));
}
stddiv_low = MathSqrt(tmp_div/n);
stddiv_high = MathSqrt(tmp_div/n);
x_n_upOut = y1 + StDevOutside*stddiv_high;
x_1_upOut = y2 + StDevOutside*stddiv_high;
x_n_downOut = y1 - StDevOutside*stddiv_low;
x_1_downOut = y2 - StDevOutside*stddiv_low;
x_n_upIn = y1 + StDevInside*stddiv_high;
x_1_upIn = y2 + StDevInside*stddiv_high;
x_n_downIn = y1 - StDevInside*stddiv_low;
x_1_downIn = y2 - StDevInside*stddiv_low;
//OUTSIDE
//upper
ObjectSet("Regression_Outside_upper"+NumberName, OBJPROP_TIME1, Time[n_begin]);
ObjectSet("Regression_Outside_upper"+NumberName, OBJPROP_TIME2, Time[n_end]);
ObjectSet("Regression_Outside_upper"+NumberName, OBJPROP_PRICE1, x_n_upOut);
ObjectSet("Regression_Outside_upper"+NumberName, OBJPROP_PRICE2, x_1_upOut);
//lower
ObjectSet("Regression_Outside_lower"+NumberName, OBJPROP_TIME1, Time[n_begin]);
ObjectSet("Regression_Outside_lower"+NumberName, OBJPROP_TIME2, Time[n_end]);
ObjectSet("Regression_Outside_lower"+NumberName, OBJPROP_PRICE1, x_n_downOut);
ObjectSet("Regression_Outside_lower"+NumberName, OBJPROP_PRICE2, x_1_downOut);
//INSIDE
//upper
ObjectSet("Regression_Inside_upper"+NumberName, OBJPROP_TIME1, Time[n_begin]);
ObjectSet("Regression_Inside_upper"+NumberName, OBJPROP_TIME2, Time[n_end]);
ObjectSet("Regression_Inside_upper"+NumberName, OBJPROP_PRICE1, x_n_upIn);
ObjectSet("Regression_Inside_upper"+NumberName, OBJPROP_PRICE2, x_1_upIn);
//lower
ObjectSet("Regression_Inside_lower"+NumberName, OBJPROP_TIME1, Time[n_begin]);
ObjectSet("Regression_Inside_lower"+NumberName, OBJPROP_TIME2, Time[n_end]);
ObjectSet("Regression_Inside_lower"+NumberName, OBJPROP_PRICE1, x_n_downIn);
ObjectSet("Regression_Inside_lower"+NumberName, OBJPROP_PRICE2, x_1_downIn);
}
//-------------------------------------------------------------------+
Comments