English Deutsch 日本語
preview
Адаптивная архитектура Smart Money (ASMA): Интеграция логики SMC с анализом сентимента для динамического переключения стратегий

Адаптивная архитектура Smart Money (ASMA): Интеграция логики SMC с анализом сентимента для динамического переключения стратегий

MetaTrader 5Примеры |
355 16
Hlomohang John Borotho
Hlomohang John Borotho

Оглавление:

  1. Введение
  2. Обзор стратегии
  3. Приступаем к реализации
  4. Результаты бэктеста
  5. Заключение


Введение

На последних этапах разработки мы успешно объединили Order Blocks (OB), Fair Value Gaps (FVG) и Break of Structure (BOS) в единый модуль Smart Money Concepts — мощную рабочую модель, позволяющую точно интерпретировать институциональную логику движения цены. Развивая эту основу, мы также разработали собственный индикатор рыночного настроения, который интерпретирует силу тренда, характер волатильности и согласованность импульсной динамики, чтобы классифицировать рынок как бычий, медвежий или нейтральный. Эти два достижения дают нам отличную возможность объединить структурное поведение цены с рыночным настроением в реальном времени в одну адаптивную торговую систему.

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


Обзор стратегии: SMC-торговая система на основе рыночных настроений

Эта интеллектуальная торговая система объединяет три ключевые стратегии Smart Money Concepts (SMC) — Order Blocks (OB), Fair Value Gaps (FVG) и Break of Structure (BOS) — с анализом рыночного настроения в реальном времени, чтобы создать торговый алгоритм, учитывающий рыночный контекст. Система работает в мультитаймфреймовой структуре, анализируя поведение цены на старших таймфреймах (H4), средних таймфреймах (H1) и младших таймфреймах (M30), чтобы определить общее направление рынка и его текущее настроение. На основе рассчитанных оценок рыночного настроения — от Strong Bullish (сильно бычьего) до Strong Bearish (сильно медвежьего), а также режимов Risk-On, Risk-Off и нейтральных условий — советник динамически выбирает и приоритизирует наиболее подходящую стратегию SMC, обеспечивая соответствие торговых решений текущим рыночным условиям, а не использование единой стратегии на все рыночные условия.

Нейтральный рыночный фон + стратегия Order Blocks

В нейтральных рыночных условиях, характеризующихся консолидацией цены возле скользящих средних и отсутствием четкого направления на старшем таймфрейме, система активирует стратегию Order Blocks (OB) как основной метод торговли. Нейтральное настроение обычно указывает на боковой рынок, где цена колеблется между установленными уровнями поддержки и сопротивления без сильного направленного импульса. В такой среде Order Blocks становятся особенно эффективными, поскольку они определяют области, где ранее размещались институциональные ордера, создавая естественные зоны реакции. Советник выявляет бычьи OB (медвежья свеча, за которой следует сильная бычья свеча) и медвежьи OB (бычья свеча, за которой следует сильная медвежья свеча), демонстрирующие значительный дисбаланс потока ордеров. Когда цена возвращается к этим выявленным зонам OB, система открывает сделки в расчете на возврат цены к среднему значению, используя склонность рынка реагировать на ранее сформированные области накопления ордеров во время фаз консолидации.

Трендовый рынок (бычий/медвежий) + стратегия Break of Structure

Когда система обнаруживает сильное бычье или сильное медвежье рыночное настроение, указывающее на четкие направленные тренды, подтвержденные на нескольких таймфреймах, она отдает приоритет стратегии Break of Structure (BOS), чтобы использовать продолжение импульса. На трендовых рынках, характеризующихся более высокими максимумами и более высокими минимумами (бычий тренд) или более низкими максимумами и более низкими минимумами (медвежий тренд), BOS определяет ключевые локальные экстремумы, где рыночная структура была пробита, что сигнализирует о потенциальном ускорении в преобладающем направлении. Советник отслеживает пробой ценой недавних свинг-максимумов в бычьих трендах или недавних свинг-минимумов в медвежьих трендах, интерпретируя такие пробои как снятие ликвидности, которое часто предшествует устойчивым направленным движениям. Эта стратегия идеально соответствует трендовым условиям, поскольку фокусируется на входе в направлении установленного тренда после структурного подтверждения и избегает контртрендовых сделок, вероятность успеха которых ниже во время сильных направленных движений.

Настроение Risk-On/Risk-Off + стратегия Fair Value Gaps

