Разрабатываем пользовательский индикатор рыночных настроений
Введение
Определить истинное направление рынка непросто, особенно когда разные таймфреймы дают противоречивые сигналы. Трейдер может видеть сильное бычье движение на 30-минутном графике, тогда как 4-часовой график все еще указывает на медвежье давление. Это часто приводит к путанице, несогласованным сделкам или входам против доминирующего рыночного уклона. Без структурированного способа согласования сигналов старшего и младших таймфреймов трейдеры рискуют принимать импульсивные решения на основе неполной информации, что в итоге снижает стабильность и прибыльность.
Пользовательский индикатор Market Sentiment решает эту проблему, сводя сигналы нескольких таймфреймов в единую наглядную панель. Анализируя тренды старшего таймфрейма вместе со структурами младших таймфреймов, он классифицирует рыночные настроения по пяти понятным категориям: бычьи, медвежьи, режим risk-on, режим risk-off или нейтральные. Такой многоуровневый подход помогает трейдерам не терять из виду общую рыночную картину и при этом выбирать момент входа с учетом краткосрочных подтверждений. В результате он упрощает принятие решений, снижает неопределенность и помогает согласовывать сделки с текущим рыночным контекстом.
Разработка и логика
Бычьи настроения:
Возникают, когда трейдеры и инвесторы в целом ожидают роста цен. Для них характерно более сильное давление покупателей по сравнению с давлением продавцов. Типичные признаки включают более высокие максимумы и более высокие минимумы в ценовом движении, высокий объем на восходящих импульсах, а также позитивный экономический или новостной фон. В крайней форме бычьи настроения могут привести к эйфории, когда оптимизм становится чрезмерным, часто ближе к завершению бычьего рынка.

Медвежьи настроения:
Отражают ожидание снижения цен, когда давление продавцов превышает давление покупателей. Обычно они определяются по более низким максимумам и более низким минимумам в ценовом движении, высокому объему во время нисходящих импульсов, а также негативным экономическим или новостным факторам. В крайней форме медвежьи настроения могут проявляться как паника, вызывая агрессивные продажи, которые часто возникают на рыночных минимумах или рядом с ними.

Нейтральные настроения:
Возникают, когда участники рынка не определились с направлением или видят баланс между покупателями и продавцами. В такой среде цены обычно движутся в диапазоне, не формируя явного восходящего или нисходящего тренда. Ключевые признаки включают фазы консолидации, низкую волатильность и ожидание трейдерами подтверждения перед открытием позиций.

Режим risk-on:
Описывает рыночный режим, при котором инвесторы готовы принимать больший риск и чаще переходят в акции, сырьевые товары и высокодоходные активы. Капитал направляется в инструменты с более высоким потенциалом доходности. Типичные признаки включают рост фондовых индексов и слабый спрос на защитные активы, такие как золото или государственные облигации.

Режим risk-off:
Режим risk-off, напротив, возникает, когда инвесторы уходят в защитные активы из-за страха или неопределенности. В этом случае капитал перемещается в традиционно более безопасные активы, такие как золото, доллар США, швейцарский франк или государственные облигации. Обычно такой режим характеризуется снижением фондовых индексов и ростом спроса на защитные валюты и активы.

Взаимосвязь таймфреймов:

Архитектурная схема:

