#property indicator_chart_window
#property strict
#property version "2.4"
#property description "Scans multiple pairs for ADR/AWR, Round Numbers, Daily Change, SWEEP signals, and Strength."

// --- Dashboard Configuration ---
#define REFRESH_INTERVAL_SECONDS 1
#define G_PREFIX "RND_"
#define MIN_ROW_HEIGHT 20
#define MAX_ROW_HEIGHT 50
#define MIN_FONT_SIZE 9
#define MAX_FONT_SIZE 16

// --- Structures for Data Handling ---
struct SymbolData {
    string  name;
    double  adrValue, currentDayRange;
    color   adrColor;
    double  awrValue, currentWeekRange;
    color   awrColor;
    color   roundTouchColor;
    string  roundTouchText;
    double  dailyPercentageChange, yesterdayPercentageChange;
    color   dailyPercentageColor, yesterdayPercentageColor;
    color   sweepColor;
    string  sweepText;
    int     sweepOrder;
    bool    isVisible;
};
SymbolData G_SymbolInfos[];

struct CurrencyStrength {
    string  name;
    double  strengthValue;
    color   strengthColor;
};
CurrencyStrength G_CurrentStrengths[], G_YesterdayStrengths[];

// --- Global Arrays for Configuration ---
string G_SYMBOLS_BASE[28] = {
    "EURUSD", "GBPUSD", "USDJPY", "USDCHF", "AUDUSD",
    "USDCAD", "NZDUSD", "EURGBP", "EURJPY", "EURCHF",
    "EURAUD", "EURCAD", "EURNZD", "GBPJPY", "GBPCHF",
    "GBPAUD", "GBPCAD", "GBPNZD", "AUDJPY", "AUDNZD",
    "AUDCAD", "AUDCHF", "CADJPY", "CADCHF", "CHFJPY",
    "NZDJPY", "NZDCAD", "NZDCHF"
};
string G_SYMBOLS_FULL[];
string G_MAJOR_CURRENCIES[] = {"EUR", "USD", "JPY", "GBP", "AUD", "NZD", "CAD", "CHF"};
string G_HIDDEN_SYMBOLS[];

//+------------------------------------------------------------------+
//| User Inputs                                                      |
//+------------------------------------------------------------------+
extern string INP_HEADER_GENERAL = "===== General Settings =====";
extern ENUM_TIMEFRAMES AnalysisTimeFrame = PERIOD_CURRENT;
extern string SymbolSuffix = "";

extern string INP_HEADER_COLUMNS = "===== Column Activation =====";
extern bool Show_ADR_Column = true;
extern bool Show_AWR_Column = true;
extern bool Show_SWEEP_Column = true;
extern bool Show_Round_Number_Column = true;
extern bool Show_Today_Change_Column = true;
extern bool Show_Yesterday_Change_Column = true;
extern bool Show_Today_Strength_Column = true;
extern bool Show_Yesterday_Strength_Column = true;

enum ENUM_SORT_METHOD {
    SORT_BY_SWEEP,
    SORT_BY_TODAY_CHANGE,
    SORT_BY_YESTERDAY_CHANGE,
    SORT_ALPHABETICALLY
};
extern string INP_HEADER_SORT = "===== Sorting Method =====";
extern ENUM_SORT_METHOD SymbolSortOrder = SORT_BY_SWEEP;
extern string HiddenSymbols_CommaSeparated = "";

extern string INP_HEADER_SWEEP = "===== SWEEP Signal Settings =====";
extern int SWEEP_Doji_Max_Body_Pips = 5;
extern bool SWEEP_Alert_Outside_Range = false;

extern string INP_HEADER_ADR_AWR = "===== ADR/AWR Settings =====";
extern int ADR_Period = 14;
extern int AWR_Period = 14;

extern string INP_HEADER_STYLE = "===== Style Settings =====";
extern int FontSizeAdjustment = 0; // NEW: Adjust font size (+2, -1, etc.)
extern color TextColor = clrBlack;
extern color TextColorOnColor = clrWhite;