В рыночных условиях Risk-On или Risk-Off, характеризующихся пробоями из сформированных диапазонов в сочетании с доминирующим направлением старшего таймфрейма, система использует стратегию Fair Value Gaps (FVG). Такие условия обычно возникают, когда цена консолидировалась, но затем внезапно получает расширение импульса, создавая зоны дисбаланса между последовательными свечами, где торговля была минимальной. Советник определяет эти зоны дисбаланса, где давление покупателей или продавцов создало значительные ценовые пустоты, ожидая, что цена в итоге вернется к «справедливой стоимости» внутри этих зон. Система торгует именно на 50% уровне равновесия этих зон, обеспечивая оптимальные точки входа с точки зрения соотношения риск/доходность в периоды волатильных пробоев. Такой подход использует склонность рынка заполнять ценовые неэффективности, при этом учитывая доминирующее направление рынка, что делает его идеальным для переходных фаз рынка, когда импульс уже нарастает, но тренд еще может быть не полностью сформирован.

Приступаем к реализации

//+------------------------------------------------------------------+
//|                                                     SMC_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   "2.00"
#property description "Intelligent SMC EA with Market Sentiment-Based Strategy Switching"
#property copyright "Based on MARKSENT and SMCALL"

#include <Trade/Trade.mqh>
#include <Trade/PositionInfo.mqh>
#include <Arrays/ArrayObj.mqh>

// Market Sentiment Component (from MARKSENT)
input group "=== Market Sentiment Settings ==="
input ENUM_TIMEFRAMES HigherTF = PERIOD_H4;
input ENUM_TIMEFRAMES LowerTF1 = PERIOD_H1;
input ENUM_TIMEFRAMES LowerTF2 = PERIOD_M30;
input int MAPeriod = 200;
input int SwingLookback = 5;
input double ATRThreshold = 0.002;

input group "=== Trading Settings ==="
input double LotSize = 0.02;
input double StopLoss = 500;
input double TakeProfit = 1500;
input long MagicNumber = 76543;
input bool EnableTrading = true;
input bool DrawAllObjects = true; // Draw all trading objects

input group "=== Strategy Selection ==="
input bool UseSentimentFilter = true; // Use sentiment to choose strategies
input bool AllowBOS = true;           // Allow Break of Structure strategy
input bool AllowOB = true;            // Allow Order Blocks strategy  
input bool AllowFVG = true;           // Allow Fair Value Gaps strategy

input group "=== Visual Settings ==="
input int PanelCorner = 0;           // Top-left corner
input int PanelX = 10;
input int PanelY = 10;
input string FontFace = "Arial";
input int FontSize = 10;

// Color scheme based on market sentiment
input color BullishColor = clrLimeGreen;
input color BearishColor = clrRed;
input color RiskOnColor = clrDodgerBlue;
input color RiskOffColor = clrOrangeRed;
input color NeutralColor = clrGold;

// Strategy drawing colors
input color OB_BullColor = clrLime;
input color OB_BearColor = clrRed;
input color FVG_BullColor = clrPaleGreen;
input color FVG_BearColor = clrMistyRose;
input color BOS_BullColor = clrDodgerBlue;
input color BOS_BearColor = clrTomato;

// Cleanup settings
input bool RemoveObjectsAfterTradeClose = true;
input int RemoveObjectsAfterBars = 10; // Remove objects after X bars

// Global variables
CTrade trade;
CPositionInfo poss;

// Market Sentiment Handles
int higherTFHandle, lowerTF1Handle, lowerTF2Handle;
double higherTFMA[], lowerTF1MA[], lowerTF2MA[];
datetime lastSentimentUpdate = 0;
int currentSentiment = 0; // -2:RiskOff, -1:Bearish, 0:Neutral, 1:Bullish, 2:RiskOn
string currentSentimentText = "Neutral";

// SMC Trading Variables
datetime lastBarTime = 0;
double Bid, Ask;
string currentStrategy = "ALL";

Мы начинаем с подключения необходимых библиотек MQL5 для выполнения торговых операций, получения информации о позициях и управления массивами, формируя основу как для торговых операций, так и для хранения данных, требуемых советнику. Первый раздел определяет все входные параметры компонента Market Sentiment, который анализирует и обрабатывает данные на нескольких таймфреймах (H4, H1, M30), используя такие инструменты, как 200-периодная скользящая средняя, глубина поиска свингов и пороги ATR. Эти параметры относятся к собственному модулю анализа рыночного настроения (MARKSENT) и позволяют советнику классифицировать рыночную среду как бычью, медвежью, Risk-On, Risk-Off или нейтральную. Анализируя эти разные таймфреймы вместе, советник формирует надежное понимание текущего направления рынка и характеристик волатильности.