Начало работы
//+------------------------------------------------------------------+ //| 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;
Начнем с настройки основы пользовательского индикатора рыночных настроений в MQL5. Верхний раздел включает метаданные, такие как copyright, version и link, а также директивы, определяющие свойства индикатора. Значения indicator_buffers 0 и indicator_plots 0 означают, что стандартные буферы и графические построения не используются, поскольку этот индикатор задуман скорее как визуальный инструмент в виде панели, а не как построение линий или гистограмм. Эти настройки задают среду, в которой будет работать логика анализа рыночных настроений.
Входные параметры дают трейдерам гибкость при настройке индикатора. Группа “Timeframe Settings” позволяет выбрать старший таймфрейм (по умолчанию H4) и два младших таймфрейма (H1 и M30) для анализа рыночных настроений. В группе “Indicator Settings” трейдеры могут настраивать технические параметры, такие как период скользящей средней, период анализа локальных экстремумов и порог ATR, которые используются для интерпретации ценового поведения и волатильности. Наконец, группа “Visual Settings” управляет отображением панели рыночных настроений на графике, включая ее положение, стиль и размер шрифта, а также конкретные цвета для бычьих, медвежьих, нейтральных настроений, а также для режимов risk-on и risk-off. Вместе эти входные параметры создают гибкую основу для выявления и визуализации рыночных настроений на нескольких таймфреймах.
//+------------------------------------------------------------------+ //| 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?"; } }
В этом разделе определяются глобальные переменные и вспомогательная функция, необходимые для индикатора рыночных настроений. Три дескриптора индикатора (higherTFHandle, lowerTF1Handle и lowerTF2Handle) используются для хранения ссылок на расчеты скользящей средней на разных таймфреймах, а массивы (higherTFMA[], lowerTF1MA[], lowerTF2MA[]) хранят рассчитанные значения MA. Переменная lastUpdateTime инициализируется для отслеживания времени последнего обновления индикатора, что позволяет обновлять его без лишних вычислений, а indicatorName задает единый префикс/идентификатор для объектов, создаваемых на графике. Кроме того, вспомогательная функция TFtoString() преобразует числовые константы таймфреймов в читаемые строки (например, PERIOD_H1 -> "H1"), что полезно для подписей и отображения информации на панели индикатора.
//+------------------------------------------------------------------+ //| 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); }
Функция OnInit() инициализирует индикатор рыночных настроений: задает уникальные имена для объектов графика с использованием идентификатора графика и создает дескрипторы скользящих средних для старшего и младших таймфреймов с указанным периодом и методом EMA. Она также задает для массивов MA режим таймсерий, что упрощает обращение к последним значениям. Затем вызывается функция CreatePanel() для отрисовки панели рыночных настроений на графике, после чего возвращается INIT_SUCCEEDED для подтверждения успешной инициализации.
//+------------------------------------------------------------------+ void OnDeinit(const int reason) { ObjectsDeleteAll(0, indicatorName); IndicatorRelease(higherTFHandle); IndicatorRelease(lowerTF1Handle); IndicatorRelease(lowerTF2Handle); }
Функция OnDeinit() обеспечивает корректную очистку при удалении индикатора: удаляет все объекты графика, связанные с его уникальным indicatorName, и освобождает дескрипторы скользящих средних старшего и младших таймфреймов. Это предотвращает утечки памяти и поддерживает чистоту среды графика.
//+------------------------------------------------------------------+ 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); }
Функция OnCalculate() выступает основным циклом обработки индикатора и запускается при поступлении новых ценовых данных или тиков. Сначала используется ограничение частоты обновления: расчеты выполняются только если с момента последнего обновления прошло не менее 10 секунд, что позволяет избегать лишних вычислений. Затем функция копирует значения скользящих средних из буферов старшего и младших таймфреймов и получает последние цены закрытия для каждого таймфрейма, формируя основу для оценки рыночных настроений.
После получения цен и значений MA функция определяет направленный уклон старшего таймфрейма и проверяет структуру рынка на младших таймфреймах — наличие бычьей или медвежьей структуры. Она также подтверждает потенциальные пробои в соответствии с направленным уклоном старшего таймфрейма. Эти условия объединяются в функции DetermineSentiment(), чтобы классифицировать рыночные настроения как бычьи, медвежьи, в режиме risk-on, в режиме risk-off или нейтральные. В конце результаты визуально отображаются на графике через UpdatePanel(), предоставляя трейдерам панель рыночных настроений по нескольким таймфреймам в реальном времени.
//+------------------------------------------------------------------+ //| 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; }
Эта функция оценивает направленный уклон старшего таймфрейма, сравнивая текущую цену со значением ее скользящей средней. Если цена выше MA и отклонение превышает заданный порог ATR, функция возвращает 1 (бычий направленный уклон); если цена ниже и отклонение достаточно велико, она возвращает -1 (медвежий направленный уклон). Если ни одно условие не выполнено, возвращается 0, что указывает на нейтральный или неопределенный направленный уклон старшего таймфрейма.
//+------------------------------------------------------------------+ //| 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)); }
Функция IsBullishStructure() выявляет бычью ценовую структуру на заданном таймфрейме, сравнивая последние локальные максимумы и локальные минимумы с предыдущими свинговыми точками. Сначала она находит текущие и предыдущие локальные максимумы и локальные минимумы с помощью функций iHighest и iLowest. Если текущий максимум выше предыдущего максимума, а текущий минимум выше предыдущего минимума, функция возвращает true, сигнализируя о бычьей структуре; в противном случае возвращается false.
Аналогично, функция IsBearishStructure() выявляет медвежью структуру, сравнивая недавние локальные экстремумы с предыдущими. Если текущий максимум ниже предыдущего максимума, а текущий минимум ниже предыдущего минимума, она возвращает true, указывая на медвежью структуру. Обе функции опираются на анализ локальных экстремумов за заданный период, предоставляя индикатору способ оценивать краткосрочные ценовые тренды относительно их предыдущих движений.
//+------------------------------------------------------------------+ 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; }
Эта функция проверяет, пробила ли текущая цена последние локальные экстремумы вверх или вниз на указанном таймфрейме с учетом направленного уклона старшего таймфрейма. Она определяет последние локальный максимум и локальный минимум; если какой-либо из них недоступен, возвращается false. При бычьем направленном уклоне старшего таймфрейма функция возвращает true, если текущая цена превышает локальный максимум, а при медвежьем направленном уклоне — если цена опускается ниже локального минимума. Если направленный уклон старшего таймфрейма нейтральный, пробой не учитывается, и функция возвращает 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; }
Функция DetermineSentiment() объединяет направленный уклон старшего таймфрейма, структуру младших таймфреймов и сигналы пробоя, чтобы классифицировать общие рыночные настроения. Она возвращает 1 для бычьих настроений, если старший таймфрейм бычий и оба младших таймфрейма показывают бычьи структуры; -1 для медвежьих настроений при обратной комбинации условий; 2 для режима risk-on, если на фоне бычьего старшего таймфрейма на младших таймфреймах появляются пробои; и -2 для режима risk-off, если похожие пробои появляются при медвежьем старшем таймфрейме. Если ни одно из условий не выполнено, возвращается 0, что указывает на нейтральные или боковые рыночные настроения.
//+------------------------------------------------------------------+ //| 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); }
Функция CreatePanel() инициализирует визуально упорядоченную панель в левом верхнем углу графика, используя темную тему, хорошо читаемую на светлом фоне графика. Сначала создается фоновый прямоугольник с черной заливкой и серой рамкой; он располагается позади других объектов графика и не может быть выбран. Затем в верхней части панели добавляется заголовок, четко обозначающий индикатор как "Market Sentiment", с белым текстом для хорошей читаемости на темном фоне.
Ниже заголовка функция создает подписи для каждого из трех отслеживаемых таймфреймов — старшего и младших, — отображая их названия рядом с текущими значениями рыночных настроений, изначально установленными как "N/A" нейтральным цветом. Внизу размещается более крупная подпись, суммирующая итоговые рыночные настроения, которые изначально заданы как "Neutral". Такая настройка позволяет удобно визуально отслеживать рыночный уклон на нескольких таймфреймах в одной компактной панели.
//+------------------------------------------------------------------+ //| 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); }
Функция UpdatePanel() динамически обновляет панель рыночных настроений на основе последнего анализа. Сначала она оценивает направленный уклон старшего таймфрейма и обновляет соответствующую метку значением "Bullish", "Bearish" или "Neutral" и задает нужный цвет. Затем она выполняет то же самое для двух младших таймфреймов, проверяя их бычьи или медвежьи структуры и отображая результаты в соответствующих метках с правильной цветовой индикацией.
Наконец, функция определяет общие рыночные настроения, сопоставляя направленный уклон, структуру и пробои на всех таймфреймах. Итоговая метка обновляется и показывает интерфейсные значения "Bullish", "Bearish", "Risk-On", "Risk-Off" или "Neutral" с соответствующим цветом; в русскоязычном описании им соответствуют бычьи настроения, медвежьи настроения, режим risk-on, режим risk-off и нейтральные рыночные настроения. Префикс "Final" в панели обозначает итоговую оценку. Благодаря этому трейдеры могут мгновенно оценить рыночный уклон на нескольких таймфреймах одним взглядом.

