//+------------------------------------------------------------------+
//|                                    Kiosotto Reverse Smoothed.mq4 |
//|                                  Copyright 2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "forex-station.com - Modified by Ptr777"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 25
#property indicator_buffers 6
#property indicator_color1 Lime
#property indicator_color2 Red
#property indicator_color3 Lime
#property indicator_color4 Red
#property indicator_width1 2
#property indicator_width2 2
#property indicator_width3 1
#property indicator_width4 1
#property indicator_level1 12
#property indicator_level2 5
#property indicator_levelcolor clrLightGray

// Input parameters
input int    period_1 = 5;
input int    period_2 = 13;
input int    period_3 = 21;
input bool   rsi      = false;
input bool   hi_lo    = false;
input bool   price_1  = true;
input double kf_2     = 0.834;
input double kf_3     = 0.715;
input int    NLEMA_Period = 14; // Non-Lag EMA period
input bool   EnableAlerts = false;

// Buffers
double BullBuffer[], BearBuffer[];
double NLEMA_Bull[], NLEMA_Bear[];
double B2[], B3[], B4[], B5[];

int init()
{
   IndicatorBuffers(8);
   
   // Main trend histograms
   SetIndexBuffer(0, BullBuffer);
   SetIndexStyle(0, DRAW_HISTOGRAM);
   SetIndexBuffer(1, BearBuffer);
   SetIndexStyle(1, DRAW_HISTOGRAM);
   
   // Non-Lag EMA signals
   SetIndexBuffer(2, NLEMA_Bull);
   SetIndexStyle(2, DRAW_LINE);
   SetIndexBuffer(3, NLEMA_Bear);
   SetIndexStyle(3, DRAW_LINE);
   
   // Calculation buffers
   SetIndexBuffer(4, B2);
   SetIndexBuffer(5, B3);
   SetIndexBuffer(6, B4);
   SetIndexBuffer(7, B5);
   
   IndicatorDigits(0);
   IndicatorShortName("Kiosotto Reverse Smoothed");
   return(0);
}

// Non-Lag EMA Calculation
double NLEMA(int index, int length, double& priceArray[])
{
    double alpha = 2.0 / (length + 1);
    double sum = 0;
    double weightSum = 0;
    
    for(int i = 0; i < length; i++)
    {
        double weight = MathPow(1 - alpha, i);
        sum += priceArray[index + i] * weight;
        weightSum += weight;
    }
    
    return sum / weightSum;
}