В следующем разделе мы определяем Trading Settings и Strategy Selection, которые дают советнику гибкость в работе. Такие входные параметры, как размер лота, стоп-лосс, тейк-профит, magic number и настройки отрисовки объектов, определяют, как исполняются и визуализируются ордера. Что особенно важно, блок Strategy Selection позволяет пользователю включать или отключать реакцию на рыночное настроение и выборочно активировать логику BOS, OB и FVG. Это означает, что советника можно настроить на торговлю с опорой только на фильтр настроения, исключительно по паттернам SMC или в гибридном режиме, где он интеллектуально переключает стратегии в зависимости от текущего рыночного настроения, обнаруженного индикатором. В сочетании с настраиваемыми визуальными параметрами этот раздел обеспечивает и функциональность, и ясность на графике.

Затем мы настраиваем все глобальные переменные и буферы, необходимые для расчетов в реальном времени, включая хэндлы MA для старших и младших таймфреймов, отслеживание текущего рыночного настроения и активность стратегии SMC. Такие переменные, как currentSentiment, currentSentimentText и currentStrategy, служат опорными точками для принятия решений: они хранят текущее состояние рынка и активную стратегию, которая будет использоваться при следующем сигнале. Советник постоянно обновляет цены Bid/Ask, определяет новые бары и решает, когда удалять старые объекты SMC с графика для эффективной визуализации. Вместе эти глобальные компоненты создают базовую архитектуру, которая позволяет советнику объединить анализ рыночного настроения со Smart Money Concepts, формируя адаптивную торговую систему, которая корректирует свою логику по мере изменения рынка.

// Trade information structure
struct TradeInfo
{
   long ticket;
   string symbol;
   datetime openTime;
   double openPrice;
   ENUM_ORDER_TYPE type;
   string strategy;
   long magic;
   
   TradeInfo() : ticket(-1), symbol(""), openTime(0), openPrice(0), type(WRONG_VALUE), strategy(""), magic(0) {}
};

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
    trade.SetExpertMagicNumber(MagicNumber);
    indicatorName = "IntelligentSMC_" + IntegerToString(ChartID());
    
    // Initialize market sentiment indicators
    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);
    
    // Initialize arrays
    detectedFVGs = new CArrayObj();
    detectedBOSZones = new CArrayObj();
    tradedOBs = new CArrayObj();
    activeTrades = new CArrayObj();
    
    CreateControlPanel();
    
    Print("Intelligent SMC EA Started - Strategy Switching & Clean Drawing Enabled");
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    IndicatorRelease(higherTFHandle);
    IndicatorRelease(lowerTF1Handle);
    IndicatorRelease(lowerTF2Handle);
    
    // Clean up all objects
    CleanupAllObjects();
    
    if(currentOB != NULL) 
    {
        delete currentOB;
        currentOB = NULL;
    }
    
    // Clean up FVGs
    if(detectedFVGs != NULL)
    {
        for(int i = detectedFVGs.Total()-1; i >= 0; i--)
        {
            CFVG* fvg = (CFVG*)detectedFVGs.At(i);
            if(fvg != NULL) delete fvg;
        }
        delete detectedFVGs;
    }
    
    // Clean up BOS zones
    if(detectedBOSZones != NULL)
    {
        for(int i = detectedBOSZones.Total()-1; i >= 0; i--)
        {
            CBOSZone* bos = (CBOSZone*)detectedBOSZones.At(i);
            if(bos != NULL) delete bos;
        }
        delete detectedBOSZones;
    }
    
    // Clean up traded OBs
    if(tradedOBs != NULL)
    {
        for(int i = tradedOBs.Total()-1; i >= 0; i--)
        {
            COrderBlock* ob = (COrderBlock*)tradedOBs.At(i);
            if(ob != NULL) delete ob;
        }
        delete tradedOBs;
    }
    
    // Clean up active trades
    if(activeTrades != NULL)
    {
        delete activeTrades;
    }
    
    ObjectsDeleteAll(0, indicatorName);
    Comment("");
}

//+------------------------------------------------------------------+
//| Cleanup all graphical objects                                    |
//+------------------------------------------------------------------+
void CleanupAllObjects()
{
    // Clean up old objects
    string prefix = "";
    int total = ObjectsTotal(0);
    
    for(int i = total-1; i >= 0; i--)
    {
        string name = ObjectName(0, i);
        if(StringFind(name, "OB_", 0) == 0 ||
           StringFind(name, "FVG_", 0) == 0 ||
           StringFind(name, "BOS_", 0) == 0 ||
           StringFind(name, "Trade_", 0) == 0)
        {
            ObjectDelete(0, name);
        }
    }
}

В этом разделе определяется структура TradeInfo, которая хранит всю ключевую информацию о сделках, открытых советником: тикет, символ, время входа, цену, тип ордера, использованную стратегию и magic number. Конструктор по умолчанию инициализирует каждое поле безопасным «пустым» состоянием, гарантируя, что неинициализированные значения не вызовут логических ошибок при обработке или хранении торговых данных советником. Эта структура становится особенно важной для такой адаптивной мультистратегической системы, поскольку позволяет советнику отслеживать, какая стратегия (OB, FVG или BOS) запустила каждую сделку, открывая возможности для отслеживания эффективности, очистки или управления сделками по конкретным стратегиям.

Функции OnInit() и OnDeinit() отвечают за настройку и завершение работы всего советника. При инициализации советник задает magic number, подготавливает уникальные имена индикаторов и создает все хэндлы скользящих средних, используемые модулем анализа рыночного настроения на нескольких таймфреймах. Он также настраивает массивы как временные ряды (series) и создает контейнеры для хранения обнаруженных структур SMC — FVG, зон BOS и OB, по которым уже были совершены сделки, а также для отслеживания активных сделок. Для мониторинга на графике создается панель управления, и советник выводит сообщение о запуске динамической SMC-логики и механизма переключения стратегий. В свою очередь, OnDeinit() обеспечивает корректное завершение работы: освобождает хэндлы индикаторов, удаляет все динамически выделенные объекты SMC, очищает массивы сделок и убирает с графика все отрисовки OB/FVG/BOS. Отдельная функция CleanupAllObjects() помогает поддерживать чистый график, систематически удаляя любой графический объект, соответствующий соглашениям именования SMC. Вместе эти процедуры гарантируют, что советник чисто инициализируется, ответственно управляет памятью и не оставляет мусора после удаления.

// Market Sentiment Calculation Component
int CalculateMarketSentiment()
{
    if(TimeCurrent() - lastSentimentUpdate < 5) 
        return currentSentiment;
    
    lastSentimentUpdate = TimeCurrent();
    
    // Get MA values from multiple timeframes
    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);
    
    // Calculate biases across timeframes
    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);
    
    // Determine final sentiment based on multi-timeframe analysis
    currentSentiment = DetermineSentiment(higherTFBias, 
        lowerTF1Bullish, lowerTF1Bearish, lowerTF1Breakout,
        lowerTF2Bullish, lowerTF2Bearish, lowerTF2Breakout);
    
    // Update sentiment text for display
    switch(currentSentiment)
    {
        case 1: currentSentimentText = "Bullish"; break;
        case -1: currentSentimentText = "Bearish"; break;
        case 2: currentSentimentText = "Risk-On"; break;
        case -2: currentSentimentText = "Risk-Off"; break;
        default: currentSentimentText = "Neutral"; break;
    }
    
    return currentSentiment;
}

// Strategy Selection Logic based on Market Sentiment
string SelectTradingStrategy()
{
    if(!UseSentimentFilter) 
    {
        currentStrategy = "ALL"; // Use all strategies if no filter
        return currentStrategy;
    }
    
    int sentiment = CalculateMarketSentiment();
    
    // Strategy assignment based on market conditions
    switch(sentiment)
    {
        case 1:  // Strong Bullish
        case -1: // Strong Bearish
            currentStrategy = "BOS"; // Use Break of Structure in strong trends
            break;
            
        case 2:  // Risk-On (Bullish with breakout)
        case -2: // Risk-Off (Bearish with breakout)  
            currentStrategy = "FVG"; // Use Fair Value Gaps during breakouts
            break;
            
        case 0:  // Neutral/Ranging
        default:
            currentStrategy = "OB"; // Use Order Blocks in ranging markets
            break;
    }
    
    return currentStrategy;
}

