Desarrollo de un indicador personalizado de sentimiento del mercado
Introducción
Identificar la verdadera dirección del mercado supone todo un reto, sobre todo cuando los distintos marcos temporales apuntan a escenarios contradictorios. Un operador puede observar un fuerte movimiento alcista en el gráfico de 30 minutos, mientras que el gráfico de 4 horas sigue indicando una presión bajista. Esto suele provocar confusión, operaciones mal alineadas con el mercado o la apertura de posiciones en contra del sesgo dominante del mercado. Sin un método estructurado para alinear las señales de los marcos temporales superiores e inferiores, los operadores corren el riesgo de tomar decisiones impulsivas basadas en información incompleta, lo que, en última instancia, reduce la consistencia y la rentabilidad.
El indicador personalizado de sentimiento del mercado aborda este problema combinando señales de varios marcos temporales en un único panel de fácil lectura. Analizando las tendencias de los marcos temporales superiores junto con las estructuras de los marcos temporales inferiores, clasifica las condiciones del mercado en cinco estados claros según el sentimiento: alcistas, bajistas, de apetito por el riesgo (risk-on), de aversión al riesgo (risk-off) o neutras. Este enfoque por capas ayuda a los operadores a mantenerse alineados con el panorama general, al tiempo que les permite afinar sus entradas con confirmaciones de corto plazo. Como resultado, simplifica la toma de decisiones, reduce la incertidumbre y mejora la alineación de las operaciones con las condiciones imperantes del mercado.
Desarrollo y lógica
Sentimiento alcista:
Este se produce cuando los operadores e inversores, en general, esperan que los precios suban. Esto se caracteriza por una presión de compra mayor que la presión de venta. Entre los indicios más comunes se encuentran máximos y mínimos crecientes en la acción del precio, un volumen elevado en los movimientos alcistas y unas perspectivas económicas o de noticias positivas. En su forma más extrema, el sentimiento alcista puede dar lugar a la euforia, en la que el optimismo se vuelve excesivo, a menudo cerca del final de un tramo alcista.

Sentimiento bajista:
Refleja la expectativa de que los precios bajen, con una mayor presión vendedora que compradora. Se identifica habitualmente por máximos y mínimos cada vez más bajos en la acción del precio, un volumen elevado durante los movimientos bajistas y acontecimientos económicos o noticias negativas. En su forma más extrema, el sentimiento bajista puede manifestarse como pánico, lo cual provoca ventas agresivas que suelen producirse en los mínimos del mercado o cerca de ellos.

Sentimiento neutral:
Se produce cuando los participantes en el mercado se muestran indecisos o perciben un equilibrio entre compradores y vendedores. En este contexto, los precios suelen oscilar dentro de un rango sin formar una tendencia alcista o bajista clara. Entre los indicios clave se encuentran las fases de consolidación, la baja volatilidad y la espera de confirmación antes de abrir posiciones.

Sentimiento de apetito por el riesgo:
Describe un estado de ánimo del mercado en el que los inversores se muestran más dispuestos a asumir riesgos, lo que a menudo les lleva a invertir en acciones, materias primas y activos de alto rendimiento. El capital se dirige hacia instrumentos con mayor potencial de rentabilidad. Entre los indicios típicos se encuentran el alza de los índices bursátiles y la escasa demanda de activos refugio, como el oro o los bonos del Estado.

Sentimiento de aversión al riesgo:
Por otro lado, se produce cuando los inversores buscan seguridad debido al miedo o a la incertidumbre. En este caso, el capital se desplaza hacia activos tradicionalmente más seguros, como el oro, el dólar estadounidense, el franco suizo o los bonos del Estado. Se caracteriza, por lo general, por la caída de los índices bursátiles y el aumento de la demanda de divisas refugio y activos refugio.

Relación entre marcos temporales:

Diagrama de arquitectura:

Primeros pasos
//+------------------------------------------------------------------+ //| Market_Sent.mq5 | //| GIT under Copyright 2025, MetaQuotes Ltd. | //| https://www.mql5.com/en/users/johnhlomohang/ | //+------------------------------------------------------------------+ #property copyright "GIT under Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com/en/users/johnhlomohang/" #property version "1.00" #property strict #property indicator_chart_window #property indicator_buffers 0 #property indicator_plots 0 //+------------------------------------------------------------------+ //| Input parameters | //+------------------------------------------------------------------+ input group "Timeframe Settings" input ENUM_TIMEFRAMES HigherTF = PERIOD_H4; input ENUM_TIMEFRAMES LowerTF1 = PERIOD_H1; input ENUM_TIMEFRAMES LowerTF2 = PERIOD_M30; input group "Indicator Settings" input int MAPeriod = 200; input int SwingLookback = 5; input double ATRThreshold = 0.002; input group "Visual Settings" // force top-left dark theme input int PanelCorner = 0; input int PanelX = 10; input int PanelY = 10; input string FontFace = "Arial"; input int FontSize = 10; input color BullishColor = clrLimeGreen; input color BearishColor = clrRed; input color RiskOnColor = clrDodgerBlue; input color RiskOffColor = clrOrangeRed; input color NeutralColor = clrGold;
Empezamos por configurar la estructura base de un indicador personalizado del sentimiento del mercado en MQL5. La sección superior incluye metadatos como los derechos de autor, la versión y el enlace, junto con directivas que definen las propiedades del indicador. Los valores «indicator_buffers 0» e «indicator_plots 0» significan que no se utilizan búferes estándar ni trazados del indicador, ya que este indicador está concebido como un panel visual, no como un indicador destinado a trazar líneas o histogramas. Estos ajustes iniciales definen, en esencia, el entorno en el que se ejecutará la lógica personalizada de análisis del sentimiento.
Los parámetros de entrada ofrecen a los operadores flexibilidad a la hora de configurar el indicador. El grupo «Configuración de marcos temporales» permite al usuario seleccionar un marco temporal superior (por defecto, H4) y dos marcos temporales inferiores (H1 y M30) para el análisis del sentimiento del mercado. En la sección «Configuración del indicador», los operadores pueden ajustar parámetros técnicos como el periodo de la media móvil, el periodo de búsqueda de swings y el umbral de ATR, que se utilizan para interpretar el comportamiento del precio y la volatilidad. Por último, el grupo «Configuración visual» controla cómo se mostrará el panel de sentimiento en el gráfico, incluyendo su posición, el estilo de fuente, el tamaño y los colores específicos utilizados para representar las condiciones alcistas, bajistas, de apetito por el riesgo, de aversión al riesgo y neutras. En conjunto, estos datos constituyen una base flexible para detectar y visualizar el sentimiento del mercado en distintos marcos temporales.
//+------------------------------------------------------------------+ //| Global variables | //+------------------------------------------------------------------+ int higherTFHandle, lowerTF1Handle, lowerTF2Handle; double higherTFMA[], lowerTF1MA[], lowerTF2MA[]; datetime lastUpdateTime = 0; string indicatorName = "MarketSentiment"; //--- helper: convert timeframe to string string TFtoString(int tf) { switch(tf) { case PERIOD_M1: return "M1"; case PERIOD_M5: return "M5"; case PERIOD_M15: return "M15"; case PERIOD_M30: return "M30"; case PERIOD_H1: return "H1"; case PERIOD_H4: return "H4"; case PERIOD_D1: return "D1"; case PERIOD_W1: return "W1"; case PERIOD_MN1: return "MN"; default: return "TF?"; } }
En esta sección se definen las variables globales y la función auxiliar necesarias para el indicador de sentimiento del mercado. Las tres variables de manejador (higherTFHandle, lowerTF1Handle y lowerTF2Handle) se usan para almacenar referencias a los cálculos de la media móvil en distintos marcos temporales, mientras que los arrays (higherTFMA[], lowerTF1MA[], lowerTF2MA[]) contienen los valores correspondientes. Luego se inicializa una variable lastUpdateTime para registrar cuándo se actualizó por última vez el indicador, lo que garantiza actualizaciones eficientes, e indicatorName proporciona una etiqueta coherente para los objetos que se dibujan en el gráfico. Además, la función auxiliar TFtoString() convierte las constantes numéricas de los marcos temporales en cadenas legibles (por ejemplo, PERIOD_H1 -> «H1»), lo cual resulta útil para etiquetar o mostrar información en el panel del indicador.
//+------------------------------------------------------------------+ //| OnInit | //+------------------------------------------------------------------+ int OnInit() { indicatorName = "MarketSentiment_" + IntegerToString(ChartID()); higherTFHandle = iMA(_Symbol, HigherTF, MAPeriod, 0, MODE_EMA, PRICE_CLOSE); lowerTF1Handle = iMA(_Symbol, LowerTF1, MAPeriod, 0, MODE_EMA, PRICE_CLOSE); lowerTF2Handle = iMA(_Symbol, LowerTF2, MAPeriod, 0, MODE_EMA, PRICE_CLOSE); ArraySetAsSeries(higherTFMA, true); ArraySetAsSeries(lowerTF1MA, true); ArraySetAsSeries(lowerTF2MA, true); CreatePanel(); return(INIT_SUCCEEDED); }
La función OnInit() inicializa el indicador de sentimiento del mercado estableciendo nombres únicos para los objetos del gráfico a partir del ID del gráfico y creando manejadores de media móvil para el marco temporal superior y los marcos temporales inferiores con el periodo y el método EMA especificados. Además, configura los arrays de MA para que estén orientados como series temporales, lo que facilita la indexación a la hora de acceder a los valores recientes. Por último, llama a la función CreatePanel() para dibujar el panel de visualización del sentimiento en el gráfico y, a continuación, devuelve INIT_SUCCEEDED para confirmar que la inicialización se ha realizado correctamente.
//+------------------------------------------------------------------+ void OnDeinit(const int reason) { ObjectsDeleteAll(0, indicatorName); IndicatorRelease(higherTFHandle); IndicatorRelease(lowerTF1Handle); IndicatorRelease(lowerTF2Handle); }
La función OnDeinit() garantiza una limpieza adecuada cuando se elimina el indicador, borrando todos los objetos del gráfico asociados a su nombre de indicador único (indicatorName) y liberando los manejadores de las medias móviles del marco temporal superior y de los marcos temporales inferiores, lo que evita fugas de memoria y mantiene limpio el entorno del gráfico.
//+------------------------------------------------------------------+ 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 (TimeCurrent() - lastUpdateTime < 10 && prev_calculated > 0) return(rates_total); lastUpdateTime = TimeCurrent(); CopyBuffer(higherTFHandle, 0, 0, 3, higherTFMA); CopyBuffer(lowerTF1Handle, 0, 0, 3, lowerTF1MA); CopyBuffer(lowerTF2Handle, 0, 0, 3, lowerTF2MA); double higherTFPrice = iClose(_Symbol, HigherTF, 0); double lowerTF1Price = iClose(_Symbol, LowerTF1, 0); double lowerTF2Price = iClose(_Symbol, LowerTF2, 0); int higherTFBias = GetHigherTFBias(higherTFPrice, higherTFMA[0]); bool lowerTF1Bullish = IsBullishStructure(LowerTF1, SwingLookback); bool lowerTF1Bearish = IsBearishStructure(LowerTF1, SwingLookback); bool lowerTF2Bullish = IsBullishStructure(LowerTF2, SwingLookback); bool lowerTF2Bearish = IsBearishStructure(LowerTF2, SwingLookback); bool lowerTF1Breakout = HasBreakout(LowerTF1, SwingLookback, higherTFBias); bool lowerTF2Breakout = HasBreakout(LowerTF2, SwingLookback, higherTFBias); int sentiment = DetermineSentiment( higherTFBias, lowerTF1Bullish, lowerTF1Bearish, lowerTF1Breakout, lowerTF2Bullish, lowerTF2Bearish, lowerTF2Breakout ); UpdatePanel(higherTFBias, lowerTF1Bullish, lowerTF1Bearish, lowerTF2Bullish, lowerTF2Bearish, sentiment); return(rates_total); }
La función OnCalculate() actúa como el bucle de procesamiento principal del indicador y se ejecuta cada vez que llegan nuevos datos de precios o ticks. Comienza con un control de frecuencia de actualización, lo que garantiza que los cálculos solo se realicen si han transcurrido al menos 10 segundos desde la última actualización, mejorando así la eficiencia. A continuación, la función copia los valores de la media móvil desde los búferes del marco temporal superior y de los marcos temporales inferiores, y recupera los últimos precios de cierre de cada marco temporal, que constituyen la base para la evaluación del sentimiento del mercado.
Tras recopilar los datos de precios y de medias móviles, la función determina el sesgo direccional en el marco temporal superior y comprueba las condiciones estructurales (patrones alcistas o bajistas) en los marcos temporales inferiores. Asimismo, valida posibles rupturas en consonancia con el sesgo del marco temporal superior. Dichas condiciones se combinan en la función DetermineSentiment() para clasificar el mercado en estados alcistas, bajistas, de apetito por el riesgo, de aversión al riesgo o neutros. Por último, los resultados se reflejan visualmente en el gráfico mediante UpdatePanel(), lo que ofrece a los traders un panel de sentimiento del mercado en tiempo real en múltiples marcos temporales.
//+------------------------------------------------------------------+ //| Determine higher timeframe bias | //+------------------------------------------------------------------+ int GetHigherTFBias(double price, double maValue) { double deviation = MathAbs(price - maValue) / maValue; if (price > maValue && deviation > ATRThreshold) return 1; else if (price < maValue && deviation > ATRThreshold) return -1; else return 0; }
Esta función evalúa la dirección de la tendencia en el marco temporal superior comparando el precio actual con el valor de su media móvil. Si el precio se encuentra por encima de la media móvil y la desviación supera el umbral de ATR definido, devuelve 1 (sesgo alcista), mientras que, si el precio se encuentra por debajo de ella con una desviación suficiente, devuelve -1 (sesgo bajista). Si no se cumple ninguna de las dos condiciones, devuelve 0, lo cual indica un sesgo del marco temporal superior neutral o indeciso.
//+------------------------------------------------------------------+ //| Bullish structure | //+------------------------------------------------------------------+ bool IsBullishStructure(ENUM_TIMEFRAMES tf, int lookback) { int swingHighIndex = iHighest(_Symbol, tf, MODE_HIGH, lookback * 2, 1); int swingLowIndex = iLowest (_Symbol, tf, MODE_LOW, lookback * 2, 1); int prevHigh = iHighest(_Symbol, tf, MODE_HIGH, lookback, lookback+1); int prevLow = iLowest (_Symbol, tf, MODE_LOW, lookback, lookback+1); if (swingHighIndex==-1 || swingLowIndex==-1 || prevHigh==-1 || prevLow==-1) return false; return (iHigh(_Symbol, tf, swingHighIndex) > iHigh(_Symbol, tf, prevHigh) && iLow(_Symbol, tf, swingLowIndex) > iLow (_Symbol, tf, prevLow)); } //+------------------------------------------------------------------+ //| Bearish structure | //+------------------------------------------------------------------+ bool IsBearishStructure(ENUM_TIMEFRAMES tf, int lookback) { int swingHighIndex = iHighest(_Symbol, tf, MODE_HIGH, lookback * 2, 1); int swingLowIndex = iLowest (_Symbol, tf, MODE_LOW, lookback * 2, 1); int prevHigh = iHighest(_Symbol, tf, MODE_HIGH, lookback, lookback+1); int prevLow = iLowest (_Symbol, tf, MODE_LOW, lookback, lookback+1); if (swingHighIndex==-1 || swingLowIndex==-1 || prevHigh==-1 || prevLow==-1) return false; return (iHigh(_Symbol, tf, swingHighIndex) < iHigh(_Symbol, tf, prevHigh) && iLow(_Symbol, tf, swingLowIndex) < iLow (_Symbol, tf, prevLow)); }
La función IsBullishStructure() identifica un patrón alcista del precio en un marco temporal determinado comparando los máximos y mínimos de oscilación más recientes con los puntos de oscilación anteriores. En primer lugar, localiza los máximos y mínimos de oscilación actuales y anteriores mediante las funciones iHighest e iLowest. Si el máximo actual es superior al máximo anterior y el mínimo actual es superior al mínimo anterior, la función devuelve «true», lo que indica una estructura alcista; en caso contrario, devuelve «false».
Del mismo modo, la función IsBearishStructure() detecta un patrón bajista comparando los puntos de oscilación recientes con las oscilaciones anteriores. Si el máximo actual es inferior al máximo anterior y el mínimo actual es inferior al mínimo anterior, devuelve «true», lo que indica una estructura bajista. Ambas funciones se basan en el análisis de oscilaciones durante un periodo de análisis retrospectivo especificado, lo cual proporciona al indicador un método para evaluar las tendencias del precio a corto plazo en relación con sus movimientos anteriores.
//+------------------------------------------------------------------+ bool HasBreakout(ENUM_TIMEFRAMES tf, int lookback, int higherTFBias) { int swingHighIndex = iHighest(_Symbol, tf, MODE_HIGH, lookback, 1); int swingLowIndex = iLowest (_Symbol, tf, MODE_LOW, lookback, 1); if (swingHighIndex==-1 || swingLowIndex==-1) return false; double swingHigh = iHigh(_Symbol, tf, swingHighIndex); double swingLow = iLow (_Symbol, tf, swingLowIndex); double price = iClose(_Symbol, tf, 0); if (higherTFBias==1) return (price > swingHigh); if (higherTFBias==-1) return (price < swingLow); return false; }
Esta función comprueba si el precio actual ha roto por encima o por debajo de los puntos de oscilación recientes en un marco temporal especificado, considerando el sesgo del marco temporal superior. Identifica el máximo y el mínimo de oscilación más recientes y, si alguno de ellos no está disponible, devuelve «false». En el caso de un sesgo alcista del marco temporal superior, devuelve «true» si el precio actual supera el máximo de oscilación, mientras que, en el caso de un sesgo bajista, devuelve «true» si el precio cae por debajo del mínimo de oscilación. Si el sesgo del marco temporal superior es neutral, no se considera ninguna ruptura y la función devuelve «false».
//+------------------------------------------------------------------+ int DetermineSentiment(int higherTFBias, bool tf1Bullish, bool tf1Bearish, bool tf1Breakout, bool tf2Bullish, bool tf2Bearish, bool tf2Breakout) { if (higherTFBias==1 && tf1Bullish && tf2Bullish) return 1; if (higherTFBias==-1 && tf1Bearish && tf2Bearish) return -1; if (higherTFBias==1 && (tf1Breakout||tf2Breakout)) return 2; if (higherTFBias==-1 && (tf1Breakout||tf2Breakout)) return -2; return 0; }
La función DetermineSentiment() sintetiza las condiciones del mercado en distintos marcos temporales para clasificar el sentimiento general del mercado. Devuelve 1 para el sentimiento alcista si el marco temporal superior es alcista y ambos marcos temporales inferiores muestran estructuras alcistas; -1 para el sentimiento bajista en las condiciones opuestas; 2 para el apetito por el riesgo si un marco temporal superior alcista experimenta rupturas en los marcos temporales inferiores; y -2 para la aversión al riesgo si un marco temporal superior bajista presenta rupturas similares. Si no se cumple ninguna de estas condiciones, devuelve 0, lo cual indica un un mercado neutral o lateral.
//+------------------------------------------------------------------+ //| Panel Creation (dark theme, top-left) | //+------------------------------------------------------------------+ void CreatePanel() { string bg = indicatorName + "_BG"; ObjectCreate(0, bg, OBJ_RECTANGLE_LABEL, 0, 0, 0); ObjectSetInteger(0, bg, OBJPROP_XDISTANCE, PanelX); ObjectSetInteger(0, bg, OBJPROP_YDISTANCE, PanelY); ObjectSetInteger(0, bg, OBJPROP_XSIZE, 200); ObjectSetInteger(0, bg, OBJPROP_YSIZE, 120); ObjectSetInteger(0, bg, OBJPROP_CORNER, 0); ObjectSetInteger(0, bg, OBJPROP_BGCOLOR, clrBlack); ObjectSetInteger(0, bg, OBJPROP_BORDER_COLOR, clrGray); ObjectSetInteger(0, bg, OBJPROP_BACK, true); ObjectSetInteger(0, bg, OBJPROP_SELECTABLE, false); ObjectSetInteger(0, bg, OBJPROP_HIDDEN, true); string title = indicatorName + "_Title"; ObjectCreate(0, title, OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, title, OBJPROP_XDISTANCE, PanelX+10); ObjectSetInteger(0, title, OBJPROP_YDISTANCE, PanelY+10); ObjectSetInteger(0, title, OBJPROP_CORNER, 0); ObjectSetString (0, title, OBJPROP_TEXT, "Market Sentiment"); ObjectSetInteger(0, title, OBJPROP_COLOR, clrWhite); ObjectSetString (0, title, OBJPROP_FONT, FontFace); ObjectSetInteger(0, title, OBJPROP_FONTSIZE, FontSize); string tfs[3] = { TFtoString(HigherTF), TFtoString(LowerTF1), TFtoString(LowerTF2) }; for(int i=0;i<3;i++) { string tfLabel = indicatorName+"_TF"+(string)i; ObjectCreate(0, tfLabel, OBJ_LABEL, 0,0,0); ObjectSetInteger(0, tfLabel, OBJPROP_XDISTANCE, PanelX+10); ObjectSetInteger(0, tfLabel, OBJPROP_YDISTANCE, PanelY+30+i*20); ObjectSetInteger(0, tfLabel, OBJPROP_CORNER, 0); ObjectSetString (0, tfLabel, OBJPROP_TEXT, tfs[i]+":"); ObjectSetInteger(0, tfLabel, OBJPROP_COLOR, clrLightGray); ObjectSetString (0, tfLabel, OBJPROP_FONT, FontFace); ObjectSetInteger(0, tfLabel, OBJPROP_FONTSIZE, FontSize); string sentLabel = indicatorName+"_Sentiment"+(string)i; ObjectCreate(0, sentLabel, OBJ_LABEL, 0,0,0); ObjectSetInteger(0, sentLabel, OBJPROP_XDISTANCE, PanelX+100); ObjectSetInteger(0, sentLabel, OBJPROP_YDISTANCE, PanelY+30+i*20); ObjectSetInteger(0, sentLabel, OBJPROP_CORNER, 0); ObjectSetString (0, sentLabel, OBJPROP_TEXT, "N/A"); ObjectSetInteger(0, sentLabel, OBJPROP_COLOR, NeutralColor); ObjectSetString (0, sentLabel, OBJPROP_FONT, FontFace); ObjectSetInteger(0, sentLabel, OBJPROP_FONTSIZE, FontSize); } string fnl = indicatorName+"_Final"; ObjectCreate(0, fnl, OBJ_LABEL, 0,0,0); ObjectSetInteger(0, fnl, OBJPROP_XDISTANCE, PanelX+10); ObjectSetInteger(0, fnl, OBJPROP_YDISTANCE, PanelY+100); ObjectSetInteger(0, fnl, OBJPROP_CORNER, 0); ObjectSetString (0, fnl, OBJPROP_TEXT, "Final: Neutral"); ObjectSetInteger(0, fnl, OBJPROP_COLOR, NeutralColor); ObjectSetString (0, fnl, OBJPROP_FONT, FontFace); ObjectSetInteger(0, fnl, OBJPROP_FONTSIZE, FontSize+2); }
La función CreatePanel() inicializa un panel organizado visualmente en la esquina superior izquierda del gráfico, utilizando un tema oscuro adecuado para gráficos con fondo claro. En primer lugar, crea un rectángulo de fondo con relleno negro y borde gris, asegurándose de que quede detrás de los demás objetos del gráfico y no sea seleccionable. A continuación, se añade una etiqueta de título en la parte superior del panel, que lo identifica claramente como el indicador «Sentimiento del mercado», usando texto blanco para que destaque sobre el fondo oscuro.
Debajo del título, la función genera etiquetas para cada uno de los tres marcos temporales supervisados —superior e inferiores—, mostrando sus nombres junto a los valores provisionales del sentimiento inicializados como «N/A» en un color neutro. Por último, una etiqueta más grande situada en la parte inferior resume el sentimiento final del mercado, que inicialmente se establece en «Neutral». Esta configuración permite realizar un seguimiento visual sencillo del sesgo del mercado en distintos marcos temporales en un único panel compacto.
//+------------------------------------------------------------------+ //| Panel Update | //+------------------------------------------------------------------+ void UpdatePanel(int higherTFBias, bool tf1Bullish, bool tf1Bearish, bool tf2Bullish, bool tf2Bearish, int sentiment) { // Higher TF string txt="Neutral"; color col=NeutralColor; if(higherTFBias==1){txt="Bullish"; col=BullishColor;} else if(higherTFBias==-1){txt="Bearish"; col=BearishColor;} ObjectSetString(0, indicatorName+"_Sentiment0", OBJPROP_TEXT, txt); ObjectSetInteger(0, indicatorName+"_Sentiment0", OBJPROP_COLOR, col); // Lower TF1 txt="Neutral"; col=NeutralColor; if(tf1Bullish){txt="Bullish"; col=BullishColor;} else if(tf1Bearish){txt="Bearish"; col=BearishColor;} ObjectSetString(0, indicatorName+"_Sentiment1", OBJPROP_TEXT, txt); ObjectSetInteger(0, indicatorName+"_Sentiment1", OBJPROP_COLOR, col); // Lower TF2 txt="Neutral"; col=NeutralColor; if(tf2Bullish){txt="Bullish"; col=BullishColor;} else if(tf2Bearish){txt="Bearish"; col=BearishColor;} ObjectSetString(0, indicatorName+"_Sentiment2", OBJPROP_TEXT, txt); ObjectSetInteger(0, indicatorName+"_Sentiment2", OBJPROP_COLOR, col); // Final string finalSent="Neutral"; color finalCol=NeutralColor; switch(sentiment){ case 1: finalSent="Bullish"; finalCol=BullishColor; break; case -1: finalSent="Bearish"; finalCol=BearishColor; break; case 2: finalSent="Risk-On"; finalCol=RiskOnColor; break; case -2: finalSent="Risk-Off"; finalCol=RiskOffColor; break; } ObjectSetString(0, indicatorName+"_Final", OBJPROP_TEXT, "Final: "+finalSent); ObjectSetInteger(0, indicatorName+"_Final", OBJPROP_COLOR, finalCol); }
La función UpdatePanel() actualiza dinámicamente el panel de sentimiento del mercado en función de los últimos análisis. En primer lugar, evalúa el sesgo del marco temporal superior y actualiza la etiqueta correspondiente con «Alcista», «Bajista» o «Neutral», aplicándole el color adecuado. A continuación, hace lo mismo con los dos marcos temporales inferiores, comprobando sus estructuras alcistas o bajistas y reflejando los resultados en sus respectivas etiquetas con la codificación de colores adecuada.
Por último, la función determina el sentimiento general del mercado evaluando los sesgos y las rupturas combinados en todos los marcos temporales. La etiqueta de sentimiento final se actualiza para mostrar «Alcista», «Bajista», «Apetito por el riesgo», «Aversión al riesgo» o «Neutral», con el color correspondiente, con el fin de ofrecer un resumen rápido y visualmente claro de la situación actual del mercado. Esto garantiza que los operadores puedan evaluar al instante y de un solo vistazo la dirección del mercado en distintos marcos temporales.