// --- Global Variables ---
datetime G_LastUpdateTime = 0;
int G_LastChartHeight = 0, G_LastChartWidth = 0;
int G_X_START, G_Y_START, G_RowHeight, G_TitleHeight, G_HeaderHeight, G_ColumnSpacing;
int G_PanelWidth, G_PanelHeight, G_CS_PanelWidth;
int G_SymbolColWidth, G_AdrColWidth, G_AwrColWidth, G_RnColWidth, G_TodayChangeColWidth, G_YesterdayChangeColWidth, G_SweepColWidth;
int G_FontSize; // Now calculated dynamically

//+------------------------------------------------------------------+
//| Helper Functions                                                 |
//+------------------------------------------------------------------+
string StringTrim(string text) {
    int len = StringLen(text), start = 0;
    while (start < len && StringSubstr(text, start, 1) == " ") start++;
    int end = len - 1;
    while (end >= start && StringSubstr(text, end, 1) == " ") end--;
    return (start > end) ? "" : StringSubstr(text, start, end - start + 1);
}

void ParseCommaSeparatedString(string inputString, string &outputArray[]) {
    ArrayResize(outputArray, 0);
    if (inputString == "") return;
    string parts[];
    int count = StringSplit(inputString, (ushort)',', parts);
    for (int i = 0; i < count; i++) {
        string trimmed = StringTrim(parts[i]);
        if (trimmed != "") {
            int curSize = ArraySize(outputArray);
            ArrayResize(outputArray, curSize + 1);
            outputArray[curSize] = trimmed;
        }
    }
}

bool IsSymbolHidden(string symbol) {
    for (int i = 0; i < ArraySize(G_HIDDEN_SYMBOLS); i++) {
        if (G_HIDDEN_SYMBOLS[i] == symbol) return true;
    }
    return false;
}

double GetPipValue(string symbol) {
    double point = MarketInfo(symbol, MODE_POINT);
    int digits = (int)MarketInfo(symbol, MODE_DIGITS);
    if (digits == 3 || digits == 5) return point * 10;
    return point;
}

//+------------------------------------------------------------------+
//| Calculation Functions                                            |
//+------------------------------------------------------------------+
void CheckSweepCondition(string symbol, ENUM_TIMEFRAMES timeframe, int &out_sweepOrder, color &out_color, string &out_text) {
    out_sweepOrder = 0; out_color = clrLightGray; out_text = "NONE";
    if (iBars(symbol, timeframe) < 3) return;
    double c2_open = iOpen(symbol, timeframe, 1), c2_high = iHigh(symbol, timeframe, 1), c2_low = iLow(symbol, timeframe, 1), c2_close = iClose(symbol, timeframe, 1);
    double c1_high = iHigh(symbol, timeframe, 2), c1_low = iLow(symbol, timeframe, 2);
    if (c2_open == 0 || c1_high == 0) return;
    double dojiMaxPoints = SWEEP_Doji_Max_Body_Pips * GetPipValue(symbol);
    bool isBullishOrDoji = (c2_close > c2_open) || (MathAbs(c2_close - c2_open) <= dojiMaxPoints);
    if (isBullishOrDoji && c2_low < c1_low) {
        if ((c2_close < c1_high && c2_close > c1_low) || (SWEEP_Alert_Outside_Range && c2_close >= c1_high)) {
            out_sweepOrder = 2; out_color = clrDodgerBlue; out_text = "UP"; return;
        }
    }
    bool isBearishOrDoji = (c2_close < c2_open) || (MathAbs(c2_close - c2_open) <= dojiMaxPoints);
    if (isBearishOrDoji && c2_high > c1_high) {
        if ((c2_close < c1_high && c2_close > c1_low) || (SWEEP_Alert_Outside_Range && c2_close <= c1_low)) {
            out_sweepOrder = 1; out_color = clrRed; out_text = "DOWN"; return;
        }
    }
}