Здесь мы рассчитываем состояние рынка, объединяя мультитаймфреймовые скользящие средние, структурный анализ свингов и обнаружение пробоев в одну общую оценку направленности рынка. Функция сначала ограничивает перерасчеты интервалом в 5 секунд для эффективности, затем получает значения MA из хэндлов старшего и младших таймфреймов. Она анализирует цену относительно MA, чтобы определить направленность старшего таймфрейма, одновременно изучая структуры младших таймфреймов с помощью функций IsBullishStructure, IsBearishStructure и HasBreakout. Эти уровни анализа — тренд, структура и пробои — передаются в DetermineSentiment, которая возвращает классификацию рыночного настроения от «сильно бычьего сентимента» (1) до Risk-Off (-2). После определения числового значения рыночного настроения советник назначает описательную метку («Bullish», «Bearish» и т. д.) для отображения на панели.

Затем логика выбора стратегии использует этот результат настроения, чтобы динамически определить, какой метод SMC должен торговать советник. Если фильтр настроения отключен, советник просто включает все стратегии. Но когда он активен, советник интеллектуально адаптируется: сильные бычьи или медвежьи условия активируют торговлю продолжения BOS, пробойные среды Risk-On и Risk-Off отдают приоритет торговле дисбалансами FVG, а нейтральные условия или рынки в диапазоне — развороты от Order Block. Это создает адаптивную систему, где советник автоматически переключается между стратегиями BOS, FVG и OB на основе рыночного настроения в реальном времени и поведения цены, воспроизводя логику профессионального трейдера, который меняет подход в зависимости от рыночного режима.

// Execute Trade with Sentiment Filtering
bool ExecuteTradeWithFilter(ENUM_ORDER_TYPE type, string strategy)
{
    if(!EnableTrading) return false;
    
    // Check if selected strategy is allowed
    if((strategy == "BOS" && !AllowBOS) || 
       (strategy == "OB" && !AllowOB) ||
       (strategy == "FVG" && !AllowFVG))
        return false;
    
    // Check sentiment alignment before executing trade
    int sentiment = CalculateMarketSentiment();
    bool sentimentAligned = false;
    
    // Bullish trades aligned with bullish sentiment
    if((type == ORDER_TYPE_BUY && (sentiment == 1 || sentiment == 2)) ||
       // Bearish trades aligned with bearish sentiment
       (type == ORDER_TYPE_SELL && (sentiment == -1 || sentiment == -2)))
        sentimentAligned = true;
    
    // Allow neutral sentiment trades with caution
    if(sentiment == 0) sentimentAligned = true;
    
    if(!sentimentAligned)
    {
        Print("Trade rejected: Not aligned with market sentiment (", currentSentimentText, ")");
        return false;
    }
    
    // Execute the trade with strategy context
    double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
    double price = (type == ORDER_TYPE_BUY) ? Ask : Bid;
    double sl = (type == ORDER_TYPE_BUY) ? price - StopLoss * point : price + StopLoss * point;
    double tp = (type == ORDER_TYPE_BUY) ? price + TakeProfit * point : price - TakeProfit * point;
    
    sl = NormalizeDouble(sl, _Digits);
    tp = NormalizeDouble(tp, _Digits);
    
    trade.SetExpertMagicNumber(MagicNumber);
    bool result = trade.PositionOpen(_Symbol, type, LotSize, price, sl, tp, 
       "SMC_" + strategy + "_Sent:" + currentSentimentText);
    
    if(result)
    {
        long ticket = trade.ResultOrder();
        Print("Trade executed: ", EnumToString(type), 
              " | Strategy: ", strategy, 
              " | Sentiment: ", currentSentimentText,
              " | Price: ", DoubleToString(price, _Digits),
              " | Ticket: ", ticket);
        
        return true;
    }
    
    return false;
}

Эта функция гарантирует, что каждая сделка, исполняемая советником, одновременно одобрена стратегией и согласована с настроением, создавая защитный слой, который предотвращает открытие сделок против преобладающих рыночных условий. Она начинается с проверки, включена ли торговля и разрешена ли выбранная стратегия SMC (BOS, OB или FVG). Затем функция определяет текущее рыночное настроение и проверяет, совпадает ли предполагаемое направление ордера с этим настроением: например, сделки на покупку разрешены только в бычьих условиях или условиях Risk-On, а сделки на продажу требуют медвежьего настроения или условий Risk-Off.

Нейтральные рынки допускают сделки, но с дополнительной осторожностью. Если рыночное настроение и стратегия согласованы, функция рассчитывает нормализованные уровни SL и TP, назначает magic number советника и открывает новую позицию с комментарием, описывающим использованные стратегию и сентимент. Успешные сделки логируются с подробной информацией, обеспечивая прозрачность и полную отслеживаемость того, как рыночное настроение повлияло на исполнение.

// Market Sentiment Helper Functions
int GetHigherTFBias(double price, double maValue)
{
    double deviation = MathAbs(price - maValue) / maValue;
    if(price > maValue && deviation > ATRThreshold) return 1;   // Bullish bias
    else if(price < maValue && deviation > ATRThreshold) return -1; // Bearish bias
    else return 0; // Neutral/no bias
}

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);
    if(swingHighIndex == -1 || swingLowIndex == -1) return false;
    
    // Bullish structure: Higher highs AND higher lows
    return (iHigh(_Symbol, tf, swingHighIndex) > iHigh(_Symbol, tf, swingHighIndex + lookback) &&
            iLow(_Symbol, tf, swingLowIndex) > iLow(_Symbol, tf, swingLowIndex + lookback));
}

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);
    if(swingHighIndex == -1 || swingLowIndex == -1) return false;
    
    // Bearish structure: Lower highs AND lower lows
    return (iHigh(_Symbol, tf, swingHighIndex) < iHigh(_Symbol, tf, swingHighIndex + lookback) &&
            iLow(_Symbol, tf, swingLowIndex) < iLow(_Symbol, tf, swingLowIndex + lookback));
}

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);
    
    // Breakout in direction of higher timeframe bias
    if(higherTFBias == 1) return (price > swingHigh); // Bullish breakout
    if(higherTFBias == -1) return (price < swingLow); // Bearish breakout
    
    return false;
}

Эти вспомогательные функции образуют аналитическую основу модуля анализа рыночных настроений советника, оценивая поведение цены на нескольких таймфреймах и преобразуя его в оценки направленного смещения. GetHigherTFBias() сравнивает текущую цену со скользящей средней старшего таймфрейма, используя как направление, так и величину отклонения, чтобы определить, является ли рынок бычьим, медвежьим или не показывает явного направления. Затем функции IsBullishStructure() и IsBearishStructure() изучают рыночную структуру, сравнивая недавние свинг-максимумы и свинг-минимумы: формации higher high/higher low подтверждают бычью структуру, а паттерны lower high/lower low подтверждают медвежью структуру. Эти функции помогают советнику обнаруживать реальные структурные сдвиги, а не реагировать на шум.

Функция HasBreakout() добавляет динамический слой, проверяя, пробила ли цена недавние свинг-уровни в согласии с доминирующим направлением старшего таймфрейма. Например, в бычьей среде советник считает пробои значимыми только тогда, когда цена превышает недавние свинговые максимумы, сигнализируя о продолжении импульса. Когда эти три компонента — направленность рынка, структурное направление и подтверждение пробоя — объединяются, они формируют надежную многотаймфреймовую оценку рыночного настроения, которую советник использует для выбора стратегии, фильтрации сделок и интеллектуальной адаптации к меняющимся рыночным условиям.

int DetermineSentiment(int higherTFBias, 
                      bool tf1Bullish, bool tf1Bearish, bool tf1Breakout,
                      bool tf2Bullish, bool tf2Bearish, bool tf2Breakout)
{
    // Strong Bullish: Higher TF bullish + both lower TFs bullish
    if(higherTFBias == 1 && tf1Bullish && tf2Bullish) return 1;
    
    // Strong Bearish: Higher TF bearish + both lower TFs bearish
    if(higherTFBias == -1 && tf1Bearish && tf2Bearish) return -1;
    
    // Risk-On: Higher TF bullish + breakout on either lower TF
    if(higherTFBias == 1 && (tf1Breakout || tf2Breakout)) return 2;
    
    // Risk-Off: Higher TF bearish + breakout on either lower TF
    if(higherTFBias == -1 && (tf1Breakout || tf2Breakout)) return -2;
    
    // Neutral: No clear bias or conflicting signals
    return 0;
}

// Main Execution Flow with Sentiment-Strategy Integration
void OnTick()
{
    Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
    Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
    
    if(!IsNewBar()) return;
    
    // Clean up expired objects
    CleanupExpiredObjects();
    
    // Calculate current market sentiment
    CalculateMarketSentiment();
    
    // Select strategy based on sentiment
    string selectedStrategy = SelectTradingStrategy();
    
    // Execute selected strategies based on sentiment
    if(selectedStrategy == "ALL" || selectedStrategy == "BOS")
        DetectAndTradeBOS(); // Break of Structure strategy
        
    if(selectedStrategy == "ALL" || selectedStrategy == "OB")
        DetectAndTradeOrderBlocks(); // Order Blocks strategy
        
    if(selectedStrategy == "ALL" || selectedStrategy == "FVG")
        DetectAndTradeFVGs(); // Fair Value Gaps strategy
    
    // Display current status with sentiment info
    DisplayStatus();
}

// Display status with sentiment information
void DisplayStatus()
{
    int fvgCount = (detectedFVGs != NULL) ? detectedFVGs.Total() : 0;
    int bosCount = (detectedBOSZones != NULL) ? detectedBOSZones.Total() : 0;
    int obCount = (tradedOBs != NULL) ? tradedOBs.Total() : 0;
    if(currentOB != NULL) obCount++;
    
    string status = "SMC Strategy with Market Sentiment\n" +
                   "══════════════════════════════════\n" +
                   "Market Sentiment: " + currentSentimentText + "\n" +
                   "Active Strategy: " + currentStrategy + "\n" +
                   "══════════════════════════════════\n" +
                   "Patterns Detected:\n" +
                   "• Order Blocks: " + IntegerToString(obCount) + "\n" +
                   "• FVGs: " + IntegerToString(fvgCount) + "\n" +
                   "• BOS Zones: " + IntegerToString(bosCount) + "\n" +
                   "══════════════════════════════════\n" +
                   "Trading Status: " + (EnableTrading ? "ACTIVE" : "PAUSED");
    
    Comment(status);
}

Функция DetermineSentiment() выступает финальным уровнем принятия решений в модуле анализа настроения, объединяя направленность рынка старшего таймфрейма со структурой младших таймфреймов и подтверждением пробоя. Она классифицирует настроение по пяти отдельным состояниям — сильно бычье, сильно медвежье, Risk-On, Risk-Off и нейтральное — в зависимости от того, насколько хорошо таймфреймы согласуются друг с другом. Когда оба младших таймфрейма совпадают с трендом старшего таймфрейма, рыночное настроение классифицируется как сильное в этом направлении. Когда со старшим таймфреймом совпадает только пробойный импульс, рыночное настроение переходит в режим Risk-On или Risk-Off. Любые противоречивые или неясные условия по умолчанию переходят в нейтральное состояние, не позволяя советнику принимать агрессивные или несогласованные решения.

Функция OnTick() управляет основным рабочим процессом советника, интегрируя анализ рыночного настроения с выбором стратегии и исполнением сделок. На каждом новом баре советник очищает объекты, обновляет оценку рыночного настроения и выбирает наиболее подходящую стратегию — BOS, OB, FVG или все — на основе текущего рыночного настроения. Затем он активирует соответствующие модули обнаружения и торговли, позволяя системе плавно адаптировать свое поведение к рыночным условиям в реальном времени. Так формируется система, которая не полагается на единственную торговую технику, а интеллектуально переключает стратегии в зависимости от того, находится ли рынок в тренде, консолидации или пробое.

Наконец, функция DisplayStatus() повышает прозрачность, показывая трейдеру структурированную сводку внутреннего состояния советника в реальном времени, включая обнаруженные паттерны SMC, текущее состояние рынка, активную стратегию и статус включения торговли. Такая визуальная обратная связь позволяет пользователю ясно понимать, почему советник принимает определенные решения, что делает поведение системы более прозрачным для пользователя и упрощает ее мониторинг и отладку.



Результаты бэктеста

Ниже показаны результаты бэктеста, проведенного на таймфрейме H1 в рамках тестового периода продолжительностью около двух месяцев (с 01 октября 2025 года по 01 декабря 2025 года) со следующими настройками:

Ниже представлены кривая капитала и результаты бэктеста:


Заключение

В итоге мы разработали интеллектуального SMC-советника, объединив три ключевые стратегии Smart Money Concept — Order Blocks, Fair Value Gaps и Break of Structure — с анализом рыночного настроения в реальном времени на нескольких таймфреймах. Мы создали динамическую систему, которая автоматически выбирает наиболее подходящую стратегию на основе преобладающих рыночных условий: Order Blocks для нейтральных/боковых рынков, Break of Structure для сильных трендовых сред и Fair Value Gaps для переходных сценариев пробоя. Советник включает комплексную визуальную отрисовку с управлением графическими объектами, привязанным к сделкам: графические элементы рисуются только от момента их возникновения до времени исполнения сделки и автоматически очищаются при закрытии сделок, сохраняя график чистым. Мы также улучшили Break of Structure, чтобы он четко показывал направление структурных пробоев, что позволяет трейдерам сразу видеть направление рыночных движений.

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

Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/20414

Прикрепленные файлы |
SMC_Sent.mq5 (109.63 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (16)
chhotu choudhary
chhotu choudhary | 13 дек. 2025 в 17:40
Мне нужен этот советник. Можно ли сначала посмотреть демо-версию? И сколько он стоит?
Juvenille Emperor Limited
Eleni Anna Branou | 13 дек. 2025 в 19:31
chhotu choudhary #:
Мне нужен этот советник. Можно ли сначала посмотреть демо-версию? И сколько он стоит?
Пожалуйста, прочтите статью в первом сообщении этой темы.
Hlomohang John Borotho
Hlomohang John Borotho | 17 дек. 2025 в 12:34
YDILLC #:
Друг мой, ты уверен, что это те же самые параметры для бэктеста? Возможно, что-то не так, но я ввёл точно такие же настройки — и счет просто разрывается.
Результаты могут различаться — иногда это связано с вашим брокером или типом счёта.
Hlomohang John Borotho
Hlomohang John Borotho | 17 дек. 2025 в 12:35
Ariston Hutauruk #:
Спасибо, друзья, ваш код мне очень помог
Не за что.
Hlomohang John Borotho
Hlomohang John Borotho | 17 дек. 2025 в 12:37
GL99K приложенном изображении — скриншот моего результата.


Выражаю глубокое уважение Хломохангу Джону Борото за его глубокую и всестороннюю работу. Думаю, у него, должно быть, отличные знания по математике, физике и информатике. Да благословит его Господь.

Спасибо, пожалуйста.
Рыночные секреты Ларри Уильямса (Часть 8): Объединение волатильности, структуры и временных фильтров Рыночные секреты Ларри Уильямса (Часть 8): Объединение волатильности, структуры и временных фильтров
Подробный разбор создания советника MQL5 для торговли пробоями волатильности, вдохновленного идеями Ларри Уильямса: свинг-структура, входы на основе волатильности, фильтр торгового дня недели, временные фильтры и гибкое управление риском, с полной реализацией и воспроизводимой тестовой конфигурацией.
Моделирование рынка: Position View (IV) Моделирование рынка: Position View (IV)
Здесь мы начнем объединять различные компоненты или приложения, которые ранее были полностью изолированы друг от друга. Chart Trade, индикатор мыши и советник уже были связаны между собой, однако всё ещё отсутствовал способ прямой визуализации на графике открытых на торговом сервере позиций, которые зачастую обрабатывались через систему встречных ордеров. С этого момента это становится возможным, открывая путь для различных идей и будущих реализаций. Хотя мы только начинаем внедрять эти компоненты в работу, у нас уже появится направление для дальнейшего развития.
Преодоление проблем доступности в торговых инструментах на MQL5 (Часть III): Двунаправленное голосовое взаимодействие между трейдером и советником Преодоление проблем доступности в торговых инструментах на MQL5 (Часть III): Двунаправленное голосовое взаимодействие между трейдером и советником
Создадим локальный двунаправленный голосовой интерфейс для MetaTrader 5 с помощью WebRequest в MQL5 и двух сервисов Python. В статье реализовано автономное распознавание речи с помощью Vosk, обнаружение фразы активации, HTTP‑endpoint для получения команд и сервер преобразования текста в речь на локальном хосте. Вы подключите советника, который будет получать команды, открывать сделки и возвращать голосовые подтверждения для возможности работать без помощи рук.
Рыночные секреты Ларри Уильямса (Часть 7): Эмпирическое исследование концепции "торгового дня недели" Рыночные секреты Ларри Уильямса (Часть 7): Эмпирическое исследование концепции "торгового дня недели"
Эмпирическое исследование концепции торгового дня недели по Ларри Уильямсу: как измерять, тестировать и применять временную поведенческую закономерность рынка с помощью MQL5. В статье представлена структурированная методика анализа для анализа win rate (процент прибыльных сделок) и результатов по торговым дням, чтобы улучшать краткосрочные торговые системы.