//+------------------------------------------------------------------+
//|                                                     LinearRegressionChannel.mq4 |
//|                       Converted from Pine Script to MQL4                       |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Red
#property indicator_color2 Aqua
#property indicator_color3 Yellow

input bool bands = true; // Plot Linear Regression Bands
input int window = 150; // Length
input double devlen_b = 3.0; // Deviation for Bands
input bool channel = false; // Plot Linear Regression Channel
input int window1 = 150; // Channel Length
input double devlen1 = 1.0; // Deviation for Channel
input bool channel1 = false; // Plot Future Projection of linear regression
input bool arr_dirc = false; // Plot Arrow Direction
input int window2 = 50; // Future Projection Length
input double devlen2 = 1.0; // Deviation for Future Projection

double upperBuffer[], lowerBuffer[], midBuffer[];

int init() {
    SetIndexBuffer(0, upperBuffer);
    SetIndexBuffer(1, lowerBuffer);
    SetIndexBuffer(2, midBuffer);
    return(INIT_SUCCEEDED);
}

int start() {
    int rates_total = Bars;

    if(rates_total < window) return 0;

    double sum_x, sum_y, sum_xy, sum_x_sq;

    for(int i = window; i < rates_total; i++) {
        sum_x = sum_y = sum_xy = sum_x_sq = 0.0;
        
        for(int j = 0; j < window; j++) {
            double val = Close[i - j];
            sum_x += j + 1;
            sum_y += val;
            sum_xy += (j + 1) * val;
            sum_x_sq += MathPow(j + 1, 2);
        }

        double slope = (window * sum_xy - sum_x * sum_y) / (window * sum_x_sq - MathPow(sum_x, 2));
        double intercept = (sum_y - slope * sum_x) / window;

        // Calculating mid, upper, and lower lines
        midBuffer[i] = intercept + slope * (window - 1);
        double deviation = 0.0;
        
        for(int m = 0; m < window; m++) {
            double predicted = slope * (window - m) + intercept;
            deviation += MathPow(Close[i - m] - predicted, 2);
        }
        
        deviation = MathSqrt(deviation / window);

        // Calculate average range for upper/lower bounds
        double avgHigh = iMA(NULL, 0, window, 0, MODE_SMA, PRICE_HIGH, i);
        double avgLow = iMA(NULL, 0, window, 0, MODE_SMA, PRICE_LOW, i);
        double avgRange = avgHigh - avgLow;

        upperBuffer[i] = midBuffer[i] + avgRange * devlen_b;
        lowerBuffer[i] = midBuffer[i] - avgRange * devlen_b;
    }

    return(0);
}
