From f4152b8f6c00bb0c626577e409aa2e0bbf4afee1 Mon Sep 17 00:00:00 2001 From: Toh4iem9 Date: Mon, 6 Jul 2026 08:55:17 +0200 Subject: [PATCH] new files added --- .../Quant/LinReg_R2_Dashboard_Pro.mq5 | 337 ++++++++++++++++++ 1 file changed, 337 insertions(+) create mode 100644 Indicators/MyIndicators/Quant/LinReg_R2_Dashboard_Pro.mq5 diff --git a/Indicators/MyIndicators/Quant/LinReg_R2_Dashboard_Pro.mq5 b/Indicators/MyIndicators/Quant/LinReg_R2_Dashboard_Pro.mq5 new file mode 100644 index 0000000..76bfbe0 --- /dev/null +++ b/Indicators/MyIndicators/Quant/LinReg_R2_Dashboard_Pro.mq5 @@ -0,0 +1,337 @@ +//+------------------------------------------------------------------+ +//| LinReg_R2_Dashboard_Pro.mq5 | +//| Copyright 2026, xxxxxxxx| +//+------------------------------------------------------------------+ +#property copyright "Copyright 2026, xxxxxxxx" +#property version "1.00" // Fully functional dynamic Multi-Asset LinReg R2 Thermal Scanner +#property description "Minimalist and Live-Updating LinReg R2 Multi-Asset Thermal Scanner." +#property description "Companion dashboard for LinReg_R2_Pro. Displays R2 Trend Quality and Slope Direction." +#property indicator_chart_window +#property indicator_buffers 0 +#property indicator_plots 0 + +#include + +//--- Input Parameters --- +input group "Scanner Asset Settings" +input string InpCustomSymbols = ""; // Custom Symbols (Comma separated, empty for Market Watch) +input int InpMaxSymbols = 15; // Maximum Symbols to display +input ENUM_TIMEFRAMES InpTimeframe = PERIOD_M15; // Target Timeframe +input int InpPeriod = 20; // Regression Period (N) +input double InpTrendLevel = 0.7; // Strong Trend Level (R2 Threshold) + +input group "Display Settings" +input int InpTableX = 20; // Table X Offset (Pixels) +input int InpTableY = 60; // Table Y Offset (Pixels) +input int InpFontSize = 9; // UI Font Size +input int InpRefreshSeconds = 3; // Background Timer Fallback (Seconds) + +//--- Global Variables --- +string g_symbols[]; +int g_symbols_total = 0; +string g_prefix = ""; +bool g_updating = false; +ulong g_last_update_ms = 0; // Throttle timestamp + +//+------------------------------------------------------------------+ +//| EnsureDataReady (History sync helper) | +//+------------------------------------------------------------------+ +bool EnsureDataReady(const string symbol, const ENUM_TIMEFRAMES timeframe, const int required_bars) + { + ResetLastError(); + if(!SymbolInfoInteger(symbol, SYMBOL_SELECT)) + { + SymbolSelect(symbol, true); + } + datetime times[]; + int copied = CopyTime(symbol, timeframe, 0, required_bars, times); + return (copied >= required_bars); + } + +//+------------------------------------------------------------------+ +//| GetLinRegValues | +//+------------------------------------------------------------------+ +bool GetLinRegValues(string symbol, ENUM_TIMEFRAMES tf, int period, double &out_r2, double &out_slope) + { + int required_bars = period + 20; + + if(!EnsureDataReady(symbol, tf, required_bars)) + return false; + + int htf_bars = iBars(symbol, tf); + if(htf_bars < required_bars) + return false; + + int count = MathMin(htf_bars, 300); + + double h_open[], h_high[], h_low[], h_close[]; + datetime h_time[]; + + ArrayResize(h_open, count); + ArrayResize(h_high, count); + ArrayResize(h_low, count); + ArrayResize(h_close, count); + ArrayResize(h_time, count); + + if(CopyTime(symbol, tf, 0, count, h_time) != count || + CopyOpen(symbol, tf, 0, count, h_open) != count || + CopyHigh(symbol, tf, 0, count, h_high) != count || + CopyLow(symbol, tf, 0, count, h_low) != count || + CopyClose(symbol, tf, 0, count, h_close) != count) + { + return false; + } + + CLinearRegressionCalculator calc; + if(!calc.Init(period)) + return false; + + double h_s[], h_r2[], h_f[]; + ArrayResize(h_s, count); + ArrayResize(h_r2, count); + ArrayResize(h_f, count); + + calc.CalculateState(count, 0, h_open, h_high, h_low, h_close, PRICE_CLOSE, h_s, h_r2, h_f); + + out_r2 = h_r2[count - 1]; + out_slope = h_s[count - 1]; + return true; + } + +//+------------------------------------------------------------------+ +//| ParseSymbols | +//+------------------------------------------------------------------+ +void ParseSymbols() + { + ArrayFree(g_symbols); + + if(InpCustomSymbols != "" && InpCustomSymbols != NULL) + { + string temp[]; + int split = StringSplit(InpCustomSymbols, ',', temp); + int valid_count = 0; + + for(int i = 0; i < split; i++) + { + string sym = temp[i]; + StringTrimLeft(sym); + StringTrimRight(sym); + if(sym != "" && SymbolInfoInteger(sym, SYMBOL_SELECT) != 0) + { + ArrayResize(g_symbols, valid_count + 1); + g_symbols[valid_count] = sym; + valid_count++; + } + if(valid_count >= InpMaxSymbols) + break; + } + g_symbols_total = valid_count; + } + else + { + int total = SymbolsTotal(true); + int count = 0; + for(int i = 0; i < total; i++) + { + string sym = SymbolName(i, true); + if(sym != "" && sym != NULL) + { + ArrayResize(g_symbols, count + 1); + g_symbols[count] = sym; + count++; + } + if(count >= InpMaxSymbols) + break; + } + g_symbols_total = count; + } + } + +//+------------------------------------------------------------------+ +//| CreateButton | +//+------------------------------------------------------------------+ +void CreateButton(string name, string text, int x, int y, int w, int h, color bg_color, color text_color) + { + if(ObjectFind(0, name) < 0) + { + ObjectCreate(0, name, OBJ_BUTTON, 0, 0, 0); + ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_UPPER); + ObjectSetInteger(0, name, OBJPROP_FONTSIZE, InpFontSize); + ObjectSetString(0, name, OBJPROP_FONT, "Trebuchet MS"); + ObjectSetInteger(0, name, OBJPROP_BORDER_TYPE, BORDER_FLAT); + ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false); + } + ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x); + ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y); + ObjectSetInteger(0, name, OBJPROP_XSIZE, w); + ObjectSetInteger(0, name, OBJPROP_YSIZE, h); + ObjectSetString(0, name, OBJPROP_TEXT, text); + ObjectSetInteger(0, name, OBJPROP_BGCOLOR, bg_color); + ObjectSetInteger(0, name, OBJPROP_COLOR, text_color); + } + +//+------------------------------------------------------------------+ +//| RenderCell | +//+------------------------------------------------------------------+ +void RenderCell(string symbol, double r2_val, double slope_val, int x, int y, int w, int h) + { + string name = g_prefix + "_" + symbol + "_Val"; + string text = ""; + color bg_color = clrWhite; + color text_color = clrBlack; + + if(r2_val == EMPTY_VALUE) + { + text = "Sync..."; + bg_color = clrWhite; + text_color = clrSilver; + } + else + { + string arrow = (slope_val > 0.0) ? "▲ " : ((slope_val < 0.0) ? "▼ " : "■ "); + text = arrow + DoubleToString(r2_val, 3); + + //--- Dynamic 3-Zone Thermal Palette (Chop = Gray, Weak = Orange, Strong = Lime) + if(r2_val >= InpTrendLevel) + { + bg_color = clrMediumSeaGreen; // Strong Trend (Green) + text_color = clrWhite; + } + else + if(r2_val <= 0.3) + { + bg_color = clrSlateGray; // Chop / Range (Gray) + text_color = clrWhite; + } + else + { + bg_color = clrOrange; // Weak Trend / Transition (Orange) + text_color = clrBlack; + } + } + CreateButton(name, text, x, y, w, h, bg_color, text_color); + } + +//+------------------------------------------------------------------+ +//| RenderDashboard | +//+------------------------------------------------------------------+ +void RenderDashboard() + { + if(g_updating || g_symbols_total <= 0) + return; + + g_updating = true; + + int col_w_sym = 100; + int col_w_val = 90; + int row_h = 22; + +//--- 1. Render Table Header + int header_y = InpTableY; + string tf_name = StringSubstr(EnumToString(InpTimeframe), 7); + CreateButton(g_prefix + "H_Sym", "Symbol (" + tf_name + ")", InpTableX, header_y, col_w_sym, row_h, clrDarkSlateGray, clrWhite); + CreateButton(g_prefix + "H_Val", "R2 & Slope", InpTableX + col_w_sym + 2, header_y, col_w_val, row_h, clrDarkSlateGray, clrWhite); + +//--- 2. Loop and Calculate each asset row + for(int r = 0; r < g_symbols_total; r++) + { + string sym = g_symbols[r]; + int row_y = InpTableY + row_h + 2 + (r * (row_h + 2)); + + // Symbol Button (Clickable chart switcher) + CreateButton(g_prefix + "_SymBtn_" + sym, sym, InpTableX, row_y, col_w_sym, row_h, clrLightGray, clrBlack); + + // Get exact real-time Linear Regression R2 and Slope + double r2_val = EMPTY_VALUE; + double slope_val = 0.0; + + GetLinRegValues(sym, InpTimeframe, InpPeriod, r2_val, slope_val); + + // Render the thermal cell + RenderCell(sym, r2_val, slope_val, InpTableX + col_w_sym + 2, row_y, col_w_val, row_h); + } + + ChartRedraw(); + g_updating = false; + } + +//+------------------------------------------------------------------+ +//| OnInit | +//+------------------------------------------------------------------+ +int OnInit() + { + g_updating = false; + g_last_update_ms = 0; + g_prefix = StringFormat("LRR2D_%I64d_", ChartID()); // Cleaned with dynamic LRR2D prefix + + ObjectsDeleteAll(0, g_prefix); + + ParseSymbols(); + RenderDashboard(); + + EventSetTimer(InpRefreshSeconds); + return(INIT_SUCCEEDED); + } + +//+------------------------------------------------------------------+ +//| OnDeinit | +//+------------------------------------------------------------------+ +void OnDeinit(const int reason) + { + EventKillTimer(); + ObjectsDeleteAll(0, g_prefix); + Comment(""); + } + +//+------------------------------------------------------------------+ +//| OnCalculate | +//+------------------------------------------------------------------+ +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[]) + { +//--- Real-time high frequency tick throttling (Max 5 updates per second / 200ms) + ulong current_ms = GetTickCount64(); + if(current_ms - g_last_update_ms >= 200) + { + g_last_update_ms = current_ms; + RenderDashboard(); + } + return(rates_total); + } + +//+------------------------------------------------------------------+ +//| OnTimer | +//+------------------------------------------------------------------+ +void OnTimer() + { + RenderDashboard(); + } + +//+------------------------------------------------------------------+ +//| OnChartEvent | +//+------------------------------------------------------------------+ +void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) + { + if(id == CHARTEVENT_OBJECT_CLICK) + { + if(StringFind(sparam, g_prefix) == 0 && StringFind(sparam, "_SymBtn_") != -1) + { + string symbol = ObjectGetString(0, sparam, OBJPROP_TEXT); + if(symbol != "" && symbol != NULL) + { + ChartSetSymbolPeriod(0, symbol, _Period); + ObjectSetInteger(0, sparam, OBJPROP_STATE, false); + ChartRedraw(); + } + } + } + } +//+------------------------------------------------------------------+