int start()
{
    int limit = Bars - IndicatorCounted() - 1;
    if(limit < 0) limit = 0;
    
    // Prevent repainting by only calculating for completed bars
    if(limit > 0) limit--;
    
    // Calculate base values
    for(int i = limit; i >= 0; i--)
    {
        if(rsi == false)
        {
            B2[i] = 1;
        }
        else
        {
            B2[i] = iRSI(NULL, 0, period_1, PRICE_CLOSE, i);
        }
        
        if(hi_lo == false)
        {
            B3[i] = Close[i];
            B4[i] = Close[i];
        }
        else
        {
            B3[i] = High[i];
            B4[i] = Low[i];
        }
        
        if(price_1 == false)
        {
            B5[i] = Close[i];
        }
        else
        {
            B5[i] = 1;
        }
    }
    
    if(limit > 0)
    {
        limit = limit - period_3;
        if(limit < 0) limit = 0;
    }
    
    // Main calculation loop
    for(int i = limit; i >= 0; i--)
    {
        double TSBUL_1 = 0, TSBER_1 = 0;
        double TSBUL_2 = 0, TSBER_2 = 0;
        double TSBUL_3 = 0, TSBER_3 = 0;
        double hpres_1 = -1000000000, lpres_1 = 1000000000;
        double hpres_2 = -1000000000, lpres_2 = 1000000000;
        double hpres_3 = -1000000000, lpres_3 = 1000000000;
        
        // Period 1 calculation
        for(int j = 0; j < period_1; j++)
        {
            int i2 = i + j;
            double rs = B2[i2];
            double hnw = B3[i2];
            double lnw = B4[i2];
            double cle = B5[i2];
            
            if(hnw > hpres_1)
            {
                hpres_1 = hnw;
                TSBUL_1 += rs * cle;
            }
            
            if(lpres_1 > lnw)
            {
                lpres_1 = lnw;
                TSBER_1 += rs * cle;
            }
        }
        
        // Period 2 calculation
        for(int j = 0; j < period_2; j++)
        {
            int i2 = i + j;
            double rs = B2[i2];
            double hnw = B3[i2];
            double lnw = B4[i2];
            double cle = B5[i2];
            
            if(hnw > hpres_2)
            {
                hpres_2 = hnw;
                TSBUL_2 += rs * cle;
            }
            
            if(lpres_2 > lnw)
            {
                lpres_2 = lnw;
                TSBER_2 += rs * cle;
            }
        }
        
        // Period 3 calculation
        for(int j = 0; j < period_3; j++)
        {
            int i2 = i + j;
            double rs = B2[i2];
            double hnw = B3[i2];
            double lnw = B4[i2];
            double cle = B5[i2];
            
            if(hnw > hpres_3)
            {
                hpres_3 = hnw;
                TSBUL_3 += rs * cle;
            }
            
            if(lpres_3 > lnw)
            {
                lpres_3 = lnw;
                TSBER_3 += rs * cle;
            }
        }
        
        // Combine periods with weights
        double bullValue = MathMax(MathMax(TSBER_1/TSBUL_1, TSBER_2/TSBUL_2*kf_2), TSBER_3/TSBUL_3*kf_3) * 4;
        double bearValue = MathMax(MathMax(TSBUL_1/TSBER_1, TSBUL_2/TSBER_2*kf_2), TSBUL_3/TSBER_3*kf_3) * 4;
        
        // Cap values at 80
        bullValue = MathMin(bullValue, 80);
        bearValue = MathMin(bearValue, 80);
        
        // Apply trend rules
        if(bullValue > bearValue)
        {
            BullBuffer[i] = bullValue;
            BearBuffer[i] = 0;
            
            // Additional confirmation
            if(Close[i+1] > Close[i]) BullBuffer[i] = bullValue;
            else BullBuffer[i] = 0;
        }
        else if(bullValue < bearValue)
        {
            BullBuffer[i] = 0;
            BearBuffer[i] = bearValue;
            
            // Additional confirmation
            if(Close[i+1] < Close[i]) BearBuffer[i] = bearValue;
            else BearBuffer[i] = 0;
        }
        else
        {
            BullBuffer[i] = 0;
            BearBuffer[i] = 0;
        }
        
        // Apply threshold levels
        if(BullBuffer[i] >= 44 && BullBuffer[i] < 54) BullBuffer[i] = 54;
        if(BearBuffer[i] >= 44 && BearBuffer[i] < 54) BearBuffer[i] = 54;
        if(BullBuffer[i] >= 20 && BullBuffer[i] < 30) BullBuffer[i] = 30;
        if(BearBuffer[i] >= 20 && BearBuffer[i] < 30) BearBuffer[i] = 30;
    }
    
    // Calculate Non-Lag EMA for smoothed signals
    for(int i = limit; i >= 0; i--)
    {
        NLEMA_Bull[i] = NLEMA(i, NLEMA_Period, BullBuffer);
        NLEMA_Bear[i] = NLEMA(i, NLEMA_Period, BearBuffer);
        
        // Generate alerts
        if(EnableAlerts && i == 0)
        {
            static int lastAlert = 0;
            if(NLEMA_Bull[0] > NLEMA_Bear[0] && lastAlert != 1)
            {
                Alert("BUY Signal on ", Symbol(), " ", Period());
                lastAlert = 1;
            }
            else if(NLEMA_Bull[0] < NLEMA_Bear[0] && lastAlert != -1)
            {
                Alert("SELL Signal on ", Symbol(), " ", Period());
                lastAlert = -1;
            }
        }
    }
    
    return(0);
}