#property copyright "KK"
#property strict
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   4

#property description "RSI arrows based on the cross of the 50 level from below or from above."
#property description "Displays red and blue arrows for Short and Long signals."
#property description "Includes dual EMAs (50 blue, 100 red) with dashed lines."
#property description "5 RSI period options with on-chart buttons: 7, 14, 28, 56, 70"

// EMA buffers (drawn first)
#property indicator_color1  clrBlue
#property indicator_type1   DRAW_LINE
#property indicator_style1  STYLE_DASHDOT
#property indicator_width1  1
#property indicator_label1  "EMA 50"

#property indicator_color2  clrRed
#property indicator_type2   DRAW_LINE
#property indicator_style2  STYLE_DASHDOT
#property indicator_width2  1
#property indicator_label2  "EMA 100"

// Arrow buffers (drawn on top)
#property indicator_color3  clrAqua
#property indicator_type3   DRAW_ARROW
#property indicator_width3  1
#property indicator_label3  "RSI Buy"

#property indicator_color4  clrYellow
#property indicator_type4   DRAW_ARROW
#property indicator_width4  1
#property indicator_label4  "RSI Sell"

enum enum_candle_to_check
{
    Current,
    Previous
};

input int RSI_Period_1 = 7;    // RSI Period 1
input int RSI_Period_2 = 14;   // RSI Period 2
input int RSI_Period_3 = 28;   // RSI Period 3
input int RSI_Period_4 = 56;   // RSI Period 4
input int RSI_Period_5 = 70;   // RSI Period 5
input int EMA_Fast = 50;        // Fast EMA Period
input int EMA_Slow = 100;       // Slow EMA Period
input bool UseEMAFilter = false; // Use EMA Trend Filter
input int BarsToScan = 200;     // Bars To Scan (for arrows)
input bool EnableNativeAlerts = false;
input bool EnableEmailAlerts = false;
input bool EnablePushAlerts = false;
input enum_candle_to_check TriggerCandle = Previous;
input int ButtonX = 1450;         // Button X Position
input int ButtonY = 200;         // Button Y Position

double dEMA_Fast[];
double dEMA_Slow[];
double dUpRSIBuffer[];
double dDownRSIBuffer[];

int myEMA_Fast;
int myEMA_Slow;

int LastAlertDirection;
datetime LastAlertTime;
bool FirstRun;

// RSI Period options
int RSI_Periods[5];
int CurrentPeriodIndex = 0;
int CurrentRSI_Period;

// Button names
string ButtonNames[5];

// Multiple RSI handles - one for each period
int RSI_Handles[5];

void OnInit()
{
    FirstRun = true;
    LastAlertDirection = 0;
    LastAlertTime = D'01.01.1970';
    
    // Initialize RSI periods from inputs
    RSI_Periods[0] = RSI_Period_1;
    RSI_Periods[1] = RSI_Period_2;
    RSI_Periods[2] = RSI_Period_3;
    RSI_Periods[3] = RSI_Period_4;
    RSI_Periods[4] = RSI_Period_5;
    
    // Read saved period index from global variable
    string gvName = "RSI_Period_Index_" + _Symbol + "_" + IntegerToString(_Period);
    if(GlobalVariableCheck(gvName))
    {
        CurrentPeriodIndex = (int)GlobalVariableGet(gvName);
        if(CurrentPeriodIndex < 0 || CurrentPeriodIndex > 4)
            CurrentPeriodIndex = 0;
    }
    
    CurrentRSI_Period = RSI_Periods[CurrentPeriodIndex];

    // EMA buffers (index 0 and 1 - drawn first/behind)
    SetIndexBuffer(0, dEMA_Fast, INDICATOR_DATA);
    SetIndexBuffer(1, dEMA_Slow, INDICATOR_DATA);
    
    // Arrow buffers (index 2 and 3 - drawn on top)
    SetIndexBuffer(2, dUpRSIBuffer, INDICATOR_DATA);
    SetIndexBuffer(3, dDownRSIBuffer, INDICATOR_DATA);
    
    ArraySetAsSeries(dEMA_Fast, true);
    ArraySetAsSeries(dEMA_Slow, true);
    ArraySetAsSeries(dUpRSIBuffer, true);
    ArraySetAsSeries(dDownRSIBuffer, true);

    PlotIndexSetInteger(2, PLOT_ARROW, 233);
    PlotIndexSetInteger(3, PLOT_ARROW, 234);

    PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
    PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0);
    PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0.0);
    PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, 0.0);
    
    // Create ALL RSI handles at once - one for each period
    for(int i = 0; i < 5; i++)
    {
        RSI_Handles[i] = iRSI(_Symbol, _Period, RSI_Periods[i], PRICE_CLOSE);
        if(RSI_Handles[i] == INVALID_HANDLE)
        {
            Print("Error creating RSI handle for period ", RSI_Periods[i], ": ", GetLastError());
        }
    }
    
    // Create EMA handles
    myEMA_Fast = iMA(_Symbol, _Period, EMA_Fast, 0, MODE_EMA, PRICE_CLOSE);
    myEMA_Slow = iMA(_Symbol, _Period, EMA_Slow, 0, MODE_EMA, PRICE_CLOSE);
    
    if(myEMA_Fast == INVALID_HANDLE || myEMA_Slow == INVALID_HANDLE)
    {
        Print("Error creating EMA handles: ", GetLastError());
    }
    
    UpdateIndicatorName();
    CreateButtons();
}

void OnDeinit(const int reason)
{
    DeleteButtons();
    
    // Release ALL RSI handles
    for(int i = 0; i < 5; i++)
    {
        if(RSI_Handles[i] != INVALID_HANDLE) IndicatorRelease(RSI_Handles[i]);
    }
    
    if(myEMA_Fast != INVALID_HANDLE) IndicatorRelease(myEMA_Fast);
    if(myEMA_Slow != INVALID_HANDLE) IndicatorRelease(myEMA_Slow);
}

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
    if(id == CHARTEVENT_OBJECT_CLICK)
    {
        // Check which button was clicked
        for(int i = 0; i < 5; i++)
        {
            if(sparam == ButtonNames[i])
            {
                ObjectSetInteger(0, ButtonNames[i], OBJPROP_STATE, false);
                
                if(CurrentPeriodIndex == i) return; // Already on this period
                
                CurrentPeriodIndex = i;
                CurrentRSI_Period = RSI_Periods[i];
                
                // Save to global variable
                string gvName = "RSI_Period_Index_" + _Symbol + "_" + IntegerToString(_Period);
                GlobalVariableSet(gvName, CurrentPeriodIndex);
                
                UpdateButtons();
                UpdateIndicatorName();
                
                // Force recalculation
                ChartSetSymbolPeriod(ChartID(), _Symbol, _Period);
                
                return;
            }
        }
    }
}

void CreateButtons()
{
    int buttonWidth = 70;
    int buttonHeight = 25;
    int buttonSpacing = 5;
    
    for(int i = 0; i < 5; i++)
    {
        ButtonNames[i] = "RSI_Button_" + IntegerToString(RSI_Periods[i]);
        
        if(ObjectCreate(0, ButtonNames[i], OBJ_BUTTON, 0, 0, 0))
        {
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_XDISTANCE, ButtonX);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_YDISTANCE, ButtonY + (buttonHeight + buttonSpacing) * i);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_XSIZE, buttonWidth);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_YSIZE, buttonHeight);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_CORNER, CORNER_LEFT_UPPER);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_FONTSIZE, 9);
            ObjectSetString(0, ButtonNames[i], OBJPROP_TEXT, "RSI " + IntegerToString(RSI_Periods[i]));
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_COLOR, clrWhite);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_BGCOLOR, (i == CurrentPeriodIndex) ? clrGreen : clrDarkSlateGray);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_BORDER_COLOR, clrBlack);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_SELECTABLE, false);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_SELECTED, false);
        }
    }
}

void UpdateButtons()
{
    for(int i = 0; i < 5; i++)
    {
        if(ObjectFind(0, ButtonNames[i]) >= 0)
        {
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_BGCOLOR, (i == CurrentPeriodIndex) ? clrGreen : clrDarkSlateGray);
            ObjectSetInteger(0, ButtonNames[i], OBJPROP_STATE, false);
        }
    }
    ChartRedraw();
}

void DeleteButtons()
{
    for(int i = 0; i < 5; i++)
    {
        if(ObjectFind(0, ButtonNames[i]) >= 0)
        {
            ObjectDelete(0, ButtonNames[i]);
        }
    }
}

void UpdateIndicatorName()
{
    string filterStatus = UseEMAFilter ? " [Filter ON]" : " [Filter OFF]";
    IndicatorSetString(INDICATOR_SHORTNAME, "KK_RSI_Arrows_with_EMA (" + IntegerToString(CurrentRSI_Period) + ")" + filterStatus + " + EMA(" + IntegerToString(EMA_Fast) + "," + IntegerToString(EMA_Slow) + ")");
}

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[])
{
    if(rates_total < 100) return 0; // Not enough bars
    
    ArraySetAsSeries(High, true);
    ArraySetAsSeries(Low, true);
    ArraySetAsSeries(Time, true);

    // Prepare temp arrays for indicator data
    double RSIBuffer[];
    double EMA_FastBuffer[];
    double EMA_SlowBuffer[];
    
    ArraySetAsSeries(RSIBuffer, true);
    ArraySetAsSeries(EMA_FastBuffer, true);
    ArraySetAsSeries(EMA_SlowBuffer, true);
    
    // Calculate how many bars to process for EMAs (all bars)
    int ema_limit;
    if(prev_calculated == 0)
    {
        ema_limit = rates_total - 100; // Skip old bars on first run
    }
    else
    {
        ema_limit = rates_total - prev_calculated + 1; // Only new bars
    }
    
    // Copy EMA data for all bars being processed
    int ema_copy_bars = ema_limit + 2;
    if(CopyBuffer(myEMA_Fast, 0, 0, ema_copy_bars, EMA_FastBuffer) <= 0) return 0;
    if(CopyBuffer(myEMA_Slow, 0, 0, ema_copy_bars, EMA_SlowBuffer) <= 0) return 0;
    
    // Calculate EMAs for all bars
    for (int i = 0; i < ema_limit; i++)
    {
        dEMA_Fast[i] = EMA_FastBuffer[i];
        dEMA_Slow[i] = EMA_SlowBuffer[i];
    }

    // Calculate arrows only for BarsToScan most recent bars
    int arrow_limit = MathMin(BarsToScan, rates_total - 100);
    
    // Copy RSI data only for arrow calculation
    int arrow_copy_bars = arrow_limit + 2;
    if(CopyBuffer(RSI_Handles[CurrentPeriodIndex], 0, 0, arrow_copy_bars, RSIBuffer) <= 0) return 0;
    
    // Initialize arrow buffers for the arrow range
    if(prev_calculated == 0)
    {
        ArrayInitialize(dUpRSIBuffer, 0);
        ArrayInitialize(dDownRSIBuffer, 0);
    }

    for (int i = 0; i < arrow_limit; i++)
    {
        // Initialize arrow buffers
        dUpRSIBuffer[i] = 0;
        dDownRSIBuffer[i] = 0;

        double myRSInow = RSIBuffer[i];
        double myRSI2 = RSIBuffer[i + 1]; // RSI one bar ago

        // Determine if we should check trend
        bool trendOK = true;
        if(UseEMAFilter)
        {
            trendOK = false; // Will be set to true if trend condition met
        }

        if (myRSInow >= 50) // Is above 50
        {
            if((myRSInow > 50) && (myRSI2 < 50)) // Did it cross from below 50?
            {
                if(UseEMAFilter)
                {
                    // Check uptrend
                    if(dEMA_Fast[i] > dEMA_Slow[i])
                        trendOK = true;
                }
                
                if(trendOK)
                {
                    int highest = iHighest(_Symbol, _Period, MODE_HIGH, 20, i);
                    int lowest = iLowest(_Symbol, _Period, MODE_LOW, 20, i);
                    double distance = (High[highest] - Low[lowest]) * 0.02;
                    dUpRSIBuffer[i] = Low[i] - 2 * distance;
                }
            }
        }

        if (myRSInow < 50) // Is below 50
        {
            if((myRSInow < 50) && (myRSI2 > 50)) // Did it cross from above 50?
            {
                if(UseEMAFilter)
                {
                    // Check downtrend
                    if(dEMA_Fast[i] < dEMA_Slow[i])
                        trendOK = true;
                }
                
                if(trendOK)
                {
                    int highest = iHighest(_Symbol, _Period, MODE_HIGH, 20, i);
                    int lowest = iLowest(_Symbol, _Period, MODE_LOW, 20, i);
                    double distance = (High[highest] - Low[lowest]) * 0.02;
                    dDownRSIBuffer[i] = High[i] + 2 * distance;
                }
            }
        }
    }

    // Alert logic
    if ((!FirstRun) && ((EnableNativeAlerts) || (EnableEmailAlerts) || (EnablePushAlerts)))
    {
        if (((TriggerCandle > 0) && (Time[0] > LastAlertTime)) || (TriggerCandle == 0))
        {
            string Text;
            // Up arrow alert
            if ((dUpRSIBuffer[TriggerCandle] != 0) && (LastAlertDirection != 1))
            {
                Text = "Up Arrow";
                if (EnableNativeAlerts) Alert(Text);
                Text = "RSI Arrows (" + IntegerToString(CurrentRSI_Period) + "): " + _Symbol + " - " + StringSubstr(EnumToString((ENUM_TIMEFRAMES)_Period), 7) + " - " + Text + ".";
                if (EnableEmailAlerts) SendMail("RSI Arrows Alert", Text);
                if (EnablePushAlerts) SendNotification(Text);
                LastAlertTime = Time[0];
                LastAlertDirection = 1;
            }
            // Down arrow alert
            if ((dDownRSIBuffer[TriggerCandle] != 0) && (LastAlertDirection != -1))
            {
                Text = "Down Arrow";
                if (EnableNativeAlerts) Alert(Text);
                Text = "RSI Arrows (" + IntegerToString(CurrentRSI_Period) + "): " + _Symbol + " - " + StringSubstr(EnumToString((ENUM_TIMEFRAMES)_Period), 7) + " - " + Text + ".";
                if (EnableEmailAlerts) SendMail("RSI Arrows Alert", Text);
                if (EnablePushAlerts) SendNotification(Text);
                LastAlertTime = Time[0];
                LastAlertDirection = -1;
            }
        }
    }
    
    FirstRun = false;

    return rates_total;
}
//+------------------------------------------------------------------+