//+------------------------------------------------------------------+
//|                                                 A! Sempoi BB.mq4 |
//|                                  Copyright 2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property strict
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_color1 Red    // Upper Band
#property indicator_color2 Gray   // Middle Band
#property indicator_color3 Blue   // Lower Band
#property indicator_color4 Red    // Upper Band Touch Points
#property indicator_color5 Blue   // Lower Band Touch Points
#property indicator_width1 3
#property indicator_width2 3
#property indicator_width3 3
#property indicator_width4 3
#property indicator_width5 3

// Input Parameters
extern int    BandsPeriod = 20;         // Bollinger Bands Period
extern double BandsDeviation = 2;       // Standard Deviation
extern int    BarsToCalculate = 116;    // Calculation Limit
extern int    LineWidth = 1;            // Line Width
extern bool   EnableDotOperation = true; // New boolean parameter to control dot operation

// Indicator Buffers
double UpperBuffer[];
double MiddleBuffer[];
double LowerBuffer[];
double UpperTouchBuffer[];
double LowerTouchBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                           |
//+------------------------------------------------------------------+
int OnInit()
{
    // Set Indicator Buffers
    SetIndexBuffer(0, UpperBuffer);
    SetIndexBuffer(1, MiddleBuffer);
    SetIndexBuffer(2, LowerBuffer);
    SetIndexBuffer(3, UpperTouchBuffer);
    SetIndexBuffer(4, LowerTouchBuffer);
    
    // Set Indicator Labels
    SetIndexLabel(0, "Upper Band");
    SetIndexLabel(1, "Middle Band");
    SetIndexLabel(2, "Lower Band");
    SetIndexLabel(3, "Upper Touch");
    SetIndexLabel(4, "Lower Touch");
    
    // Set Drawing Styles
    SetIndexStyle(0, DRAW_LINE, STYLE_DASH, LineWidth);
    SetIndexStyle(1, DRAW_LINE, STYLE_DOT, LineWidth);      // Middle band as dotted
    SetIndexStyle(2, DRAW_LINE, STYLE_DASH, LineWidth);     // Lower band as dash-dot
    SetIndexStyle(3, DRAW_ARROW);
    SetIndexStyle(4, DRAW_ARROW);
    
    // Set Arrow Codes
    SetIndexArrow(3, 159);  // Down arrow for upper band touch
    SetIndexArrow(4, 159);  // Up arrow for lower band touch
    
    // Prevent repainting by shifting the signals
    SetIndexShift(3, 1);
    SetIndexShift(4, 1);
    
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                                |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
    int limit = rates_total - prev_calculated;
    if(limit > BarsToCalculate) limit = BarsToCalculate;
    
    // Calculate Bollinger Bands
    for(int i = limit; i >= 1; i--)  // Changed from i >= 0 to i >= 1
    {
        // Calculate bands for the previous completed candle
        MiddleBuffer[i] = iMA(NULL, 0, BandsPeriod, 0, MODE_SMA, PRICE_CLOSE, i);
        double stdDev = iStdDev(NULL, 0, BandsPeriod, 0, MODE_SMA, PRICE_CLOSE, i);
        
        UpperBuffer[i] = MiddleBuffer[i] + (BandsDeviation * stdDev);
        LowerBuffer[i] = MiddleBuffer[i] - (BandsDeviation * stdDev);
        
        if (EnableDotOperation)
        {
            // Only plot signals for completed candles
            if(i < rates_total - 1)  // Skip the current forming candle
            {
                // Check for price touching the bands
                if(high[i] >= UpperBuffer[i])
                    UpperTouchBuffer[i] = high[i];
                else
                    UpperTouchBuffer[i] = EMPTY_VALUE;
                    
                if(low[i] <= LowerBuffer[i])
                    LowerTouchBuffer[i] = low[i];
                else
                    LowerTouchBuffer[i] = EMPTY_VALUE;
            }
        }
    }
    
    // Calculate current candle's bands (without signals)
    if(rates_total > 0)
    {
        int current = 0;
        MiddleBuffer[current] = iMA(NULL, 0, BandsPeriod, 0, MODE_SMA, PRICE_CLOSE, current);
        double currentStdDev = iStdDev(NULL, 0, BandsPeriod, 0, MODE_SMA, PRICE_CLOSE, current);
        UpperBuffer[current] = MiddleBuffer[current] + (BandsDeviation * currentStdDev);
        LowerBuffer[current] = MiddleBuffer[current] - (BandsDeviation * currentStdDev);
        
        if (!EnableDotOperation)
        {
            // Set current candle signals to EMPTY_VALUE to prevent repainting
            UpperTouchBuffer[current] = EMPTY_VALUE;
            LowerTouchBuffer[current] = EMPTY_VALUE;
        }
    }
    
    return(rates_total);
}
