//+------------------------------------------------------------------+ //| SISTEMA_AR_HUD_Premium.mq5 | //| Copyright 2023, Tu Nombre/A.I. | //+------------------------------------------------------------------+ #property copyright "SISTEMA A.R. - MT5 Version" #property link "" #property version "2.00" #property indicator_chart_window // Se dibuja sobre el gráfico #property indicator_plots 0 // No dibuja líneas, solo el panel //--- Inputs input ENUM_BASE_CORNER InpCorner = CORNER_RIGHT_LOWER; // Ubicación en Pantalla input int InpX_Dist = 15; // Distancia en X (Margen) input int InpY_Dist = 15; // Distancia en Y (Margen) input bool InpAlerts = true; // Activar Alertas Pop-up //--- Variables Globales int h_sma_15, h_sma_5, h_rsi; string last_veredicto = "ESCANEO"; // Memoria para evitar spam de alertas //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { // Crear manejadores de indicadores h_sma_15 = iMA(_Symbol, PERIOD_M15, 20, 0, MODE_SMA, PRICE_CLOSE); h_sma_5 = iMA(_Symbol, PERIOD_M5, 10, 0, MODE_SMA, PRICE_CLOSE); h_rsi = iRSI(_Symbol, PERIOD_CURRENT, 14, PRICE_CLOSE); if(h_sma_15 == INVALID_HANDLE || h_sma_5 == INVALID_HANDLE || h_rsi == INVALID_HANDLE) { Print("Error al crear los manejadores de indicadores"); return(INIT_FAILED); } // Construir el HUD visual CreateHUD(); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Limpiar objetos del gráfico al cerrar ObjectsDeleteAll(0, "AR_HUD_"); IndicatorRelease(h_sma_15); IndicatorRelease(h_sma_5); IndicatorRelease(h_rsi); } //+------------------------------------------------------------------+ //| 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[]) { if(rates_total < 20) return 0; // --------------------------------------------------------- // 1. CÁLCULOS TÁCTICOS (CORREGIDOS MTF) // --------------------------------------------------------- // --- Datos de 15m (Corregido: usa cierre de 15m, no del gráfico actual) --- double sma_15_buf[1], close_15_buf[1]; CopyBuffer(h_sma_15, 0, 0, 1, sma_15_buf); CopyClose(_Symbol, PERIOD_M15, 0, 1, close_15_buf); string trend_15m = (close_15_buf[0] > sma_15_buf[0]) ? "ALCISTA" : "BAJISTA"; // --- Datos de 5m --- double sma_5_buf[1], close_5_buf[1]; CopyBuffer(h_sma_5, 0, 0, 1, sma_5_buf); CopyClose(_Symbol, PERIOD_M5, 0, 1, close_5_buf); string trend_5m = (close_5_buf[0] > sma_5_buf[0]) ? "ALCISTA" : "BAJISTA"; // --- Volumen 5m --- long vol_5m_arr[20]; ArraySetAsSeries(vol_5m_arr, true); CopyTickVolume(_Symbol, PERIOD_M5, 0, 20, vol_5m_arr); double vol_5m_avg = 0; for(int i=0; i<20; i++) vol_5m_avg += (double)vol_5m_arr[i]; vol_5m_avg /= 20.0; string vol_5m = ((double)tick_volume[0] > vol_5m_avg * 1.5) ? "FUEGO" : "CALMA"; // --- RSI y Volumen Actual --- double rsi_buf[1]; CopyBuffer(h_rsi, 0, 0, 1, rsi_buf); double rsi_val = rsi_buf[0]; ArraySetAsSeries(tick_volume, true); double vol_actual_avg = 0; for(int i=0; i<20; i++) vol_actual_avg += (double)tick_volume[i]; vol_actual_avg /= 20.0; double vol_ratio = (vol_actual_avg > 0) ? (double)tick_volume[0] / vol_actual_avg : 0; // --- Lógica Radar A.R. --- string veredicto = "ESCANEO"; string razon = "Analizando flujo institucional..."; color c_alerta = clrGray; if(vol_ratio >= 2.5 && (rsi_val > 60 || rsi_val < 40)) { veredicto = "VALIDADO"; razon = "Confluencia Vol y Fuerza"; c_alerta = clrLime; } else if(vol_ratio < 1.0) { veredicto = "ESPERA"; razon = "Falta Volumen Institucional"; c_alerta = clrOrange; } // --------------------------------------------------------- // 2. ACTUALIZAR HUD // --------------------------------------------------------- color c_up = clrLime, c_down = clrRed; UpdateCell(1, 0, "Trend 15m", clrGray, clrBlack); UpdateCell(1, 1, trend_15m, (trend_15m=="ALCISTA"? c_up : c_down), clrBlack); UpdateCell(2, 0, "Trend 5m", clrGray, clrBlack); UpdateCell(2, 1, trend_5m, (trend_5m=="ALCISTA"? c_up : c_down), clrBlack); UpdateCell(3, 0, "Volumen 5m", clrGray, clrBlack); UpdateCell(3, 1, vol_5m, (vol_5m=="FUEGO"? clrOrange : clrGray), clrBlack); UpdateCell(5, 0, "SISTEMA A.R.", clrWhite, c_alerta); UpdateCell(5, 1, "RADAR V2.0", clrWhite, c_alerta); UpdateCell(6, 0, veredicto, c_alerta, clrBlack); // Texto grande UpdateCell(6, 1, "", c_alerta, clrBlack); UpdateCell(7, 0, "DIAGNÓSTICO:", clrGray, clrBlack); UpdateCell(7, 1, razon, clrWhite, clrBlack); string metrics = StringFormat("VOL: %.2fx | RSI: %.1f", vol_ratio, rsi_val); UpdateCell(8, 0, "MÉTRICAS:", clrGray, clrBlack); UpdateCell(8, 1, metrics, clrWhite, clrBlack); // --------------------------------------------------------- // 3. SISTEMA DE ALERTAS (ANTI-SPAM) // --------------------------------------------------------- if(InpAlerts && veredicto != last_veredicto) { if(veredicto == "VALIDADO") Alert("🔔 SISTEMA A.R.: Confluencia detectada en ", _Symbol, " - VOL: ", DoubleToString(vol_ratio,2)); else if(veredicto == "ESPERA") Alert("⚠️ SISTEMA A.R.: Falta volumen en ", _Symbol); last_veredicto = veredicto; // Se actualiza la memoria } return(rates_total); } //+------------------------------------------------------------------+ //| FUNCIONES DE CONSTRUCCIÓN GRÁFICA | //+------------------------------------------------------------------+ void CreateHUD() { int cell_w = 120; // Ancho de celda int cell_h = 18; // Alto de celda int sep_h = 5; // Alto separador for(int row = 0; row <= 8; row++) { for(int col = 0; col <= 1; col++) { string name_bg = StringFormat("AR_HUD_BG_%d_%d", row, col); string name_tx = StringFormat("AR_HUD_TX_%d_%d", row, col); int x = InpX_Dist + (col * (cell_w + 2)); int y = InpY_Dist + (row * (cell_h + 2)); // Si es la fila separadora (4), hacerla más pequeña if(row == 4) cell_h = sep_h; else cell_h = 18; // Crear Fondo ObjectCreate(0, name_bg, OBJ_RECTANGLE_LABEL, 0, 0, 0); ObjectSetInteger(0, name_bg, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, name_bg, OBJPROP_YDISTANCE, y); ObjectSetInteger(0, name_bg, OBJPROP_XSIZE, cell_w); ObjectSetInteger(0, name_bg, OBJPROP_YSIZE, cell_h); ObjectSetInteger(0, name_bg, OBJPROP_BGCOLOR, clrBlack); ObjectSetInteger(0, name_bg, OBJPROP_BORDER_TYPE, BORDER_FLAT); ObjectSetInteger(0, name_bg, OBJPROP_BORDER_COLOR, clrDarkGray); ObjectSetInteger(0, name_bg, OBJPROP_CORNER, InpCorner); ObjectSetInteger(0, name_bg, OBJPROP_BACK, true); // Los clics lo atraviesan ObjectSetInteger(0, name_bg, OBJPROP_SELECTABLE, false); // Crear Texto ObjectCreate(0, name_tx, OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, name_tx, OBJPROP_XDISTANCE, x + 5); ObjectSetInteger(0, name_tx, OBJPROP_YDISTANCE, y + 2); ObjectSetInteger(0, name_tx, OBJPROP_CORNER, InpCorner); ObjectSetInteger(0, name_tx, OBJPROP_FONTSIZE, (row==6) ? 10 : 8); // Fila 6 más grande ObjectSetString(0, name_tx, OBJPROP_FONT, "Arial Bold"); ObjectSetInteger(0, name_tx, OBJPROP_COLOR, clrWhite); ObjectSetInteger(0, name_tx, OBJPROP_BACK, true); ObjectSetInteger(0, name_tx, OBJPROP_SELECTABLE, false); } } } void UpdateCell(int row, int col, string text, color txt_color, color bg_color) { string name_bg = StringFormat("AR_HUD_BG_%d_%d", row, col); string name_tx = StringFormat("AR_HUD_TX_%d_%d", row, col); ObjectSetString(0, name_tx, OBJPROP_TEXT, text); ObjectSetInteger(0, name_tx, OBJPROP_COLOR, txt_color); ObjectSetInteger(0, name_bg, OBJPROP_BGCOLOR, bg_color); }