void CheckRoundNumberTouch(string symbol, ENUM_TIMEFRAMES timeframe, color &out_color, string &out_text) {
    out_color = clrLightGray; out_text = "NONE";
    if (iBars(symbol, timeframe) < 2) return;
    double openPrice = iOpen(symbol, timeframe, 1), highPrice = iHigh(symbol, timeframe, 1), lowPrice = iLow(symbol, timeframe, 1), closePrice = iClose(symbol, timeframe, 1);
    if (openPrice == 0 || highPrice == 0) return;
    int digits = (int)MarketInfo(symbol, MODE_DIGITS);
    double multiplier = MathPow(10, digits > 3 ? 3 : 2);
    for (double p = MathFloor(lowPrice * multiplier) / multiplier; p <= MathCeil(highPrice * multiplier) / multiplier + DBL_EPSILON; p += 1.0 / multiplier) {
        if (p >= lowPrice && p <= highPrice) {
            if (closePrice > openPrice && closePrice > p) { out_color = clrDodgerBlue; out_text = "UP"; return; }
            if (closePrice < openPrice && closePrice < p) { out_color = clrRed; out_text = "DOWN"; return; }
        }
    }
}

double CalculateADR(string s, int p) { if(iBars(s,PERIOD_D1)<p+1) return 0; return iATR(s, PERIOD_D1, p, 1) / GetPipValue(s); }
double CalculateCurrentDayRange(string s) { if(iBars(s,PERIOD_D1)<1) return 0; return (iHigh(s, PERIOD_D1, 0) - iLow(s, PERIOD_D1, 0)) / GetPipValue(s); }
double CalculateAWR(string s, int p) { if(iBars(s,PERIOD_W1)<p+1) return 0; return iATR(s, PERIOD_W1, p, 1) / GetPipValue(s); }
double CalculateCurrentWeekRange(string s) { if(iBars(s,PERIOD_W1)<1) return 0; return (iHigh(s, PERIOD_W1, 0) - iLow(s, PERIOD_W1, 0)) / GetPipValue(s); }

double CalculateDailyPercentageChange(string s, int shift) {
    if (iBars(s, PERIOD_D1) < shift + 2) return 0.0;
    double close_current = iClose(s, PERIOD_D1, shift);
    double close_previous = iClose(s, PERIOD_D1, shift + 1);
    if (close_previous == 0) return 0.0;
    return ((close_current - close_previous) / close_previous) * 100.0;
}

//+------------------------------------------------------------------+
//| Sorting Logic                                                    |
//+------------------------------------------------------------------+
void SortSymbols() {
    int total = ArraySize(G_SymbolInfos);
    for (int i = 0; i < total - 1; i++) {
        for (int j = i + 1; j < total; j++) {
            bool shouldSwap = false;
            switch (SymbolSortOrder) {
                case SORT_BY_SWEEP:
                    if (G_SymbolInfos[j].sweepOrder > G_SymbolInfos[i].sweepOrder) shouldSwap = true;
                    break;
                case SORT_BY_TODAY_CHANGE:
                    if (MathAbs(G_SymbolInfos[j].dailyPercentageChange) > MathAbs(G_SymbolInfos[i].dailyPercentageChange)) shouldSwap = true;
                    break;
                case SORT_BY_YESTERDAY_CHANGE:
                    if (MathAbs(G_SymbolInfos[j].yesterdayPercentageChange) > MathAbs(G_SymbolInfos[i].yesterdayPercentageChange)) shouldSwap = true;
                    break;
                case SORT_ALPHABETICALLY:
                    if (StringCompare(G_SymbolInfos[j].name, G_SymbolInfos[i].name) < 0) shouldSwap = true;
                    break;
            }
            if (shouldSwap) {
                SymbolData temp = G_SymbolInfos[i]; G_SymbolInfos[i] = G_SymbolInfos[j]; G_SymbolInfos[j] = temp;
            }
        }
    }
}

void SortCurrencyStrengths(CurrencyStrength &strengths[]) {
    int total = ArraySize(strengths);
    for (int i = 0; i < total - 1; i++) {
        for (int j = i + 1; j < total; j++) {
            if (strengths[j].strengthValue > strengths[i].strengthValue) {
                CurrencyStrength temp = strengths[i]; strengths[i] = strengths[j]; strengths[j] = temp;
            }
        }
    }
}