Conclusión
En resumen, hemos desarrollado un indicador personalizado del sentimiento del mercado que integra varios marcos temporales para ofrecer una representación clara y visual de las condiciones del mercado. El indicador calcula medias móviles en marcos temporales superiores e inferiores, identifica estructuras alcistas o bajistas utilizando máximos y mínimos de oscilación, detecta posibles rupturas y determina el sentimiento general. En la esquina superior izquierda, un panel con tema oscuro muestra el sentimiento correspondiente a cada marco temporal, así como un sentimiento final combinado, con un código de colores que permite distinguir rápidamente las condiciones alcistas, bajistas, de apetito por el riesgo, de aversión al riesgo y neutrales.
En conclusión, este indicador ayuda a los operadores a tomar decisiones más fundamentadas, ya que sintetiza datos de mercado complejos en un formato visual y fácil de interpretar. Ofreciendo un análisis del sentimiento del mercado en tiempo real y en múltiples marcos temporales, permite a los operadores evaluar rápidamente las tendencias del mercado, identificar posibles oportunidades de trading y adaptar sus estrategias a las condiciones imperantes en el mercado, lo que reduce la incertidumbre y mejora la eficacia en la toma de decisiones.
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/19422
Advertencia: todos los derechos de estos materiales pertenecen a MetaQuotes Ltd. Queda totalmente prohibido el copiado total o parcial.
Este artículo ha sido escrito por un usuario del sitio web y refleja su punto de vista personal. MetaQuotes Ltd. no se responsabiliza de la exactitud de la información ofrecida, ni de las posibles consecuencias del uso de las soluciones, estrategias o recomendaciones descritas.
Utilizando redes neuronales en MetaTrader
Arbitraje estadístico mediante acciones cointegradas (Parte 3): Configuración de la base de datos
Particularidades del trabajo con números del tipo double en MQL4
Potencie su operativa con Smart Money Concepts (SMC): OB, BOS y FVG
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso