English Deutsch
preview
Adaptive Smart Money Architecture (ASMA):SMCロジックと市場センチメントを統合した動的戦略切替システム

Adaptive Smart Money Architecture (ASMA):SMCロジックと市場センチメントを統合した動的戦略切替システム

MetaTrader 5 |
31 16
Hlomohang John Borotho
Hlomohang John Borotho

目次

  1. はじめに
  2. 戦略の概要
  3. 導入手順
  4. バックテスト結果
  5. 結論


はじめに

これまでの開発フェーズにおいて、Order Block (OB)、Fair Value Gap (FVG)、Break of Structure (BOS)を1つの統合されたSmart Money Concept(スマートマネーコンセプト)エンジンとして組み合わせることに成功しました。これにより、機関投資家の売買動向を高精度で読み取る強力なフレームワークを構築しています。さらに、トレンドの強さ、ボラティリティの状態、モメンタムの一致を解釈し、市場を強気、弱気、中立の状態に分類するカスタムの市場センチメントインジケーターも設計しました。これら2つの成果により、構造的な値動きとリアルタイムのセンチメントを単一の適応型売買システムとして統合するための土台が整いました。

続く本フェーズでは、市場の状況に応じて戦略を動的に切り替えるインテリジェントなEAの構築に焦点を当てます。固定的なパターンに依存するのではなく、センチメントインジケーターを活用して現在の市場環境(レジーム)を判定し、それに応じて最適なOB、BOS、FVG戦略を自動的に選択します。具体的には、強気相場ではBOSを用いたトレンドフォロー戦略を優先し、反転局面ではOBベースの反発を重視します。また、レンジやボラティリティ収縮局面ではFVGを活用した平均回帰戦略へと切り替えます。このように、構造分析とセンチメント駆動の適応性を融合させることで、市場に応じて自律的に判断して進化し、まるで機関トレーダーのようにポジションを構築する売買システムの実現に近づきます。


戦略の概要:市場センチメント主導型SMC売買システム

このインテリジェントな売買システムは、3つの主要なSmart Money Concept (SMC)戦略であるOrder Block (OB)、Fair Value Gap (FVG)、Break of Structure (BOS)をリアルタイムの市場センチメント分析と統合することで、適応的かつコンテキスト認識型の売買アルゴリズムを実現します。システムはマルチタイムフレーム構造で動作し、高時間足 (H4)、中時間足 (H1)、低時間足 (M30)にわたる値動きを分析することで、全体的な市場バイアスおよびセンチメントを判断します。Strong BullishからStrong Bearish、Risk-OnからRisk-Off、さらにNeutralといったセンチメントの判定結果に基づき、EAは最適なSMC戦略を動的に選択し、優先順位付けします。これにより、単一の戦略に依存するのではなく、現在の市場環境に適合した取引判断が可能になります。

Neutral市場センチメント + Order Block戦略

市場が中立的な状態にある場合(移動平均線付近での価格の収束、および高時間足における明確な方向性バイアス(方向性の偏り)の欠如が特徴)、システムはOrder Block (OB)戦略を主要な取引手法として有効化します。Neutralセンチメントは通常、レンジ相場を示唆し、価格は明確な方向性モメンタムを伴わずに、既存のサポートおよびレジスタンスの間で振動します。このような環境において、OBは非常に有効に機能します。なぜなら、過去に機関投資家の注文が蓄積された領域を特定し、流動性が反応しやすいゾーンとして機能するためです。EAは具体的に、大陽線(Strong Bull candle)に続く陰線で構成される強気のOB、および大陰線(Strong Bear candle)に続く陽線で構成される弱気のOBを検出します。これらは顕著なオーダーフローの不均衡を示します。価格がこれらのOBゾーンへリトレースした際、システムは平均回帰を想定してエントリーし、レンジ相場における「過去の注文蓄積領域が尊重されやすい」という市場特性を活用します。

トレンド市場(強気/弱気)+ Break of Structure戦略

Strong BullishまたはStrong Bearishといった明確なトレンドセンチメントが検出され、かつ複数の時間足で方向性が一致している場合、システムはBreak of Structure (BOS)戦略を優先し、モメンタムの継続を捉えます。トレンド市場では、強気であれば高値・安値の切り上げ、弱気であれば高値・安値の切り下げといった構造が形成されます。BOSは、こうした市場構造がブレイクされたポイントを特定し、既存トレンド方向への加速の可能性を示唆します。EAは、強気トレンドにおいては直近のスイングハイの上抜け、弱気トレンドにおいてはスイングローの下抜けを監視し、これらのブレイクを流動性の刈り取りとして解釈します。これはしばしば継続的な方向性のある動きに先行します。この戦略はトレンド環境と高い整合性を持ち、構造的な確認後にトレンド方向へエントリーすることに特化しています。そのため、強いトレンド局面において勝率の低い逆張りを回避することができます。