//+------------------------------------------------------------------+
//| Main Data Update Function                                        |
//+------------------------------------------------------------------+
void UpdateAllData() {
    ArrayResize(G_CurrentStrengths, ArraySize(G_MAJOR_CURRENCIES));
    ArrayResize(G_YesterdayStrengths, ArraySize(G_MAJOR_CURRENCIES));
    for (int i = 0; i < ArraySize(G_MAJOR_CURRENCIES); i++) {
        G_CurrentStrengths[i].name = G_MAJOR_CURRENCIES[i]; G_CurrentStrengths[i].strengthValue = 0;
        G_YesterdayStrengths[i].name = G_MAJOR_CURRENCIES[i]; G_YesterdayStrengths[i].strengthValue = 0;
    }

    for (int i = 0; i < ArraySize(G_SymbolInfos); i++) {
        string symbol = G_SymbolInfos[i].name;
        if (MarketInfo(symbol, MODE_POINT) == 0) continue;
        G_SymbolInfos[i].isVisible = !IsSymbolHidden(symbol);

        G_SymbolInfos[i].adrValue = CalculateADR(symbol, ADR_Period);
        G_SymbolInfos[i].currentDayRange = CalculateCurrentDayRange(symbol);
        G_SymbolInfos[i].awrValue = CalculateAWR(symbol, AWR_Period);
        G_SymbolInfos[i].currentWeekRange = CalculateCurrentWeekRange(symbol);
        G_SymbolInfos[i].adrColor = (G_SymbolInfos[i].currentDayRange > G_SymbolInfos[i].adrValue && G_SymbolInfos[i].adrValue > 0) ? clrRed : clrLightGray;
        G_SymbolInfos[i].awrColor = (G_SymbolInfos[i].currentWeekRange > G_SymbolInfos[i].awrValue && G_SymbolInfos[i].awrValue > 0) ? clrRed : clrLightGray;
        
        CheckSweepCondition(symbol, AnalysisTimeFrame, G_SymbolInfos[i].sweepOrder, G_SymbolInfos[i].sweepColor, G_SymbolInfos[i].sweepText);
        CheckRoundNumberTouch(symbol, AnalysisTimeFrame, G_SymbolInfos[i].roundTouchColor, G_SymbolInfos[i].roundTouchText);

        double currentBid = MarketInfo(symbol, MODE_BID);
        double prevDayClose = iClose(symbol, PERIOD_D1, 1);
        G_SymbolInfos[i].dailyPercentageChange = (prevDayClose > 0) ? ((currentBid - prevDayClose) / prevDayClose) * 100.0 : 0.0;
        G_SymbolInfos[i].yesterdayPercentageChange = CalculateDailyPercentageChange(symbol, 1);

        G_SymbolInfos[i].dailyPercentageColor = (G_SymbolInfos[i].dailyPercentageChange > 0) ? clrDodgerBlue : (G_SymbolInfos[i].dailyPercentageChange < 0 ? clrRed : clrLightGray);
        G_SymbolInfos[i].yesterdayPercentageColor = (G_SymbolInfos[i].yesterdayPercentageChange > 0) ? clrDodgerBlue : (G_SymbolInfos[i].yesterdayPercentageChange < 0 ? clrRed : clrLightGray);

        string base = StringSubstr(symbol, 0, 3), quote = StringSubstr(symbol, 3, 3);
        for (int j = 0; j < ArraySize(G_MAJOR_CURRENCIES); j++) {
            if (G_CurrentStrengths[j].name == base) G_CurrentStrengths[j].strengthValue += G_SymbolInfos[i].dailyPercentageChange;
            if (G_CurrentStrengths[j].name == quote) G_CurrentStrengths[j].strengthValue -= G_SymbolInfos[i].dailyPercentageChange;
            if (G_YesterdayStrengths[j].name == base) G_YesterdayStrengths[j].strengthValue += G_SymbolInfos[i].yesterdayPercentageChange;
            if (G_YesterdayStrengths[j].name == quote) G_YesterdayStrengths[j].strengthValue -= G_SymbolInfos[i].yesterdayPercentageChange;
        }
    }
    
    for(int i=0; i<ArraySize(G_CurrentStrengths); i++) {
        G_CurrentStrengths[i].strengthColor = (G_CurrentStrengths[i].strengthValue > 0) ? clrDodgerBlue : (G_CurrentStrengths[i].strengthValue < 0 ? clrRed : clrLightGray);
        G_YesterdayStrengths[i].strengthColor = (G_YesterdayStrengths[i].strengthValue > 0) ? clrDodgerBlue : (G_YesterdayStrengths[i].strengthValue < 0 ? clrRed : clrLightGray);
    }

    SortSymbols();
    SortCurrencyStrengths(G_CurrentStrengths);
    SortCurrencyStrengths(G_YesterdayStrengths);
    
    RedrawDashboard();
}

//+------------------------------------------------------------------+
//| Drawing & Layout Functions                                       |
//+------------------------------------------------------------------+
void CreateLabel(string n, string t, int x, int y, color c, int s) { string o=G_PREFIX+n; if(ObjectFind(0,o)<0){ObjectCreate(0,o,OBJ_LABEL,0,0,0); ObjectSetInteger(0,o,OBJPROP_CORNER,0); ObjectSetInteger(0,o,OBJPROP_FONTSIZE,s); ObjectSetString(0,o,OBJPROP_FONT,"Calibri"); ObjectSetInteger(0,o,OBJPROP_BACK,false);} ObjectSetInteger(0,o,OBJPROP_XDISTANCE,x); ObjectSetInteger(0,o,OBJPROP_YDISTANCE,y); ObjectSetString(0,o,OBJPROP_TEXT,t); ObjectSetInteger(0,o,OBJPROP_COLOR,c); }
void CreateRectangle(string n, int x, int y, int w, int h, color c) { string o=G_PREFIX+n; if(ObjectFind(0,o)<0){ObjectCreate(0,o,OBJ_RECTANGLE_LABEL,0,0,0); ObjectSetInteger(0,o,OBJPROP_CORNER,0); ObjectSetInteger(0,o,OBJPROP_BACK,true);} ObjectSetInteger(0,o,OBJPROP_XDISTANCE,x); ObjectSetInteger(0,o,OBJPROP_YDISTANCE,y); ObjectSetInteger(0,o,OBJPROP_XSIZE,w); ObjectSetInteger(0,o,OBJPROP_YSIZE,h); ObjectSetInteger(0,o,OBJPROP_BGCOLOR,c); }

void CalculateLayout() {
    G_LastChartWidth = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);
    G_LastChartHeight = (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS);
    G_X_START = 10; G_Y_START = 10; G_TitleHeight = 30; G_HeaderHeight = 25; G_ColumnSpacing = 5;

    // --- Dynamic Row Height & Font Size ---
    int visibleRows = 0; for(int i=0; i<ArraySize(G_SymbolInfos); i++) if(G_SymbolInfos[i].isVisible) visibleRows++;
    int meterRows = ArraySize(G_MAJOR_CURRENCIES);
    int totalRowsForHeightCalc = MathMax(visibleRows, meterRows);
    int availableHeight = G_LastChartHeight - G_Y_START - G_TitleHeight - G_HeaderHeight - 20;
    G_RowHeight = (totalRowsForHeightCalc > 0) ? (int)MathMax(MIN_ROW_HEIGHT, MathMin(MAX_ROW_HEIGHT, availableHeight / totalRowsForHeightCalc)) : MIN_ROW_HEIGHT;
    int baseFontSize = (int)MathMax(MIN_FONT_SIZE, MathMin(MAX_FONT_SIZE, G_RowHeight * 0.50));
    G_FontSize = baseFontSize + FontSizeAdjustment;

    // --- Column Width Calculation ---
    int activeMainCols = 1; // Symbol
    if (Show_ADR_Column) activeMainCols++; if (Show_AWR_Column) activeMainCols++; if (Show_SWEEP_Column) activeMainCols++; 
    if (Show_Round_Number_Column) activeMainCols++; if (Show_Today_Change_Column) activeMainCols++; if (Show_Yesterday_Change_Column) activeMainCols++;
    
    int totalWidthForMeters = 0;
    if (Show_Today_Strength_Column) totalWidthForMeters += 100 + G_ColumnSpacing;
    if (Show_Yesterday_Strength_Column) totalWidthForMeters += 100 + G_ColumnSpacing;

    int availableWidth = G_LastChartWidth - G_X_START * 2 - (activeMainCols > 1 ? (activeMainCols - 1) * G_ColumnSpacing : 0) - totalWidthForMeters;
    int stdWidth = availableWidth > 0 ? (int)(availableWidth / activeMainCols) : 50;

    G_SymbolColWidth = (int)(stdWidth * 0.9);
    G_AdrColWidth = Show_ADR_Column ? (int)(stdWidth * 1.1) : 0;
    G_AwrColWidth = Show_AWR_Column ? (int)(stdWidth * 1.1) : 0;
    G_SweepColWidth = Show_SWEEP_Column ? (int)(stdWidth * 0.8) : 0;
    G_RnColWidth = Show_Round_Number_Column ? (int)(stdWidth * 0.8) : 0;
    G_TodayChangeColWidth = Show_Today_Change_Column ? (int)(stdWidth * 1.2) : 0;
    G_YesterdayChangeColWidth = Show_Yesterday_Change_Column ? (int)(stdWidth * 1.2) : 0;
    G_CS_PanelWidth = 100;

    G_PanelWidth = G_SymbolColWidth + G_AdrColWidth + G_AwrColWidth + G_SweepColWidth + G_RnColWidth + G_TodayChangeColWidth + G_YesterdayChangeColWidth + (activeMainCols > 1 ? (activeMainCols - 1) * G_ColumnSpacing : 0);
    G_PanelHeight = G_TitleHeight + G_HeaderHeight + (MathMax(visibleRows, meterRows) * G_RowHeight) + 10;
}

