LSMA_Channel_v1
Download scriptThis script functions as a visual financial analysis tool that projects "Regression Channels" onto your trading chart. It is designed to help identify the prevailing trend of an asset by drawing geometric boundaries based on historical price movement.
Core Logic Overview
The primary goal of this tool is to take a specific number of past data points (based on your chosen period) and calculate a mathematical "line of best fit." This line represents the most direct path the price has taken over that timeframe, acting as a baseline for current momentum.
Key Components of the Analysis
1. The Baseline (Regression Line) The script analyzes the price data—which you can choose to be the Close, High, or Low prices—and performs a calculation to determine a straight line that minimizes the distance between all the price points in your selected period. This results in a central "MidLine" that shows you the primary direction of the market.
2. Standard Deviation and Volatility Beyond just finding the center line, the script calculates the "Standard Deviation." In plain terms, this measures how much the price typically fluctuates away from the baseline. If the market is volatile, the standard deviation will be high; if it is stable, it will be low. This measurement is used to determine the width of the surrounding channels.
3. Multi-Layered Channels The tool automatically generates several distinct "bands" or boundaries around the central regression line. These are calculated by applying different multipliers to the standard deviation:
- Inside Channels: These represent the core, high-probability area where the price spends the majority of its time. They are designed to show the immediate "corridor" of movement.
- Outside Channels: These represent a wider zone of activity. Prices moving into these areas are still within a normal range of historical behavior but indicate expanding volatility.
- Outside 2 Channels: These serve as the furthest boundaries. When price action moves outside these lines, it often suggests an extreme deviation from the norm, potentially signaling that a trend is exhausting or that a significant reversal might be occurring.
Summary for the User
Instead of just looking at a single moving average, this script provides a dynamic "tunnel" view of the market. It allows you to see not only where the price is going but also what the "normal" boundaries of that movement look like based on recent history. By observing how often the price touches or breaks these different colored lines, you can better identify periods of stability versus periods of extreme price expansion.
/*-----------------------------+
| |
| Shared by www.Aptrafx.com |
| |
+------------------------------*/
//+------------------------------------------------------------------+
//| LSMA_Line.mq4 |
//| Copyright © 2005, MetaQuotes Software Corp. |
//| http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net/"
#property indicator_chart_window
//---- indicator parameters
extern int IdNum = 1;
extern int RPeriod = 28;
extern color MidColor = Red;
extern int LineWeight = 1;
extern int PriceVal = 0; // 0 = Close, 1 = Low, 2 = High
extern double StDevOutside2 = 2.55;
extern color Outside2 = Red;
extern double StDevOutside = 1.618;
extern color Outside = Brown;
extern double StDevInside = 0.809;
extern color Inside = Green;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
ObjectCreate("Reg_line"+IdNum, OBJ_TREND, 0, 0,0, 0,0);
ObjectSet("Reg_line"+IdNum, OBJPROP_COLOR, MidColor);
ObjectSet("Reg_line"+IdNum, OBJPROP_STYLE, STYLE_SOLID);
ObjectSet("Reg_line"+IdNum, OBJPROP_WIDTH, LineWeight);
ObjectCreate("Reg_Outside_upper" +IdNum, OBJ_TREND, 0, 0,0, 0,0);
ObjectSet("Reg_Outside_upper"+IdNum, OBJPROP_COLOR, Outside);
ObjectSet("Reg_Outside_upper"+IdNum, OBJPROP_STYLE, STYLE_SOLID);
ObjectSet("Reg_Outside_upper"+IdNum, OBJPROP_WIDTH, LineWeight);
ObjectCreate("Reg_Outside_lower" +IdNum, OBJ_TREND, 0, 0,0, 0,0);
ObjectSet("Reg_Outside_lower"+IdNum, OBJPROP_COLOR, Outside);
ObjectSet("Reg_Outside_lower"+IdNum, OBJPROP_STYLE, STYLE_SOLID);
ObjectSet("Reg_Outside_lower"+IdNum, OBJPROP_WIDTH, LineWeight);
ObjectCreate("Reg_Inside_upper" +IdNum, OBJ_TREND, 0, 0,0, 0,0);
ObjectSet("Reg_Inside_upper"+IdNum, OBJPROP_COLOR, Inside);
ObjectSet("Reg_Inside_upper"+IdNum, OBJPROP_STYLE, STYLE_SOLID);
ObjectSet("Reg_Inside_upper"+IdNum, OBJPROP_WIDTH, LineWeight);
ObjectCreate("Reg_Inside_lower" +IdNum, OBJ_TREND, 0, 0,0, 0,0);
ObjectSet("Reg_Inside_lower"+IdNum, OBJPROP_COLOR, Inside);
ObjectSet("Reg_Inside_lower"+IdNum, OBJPROP_STYLE, STYLE_SOLID);
ObjectSet("Reg_Inside_lower"+IdNum, OBJPROP_WIDTH, LineWeight);
ObjectCreate("Reg_Outside2_upper" +IdNum, OBJ_TREND, 0, 0,0, 0,0);
ObjectSet("Reg_Outside2_upper"+IdNum, OBJPROP_COLOR, Outside2);
ObjectSet("Reg_Outside2_upper"+IdNum, OBJPROP_STYLE, STYLE_SOLID);
ObjectSet("Reg_Outside2_upper"+IdNum, OBJPROP_WIDTH, LineWeight);
ObjectCreate("Reg_Outside2_lower" +IdNum, OBJ_TREND, 0, 0,0, 0,0);
ObjectSet("Reg_Outside2_lower"+IdNum, OBJPROP_COLOR, Outside2);
ObjectSet("Reg_Outside2_lower"+IdNum, OBJPROP_STYLE, STYLE_SOLID);
ObjectSet("Reg_Outside2_lower"+IdNum, OBJPROP_WIDTH, LineWeight);
Comment("Regression channel");
return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
void deinit() {
ObjectDelete("Reg_line"+IdNum);
ObjectDelete("Reg_Outside_upper" +IdNum);
ObjectDelete("Reg_Outside_lower" +IdNum);
ObjectDelete("Reg_Inside_upper" +IdNum);
ObjectDelete("Reg_Inside_lower" +IdNum);
ObjectDelete("Reg_Outside2_upper" +IdNum);
ObjectDelete("Reg_Outside2_lower" +IdNum);
Comment("");
}
//+------------------------------------------------------------------+
//| Regression Line |
//+------------------------------------------------------------------+
int start()
{
double y1,y2, price;
double a1, a2, a3, b1, a, b;
double stddiv, tmp_div;
double x_n_upOut, x_1_upOut, x_n_downOut, x_1_downOut;
double x2_n_upOut, x2_1_upOut, x2_n_downOut, x2_1_downOut;
double x_n_upIn, x_1_upIn, x_n_downIn, x_1_downIn;
int shift, n;
//----
if(Bars<=RPeriod) return(0);
a1 = 0;
a2 = 0;
a3 = 0;
b1 = 0;
a = 0;
b = 0;
y1 = 0;
y2 = 0;
tmp_div = 0;
n = RPeriod;
for(shift=RPeriod;shift>0;shift--)
{
switch (PriceVal)
{
case 0: price = Close[shift];
break;
case 1: price = Low[shift];
break;
case 2: price = High[shift];
break;
}
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;
y2 = a + b;
ObjectSet("Reg_line"+IdNum, OBJPROP_TIME1, Time[RPeriod]);
ObjectSet("Reg_line"+IdNum, OBJPROP_TIME2, Time[0]);
ObjectSet("Reg_line"+IdNum, OBJPROP_PRICE1, y1);
ObjectSet("Reg_line"+IdNum, OBJPROP_PRICE2, y2);
for (shift=RPeriod; shift>0; shift--) {
switch (PriceVal)
{
case 0: price = Close[shift];
break;
case 1: price = Low[shift];
break;
case 2: price = High[shift];
break;
}
tmp_div = tmp_div + (price - (a + b*shift))*(price - (a + b*shift));
}
stddiv = MathSqrt(tmp_div/n);
x_n_upOut = y1 + StDevOutside*stddiv;
x_1_upOut = y2 + StDevOutside*stddiv;
x_n_downOut = y1 - StDevOutside*stddiv;
x_1_downOut = y2 - StDevOutside*stddiv;
x_n_upIn = y1 + StDevInside*stddiv;
x_1_upIn = y2 + StDevInside*stddiv;
x_n_downIn = y1 - StDevInside*stddiv;
x_1_downIn = y2 - StDevInside*stddiv;
x2_n_upOut = y1 + StDevOutside2*stddiv;
x2_1_upOut = y2 + StDevOutside2*stddiv;
x2_n_downOut = y1 - StDevOutside2*stddiv;
x2_1_downOut = y2 - StDevOutside2*stddiv;
// OUTSIDE
//upper
ObjectSet("Reg_Outside_upper"+IdNum, OBJPROP_TIME1, Time[RPeriod]);
ObjectSet("Reg_Outside_upper"+IdNum, OBJPROP_TIME2, Time[0]);
ObjectSet("Reg_Outside_upper"+IdNum, OBJPROP_PRICE1, x_n_upOut);
ObjectSet("Reg_Outside_upper"+IdNum, OBJPROP_PRICE2, x_1_upOut);
//lower
ObjectSet("Reg_Outside_lower"+IdNum, OBJPROP_TIME1, Time[RPeriod]);
ObjectSet("Reg_Outside_lower"+IdNum, OBJPROP_TIME2, Time[0]);
ObjectSet("Reg_Outside_lower"+IdNum, OBJPROP_PRICE1, x_n_downOut);
ObjectSet("Reg_Outside_lower"+IdNum, OBJPROP_PRICE2, x_1_downOut);
// OUTSIDE2
//upper
ObjectSet("Reg_Outside2_upper"+IdNum, OBJPROP_TIME1, Time[RPeriod]);
ObjectSet("Reg_Outside2_upper"+IdNum, OBJPROP_TIME2, Time[0]);
ObjectSet("Reg_Outside2_upper"+IdNum, OBJPROP_PRICE1, x2_n_upOut);
ObjectSet("Reg_Outside2_upper"+IdNum, OBJPROP_PRICE2, x2_1_upOut);
//lower
ObjectSet("Reg_Outside2_lower"+IdNum, OBJPROP_TIME1, Time[RPeriod]);
ObjectSet("Reg_Outside2_lower"+IdNum, OBJPROP_TIME2, Time[0]);
ObjectSet("Reg_Outside2_lower"+IdNum, OBJPROP_PRICE1, x2_n_downOut);
ObjectSet("Reg_Outside2_lower"+IdNum, OBJPROP_PRICE2, x2_1_downOut);
//INSIDE
//upper
ObjectSet("Reg_Inside_upper"+IdNum, OBJPROP_TIME1, Time[RPeriod]);
ObjectSet("Reg_Inside_upper"+IdNum, OBJPROP_TIME2, Time[0]);
ObjectSet("Reg_Inside_upper"+IdNum, OBJPROP_PRICE1, x_n_upIn);
ObjectSet("Reg_Inside_upper"+IdNum, OBJPROP_PRICE2, x_1_upIn);
//lower
ObjectSet("Reg_Inside_lower"+IdNum, OBJPROP_TIME1, Time[RPeriod]);
ObjectSet("Reg_Inside_lower"+IdNum, OBJPROP_TIME2, Time[0]);
ObjectSet("Reg_Inside_lower"+IdNum, OBJPROP_PRICE1, x_n_downIn);
ObjectSet("Reg_Inside_lower"+IdNum, OBJPROP_PRICE2, x_1_downIn);
return(0);
}
//+------------------------------------------------------------------+
Comments