English Deutsch
preview
MQL5でのカスタム市場レジーム検出システムの構築(第1回):インジケーター

MQL5でのカスタム市場レジーム検出システムの構築(第1回):インジケーター

MetaTrader 5トレーディング |
124 5
Sahil Bagdi
Sahil Bagdi
  1. はじめに
  2. 市場レジームについて
  3. 統計基盤の構築
  4. 市場レジーム検出器(Market Regime Detector)の実装
  5. レジーム可視化のためのカスタムインジケーターの作成
  6. 結論


はじめに

金融市場は常に変化し続けており、強いトレンド、レンジ相場(横ばい)、そして混沌とした高ボラティリティ局面が次々に入れ替わります。これは、アルゴリズムトレーダーにとって大きな課題です。トレンド相場で好成績を収める戦略も、レンジ相場では機能しないことが多く、逆に低ボラティリティ向けの戦略は、急激な変動により大きな損失を招くこともあります。それにもかかわらず、多くの取引システムは、市場の挙動が時間を通じて一貫しているという暗黙の前提に基づいて設計されています。

この前提と市場の現実との間にある根本的なギャップこそが、戦略のパフォーマンス低下というよくある問題を引き起こしているのです。システムがバックテストや初期運用では好成績を残しても、市場環境が変化するとパフォーマンスが急落する。そんな場面に直面したトレーダーは、戦略を破棄して一からやり直すか、市場が再び自分の手法に合うまで損失に耐えるかという、難しい選択を迫られます。

では、もっと優れたアプローチがあるとしたらどうでしょう?もし取引システムが現在の市場レジーム(相場環境)を客観的に認識し、それに応じて戦略を柔軟に適応できたとしたら?本記事ではまさにその実現を目指し、MQL5を用いて市場環境を明確に分類する「市場レジーム検出システム(Market Regime Detection System)」を構築します。これを基盤に、適応型の取引戦略を展開していきます。

本連載の終わりには、以下を含む市場レジーム検出システムの完全実装を手に入れることができます。
  1. 市場を客観的に分類するための堅牢な統計的基盤
  2. トレンド・レンジ・高ボラティリティといった相場環境を識別する、カスタム市場レジーム検出クラス
  3. レジームの変化をチャート上に視覚化するカスタムインジケーター
  4. 現在のレジームに応じて適切な戦略を自動で選択する適応型エキスパートアドバイザー(第2回)
  5. 実際の取引に即したパラメータ設定や最適化の例(第2回)

このシステムは、既存のアルゴリズム戦略を強化したい経験豊富なトレーダーにも、より堅牢な戦略構築を目指す初心者の方にも、有用なものです。変化の激しい金融市場を乗り越えるための、実践的かつ強力なツールとなるでしょう。


市場レジームについて

実装の詳細に入る前に、市場レジームとは何か、そしてそれがトレーダーにとってなぜ重要なのかを理解することが重要です。市場は常に一様に動くわけではなく、異なる行動パターンや「レジーム」の間を移行していきます。これらのレジームは価格の動きに大きな影響を与え、それに伴って取引戦略の成績も大きく変わります。

市場レジームとは

市場レジームとは、価格変動の特定の統計的性質によって特徴付けられる、市場行動の明確に異なるパターンのことです。市場レジームの分類には様々な方法がありますが、ここでは取引戦略の開発に最も関連性が高い3つの主要なタイプに注目します。
  1. トレンドレジーム:市場が強い方向性を持って動き、平均回帰がほとんど見られません。価格は一方向に継続的に動き、押し戻しも浅い傾向があります。統計的には、トレンド相場はリターンの自己相関が正であり、一方向の動きが次の動きも同じ方向になる可能性が高いことを示します。
  2. レンジレジーム:市場はサポートとレジスタンスの間で振動し、強い平均回帰傾向を持ちます。価格はどちらかの方向にブレイクアウトするのではなく、定義された範囲内で跳ね返る傾向があります。統計的には、レンジ相場はリターンの自己相関が負であり、上昇の後には下降が来やすく、逆もまた然りです。
  3. 高ボラティリティレジーム:市場は大きく、不規則な価格変動を経験し、方向性が明確でない状態です。これは不確実性、ニュースイベント、市場のストレス期に多く見られます。統計的には、高ボラティリティ相場はリターンの標準偏差が高く、自己相関パターンは予測不可能です。

現在の市場がどのレジームにあるかを理解することは、取引の意思決定において非常に重要な文脈を提供します。トレンド相場に最適化された戦略はレンジ相場での成績が悪くなる可能性が高く、逆にレンジ相場向けの平均回帰戦略は強いトレンドが発生すると大きな損失を招くことがあります。

従来のインジケーターでは不十分な理由

多くのテクニカル指標は、特定の価格パターンや市場の状態を捉えるために設計されており、市場レジームを分類することを目的としていません。以下はその例です。
  • 移動平均線やMACDはトレンドを検出するのに有効ですが、「トレンド相場」と「ボラティリティが高いだけの相場」とを区別することはできません。
  • RSIやストキャスティクスはレンジ相場で効果を発揮しますが、トレンドが発生している場面では誤ったシグナルを出すことが多くなります。
  • ボリンジャーバンドはボラティリティに適応しますが、レジームの転換を明確に識別するものではありません。
こうした限界により、多くの取引システムには大きな盲点が生じます。現在の市場レジームを知らないままでは、トレーダーは市場環境が自分の戦略の前提に合っていることを「期待するだけ」で戦略を適用している状態になります。これは、状況に応じた判断とは言えず、手探りで取引しているようなものです。

レジーム検出の統計的基盤

効果的な市場レジーム検出システムを構築するには、市場の挙動を客観的に分類するための統計的指標を活用する必要があります。このプロジェクトで使用する主な統計概念は以下のとおりです。
  1. 自己相関:時系列データとその遅延バージョンとの相関を測定します。正の自己相関はトレンド傾向を、負の自己相関は平均回帰傾向(レンジ)を示します。
  2. ボラティリティ:通常はリターンの標準偏差で測定され、価格変動の激しさを表します。ボラティリティの急上昇は、レジームの変化を示唆することがあります。
  3. トレンドの強さ:自己相関の絶対値、線形回帰の傾き、あるいはADXのような専用インジケーターを用いて定量化できます。

これらの統計指標を組み合わせることで、市場レジームを客観的かつ堅牢に分類できるフレームワークを構築することが可能になります。次のセクションでは、これらの概念をMQL5のコードに実装し、実際の「市場レジーム検出システム」を構築していきます。


統計基盤の構築

このセクションでは、市場レジーム検出システムに必要な統計的コア要素を実装していきます。ここでは、レジーム分類に必要なすべての数学的計算を処理する、堅牢なCStatisticsクラスを作成します。

CStatisticsクラス

私たちのレジーム検出システムの土台となるのは、価格データに対して様々な計算を実行できる高機能な統計クラスです。以下では、このクラスの主要な構成要素について解説していきます。

//+------------------------------------------------------------------+
//| Class for statistical calculations                               |
//+------------------------------------------------------------------+
class CStatistics
{
private:
    double      m_data[];           // Data array for calculations
    int         m_dataSize;         // Size of the data array
    bool        m_isSorted;         // Flag indicating if data is sorted
    double      m_sortedData[];     // Sorted copy of data for percentile calculations
    
public:
    // Constructor and destructor
    CStatistics();
    ~CStatistics();
    
    // Data management methods
    bool        SetData(const double &data[], int size);
    bool        AddData(double value);
    void        Clear();
    
    // Basic statistical methods
    double      Mean() const;
    double      StandardDeviation() const;
    double      Variance() const;
    
    // Range and extremes
    double      Min() const;
    double      Max() const;
    double      Range() const;
    
    // Time series specific methods
    double      Autocorrelation(int lag) const;
    double      TrendStrength() const;
    double      MeanReversionStrength() const;
    
    // Percentile calculations
    double      Percentile(double percentile);
    double      Median();
};

このクラスは、価格データを分析し、現在の市場レジームを判別するための統計関数を網羅的に提供します。それでは、主要なメソッドのいくつかを詳しく見ていきましょう。

コンストラクタとデストラクタ

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CStatistics::CStatistics()
{
    m_dataSize = 0;
    m_isSorted = false;
    ArrayResize(m_data, 0);
    ArrayResize(m_sortedData, 0);
}

//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CStatistics::~CStatistics()
{
    Clear();
}

コンストラクタとデストラクタは、クラスの初期化とクラスの初期化解除に役立ちます。 コンストラクタはメンバー変数と配列を初期化し、デストラクタはClearメソッドを呼び出して適切なクリーンアップを確実におこないます。適切な初期化とクリーンアップの徹底は、MQL5におけるメモリリークの防止や安定した動作の確保において非常に重要です。

データ管理メソッド


次に、データを設定、追加、消去できるデータ管理メソッドを実装しましょう。

bool CStatistics::SetData(const double &data[], int size)
{
    if(size <= 0)
        return false;
        
    m_dataSize = size;
    ArrayResize(m_data, size);
    
    for(int i = 0; i < size; i++)
        m_data[i] = data[i];
        
    m_isSorted = false;
    return true;
}

bool CStatistics::AddData(double value)
{
    m_dataSize++;
    ArrayResize(m_data, m_dataSize);
    m_data[m_dataSize - 1] = value;
    m_isSorted = false;
    return true;
}

void CStatistics::Clear()
{
    m_dataSize = 0;
    ArrayResize(m_data, 0);
    ArrayResize(m_sortedData, 0);
    m_isSorted = false;
}
                        

SetDataメソッドは、データ全体を新しい配列に置き換えることができます。これは、過去の価格データを処理する際に便利です。一方、AddDataメソッドは、1つの値を既存のデータに追加するためのもので、新しい価格データが到着したときに段階的な更新を行う際に役立ちます。Clearメソッドは、オブジェクトを初期状態にリセットし、割り当てられたメモリを解放します。

なお、データが変更されるたびに「m_isSorted = false」と設定していることに注目してください。このフラグは、パーセンタイル計算の際にのみ必要に応じてソートをおこなうことで、パフォーマンスの最適化に役立ちます。

基本的な統計メソッド

次に、平均、標準偏差、分散を計算するための基本的な統計メソッドを実装していきましょう。

double CStatistics::Mean() const
{
    if(m_dataSize <= 0)
        return 0.0;
        
    double sum = 0.0;
    for(int i = 0; i < m_dataSize; i++)
        sum += m_data[i];
        
    return sum / m_dataSize;
}

double CStatistics::StandardDeviation() const
{
    if(m_dataSize <= 1)
        return 0.0;
        
    double mean = Mean();
    double sum = 0.0;
    
    for(int i = 0; i < m_dataSize; i++)
        sum += MathPow(m_data[i] - mean, 2);
        
    return MathSqrt(sum / (m_dataSize - 1));
}

double CStatistics::Variance() const
{
    if(m_dataSize <= 1)
        return 0.0;
        
    double stdDev = StandardDeviation();
    return stdDev * stdDev;
}

これらのメソッドは、標準的な統計の公式に基づいて実装されています。Meanメソッドは、すべてのデータ点の平均値を計算します。StandardDeviationメソッドは、データが平均からどの程度散らばっているか、つまり分布のばらつき(散布度)を測定します。これは、ボラティリティの高い市場レジームを識別する上で非常に重要です。Varianceメソッドは標準偏差の二乗で、同じくデータの分散性を示す指標です。

また、データが空である場合や、要素数が1つだけのケースにも注意して、ゼロを返すように設計されています。このような防御的プログラミングにより、十分なデータが揃っていない状況でもエラーを回避し、プログラムの安定性を確保することができます。

範囲と極値のメソッド

//+------------------------------------------------------------------+
//| Calculate minimum value in the data                              |
//+------------------------------------------------------------------+
double CStatistics::Min() const
{
    if(m_dataSize <= 0)
        return 0.0;
        
    double min = m_data[0];
    for(int i = 1; i < m_dataSize; i++)
        if(m_data[i] < min)
            min = m_data[i];
            
    return min;
}

//+------------------------------------------------------------------+
//| Calculate maximum value in the data                              |
//+------------------------------------------------------------------+
double CStatistics::Max() const
{
    if(m_dataSize <= 0)
        return 0.0;
        
    double max = m_data[0];
    for(int i = 1; i < m_dataSize; i++)
        if(m_data[i] > max)
            max = m_data[i];
            
    return max;
}

//+------------------------------------------------------------------+
//| Calculate range (max - min) of the data                          |
//+------------------------------------------------------------------+
double CStatistics::Range() const
{
    return Max() - Min();
}
                            

これらのメソッドは、データの分布に関する追加情報を提供します。MinメソッドとMaxメソッドはそれぞれデータセット内の最小値と最大値を見つけ、Rangeメソッドはそれらの差を計算します。これらの値は、市場の値幅や急激な変動の兆候を判断する材料として使われます。

時系列特有メソッド

次に、レジーム検出に不可欠な時系列特有のメソッドを実装していきましょう。

double CStatistics::Autocorrelation(int lag) const
{
    if(m_dataSize <= lag || lag <= 0)
        return 0.0;
        
    double mean = Mean();
    double numerator = 0.0;
    double denominator = 0.0;
    
    for(int i = 0; i < m_dataSize - lag; i++)
    {
        numerator += (m_data[i] - mean) * (m_data[i + lag] - mean);
    }
    
    for(int i = 0; i < m_dataSize; i++)
    {
        denominator += MathPow(m_data[i] - mean, 2);
    }
    
    if(denominator == 0.0)
        return 0.0;
        
    return numerator / denominator;
}

double CStatistics::TrendStrength() const
{
    // Use lag-1 autocorrelation as a measure of trend strength
    double ac1 = Autocorrelation(1);
    
    // Positive autocorrelation indicates trending behavior
    return ac1;
}

double CStatistics::MeanReversionStrength() const
{
    // Negative autocorrelation indicates mean-reverting behavior
    double ac1 = Autocorrelation(1);
    
    // Return the negative of autocorrelation, so positive values
    // indicate stronger mean reversion
    return -ac1;
}

Autocorrelationメソッドは、データ系列とその遅延した系列との相関を計算します。これは、トレンド相場とレンジ相場を区別するための強力な指標です。正の自己相関(0より大きい値)はトレンド傾向を示し、負の自己相関(0より小さい値)は平均回帰(レンジ)傾向を示します。

TrendStrengthメソッドは、ラグ1の自己相関をトレンドの強さの直接的な指標として利用します。値が高く正のほど、トレンドが強いことを意味します。一方、MeanReversionStrengthメソッドは自己相関の符号を反転させて返し、正の値は平均回帰傾向が強いことを示します。

これらのメソッドは、私たちのレジーム検出システムの統計的基盤を形成し、市場の挙動を客観的に測定することでレジーム分類に活用されます。

パーセンタイル計算

最後に、パーセンタイルと中央値を計算するメソッドを実装しましょう。

double CStatistics::Percentile(double percentile)
{
    if(m_dataSize <= 0 || percentile < 0.0 || percentile > 100.0)
        return 0.0;
        
    // Sort data if needed
    if(!m_isSorted)
    {
        ArrayResize(m_sortedData, m_dataSize);
        for(int i = 0; i < m_dataSize; i++)
            m_sortedData[i] = m_data[i];
            
        ArraySort(m_sortedData);
        m_isSorted = true;
    }
    
    // Calculate position
    double position = (percentile / 100.0) * (m_dataSize - 1);
    int lowerIndex = (int)MathFloor(position);
    int upperIndex = (int)MathCeil(position);
    
    // Handle edge cases
    if(lowerIndex == upperIndex)
        return m_sortedData[lowerIndex];
        
    // Interpolate
    double fraction = position - lowerIndex;
    return m_sortedData[lowerIndex] + fraction * (m_sortedData[upperIndex] - m_sortedData[lowerIndex]);
}

double CStatistics::Median()
{
    return Percentile(50.0);
}

Percentileメソッドは、データの中で指定されたパーセンテージ以下に位置する値を計算します。まずデータをソート(未ソートの場合)し、その後線形補間を使って正確なパーセンタイル値を求めます。Medianメソッドは、50パーセンタイル、つまりデータセットの中央値を返す便利な関数です。

ここで注目すべきは、m_isSortedフラグによる最適化です。このフラグのおかげで、複数のパーセンタイルを計算する場合でもデータのソートは一度だけおこなわれます。これは、MQL5コードのパフォーマンスを向上させる慎重な実装例と言えます。

こうしてCStatisticsクラスが完成し、価格データの分析や市場レジーム検出に役立つ強力なツール群が揃いました。次のセクションでは、この基盤をもとに市場レジーム検出器クラスを構築していきます。


市場レジーム検出器(Market Regime Detector)の実装

統計的基盤が整ったので、システムの中核となるコンポーネントである市場レジーム検出器を構築します。このクラスは、先ほど実装した統計指標を活用して、市場状況を特定のレジームに分類します。

市場レジームの列挙

まず、システムが識別する市場レジームの種類を定義します。これを全コンポーネントで共有できるように、MarketRegimeEnum.mqhという別ファイルに列挙型を作成します。

// Define market regime types
enum ENUM_MARKET_REGIME
{
    REGIME_TRENDING_UP = 0,    // Trending up regime
    REGIME_TRENDING_DOWN = 1,  // Trending down regime
    REGIME_RANGING = 2,        // Ranging/sideways regime
    REGIME_VOLATILE = 3,       // Volatile/chaotic regime
    REGIME_UNDEFINED = 4       // Undefined regime (default) 
};

この列挙は、システムが検出できる5つの市場レジームを定義します。現在の市場の状態を表すために、実装全体でこれらの値を使用します。

CMarketRegimeDetectorクラス

市場レジーム検出器クラスは、これまでに構築した統計ツールとレジーム分類のロジックを組み合わせたものです。その構造を詳しく見ていきましょう。

class CMarketRegimeDetector
{
private:
    // Configuration
    int         m_lookbackPeriod;       // Period for calculations
    int         m_smoothingPeriod;      // Period for smoothing regime transitions
    double      m_trendThreshold;       // Threshold for trend detection
    double      m_volatilityThreshold;  // Threshold for volatility detection
    
    // Data buffers
    double      m_priceData[];          // Price data buffer
    double      m_returns[];            // Returns data buffer
    double      m_volatility[];         // Volatility buffer
    double      m_trendStrength[];      // Trend strength buffer
    double      m_regimeBuffer[];       // Regime classification buffer
    
    // Statistics objects
    CStatistics m_priceStats;           // Statistics for price data
    CStatistics m_returnsStats;         // Statistics for returns data
    CStatistics m_volatilityStats;      // Statistics for volatility data
    
    // Current state
    ENUM_MARKET_REGIME m_currentRegime; // Current detected regime
    
    // Helper methods
    void        CalculateReturns();
    void        CalculateVolatility();
    void        CalculateTrendStrength();
    ENUM_MARKET_REGIME DetermineRegime();
    
public:
    // Constructor and destructor
    CMarketRegimeDetector(int lookbackPeriod = 100, int smoothingPeriod = 10);
    ~CMarketRegimeDetector();
    
    // Configuration methods
    void        SetLookbackPeriod(int period);
    void        SetSmoothingPeriod(int period);
    void        SetTrendThreshold(double threshold);
    void        SetVolatilityThreshold(double threshold);
    
    // Processing methods
    bool        Initialize();
    bool        ProcessData(const double &price[], int size);
    
    // Access methods
    ENUM_MARKET_REGIME GetCurrentRegime() const { return m_currentRegime; }
    string      GetRegimeDescription() const;
    double      GetTrendStrength() const;
    double      GetVolatility() const;
    
    // Buffer access for indicators
    bool        GetRegimeBuffer(double &buffer[]) const;
    bool        GetTrendStrengthBuffer(double &buffer[]) const;
    bool        GetVolatilityBuffer(double &buffer[]) const;
};

このクラスは、市場レジームを検出するために必要なすべての機能をカプセル化します。それぞれのメソッドを実装してみましょう。

コンストラクタとデストラクタ

まず、コンストラクタとデストラクタを実装しましょう。

CMarketRegimeDetector::CMarketRegimeDetector(int lookbackPeriod, int smoothingPeriod)
{
    // Set default parameters
    m_lookbackPeriod = (lookbackPeriod > 20) ? lookbackPeriod : 100;
    m_smoothingPeriod = (smoothingPeriod > 0) ? smoothingPeriod : 10;
    m_trendThreshold = 0.2;
    m_volatilityThreshold = 1.5;
    
    // Initialize current regime
    m_currentRegime = REGIME_UNDEFINED;
    
    // Initialize buffers
    ArrayResize(m_priceData, m_lookbackPeriod);
    ArrayResize(m_returns, m_lookbackPeriod - 1);
    ArrayResize(m_volatility, m_lookbackPeriod - 1);
    ArrayResize(m_trendStrength, m_lookbackPeriod - 1);
    ArrayResize(m_regimeBuffer, m_lookbackPeriod);
    
    // Initialize buffers with zeros
    ArrayInitialize(m_priceData, 0.0);
    ArrayInitialize(m_returns, 0.0);
    ArrayInitialize(m_volatility, 0.0);
    ArrayInitialize(m_trendStrength, 0.0);
    ArrayInitialize(m_regimeBuffer, (double)REGIME_UNDEFINED);
}

CMarketRegimeDetector::~CMarketRegimeDetector()
{
    // Free memory (not strictly necessary in MQL5, but good practice)
    ArrayFree(m_priceData);
    ArrayFree(m_returns);
    ArrayFree(m_volatility);
    ArrayFree(m_trendStrength);
    ArrayFree(m_regimeBuffer);
}

コンストラクタは、すべてのメンバー変数と配列をデフォルト値で初期化します。統計的に有意な結果を得るため、ルックバック期間が少なくとも20バー以上であること、および平滑化期間が正の値であることを確認するパラメータの検証も含まれています。デストラクタでは、配列に割り当てられたメモリを解放します。MQL5には自動的なガベージコレクションがあるとはいえ、こうした明示的なクリーンアップは良い習慣です。

設定メソッド

次に、ユーザーが検出器の動作をカスタマイズできるようにする設定メソッドを実装していきましょう。

void CMarketRegimeDetector::SetLookbackPeriod(int period)
{
    if(period <= 20)
        return;
        
    m_lookbackPeriod = period;
    
    // Resize buffers
    ArrayResize(m_priceData, m_lookbackPeriod);
    ArrayResize(m_returns, m_lookbackPeriod - 1);
    ArrayResize(m_volatility, m_lookbackPeriod - 1);
    ArrayResize(m_trendStrength, m_lookbackPeriod - 1);
    ArrayResize(m_regimeBuffer, m_lookbackPeriod);
    
    // Re-initialize
    Initialize();
}

void CMarketRegimeDetector::SetSmoothingPeriod(int period)
{
    if(period <= 0)
        return;
        
    m_smoothingPeriod = period;
}

void CMarketRegimeDetector::SetTrendThreshold(double threshold)
{
    if(threshold <= 0.0)
        return;
        
    m_trendThreshold = threshold;
}

void CMarketRegimeDetector::SetVolatilityThreshold(double threshold)
{
    if(threshold <= 0.0)
        return;
        
    m_volatilityThreshold = threshold;
}

これらのメソッドにより、ユーザーは特定の取引商品や時間枠に合わせて検出器のパラメータをカスタマイズできます。SetLookbackPeriodメソッドは、すべての内部バッファのサイズを新しい期間に合わせて変更するため、特に重要です。他のメソッドは、入力値を検証した後、対応するパラメータを更新するだけです。

初期化と処理のメソッド

次に、初期化とデータ処理のメソッドを実装します。

bool CMarketRegimeDetector::Initialize()
{
    // Initialize buffers with zeros
    ArrayInitialize(m_priceData, 0.0);
    ArrayInitialize(m_returns, 0.0);
    ArrayInitialize(m_volatility, 0.0);
    ArrayInitialize(m_trendStrength, 0.0);
    ArrayInitialize(m_regimeBuffer, (double)REGIME_UNDEFINED);
    
    // Reset current regime
    m_currentRegime = REGIME_UNDEFINED;
    
    return true;
}

bool CMarketRegimeDetector::ProcessData(const double &price[], int size)
{
    if(size < m_lookbackPeriod)
        return false;
        
    // Copy the most recent price data
    for(int i = 0; i < m_lookbackPeriod; i++)
        m_priceData[i] = price[size - m_lookbackPeriod + i];
        
    // Calculate returns, volatility, and trend strength
    CalculateReturns();
    CalculateVolatility();
    CalculateTrendStrength();
    
    // Determine the current market regime
    m_currentRegime = DetermineRegime();
    
    // Update regime buffer for indicator display
    for(int i = 0; i < m_lookbackPeriod - 1; i++)
        m_regimeBuffer[i] = m_regimeBuffer[i + 1];
        
    m_regimeBuffer[m_lookbackPeriod - 1] = (double)m_currentRegime;
    
    return true;
}

Initializeメソッドは、すべてのバッファと現在のレジームをデフォルト値にリセットします。ProcessDataメソッドは検出器の心臓部であり、新しい価格データを処理し、レジームの分類を更新します。まず最新の価格データをコピーし、次にリターン、ボラティリティ、トレンドの強さを計算し、最後に現在の市場レジームを判定します。また、インジケーター表示用のレジームバッファも更新し、値をシフトして新しいレジームのためのスペースを確保します。

計算メソッド

レジーム検出に使用する統計指標を計算するための計算メソッドを実装していきましょう。

void CMarketRegimeDetector::CalculateReturns()
{
    for(int i = 0; i < m_lookbackPeriod - 1; i++)
    {
        // Calculate percentage returns
        if(m_priceData[i] != 0.0)
            m_returns[i] = (m_priceData[i + 1] - m_priceData[i]) / m_priceData[i] * 100.0;
        else
            m_returns[i] = 0.0;
    }
    
    // Update returns statistics
    m_returnsStats.SetData(m_returns, m_lookbackPeriod - 1);
}

void CMarketRegimeDetector::CalculateVolatility()
{
    // Use a rolling window for volatility calculation
    int windowSize = MathMin(20, m_lookbackPeriod - 1);
    
    for(int i = 0; i < m_lookbackPeriod - 1; i++)
    {
        if(i < windowSize - 1)
        {
            m_volatility[i] = 0.0;
            continue;
        }
        
        double sum = 0.0;
        double mean = 0.0;
        
        // Calculate mean
        for(int j = 0; j < windowSize; j++)
            mean += m_returns[i - j];
            
        mean /= windowSize;
        
        // Calculate standard deviation
        for(int j = 0; j < windowSize; j++)
            sum += MathPow(m_returns[i - j] - mean, 2);
            
        m_volatility[i] = MathSqrt(sum / (windowSize - 1));
    }
    
    // Update volatility statistics
    m_volatilityStats.SetData(m_volatility, m_lookbackPeriod - 1);
}

void CMarketRegimeDetector::CalculateTrendStrength()
{
    // Use a rolling window for trend strength calculation
    int windowSize = MathMin(50, m_lookbackPeriod - 1);
    
    for(int i = 0; i < m_lookbackPeriod - 1; i++)
    {
        if(i < windowSize - 1)
        {
            m_trendStrength[i] = 0.0;
            continue;
        }
        
        double window[];
        ArrayResize(window, windowSize);
        
        // Copy data to window
        for(int j = 0; j < windowSize; j++)
            window[j] = m_returns[i - j];
            
        // Create temporary statistics object
        CStatistics tempStats;
        tempStats.SetData(window, windowSize);
        
        // Calculate trend strength using autocorrelation
        m_trendStrength[i] = tempStats.TrendStrength();
    }
    
    // Update price statistics
    m_priceStats.SetData(m_priceData, m_lookbackPeriod);
}
これらのメソッドは、レジーム検出に使用される主要な統計指標を計算します。
  1. CalculateReturnsは、価格データからパーセンテージのリターンを算出します。これは生の価格データよりも統計分析に適しています。
  2. CalculateVolatilityは、ローリングウィンドウ方式を用いて、各時点でのリターンの標準偏差を計算し、市場のボラティリティを測定します。
  3. CalculateTrendStrengthもローリングウィンドウ方式を用いますが、各ウィンドウに対して一時的なCStatisticsオブジェクトを生成し、そのTrendStrengthメソッドで自己相関に基づくトレンドの強さを求めます。

このようなローリングウィンドウによる計算は、ルックバック期間全体を一括で処理する方法よりも、市場状況の変化に敏感かつ正確に対応できます。

レジームの分類

システムの中核となるのがDetermineRegimeメソッドです。

ENUM_MARKET_REGIME CMarketRegimeDetector::DetermineRegime()
{
    // Get the latest values
    double latestTrendStrength = m_trendStrength[m_lookbackPeriod - 2];
    double latestVolatility = m_volatility[m_lookbackPeriod - 2];
    
    // Get the average volatility for comparison
    double avgVolatility = 0.0;
    int count = 0;
    
    for(int i = m_lookbackPeriod - 22; i < m_lookbackPeriod - 2; i++)
    {
        if(i >= 0)
        {
            avgVolatility += m_volatility[i];
            count++;
        }
    }
    
    if(count > 0)
        avgVolatility /= count;
    else
        avgVolatility = latestVolatility;
    
    // Determine price direction
    double priceChange = m_priceData[m_lookbackPeriod - 1] - m_priceData[m_lookbackPeriod - m_smoothingPeriod - 1];
    
    // Classify the regime
    if(latestVolatility > avgVolatility * m_volatilityThreshold)
    {
        // Highly volatile market
        return REGIME_VOLATILE;
    }
    else if(MathAbs(latestTrendStrength) > m_trendThreshold)
    {
        // Trending market
        if(priceChange > 0)
            return REGIME_TRENDING_UP;
        else
            return REGIME_TRENDING_DOWN;
    }
    else
    {
        // Ranging market
        return REGIME_RANGING;
    }
}
このメソッドでは、階層的な分類手法を用いて市場の状態を判定しています。
  1. 最初に、直近のボラティリティが過去20バーの平均ボラティリティを上回っているかをチェックします。閾値を超えていれば、市場は高ボラティリティと分類されます。
  2. 市場が高ボラティリティでない場合は、トレンドの強さを絶対値で評価し、設定された閾値値を超えていればトレンドと見なします。その後、平滑化期間内の価格変化に基づいて上昇トレンドか下降トレンドかを判断します。
  3. ボラティリティもトレンドも検出されなかった場合、市場はレンジ相場として分類されます。

この階層的な判定手法により、「トレンドよりもボラティリティを優先的に評価」する構造となっています。これは、トレンドフォロー戦略がボラティリティの高い局面に弱いという特性を考慮した設計です。

アクセスメソッド

最後に、現在の市場レジームに関する情報を提供するアクセスメソッドを実装しましょう。

string CMarketRegimeDetector::GetRegimeDescription() const
{
    switch(m_currentRegime)
    {
        case REGIME_TRENDING_UP:
            return "Trending Up";
            
        case REGIME_TRENDING_DOWN:
            return "Trending Down";
            
        case REGIME_RANGING:
            return "Ranging";
            
        case REGIME_VOLATILE:
            return "Volatile";
            
        default:
            return "Undefined";
    }
}

double CMarketRegimeDetector::GetTrendStrength() const
{
    if(m_lookbackPeriod <= 2)
        return 0.0;
        
    return m_trendStrength[m_lookbackPeriod - 2];
}

double CMarketRegimeDetector::GetVolatility() const
{
    if(m_lookbackPeriod <= 2)
        return 0.0;
        
    return m_volatility[m_lookbackPeriod - 2];
}

bool CMarketRegimeDetector::GetRegimeBuffer(double &buffer[]) const
{
    if(ArraySize(buffer) < m_lookbackPeriod)
        ArrayResize(buffer, m_lookbackPeriod);
        
    for(int i = 0; i < m_lookbackPeriod; i++)
        buffer[i] = m_regimeBuffer[i];
        
    return true;
}

bool CMarketRegimeDetector::GetTrendStrengthBuffer(double &buffer[]) const
{
    int size = m_lookbackPeriod - 1;
    
    if(ArraySize(buffer) < size)
        ArrayResize(buffer, size);
        
    for(int i = 0; i < size; i++)
        buffer[i] = m_trendStrength[i];
        
    return true;
}

bool CMarketRegimeDetector::GetVolatilityBuffer(double &buffer[]) const
{
    int size = m_lookbackPeriod - 1;
    
    if(ArraySize(buffer) < size)
        ArrayResize(buffer, size);
        
    for(int i = 0; i < size; i++)
        buffer[i] = m_volatility[i];
        
    return true;
}
これらのメソッドは、現在のレジームとその特徴にアクセスするための機能を提供します。
  1. GetRegimeDescriptionは、現在の市場レジームを人間が読みやすい説明文として返します。
  2. GetTrendStrengthとGetVolatilityは、それぞれ直近のトレンド強度とボラティリティの値を返します。
  3. GetRegimeBuffer、GetTrendStrengthBuffer、GetVolatilityBufferは、内部バッファの内容を外部配列にコピーします。これにより、インジケーターとしてチャートに表示することが可能になります。

これでCMarketRegimeDetectorクラスが完成し、市場レジームを検出するための強力なツールが整いました。次のセクションでは、これを活用してレジームをチャート上に視覚的に表示するカスタムインジケーターを作成します。


レジーム可視化のためのカスタムインジケーターの作成

市場レジーム検出器クラスが完成したので、今度は検出されたレジームをチャート上に直接表示するカスタムインジケーターを作成しましょう。これにより、トレーダーはレジームの変化を直感的に把握し、戦略を柔軟に適応させることができます。

MarketRegimeIndicator(市場レジームインジケーター)

私たちのカスタムインジケーターは、現在の市場レジーム、トレンド強度、およびボラティリティをチャート上に直接表示します。実装は次のとおりです。
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots   3

// Include the Market Regime Detector
#include "MarketRegimeEnum.mqh"
#include "MarketRegimeDetector.mqh"

// Indicator input parameters
input int      LookbackPeriod = 100;       // Lookback period for calculations
input int      SmoothingPeriod = 10;       // Smoothing period for regime transitions
input double   TrendThreshold = 0.2;       // Threshold for trend detection (0.1-0.5) 
input double   VolatilityThreshold = 1.5;  // Threshold for volatility detection (1.0-3.0)

// Indicator buffers
double RegimeBuffer[];        // Buffer for regime classification
double TrendStrengthBuffer[]; // Buffer for trend strength
double VolatilityBuffer[];    // Buffer for volatility

// Global variables
CMarketRegimeDetector *Detector = NULL;
インジケーターは、市場レジームの異なる側面を格納・表示するために3つのバッファを使用します。
  1. RegimeBuffer:現在のレジームを数値で保持
  2. TrendStrengthBuffer:トレンド強度の値を保持
  3. VolatilityBuffer:ボラティリティ値を保持

インジケーターの初期化

OnInit関数は、インジケーターバッファを設定し、市場レジーム検出器を生成します。

int OnInit()
{
    // Set indicator buffers
    SetIndexBuffer(0, RegimeBuffer, INDICATOR_DATA);
    SetIndexBuffer(1, TrendStrengthBuffer, INDICATOR_DATA);
    SetIndexBuffer(2, VolatilityBuffer, INDICATOR_DATA);
    
    // Set indicator labels
    PlotIndexSetString(0, PLOT_LABEL, "Market Regime");
    PlotIndexSetString(1, PLOT_LABEL, "Trend Strength");
    PlotIndexSetString(2, PLOT_LABEL, "Volatility");
    
    // Set indicator styles
    PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE);
    PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_LINE);
    PlotIndexSetInteger(2, PLOT_DRAW_TYPE, DRAW_LINE);
    
    // Set line colors
    PlotIndexSetInteger(1, PLOT_LINE_COLOR, clrBlue);
    PlotIndexSetInteger(2, PLOT_LINE_COLOR, clrRed);
    
    // Set line styles
    PlotIndexSetInteger(1, PLOT_LINE_STYLE, STYLE_SOLID);
    PlotIndexSetInteger(2, PLOT_LINE_STYLE, STYLE_SOLID);
    
    // Set line widths
    PlotIndexSetInteger(1, PLOT_LINE_WIDTH, 1);
    PlotIndexSetInteger(2, PLOT_LINE_WIDTH, 1);
    
    // Create and initialize the Market Regime Detector
    Detector = new CMarketRegimeDetector(LookbackPeriod, SmoothingPeriod);
    if(Detector == NULL)
    {
        Print("Failed to create Market Regime Detector");
        return INIT_FAILED;
    }
    
    // Configure the detector
    Detector.SetTrendThreshold(TrendThreshold);
    Detector.SetVolatilityThreshold(VolatilityThreshold);
    Detector.Initialize();
    
    // Set indicator name
    IndicatorSetString(INDICATOR_SHORTNAME, "Market Regime Detector");
    
    return INIT_SUCCEEDED;
}
この関数はいくつかの重要なタスクを実行します。
  1. インジケーターバッファを対応する配列にバインドする
  2. インジケーターの視覚的なプロパティ(ラベル、スタイル、色)を設定する
  3. ユーザー指定のパラメータで市場レジーム検出器を生成・設定する

SetIndexBufferや各種のPlotIndexSetXXX関数の使用は、MQL5インジケーター開発における標準的な手法です。これらの関数により、インジケーターがチャート上にどのように表示されるかを細かく設定します。

インジケーターの計算

