MQL5 ②HMA(ハル移動平均線)を表示したい

2024/12/14に公開

前回はHullMAで使われているWMAの処理を見てみました。

以下は、WMAコードをもとにHull Moving Average(HMA) を計算するコードを作成したものです。LWMAを再利用し、HMA特有の計算ステップを実装します。


HMAの実装ステップ

  1. LWMAを再利用:
    • LWMA計算部分を関数化して再利用可能にします。
  2. HMAの計算フロー:
    • 短期LWMA: LWMA(price, period / 2)
    • 長期LWMA: LWMA(price, period)
    • 中間結果: 2 * LWMA(period / 2) - LWMA(period)
    • HMA: 中間結果に対して LWMA(sqrt(period)) を適用します。
  3. 最適化:
    • 計算効率を高めるためにprev_calculatedを活用し、再計算を最小限に抑えます。

HMAコード

void CalculateHMA(int rates_total, int prev_calculated, int begin, const double &price[])
{
   int    start;
   double sum=0.0, lsum=0.0;

   // 初期化処理: 最初の計算またはバー数の変更時
   if(prev_calculated <= InpMAPeriod + begin)
   {
      start = InpMAPeriod + begin;
      for (int i = 0; i < start; i++)
         ExtLineBuffer[i] = 0.0; // 初期化
   }
   else
      start = prev_calculated; // 前回計算の続きから再開

   // --- HMAの計算 ---
   for (int i = start; i < rates_total && !IsStopped(); i++)
   {
      // 1. LWMA(period / 2)
      double lwma_half = CalculateLWMA(price, rates_total, i, InpMAPeriod / 2);

      // 2. LWMA(period)
      double lwma_full = CalculateLWMA(price, rates_total, i, InpMAPeriod);

      // 3. 中間結果: 2 * LWMA(period / 2) - LWMA(period)
      double intermediate = 2.0 * lwma_half - lwma_full;

      // 4. HMA: LWMA(intermediate, sqrt(period))
      ExtLineBuffer[i] = CalculateLWMA(&intermediate, rates_total, i, MathRound(MathSqrt(InpMAPeriod)));
   }
}

// --- LWMA計算関数 ---
double CalculateLWMA(const double &price[], int rates_total, int current, int period)
{
   double sum = 0.0;
   double weight_sum = 0.0;

   for (int i = 0; i < period; i++)
   {
      int index = current - i;
      double weight = period - i;  // 重みを計算
      sum += price[index] * weight; // 重み付き価格の合計
      weight_sum += weight;         // 重みの合計
   }

   return sum / weight_sum; // LWMAを返す
}

コードの詳細説明

  1. CalculateHMA関数:

    • 全体的なHMAを計算するメイン関数。
    • 入力データ(price[])を基に、LWMAを再利用してHMAの計算フローを実装。
    • 最新の足はrates_total - 1として計算
  2. CalculateLWMA関数:

    • LWMA(加重移動平均)を計算するための再利用可能な関数。
    • 任意の期間(period)に対してWMAを計算。
  3. 逐次計算:

    • 最新のデータのみを更新計算するため、prev_calculated を使用して再計算を最小化。
  4. 中間結果の処理:

    • intermediate 値を使い、最終的なHMAを計算します。
    • 中間値に対するLWMAは直接値を渡す方式で処理。
    • 中間結果をバッファ(配列)に保存し、重複計算を避ける。

TradingViewの表示

MT5での表示

いい感じですね^^

Discussion