void RedrawDashboard() {
    ObjectsDeleteAll(0, G_PREFIX);
    CalculateLayout();
    
    // --- Main Panel ---
    CreateRectangle("Panel_Main", G_X_START, G_Y_START, G_PanelWidth, G_PanelHeight, clrWhiteSmoke);
    CreateLabel("Title_Main", "SWEEP & Data Dashboard", G_X_START + 5, G_Y_START + 5, TextColor, G_FontSize + 2);

    int x = G_X_START + 2, y = G_Y_START + G_TitleHeight;
    CreateLabel("Hdr_Symbol", "Symbol", x, y, TextColor, G_FontSize); x += G_SymbolColWidth + G_ColumnSpacing;
    if (Show_ADR_Column) { CreateLabel("Hdr_ADR", "ADR ("+(string)ADR_Period+"D)", x, y, TextColor, G_FontSize); x += G_AdrColWidth + G_ColumnSpacing; }
    if (Show_AWR_Column) { CreateLabel("Hdr_AWR", "AWR ("+(string)AWR_Period+"W)", x, y, TextColor, G_FontSize); x += G_AwrColWidth + G_ColumnSpacing; }
    if (Show_SWEEP_Column) { CreateLabel("Hdr_SWEEP", "SWEEP", x, y, TextColor, G_FontSize); x += G_SweepColWidth + G_ColumnSpacing; }
    if (Show_Round_Number_Column) { CreateLabel("Hdr_RN", "Round #", x, y, TextColor, G_FontSize); x += G_RnColWidth + G_ColumnSpacing; }
    if (Show_Today_Change_Column) { CreateLabel("Hdr_Today", "Today %", x, y, TextColor, G_FontSize); x += G_TodayChangeColWidth + G_ColumnSpacing; }
    if (Show_Yesterday_Change_Column) { CreateLabel("Hdr_Yest", "Yest %", x, y, TextColor, G_FontSize); }

    y += G_HeaderHeight;
    int visible_idx = 0;
    for (int i = 0; i < ArraySize(G_SymbolInfos); i++) {
        if (!G_SymbolInfos[i].isVisible) continue;
        int cy = y + visible_idx * G_RowHeight, ty = cy + (G_RowHeight - G_FontSize) / 2;
        x = G_X_START + 2;
        CreateLabel("Sym_"+G_SymbolInfos[i].name, G_SymbolInfos[i].name, x, ty, TextColor, G_FontSize); x += G_SymbolColWidth + G_ColumnSpacing;
        if (Show_ADR_Column) { string t=StringFormat("%.1f/%.1f", G_SymbolInfos[i].currentDayRange, G_SymbolInfos[i].adrValue); CreateRectangle("Rect_ADR_"+G_SymbolInfos[i].name, x, cy, G_AdrColWidth, G_RowHeight, G_SymbolInfos[i].adrColor); CreateLabel("Lbl_ADR_"+G_SymbolInfos[i].name, t, x+5, ty, G_SymbolInfos[i].adrColor==clrLightGray?TextColor:TextColorOnColor, G_FontSize); x += G_AdrColWidth + G_ColumnSpacing; }
        if (Show_AWR_Column) { string t=StringFormat("%.1f/%.1f", G_SymbolInfos[i].currentWeekRange, G_SymbolInfos[i].awrValue); CreateRectangle("Rect_AWR_"+G_SymbolInfos[i].name, x, cy, G_AwrColWidth, G_RowHeight, G_SymbolInfos[i].awrColor); CreateLabel("Lbl_AWR_"+G_SymbolInfos[i].name, t, x+5, ty, G_SymbolInfos[i].awrColor==clrLightGray?TextColor:TextColorOnColor, G_FontSize); x += G_AwrColWidth + G_ColumnSpacing; }
        if (Show_SWEEP_Column) { CreateRectangle("Rect_SWEEP_"+G_SymbolInfos[i].name, x, cy, G_SweepColWidth, G_RowHeight, G_SymbolInfos[i].sweepColor); CreateLabel("Lbl_SWEEP_"+G_SymbolInfos[i].name, G_SymbolInfos[i].sweepText, x+5, ty, TextColorOnColor, G_FontSize); x += G_SweepColWidth + G_ColumnSpacing; }
        if (Show_Round_Number_Column) { CreateRectangle("Rect_RN_"+G_SymbolInfos[i].name, x, cy, G_RnColWidth, G_RowHeight, G_SymbolInfos[i].roundTouchColor); CreateLabel("Lbl_RN_"+G_SymbolInfos[i].name, G_SymbolInfos[i].roundTouchText, x+5, ty, G_SymbolInfos[i].roundTouchColor==clrLightGray?TextColor:TextColorOnColor, G_FontSize); x += G_RnColWidth + G_ColumnSpacing; }
        if (Show_Today_Change_Column) { string t=StringFormat("%.2f%%", G_SymbolInfos[i].dailyPercentageChange); CreateRectangle("Rect_Today_"+G_SymbolInfos[i].name, x, cy, G_TodayChangeColWidth, G_RowHeight, G_SymbolInfos[i].dailyPercentageColor); CreateLabel("Lbl_Today_"+G_SymbolInfos[i].name, t, x+5, ty, TextColorOnColor, G_FontSize); x += G_TodayChangeColWidth + G_ColumnSpacing; }
        if (Show_Yesterday_Change_Column) { string t=StringFormat("%.2f%%", G_SymbolInfos[i].yesterdayPercentageChange); CreateRectangle("Rect_Yest_"+G_SymbolInfos[i].name, x, cy, G_YesterdayChangeColWidth, G_RowHeight, G_SymbolInfos[i].yesterdayPercentageColor); CreateLabel("Lbl_Yest_"+G_SymbolInfos[i].name, t, x+5, ty, TextColorOnColor, G_FontSize); }
        visible_idx++;
    }
    
    // --- Strength Meters ---
    x = G_X_START + G_PanelWidth + G_ColumnSpacing;
    if (Show_Today_Strength_Column) {
        CreateRectangle("Panel_CS_Today", x, G_Y_START, G_CS_PanelWidth, G_PanelHeight, clrWhiteSmoke);
        CreateLabel("Title_CS_Today", "Today Strength", x + 5, G_Y_START + 5, TextColor, G_FontSize + 2);
        for(int i=0; i<ArraySize(G_CurrentStrengths); i++) {
            int cy = G_Y_START + G_TitleHeight + G_HeaderHeight + i * G_RowHeight, ty = cy + (G_RowHeight-G_FontSize)/2;
            string t = StringFormat("%s: %.2f%%", G_CurrentStrengths[i].name, G_CurrentStrengths[i].strengthValue);
            CreateRectangle("Rect_CST_"+G_CurrentStrengths[i].name, x, cy, G_CS_PanelWidth, G_RowHeight, G_CurrentStrengths[i].strengthColor);
            CreateLabel("Lbl_CST_"+G_CurrentStrengths[i].name, t, x+5, ty, TextColorOnColor, G_FontSize);
        }
        x += G_CS_PanelWidth + G_ColumnSpacing;
    }
    if (Show_Yesterday_Strength_Column) {
        CreateRectangle("Panel_CS_Yest", x, G_Y_START, G_CS_PanelWidth, G_PanelHeight, clrWhiteSmoke);
        CreateLabel("Title_CS_Yest", "Yest. Strength", x + 5, G_Y_START + 5, TextColor, G_FontSize + 2);
        for(int i=0; i<ArraySize(G_YesterdayStrengths); i++) {
            int cy = G_Y_START + G_TitleHeight + G_HeaderHeight + i * G_RowHeight, ty = cy + (G_RowHeight-G_FontSize)/2;
            string t = StringFormat("%s: %.2f%%", G_YesterdayStrengths[i].name, G_YesterdayStrengths[i].strengthValue);
            CreateRectangle("Rect_CSY_"+G_YesterdayStrengths[i].name, x, cy, G_CS_PanelWidth, G_RowHeight, G_YesterdayStrengths[i].strengthColor);
            CreateLabel("Lbl_CSY_"+G_YesterdayStrengths[i].name, t, x+5, ty, TextColorOnColor, G_FontSize);
        }
    }
    ChartRedraw();
}