OnCalculate関数は価格データを処理し、インジケーターバッファを更新します。

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[])
{
    // Check if there's enough data
    if(rates_total < LookbackPeriod)
        return 0;
    
    // Process data with the detector
    if(!Detector.ProcessData(close, rates_total))
    {
        Print("Failed to process data with Market Regime Detector");
        return 0;
    }
    
    // Get the regime buffer
    Detector.GetRegimeBuffer(RegimeBuffer);
    
    // Get the trend strength buffer
    Detector.GetTrendStrengthBuffer(TrendStrengthBuffer);
    
    // Get the volatility buffer
    Detector.GetVolatilityBuffer(VolatilityBuffer);
    
    // Display current regime in the chart corner
    string regimeText = "Current Market Regime: " + Detector.GetRegimeDescription();
    string trendText = "Trend Strength: " + DoubleToString(Detector.GetTrendStrength(), 4);
    string volatilityText = "Volatility: " + DoubleToString(Detector.GetVolatility(), 4);
    
    Comment(regimeText + "\n" + trendText + "\n" + volatilityText);
    
    // Return the number of calculated bars
    return rates_total;
}
この関数は以下の処理をおこないます。
  1. 計算に十分なデータがあるかを確認する
  2. 市場レジーム検出器を使って価格データを処理する
  3. レジーム、トレンド強度、ボラティリティのバッファを取得する
  4. 現在のレジーム情報をチャートの隅に表示する
  5. 計算済みのバー数を返す

OnCalculate関数は、新しい価格データが利用可能になった時やチャートがスクロールされた時にプラットフォームから呼び出されます。インジケーターバッファを更新し、その結果がチャート上に表示される役割を担っています。

インジケーターのクリーンアップ

OnDeinit関数は、インジケーターが削除されたときに適切なクリーンアップを保証します。

void OnDeinit(const int reason)
{
    // Clean up
    if(Detector != NULL)
    {
        delete Detector;
        Detector = NULL;
    }
    
    // Clear the comment
    Comment("");
}

この関数は、メモリリークを防ぐために市場レジーム検出器オブジェクトを削除し、チャート上のコメントを消去します。不要になったリソースを確実に解放することは、MQL5プログラミングにおいて適切なクリーンアップとして非常に重要です。

インジケーターの解釈

市場レジームインジケーターを使用する場合、トレーダーは次の点に注意する必要があります。
  1. レジームライン:現在の市場レジームを表すラインです。数値はさまざまなレジームに対応します。
    • 0:上昇トレンド
    • 1:下降トレンド
    • 2:レンジ
    • 3:高ボラティリティ
    • 4:未定義
  2. トレンド強度ライン:青いラインで、トレンドの強さを示します。正の値が大きいほど強い上昇トレンド、負の値が大きいほど強い下降トレンド、0付近の値はトレンドが弱いか存在しないことを示します。
  3. ボラティリティライン:赤いラインで、現在のボラティリティ水準を表します。このラインの急上昇はレジーム変化の前兆であり、取引のチャンスやリスクの警告となります。
  4. チャートコメント:チャートの左上に現在のレジーム、トレンド強度、ボラティリティの数値が表示され、参照しやすくなっています。

これらの要素をモニターすることで、トレーダーは現在の市場レジームを素早く把握し、戦略を適切に調整できます。たとえば、トレンドフォロー戦略はトレンド相場で効果的ですが、レンジ相場では平均回帰戦略の方が適しています。ボラティリティが高い相場では、ポジションサイズを縮小するか、市場から一時的に離れることも検討すべきです。


現在の市場がレンジ相場であることが、チャートを見ても明確に確認できます。


結論

本記事では、アルゴリズム取引における大きな課題の一つである「変化する市場環境への適応」に焦点を当て、その解決に向けたアプローチを段階的に紹介してきました。市場は常に一定の状態を保つわけではなく、異なる「レジーム」が入れ替わるという前提に立ち、そうした変化を検出できる包括的な市場レジーム検出システムの構築を目指しました。次回の記事では、この検出結果に基づき、取引戦略をどのように適応・自動化していくかについて、より実践的な観点から解説していきます。

問題から解決までの道のり

まず、多くの取引システムが抱えている根本的な問題、すなわち「市場の状態を客観的に認識し、それに応じて戦略を変化させる仕組みが存在しない」点を明らかにしました。従来の戦略やインジケーターは、特定の市場環境に最適化されているため、相場の変化によってパフォーマンスが急激に悪化することが少なくありません。ある環境では良好な成績を出す戦略が、別の環境では大きな損失を生む——これはトレーダーが日々直面している現実です。

こうした課題に対して、本記事では一から市場環境を分類・検出する堅牢なシステムを構築するというアプローチを取りました。まずは、自己相関やボラティリティといった統計的な指標を用いて、市場の動向を客観的に把握するための土台を築きました。次に、それらの指標を活用して、トレンド相場・レンジ相場・高ボラティリティ相場を識別する専用の「市場レジーム検出器」クラスを開発しました。

さらに、この仕組みを視覚的にわかりやすくするため、チャート上に市場レジームの変化を表示するカスタムインジケーターも実装しました。これにより、トレーダーは現在の市場環境を一目で判断できるようになります。さらに、検出されたレジームに応じて、取引戦略を自動的に切り替える適応型EAを構築するための基礎についても取り上げました。

次回の記事では、このシステムを実際の取引に導入する際の実践的な考慮点、つまり、パラメータの最適化、レジーム遷移への対処法、既存戦略との統合などに踏み込んでいきます。これらの内容は、構築した市場レジーム検出システムをご自身の取引戦略に効果的かつ自動的に組み込むための指針として役立つはずです。それまでの間、今回ご紹介したインジケーターを手動で活用し、レジーム判定がどのように機能するかを実際にご体験ください。


ファイルの概要

この記事で作成されたすべてのファイルの概要は次のとおりです。
ファイル名 説明
MarketRegimeEnum.mqh
システム全体で使用される市場レジームの列挙型の定義
CStatistics.mqh 市場レジーム検出のための統計計算クラス
MarketRegimeDetector.mqh 市場レジーム検出器のコア実装
MarketRegimeIndicator.mq5 チャート上でレジームを視覚化するためのカスタムインジケーター

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

添付されたファイル |
CStatistics.mqh (9.28 KB)
最後のコメント | ディスカッションに移動 (5)
Robert Angers
Robert Angers | 27 4月 2025 において 21:12
コードがコンパイルされない... IsStrongSignal(value)が見つからない...
Sahil Bagdi
Sahil Bagdi | 28 4月 2025 において 06:19
Robert Angers #:
あなたのコードはコンパイルされません... IsStrongSignal(value)がありません...

どのファイルを参照していますか?

Rau Heru
Rau Heru | 21 5月 2025 において 12:48

MarketRegimeIndicator をコンパイルしようとすると、24個のエラーと1個の警告が出ます:

'MarketRegimeIndicator.mq5' 1

file 'C: \Usersrauma\AppData\RoamingMetaQuotesTerminal10CE948A1DFC9A8C27E56E827008EBD4 ❃MQL5Include ❃MarketRegimeEnum.mqh' not found MarketRegimeIndicator.mq5 14 11

file 'C:³³Users³³AppData³³Roaming³³MetaQuotes³³Terminal³³ 10CE948A1DFC9A8C27E56E827008EBD4³³MQL5³³Include³³MarketRegimeDetector.mqh' not found MarketRegimeIndicator.mq5 15 11

'CMarketRegimeDetector' - 予期しないトークン、おそらく型が見つからない? MarketRegimeIndicator.mq5 29 1

'*' - セミコロンが予期されたもの MarketRegimeIndicator.mq5 29 23

'Detector' - 宣言されていない識別子 MarketRegimeIndicator.mq5 64 5

'CMarketRegimeDetector' - 型のない宣言 MarketRegimeIndicator.mq5 64 20

'CMarkRegimeDetector' - 期待されるクラス型 MarketRegimeIndicator.mq5 64 20

関数が定義されていません MarketRegimeIndicator.mq5 64 20

'new' - 'void' 型の式が不正 MarketRegimeIndicator.mq5 64 16

'=' - 不正な操作の使用 MarketRegimeIndicator.mq5 64 14

'Detector' - 宣言されていない識別子 MarketRegimeIndicator.mq5 65 8

'==' - 不正な操作の使用 MarketRegimeIndicator.mq5 65 17

'Detector' - 宣言されていない識別子 MarketRegimeIndicator.mq5 72 5

'Detector' - 宣言されていない識別子 MarketRegimeIndicator.mq5 73 5

'Detector' - 宣言されていない識別子 MarketRegimeIndicator.mq5 74 5

'Detector' - 宣言されていない識別子 MarketRegimeIndicator.mq5 101 9

';' - 予期しないトークン MarketRegimeIndicator.mq5 103 68

'(' - アンバランスな左括弧 MarketRegimeIndicator.mq5 101 7

空の管理対象 文が見つかりました MarketRegimeIndicator.mq5 103 68

'Detector' - 宣言されていない識別子 MarketRegimeIndicator.mq5 133 8

'!=' - 不正な操作の使用 MarketRegimeIndicator.mq5 133 17

'Detector' - 宣言されていない識別子 MarketRegimeIndicator.mq5 135 16

'Detector' - 期待されるオブジェクトポインタ MarketRegimeIndicator.mq5 135 16

'Detector' - 宣言されていない識別子 MarketRegimeIndicator.mq5 136 9

'=' - 不正な操作の使用 MarketRegimeIndicator.mq5 136 18

24 エラー、1 警告 25 2


Rashid Umarov
Rashid Umarov | 21 5月 2025 において 13:02
Rau Heru #:

Market regime indicatorをコンパイルしようとすると、24のエラーと1つの警告が表示される:

'MarketRegimeIndicator.mq5' 1

file 'C: \Usersersrauma\AppData\Roaming\MetaQuotesTerminal\10CE948A1DFC9A8C27E56E827008EBD4 ❃MQL5 ❃Include ❃MarketRegimeEnum.mqh' not found MarketRegimeIndicator.mq5 14 11

file 'C:¥Users¥PetaQuotes¥AppData¥Roaming¥MetaQuotes¥Terminal¥10CE948A1DFC9A8C27E56E827008EBD4¥MQL5Include¥MarketRegimeDetector.mqh' not found MarketRegimeIndicator.mq5 15 11

The indicator searches for these files in the folderC:¥Users¥MetaQuotes¥AppData¥Roaming¥MetaQuotes¥Terminal¥10CE948A1DFC9A8C27E56E827008EBD4¥MQL5¥Include

#property copyright "Sahil Bagdi"
#property link      "https://www.mql5.com/ja/users/sahilbagdi"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots   3

// 市場レジーム検知器を含める
#include <MarketRegimeEnum.mqh>
#include <MarketRegimeDetector.mqh>
Yoshiteru Taneda
Yoshiteru Taneda | 17 7月 2025 において 10:56
Sahil Bagdi #:

どのファイルを参照していますか?

MarketRegimeDetector.mqh

の472行目

のことかと思います

'IsStrongSignal' - undeclared identifier MarketRegimeDetector.mqh 472 16

'strategySignal' - some operator expected MarketRegimeDetector.mqh 472 31

MQL5でのカスタム市場レジーム検出システムの構築(第2回):エキスパートアドバイザー MQL5でのカスタム市場レジーム検出システムの構築(第2回):エキスパートアドバイザー
この記事では、第1回で紹介したレジーム検出器を用いて、適応型のエキスパートアドバイザー(EA)、MarketRegimeEAを構築する方法を詳しく解説しています。このEAは、トレンド相場、レンジ相場、またはボラティリティの高い相場に応じて、取引戦略やリスクパラメータを自動的に切り替えます。実用的な最適化、移行時の処理、多時間枠インジケーターも含まれています。
MQL5で取引管理者パネルを作成する(第10回):外部リソースベースのインターフェイス MQL5で取引管理者パネルを作成する(第10回):外部リソースベースのインターフェイス
本日は、MQL5の機能を活用して、BMP形式の画像などの外部リソースを利用し、トレーディング管理パネル用に独自のスタイルを持ったホームインターフェイスを作成します。ここで紹介する手法は、画像やサウンドなど複数のリソースを一括でパッケージ化して配布する際に特に有効です。このディスカッションでは、こうした機能をどのように実装し、New_Admin_Panel EAにおいてモダンで視覚的に魅力的なインターフェイスを提供するかを一緒に見ていきましょう。
データサイエンスとML(第36回):偏った金融市場への対処 データサイエンスとML(第36回):偏った金融市場への対処
金融市場は完全に均衡しているわけではありません。強気の市場もあれば、弱気の市場もあり、どちらの方向にも不確かなレンジ相場を示す市場もあります。このようなバランスの取れていない情報を用いて機械学習モデルを訓練すると、市場が頻繁に変化するため、誤った予測を導く原因になります。この記事では、この問題に対処するためのいくつかの方法について議論していきます。
古典的な戦略を再構築する(第14回):高確率セットアップ 古典的な戦略を再構築する(第14回):高確率セットアップ
高確率セットアップ(high probability setups)は、私たちの取引コミュニティではよく知られていますが、残念ながら明確には定義されていません。この記事では、「高確率セットアップ」とは具体的に何かを、経験的かつアルゴリズム的な方法で定義し、それを特定して活用することを目指します。勾配ブースティング木を用いることで、任意の取引戦略のパフォーマンスを向上させる方法、そしてコンピュータに対して「何をすべきか」をより明確かつ意味のある形で伝える手段を、読者に示します。