Risk-On / Risk-Offセンチメント + Fair Value Gaps戦略

Risk-OnまたはRisk-Offといった市場環境(レンジブレイクと高位足バイアスの一致が特徴)においては、システムはFair Value Gap (FVG)戦略を適用します。これらの状況は、価格が一定期間レンジ内で推移した後、急激なモメンタム拡大が発生し、連続するローソク足間に取引の少ないギャップ(価格の空白領域)が形成される際に見られます。EAは、このような需給の不均衡ゾーンを特定し、価格がいずれその「公正価値(フェアバリュー)」へ回帰すると想定します。特に、FVGのミッドポイント(50%レベル)でのエントリーをおこない、ボラティリティの高いブレイクアウト局面において最適なリスクリワードを確保します。このアプローチは、価格が非効率な領域を埋める傾向と、全体的な方向性バイアスの両方を活用するものであり、モメンタムが形成されつつあるがトレンドが完全には確立されていない移行局面において特に有効です。

導入手順

//+------------------------------------------------------------------+
//|                                                     SMC_Sent.mq5 |
//|                        GIT under Copyright 2025, MetaQuotes Ltd. |
//|                     https://www.mql5.com/ja/users/johnhlomohang/ |
//+------------------------------------------------------------------+
#property copyright "GIT under Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com/ja/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ライブラリをインクルードします。これにより、EAにおける取引処理およびデータ管理の基盤を構築します。最初のセクションでは、市場センチメントコンポーネントに関するすべての入力パラメータを定義します。このコンポーネントは、H4、H1、M30といった複数の時間足のデータを読み取り、処理をおこないます。具体的には、200期間移動平均、スイングのルックバック、ATRの閾値などのツールを使用します。これらのパラメータはカスタムセンチメントエンジン(MARKSENT)に属しており、市場環境を強気、弱気、Risk-On、Risk-Off、Neutralといった状態に分類するために使用されます。複数時間足を統合的に分析することで、EAは現在の市場の方向性およびボラティリティ特性をより高精度に把握します。

次のセクションでは、取引設定および戦略選択について定義します。この部分により、EAの動作に柔軟性を持たせることができます。ロットサイズ、ストップロス、テイクプロフィット、マジックナンバー、オブジェクト描画制御といった入力パラメータは、注文の実行方法およびチャート上での可視化方法を決定します。さらに重要なのは、戦略選択ブロックにより、市場センチメントへの反応の有効と無効を切り替えたり、BOS、OB、FVGの各ロジックを個別に有効化できる点です。これにより、EAはセンチメントのみに基づく取引構成、SMCパターンのみに基づく構成、あるいはセンチメント状態に応じて戦略を自動的に切り替えるハイブリッド構成として動作させることが可能になります。さらに、カスタマイズ可能なビジュアル設定と組み合わせることで、機能性とチャート上での視認性の両立を実現します。

続いて、リアルタイム計算に必要なグローバル変数およびバッファをすべて設定します。これには、上位足および下位足の移動平均のハンドル、センチメント状態のトラッキング、SMC戦略のアクティビティ管理などが含まれます。currentSentiment、currentSentimentText、currentStrategyといった変数は、意思決定の中核を担う要素です。これらは現在の市場状態および次に適用されるべき戦略を保持します。EAは継続的にBid/Ask価格を更新し、新しいバーの発生を検知するとともに、チャート上の古いSMCオブジェクトを適切に削除して可視化を最適化します。これらのグローバルコンポーネントを統合することで、市場センチメントとSmart Money Conceptを結び付けるコアフレームワークが構築されます。その結果、市場の変化に応じてロジックを動的に調整する適応型売買システムが実現されます。

// 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構造体を定義します。この構造体は、EAによって開かれたポジションに関するすべての重要情報を保持します。具体的には、チケット番号、銘柄、エントリー時刻、建値、注文タイプ、使用された戦略、マジックナンバーなどが含まれます。デフォルトコンストラクタでは、すべてのフィールドを安全な「空」の状態で初期化します。これにより、EAが取引データを処理または保存する際に、未初期化の値によるロジックエラーが発生するのを防ぎます。この構造体は、特に本システムのような適応型かつマルチストラテジーのEAにおいて重要な役割を果たします。なぜなら、各ポジションがどの戦略(OB、FVG、BOS)によって発生したかを追跡できるため、パフォーマンス分析、後処理(クリーンアップ)、あるいは戦略別のポジション管理といった機能を実現できるからです。

OnInit()関数およびOnDeinit()関数は、EA全体の初期化と終了処理をそれぞれ担当します。初期化時(OnInit())には、EAはマジックナンバーを設定し、一意なインジケーター名を準備するとともに、市場センチメントエンジンで使用される複数時間足の移動平均ハンドルをすべて生成します。また、配列をシリーズ形式として設定し、検出されたSMC構造(FVG、BOSゾーン、取引済みOB)やアクティブなポジションを管理するためのオブジェクトコンテナを確保します。さらに、チャート上でのモニタリング用にコントロールパネルを作成し、動的なSMCおよび戦略切り替えロジックが準備完了であることを通知します。一方、OnDeinit()では、インジケーターハンドルの解放、動的に確保されたSMCオブジェクトの削除、ポジション配列のクリア、そしてチャート上に描画されたすべてのOB/FVG/BOSオブジェクトの削除をおこない、クリーンな状態で終了します。専用のCleanupAllObjects()関数は、SMC命名規則に一致するグラフィカルオブジェクトを体系的に削除することで、チャート環境を常に整理された状態に保つ役割を担います。これらの処理を組み合わせることで、EAはクリーンに初期化され、メモリを適切に管理し、削除時にも不要なオブジェクトを残さない堅牢な動作を実現します。

// 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値を取得します。価格と移動平均の位置関係を確認することで高時間足の方向性を判断し、同時に IsBullishStructure、IsBearishStructure、HasBreakout などの関数を用いて低時間足の構造も分析します。これらのトレンド、構造、ブレイクアウトといった複数の分析レイヤーは DetermineSentimentに渡され、Strong Bullish (1)からRisk-off (-2)までの範囲でセンチメント分類を返します。数値的なセンチメントが決定されると、EAはパネル表示用に「Bullish」「Bearish」などの説明ラベルを割り当てます。

その後の戦略選択ロジックでは、このセンチメント出力を用いて、EAがどのSMC手法で取引するかを動的に決定します。センチメントフィルタリングが無効な場合、EAは単純にすべてのストラテジーを有効化します。しかしフィルターが有効な場合、EAは市場状況に応じて適応的に振る舞います。Strong BullishやStrong BearishではBOS継続トレードが有効化され、ブレイクアウト主導のRisk-On、Risk-OffではFVGのインバランスを利用した取引が優先されます。また、Neutral(レンジ相場)ではOBの反転戦略が重視されます。このようにして、EAは市場センチメントと価格挙動に基づき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;
}

この関数は、EAによって実行されるすべての取引が、戦略的に承認され、かつセンチメントに整合していることを保証し、市場の支配的な状況に反する取引が行われるのを防ぐ安全レイヤーとして機能します。まず、取引が有効化されているかどうか、そして選択されたSMC戦略(BOS、OB、FVG)が現在許可されているかどうかを確認します。次に最新の市場センチメントを取得し、意図された注文方向がそのセンチメントと一致しているかを検証します。たとえば、買い注文は強気またはRisk-Onの状況でのみ許可され、売り注文は弱気またはRisk-Offのセンチメントでのみ許可されます。

中立的な市場では取引は許可されますが、より慎重な扱いとなります。センチメントと戦略が一致している場合、関数は正規化されたストップロス(SL)およびテイクプロフィット(TP)レベルを計算し、EAのマジックナンバーを設定した上で、使用された戦略とセンチメントを記述したコメント付きで新規ポジションを開きます。成功した取引は詳細情報とともにログに記録され、センチメントがどのように注文執行に影響したかが完全に追跡できるよう、透明性が確保されます。

// 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;
}

これらのヘルパー関数は、複数時間足における価格挙動を評価し、それを方向性バイアスへと変換することで、EAのセンチメントエンジンの分析的な基盤を形成します。GetHigherTFBias()は、高時間足の移動平均と現在価格を比較し、その方向性と乖離の大きさの両方を用いて、市場が強気トレンド、弱気トレンド、あるいは明確な方向性を持たない状態かを判断します。次にIsBullishStructure()とIsBearishStructure()は、直近のスイングハイやスイングローを比較することで市場の構造を分析します。より高い高値・より高い安値の形成は強気構造を確認し、より低い高値・より低い安値の形成は弱気構造を確認します。これらの関数はノイズに反応するのではなく、本質的な構造変化を検出する役割を担います。

HasBreakout()関数は動的な要素を追加し、価格が直近のスイングレベルをブレイクしているかどうかを高時間足のバイアスと整合させてチェックします。たとえば強気環境では、価格が直近のスイングハイを上抜けした場合のみ、それを有効なブレイクアウトとして扱い、モメンタム継続のシグナルとみなします。トレンドの偏り、構造的な方向性、ブレイクアウトの確認という3つの要素を統合することで、EAは堅牢なマルチタイムフレームセンチメントを生成します。このセンチメントは、戦略選択の指針として機能し、取引のフィルタリングや市場環境への適応を可能にします。

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()関数はセンチメントエンジンにおける最終的な判断レイヤーとして機能し、高時間足のトレンド方向と低時間足の構造、およびブレイクアウトの確認を統合します。この関数はセンチメントを「Strong Bullish」「Strong Bearish」「Risk-On」「Risk-Off」「Neutral」の5つの状態に分類し、各時間足の整合性に基づいて判定をおこないます。すべての時間足が同じ方向に一致している場合は、その方向においてStrongセンチメントとして分類されます。一方で、ブレイクアウトのモメンタムのみが高時間足のトレンドと一致している場合は、Risk-OnまたはRisk-Offの環境へと移行します。条件が矛盾している、あるいは明確な優位性が確認できない場合は「中立」に分類され、EAが積極的または不整合な判断をおこなうことを防ぎます。

OnTick()関数はEAのメイン実行ワークフローを制御し、市場センチメント、戦略選択、および取引実行を統合します。新しいバーが形成されるたびに、EAはオブジェクトのクリーンアップを実行し、センチメントを再計算し、現在のセンチメント状態に基づいて最適な戦略(BOS、OB、FVG、またはすべて)を選択します。その後、対応する検出モジュールと取引モジュールが有効化され、システムはリアルタイムで市場状況に適応します。これにより、単一の取引手法に依存するのではなく、市場がトレンド相場、レンジ相場、あるいはブレイクアウト局面のいずれであるかに応じて戦略を動的に切り替えるインテリジェントなエンジンが実現されます。

最後に DisplayStatus()関数は、トレーダーに対してEA内部状態のリアルタイムな構造化サマリーを表示することで透明性を向上させます。これには検出されたSMCパターン、現在のセンチメントレベル、アクティブな戦略、および取引が有効かどうかの状態が含まれます。この視覚的フィードバックにより、ユーザーはEAがどのような根拠で意思決定をおこなっているのかを明確に理解できるため、信頼性の向上に加え、監視およびデバッグの容易さにもつながります。



バックテスト結果

以下のバックテストは、H1時間足において約2か月間(2025年10月1日〜2025年12月1日)の期間で評価されました。設定は以下の通りです。

以下はエクイティカーブとバックテストの結果です。


結論

本プロジェクトでは、Order Block、Fair Value Gap、Break of Structureという3つの主要なSmart Money Concept (SMC)戦略を、リアルタイムのマルチタイムフレームセンチメント分析と統合することで、インテリジェントなSMC売買EAを開発しました。市場状況に応じて最適な戦略を自動的に選択するダイナミックな仕組みを構築しました。具体的には、レンジまたは中立的な市場ではOrder Block、強いトレンド環境ではBreak of Structure、そして転換的なブレイクアウト局面ではFair Value Gapを適用しました。また、取引ベースのオブジェクト管理による包括的なビジュアル描画機能を備えており、描画要素はその起点から取引執行時点までのみ表示され、ポジション決済時には自動的に削除されます。これにより、常に整理された見やすいチャートを維持できます。さらに、Break of Structureについては、構造のブレイク方向が明確に視覚化されるよう改良し、市場の動きを直感的に把握できるようにしました。

結論として、この高度なEAは、市場環境に応じてSMC戦略を適応的に切り替えるコンテキスト認識型の売買システムを提供します。これにより、戦略選択の迷いを排除し、適切な市場状況下での自動売買を実現することで、トレーダーは規律を維持しながら高確率のトレード機会を捉えることが可能になります。さらに、包括的なビジュアルフィードバックにより市場構造の理解をリアルタイムで深めることができ、自動クリーンアップ機能によって常に最適なチャート環境が保たれます。この統合的なアプローチは、取引の効率向上に加え、さまざまな市場状況におけるSMC戦略の有効性を学ぶ教育的枠組みも提供し、最終的にはトレーダーの市場理解力およびリスク管理能力の向上に寄与します。

MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/20414

添付されたファイル |
SMC_Sent.mq5 (109.63 KB)
最後のコメント | ディスカッションに移動 (16)
chhotu choudhary
chhotu choudhary | 13 12月 2025 において 17:40
このeaが欲しいのですが、まずデモをお願いできますか?
Juvenille Emperor Limited
Eleni Anna Branou | 13 12月 2025 において 19:31
chhotu choudhary #:
このeaが欲しいのですが、まずデモをお願いできますか?
このトピックの最初の投稿の記事をお読みください。
Hlomohang John Borotho
Hlomohang John Borotho | 17 12月 2025 において 12:34
YDILLC #:
本当に同じバックテスト入力ですか?何かがずれているかもしれませんが、私はそれらと全く同じ設定を入力し、口座を爆破しています。
ブローカーや口座の種類によって結果が異なることがあります。
Hlomohang John Borotho
Hlomohang John Borotho | 17 12月 2025 において 12:35
Ariston Hutauruk #:
友人たちに感謝します。
どういたしまして。
Hlomohang John Borotho
Hlomohang John Borotho | 17 12月 2025 において 12:37
GL99K 添付の画像は 私の出力のスクリーンショットです。


フロモハン・ジョン・ボロトの 洞察に満ちた包括的な仕事に敬意を表する。彼は数学、物理学、コンピューター・サイエンスの優れたバックグランドを持っているに違いない。神のご加護を。

ありがとう。
Codexパイプライン:PythonからMQL5へ ― FXI ETFを対象とした複数四半期の指標分析 Codexパイプライン:PythonからMQL5へ ― FXI ETFを対象とした複数四半期の指標分析
MetaTraderを本来のFX取引という「コンフォートゾーン」の外でどのように活用できるかという検討を継続し、FXI ETFという別の取引可能資産に着目します。前回の記事では、指標の選定にとどまらず、指標間のパターンの組み合わせにまで踏み込み、やや過度に複雑化した側面がありました。本記事では一歩引いて、指標選定そのものに焦点を当てます。最終的には、十分な価格履歴データが存在する場合に、さまざまな資産に対して適切な指標を推奨できるパイプラインの構築を目指します。
機械学習の限界を克服する(第9回):自己教師あり学習を用いた金融における相関ベース特徴学習 機械学習の限界を克服する(第9回):自己教師あり学習を用いた金融における相関ベース特徴学習
自己教師あり学習は、観測値そのものから生成された教師信号を探索する統計学習の強力なパラダイムです。このアプローチは、教師なし学習における困難な問題を、より馴染みのある教師あり学習問題へと再定式化します。この技術は、アルゴリズムトレーダーコミュニティの目的に対して、見過ごされてきた応用可能性を持っています。したがって本記事の議論は、読者に対して自己教師あり学習という未開拓の研究領域への橋渡しを提供し、さらに小規模データセットへの過学習を回避しながら、金融市場の頑健で信頼性の高い統計モデルを提供する実践的応用を提示することを目的としています。
MQL5における取引戦略の自動化(第46回):Liquidity Sweep on Break of Structure (BoS) MQL5における取引戦略の自動化(第46回):Liquidity Sweep on Break of Structure (BoS)
MQL5においてLiquidity Sweep on Break of Structure (BoS)システムを構築します。このシステムは、ユーザーが定義した期間に基づいてスイングハイとスイングローを検出し、それらをHH (Higher High) / HL (Higher Low) /LH (Lower High) /LL (Lower Low)としてラベル付けすることでBoS(上昇トレンドにおけるHH、下降トレンドにおけるLL)を識別します。また、価格がスイングをヒゲで一時的にブレイクした後、再び終値がスイング内に戻る場合を流動性スイープとして検出します。
MQL5でかぎ足をマスターする(第2回):かぎ足ベース自動売買の実装 MQL5でかぎ足をマスターする(第2回):かぎ足ベース自動売買の実装
MQL5を用いたかぎ足ベースの取引エキスパートアドバイザー(EA)の構築方法を学びます。シグナル構築から注文執行、視覚的なマーカーの表示、さらに3段階トレーリングストップに至るまでを扱い、完全なコード、テスト結果、およびダウンロード可能なセットファイルを含みます。