//+------------------------------------------------------------------+
//| MQL4 Standard Functions                                          |
//+------------------------------------------------------------------+
int OnInit() {
    ArrayResize(G_SYMBOLS_FULL, ArraySize(G_SYMBOLS_BASE));
    for (int i = 0; i < ArraySize(G_SYMBOLS_BASE); i++) G_SYMBOLS_FULL[i] = G_SYMBOLS_BASE[i] + SymbolSuffix;
    ParseCommaSeparatedString(HiddenSymbols_CommaSeparated, G_HIDDEN_SYMBOLS);
    ArrayResize(G_SymbolInfos, ArraySize(G_SYMBOLS_FULL));
    for (int i = 0; i < ArraySize(G_SYMBOLS_FULL); i++) G_SymbolInfos[i].name = G_SYMBOLS_FULL[i];
    UpdateAllData(); G_LastUpdateTime = TimeCurrent();
    return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason) { ObjectsDeleteAll(0, G_PREFIX); ChartRedraw(); }
int OnCalculate(const int r,const int p,const datetime &t[],const double &o[],const double &h[],const double &l[],const double &c[],const long &v[],const long &rv[],const int &s[]) {
    if (TimeCurrent() - G_LastUpdateTime >= REFRESH_INTERVAL_SECONDS) {
        UpdateAllData(); G_LastUpdateTime = TimeCurrent();
    } return(r);
}
void OnChartEvent(const int id, const long &lp, const double &dp, const string &sp) {
    if (id == CHARTEVENT_CHART_CHANGE) RedrawDashboard();
}
//+------------------------------------------------------------------+
