//+------------------------------------------------------------------+
//|                                                 A! MTF RZP %.mq4 |
//|                        Converted from TradingView Pine Script    |
//|                                                                  |
//+------------------------------------------------------------------+
#property strict
#property indicator_chart_window // Draw in a separate subwindow

// Timeframe Inputs
input string Heatmap1Timeframe = "D";  // Timeframe 1
input string Heatmap2Timeframe = "W";  // Timeframe 2
input string Heatmap3Timeframe = "240"; // Timeframe 3
input int RangePeriods = 5;            // Periods to Average

// Position Inputs
input int Label1_X = 160;              // Label 1 X Distance
input int Label1_Y = 30;              // Label 1 Y Distance
input int Label2_X = 160;              // Label 2 X Distance
input int Label2_Y = 50;              // Label 2 Y Distance
input int Label3_X = 160;              // Label 3 X Distance
input int Label3_Y = 70;              // Label 3 Y Distance
input ENUM_BASE_CORNER Corner = CORNER_RIGHT_LOWER; // Labels Corner Position

// Font Settings
input string FontName = "OCR A Extended";      // Font Name
input int FontSize = 15;              // Font Size
input color FontColor = clrBlack;     // Font Color
input bool FontBold = True;          // Bold Text
input bool FontItalic = false;        // Italic Text

// Global variables
int tf1, tf2, tf3;
double tf1_open, tf1_range, tf1_pos, tf1_percent;
double tf2_open, tf2_range, tf2_pos, tf2_percent;
double tf3_open, tf3_range, tf3_pos, tf3_percent;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
    // Convert timeframe strings to ENUM_TIMEFRAMES
    tf1 = GetTimeframe(Heatmap1Timeframe);
    tf2 = GetTimeframe(Heatmap2Timeframe);
    tf3 = GetTimeframe(Heatmap3Timeframe);

    if (tf1 == -1 || tf2 == -1 || tf3 == -1)
    {
        Print("Invalid timeframe input.");
        return(INIT_FAILED);
    }

    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[])
{
    // Calculate ranges and positions
    CalculateRange(tf1, tf1_open, tf1_range, tf1_pos, tf1_percent);
    CalculateRange(tf2, tf2_open, tf2_range, tf2_pos, tf2_percent);
    CalculateRange(tf3, tf3_open, tf3_range, tf3_pos, tf3_percent);

    // Display percentage data
    if (rates_total > 0)
    {
        DrawPercentages();
    }

    return(rates_total);
}

//+------------------------------------------------------------------+
//| Convert timeframe string to ENUM_TIMEFRAMES                      |
//+------------------------------------------------------------------+
int GetTimeframe(string tf)
{
    if (tf == "1") return PERIOD_M1;
    if (tf == "3") return PERIOD_M3;
    if (tf == "5") return PERIOD_M5;
    if (tf == "15") return PERIOD_M15;
    if (tf == "30") return PERIOD_M30;
    if (tf == "60") return PERIOD_H1;
    if (tf == "120") return PERIOD_H2;
    if (tf == "240") return PERIOD_H4;
    if (tf == "360") return PERIOD_H6;
    if (tf == "720") return PERIOD_H12;
    if (tf == "D") return PERIOD_D1;
    if (tf == "W") return PERIOD_W1;
    if (tf == "M") return PERIOD_MN1;
    return -1; // Invalid timeframe
}

//+------------------------------------------------------------------+
//| Calculate range and position for a given timeframe               |
//+------------------------------------------------------------------+
void CalculateRange(int timeframe, double &tf_open, double &tf_range, double &tf_pos, double &tf_percent)
{
    double highs[], lows[], closes[];
    ArraySetAsSeries(highs, true);
    ArraySetAsSeries(lows, true);
    ArraySetAsSeries(closes, true);

    CopyHigh(_Symbol, timeframe, 0, RangePeriods, highs);
    CopyLow(_Symbol, timeframe, 0, RangePeriods, lows);
    CopyClose(_Symbol, timeframe, 0, 1, closes);

    double range_sum = 0;
    for (int i = 0; i < RangePeriods; i++)
    {
        range_sum += highs[i] - lows[i];
    }
    tf_range = range_sum / RangePeriods;

    tf_open = iOpen(_Symbol, timeframe, 0);
    double relativePos = (closes[0] - tf_open) / (tf_range / 2);
    tf_pos = NormalizeValue(relativePos);

    double move = MathAbs(closes[0] - tf_open);
    tf_percent = move / tf_range * 100;
}

//+------------------------------------------------------------------+
//| Normalize value to scale (0-40)                                  |
//+------------------------------------------------------------------+
double NormalizeValue(double src)
{
    double x = src * 2;
    double val = (x > 2 ? 2 : x < -2 ? -2 : x) + 2;
    return val * 10;
}

//+------------------------------------------------------------------+
//| Draw percentage data on the chart                                |
//+------------------------------------------------------------------+
void DrawPercentages()
{
    string tf1_text = GetTimeframeLabel(Heatmap1Timeframe) + ": " + DoubleToString(tf1_percent, 2) + "%";
    string tf2_text = GetTimeframeLabel(Heatmap2Timeframe) + ": " + DoubleToString(tf2_percent, 2) + "%";
    string tf3_text = GetTimeframeLabel(Heatmap3Timeframe) + ": " + DoubleToString(tf3_percent, 2) + "%";
    
    // Create or update labels
    CreateLabel("TF1_Label", Label1_X, Label1_Y, tf1_text);
    CreateLabel("TF2_Label", Label2_X, Label2_Y, tf2_text);
    CreateLabel("TF3_Label", Label3_X, Label3_Y, tf3_text);
}

//+------------------------------------------------------------------+
//| Create or update a label                                         |
//+------------------------------------------------------------------+
void CreateLabel(string name, int x, int y, string text)
{
    if(ObjectFind(0, name) < 0)
        ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
        
    ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
    ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
    ObjectSetString(0, name, OBJPROP_TEXT, text);
    ObjectSetString(0, name, OBJPROP_FONT, FontName);
    ObjectSetInteger(0, name, OBJPROP_FONTSIZE, FontSize);
    ObjectSetInteger(0, name, OBJPROP_COLOR, FontColor);
    ObjectSetInteger(0, name, OBJPROP_CORNER, Corner);
    
    // Set font style (0 = regular, 1 = bold, 2 = italic, 3 = bold italic)
    int style = 0;
    if(FontBold && FontItalic) style = 3;
    else if(FontBold) style = 1;
    else if(FontItalic) style = 2;
    ObjectSetInteger(0, name, OBJPROP_FONTSIZE, FontSize);
    ObjectSetInteger(0, name, OBJPROP_COLOR, FontColor);
}

//+------------------------------------------------------------------+
//| Get timeframe label                                              |
//+------------------------------------------------------------------+
string GetTimeframeLabel(string tf)
{
    if (tf == "1") return "1m";
    if (tf == "3") return "3m";
    if (tf == "5") return "5m";
    if (tf == "15") return "15m";
    if (tf == "30") return "30m";
    if (tf == "60") return "1H";
    if (tf == "120") return "2H";
    if (tf == "240") return "4H";
    if (tf == "360") return "6H";
    if (tf == "720") return "12H";
    if (tf == "D") return "1D";
    if (tf == "W") return "1W";
    if (tf == "M") return "1M";
    return tf; // default case
}