225 lines
8.9 KiB
Text
225 lines
8.9 KiB
Text
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| 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);
|
||
|
|
}
|