Заключение
В итоге мы разработали пользовательский индикатор рыночных настроений, который объединяет несколько таймфреймов, чтобы дать ясное визуальное представление о рыночном уклоне и текущих настроениях. Индикатор рассчитывает скользящие средние на старшем и младших таймфреймах, определяет бычьи или медвежьи структуры с использованием локальных максимумов и локальных минимумов, выявляет потенциальные пробои и определяет общие рыночные настроения. Темная панель в левом верхнем углу отображает направленный уклон и структуру для каждого таймфрейма, а также итоговые рыночные настроения; цветовая индикация позволяет быстро различать бычьи, медвежьи, нейтральные, а также risk-on и risk-off состояния рынка.
В заключение, этот индикатор помогает трейдерам принимать более обоснованные решения, объединяя сложные рыночные данные в наглядный визуальный формат. Благодаря анализу рыночных настроений на нескольких таймфреймах в реальном времени он позволяет быстро оценивать рыночные тренды, выявлять потенциальные торговые возможности и согласовывать стратегии с текущим рыночным уклоном и настроениями, снижая неопределенность и повышая эффективность принятия решений.
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/19422
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
От начального до среднего уровня: События в объектах (I)
Советник для размещения сделок на основе риска с графическим интерфейсом на графике (Часть 1): Проектирование пользовательского интерфейса
Советник для размещения ордеров на основе риска с графическим интерфейсом на графике (Часть 2): Добавление интерактивности и логики
TradeMux как Quant Backbone: Подключение институциональных Python-пайплайнов к разным терминалам и брокерам
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования