English Deutsch
preview
プライスアクション分析ツールキットの開発(第54回):EMAと平滑化された価格変動によるトレンドのフィルタリング

プライスアクション分析ツールキットの開発(第54回):EMAと平滑化された価格変動によるトレンドのフィルタリング

MetaTrader 5テスター |
23 0
Christian Benjamin
Christian Benjamin

内容



はじめに

数十年にわたり、トレーダーは市場のノイズを取り除き、価格の本質的な動きに焦点を当てる手法を模索してきました。なかでも平均足は、ローソク足を平滑化することでトレンドをより明確にし、短期的な変動によるノイズを軽減できる点で際立っています。言い換えれば、平均足は地点AからBへ向かう道筋を示す「ロードマップ」のように機能し、価格ノイズを抑えることで全体の方向性を把握しやすくします。これまでの研究では、平均足のみに基づくプライスアクション分析システムを検証し、明確なエントリーと認識しやすいパターンが得られることを確認しました。しかし実運用では、このような単一の手法は市場環境によっては脆弱であり、強い陽線や陰線が基調トレンドを誤って示す場合があります。  

この制約に対処するため、本研究ではシグナルの信頼性を高める目的で指数移動平均(EMA)を導入しました。高値および安値に適用したEMA20は短期的な境界を定義し、終値に適用したEMA50はより広い方向性を示すフィルターとして機能します。平均足のシグナルがこれらのEMAと一致する場合、誤検出は大幅に減少し、エントリーはより規律あるものになります。この組み合わせにより、平均足の視認性を維持しつつ定量的な構造が加わり、意思決定の質を高めるとともにトレンド方向の確認を強化する、バランスの取れた手法となります。

  

以降のセクションでは、このシステムの仕組み、MQL5での実装方法、コア機能の解説、導入手順、テスト方法、そして最後に結論について説明します。  



戦略メカニクス

市場の変動が激しい局面や過渡期には、ローソク足チャート上に強いモメンタムを示す大陽線や大陰線が現れることがあります。しかし実際には、それらは短期的な価格変動に過ぎないケースも少なくありません。このような誤解を招くシグナルは、価格が根本的なトレンドを変えていないにもかかわらず、直近レンジを一時的に上抜けまたは下抜けするような、浅い押しや出来高の少ない局面で頻繁に発生します。その結果、調整局面の終盤で買ってしまったり、再上昇の直前に売ってしまったりといった判断ミスにつながりやすくなります。こうした状況は相場の乱高下を助長し、取引の一貫性を損なう要因になります。

このシステムは、このような誤検出を抑えることを目的として設計されています。平均足による平滑化と指数移動平均(EMA)によるフィルタリングの組み合わせにより、見た目の強さだけでなく、実際のモメンタムが伴っている場合にのみシグナルとする仕組みです。平均足の段階では、OHLCの平均値をもとに各バーを再計算することで、持続的なトレンドに沿って色が推移し、有効な反転が起きた場合にのみ色が変化するチャートを生成します。これにより、従来のローソク足よりも方向性が明確になり、優勢な方向性を直感的に把握しやすくなります。

さらに、平均足単体では誤判断が生じやすい状況(たとえば下降トレンド中に単発の大陽線が出現するケース)に対応するため、この戦略では第2の検証レイヤーを導入しています。終値ベースのEMA50は全体的な方向性を示し、その傾きはトレンドの強さを定量的に把握する指標として機能します。一方で、高値と安値に基づく2本のEMA20は、直近の価格レンジの上限と下限を示します。平均足のシグナルが有効と判断されるためには、価格がEMA20の境界をブレイクし、かつEMA50の傾きと方向が一致している必要があります。これらの条件のいずれかが満たされない場合、そのシグナルは無効として扱われます。

このように、視覚的に平滑化されたシグナルと、構造的なトレンド指標の一致を前提とすることで、この手法は短期的なモメンタム、長期的な方向性、ローソク足の構造がすべて同じ方向を示した場合にのみエントリーをおこないます。その結果、ノイズへの影響を抑えつつ、平均足の持つ視認性を維持しながら、一貫したルールに基づく判断が可能になります。

詳細な平均足計算

平均足は、標準的なOHLCローソク足の計算方法を調整し、小さな価格変動を抑えた平滑化データを生成する手法です。通常のように各期間の始値、高値、安値、終値をそのまま表示するのではなく、それらをもとに算出された平均値を用いてチャートを描画します。

以下は平均足の標準的な計算式です。

平均足の終値

平均足の始値

平均足の高値


平均足の安値

  • HA_Close:実際のローソク足の始値、高値、安値、終値の平均値を用いて算出され、その期間における平均的な終値水準を示します。
  • HA_Open:前の平均足の始値と終値の平均値を用いて算出され、直前のバーの平滑化された値を引き継ぐ形で新しい始値を形成します。
  • HA_High / HA_Low:平均足の始値および終値と、実際のローソク足の高値および安値の中から、それぞれ最も高い値と最も低い値を採用します。

色のロジック(トレンドの方向)

強気の平均足ローソク足:HAの終値 > HAの始値
  • 緑色(またはトレーダーが設定した強気カラー)で表示されます。
弱気の平均足ローソク足:HAの終値 < HAの始値
  • 赤色(またはトレーダーが設定した弱気カラー)で表示されます。

平均足では、新しい始値が前のローソク足の平滑化された値を引き継ぐため、生の価格が急変してもその影響は即座には反映されません。その結果、トレンド局面では同じ色のローソク足が連続しやすく、小幅な調整では不規則な色の切り替わりが抑えられます。

この特性は、トレーダーがトレンドに対してより自信を持ってポジションを維持する助けになりますが、一方でわずかな遅延も生じます。各ローソク足の値が平均化されているため、反転のシグナルは通常のローソク足チャートに比べて遅れて現れる傾向があります。強いトレンド相場では、この遅延はむしろ有利に働き、利益の出ているポジションを長く保有しやすくなります。しかし、相場が複雑な動きをする場合やレンジ局面では、平滑化によって初期の変化が見えにくくなり、エントリーやエグジットのタイミングがわずかに遅れる可能性があります。こうした弱点を補うためには、追加の分析レイヤーが不可欠です。つまり、平均足が示すシグナルを検証または補強できる指標が必要になります。この手法では、その役割を指数移動平均(EMA)が担っています。 

EMA計算設定

EMA(指数移動平均)は、一定期間における平均価格を捉える指標であり、直近の価格データにより大きな重みを与えることで、高い反応性と安定性を両立しています。この計算では、新しい価格に重点を置く乗数を適用することで、短期的なモメンタムと長期的なトレンドのバランスの変化を反映する滑らかなラインが描画されます。トレーダーは一般にEMAを用いて、動的なサポートとレジスタンスを把握し、現在のトレンド方向を評価し、モメンタムの加速および減速のポイントを見極めます。また、異なる期間のEMAを比較することで、トレンドの強さや安定性を判断できます。たとえば、50期間EMAが上昇していれば持続的な強気傾向、下降していれば弱気傾向を示します。 この戦略では、3本のEMAを使用します。

  • 終値ベースのEMA50:長期トレンドフィルター

ema50 = iMA(_Symbol, WorkTF, 50, 0, MODE_EMA, PRICE_CLOSE);

時間の経過に伴う傾きを用いて、トレンドの方向性を判断します。短期的なノイズは抑えつつ、日々の変化には十分に追従できる特性を持っています。 このシステムでは、単純に価格とEMAのクロスオーバーに依存するのではなく、最新のEMA50の値と、1本前のローソク足におけるEMA50の値との間の傾き(方向の変化)を測定します。

trendBull = (ema50_current > ema50_previous);
trendBear = (ema50_current < ema50_previous);

  • 1) 現在のEMA50が前回の値より高い場合、EMAは上向きであり、市場は上昇方向にあります。
  • 2) 現在のEMA50が前回の値より低い場合、EMAは下向きであり、市場は下降方向にあります。

単純なクロスオーバーは、レンジ相場において価格がモメンタムを伴わないままEMAを横切ることで、誤ったシグナルを生みやすい傾向があります。一方、傾きに基づく分析では、トレンドの加速と減速に沿った方向でのみ判断をおこなうため、横ばい相場でのノイズを効果的にフィルタリングできます。

  • 高値ベースのEMA20:短期的な上限


ema20_high = iMA(_Symbol, WorkTF, 20, 0, MODE_EMA, PRICE_HIGH);

直近の価格における平均的な高値を示します。このラインを終値が明確に上抜けた場合、強い上昇圧力が生じている可能性を示します。

  • 安値ベースのEMA20:短期的な下限


ema20_low = iMA(_Symbol, WorkTF, 20, 0, MODE_EMA, PRICE_LOW);

直近の平均的な安値を示します。このラインを下抜ける動きは、強い下降圧力を示します。

20期間のEMAは価格変動に素早く反応し、短期的なモメンタムの変化を捉えます。高値と安値をそれぞれ別に計算することで、2本のラインが価格を包み込むような動的なバンドを形成し、直近の取引レンジを明確に示します。一方で、50期間EMAはより緩やかに反応し、一時的なノイズを除去しながら、長期的なトレンド方向を安定して示します。

シグナルルール

買いシグナル

1) 平滑化ローソク足の終値がEMA20高値を上回っている

  • (HA終値 > EMA20高値):価格が短期的な上限を上抜けています。

2) 平均足が強気である

  • (HA終値 > HA始値):ローソク足の実体が上向きです。

3) 平滑化された終値がEMA50を上回っている

  • (HA終値 > EMA50):価格が長期トレンドフィルターの上に位置しています。

4) EMA50の傾きが正である

  • (EMA50の現在値 > EMA50の過去値):長期トレンドラインは上昇傾向にあります。

5) 前回のHA終値はEMA50を下回っていた:ブレイクアウトが発生していることを示します(価格がトレンドラインを上抜けした)。

売りシグナル

1) 平滑化ローソク足の終値がEMA20高値を上回っている
  • (HA終値 < EMA20安値):価格が短期的な下限を下抜けています。
2) 平均足が弱気である
  • (HA終値 < HA始値):ローソク足の実体が下向きです。
3) 平滑化された終値がEMA50を下回っている
  • (HA終値 < EMA50):価格が長期トレンドフィルターの下に位置しています。
4) EMA50の傾きが負である
  • (EMA50の現在値 < EMA50の過去値):長期トレンドラインは下降傾向にあります。
5) 前回のHA終値はEMA50を上回っていた:ブレイクアウトが発生していることを示します(価格がトレンドラインを下抜けした)。

    買いシグナル(承認)

    • 強気の平均足の終値がEMA20高値を上回っており、EMA50が上昇傾向にある場合。前回のHA終値はEMA50を下回っていましたが、現在のバーでそれを上抜けたことで上昇モメンタムが確認されます。  

    買いシグナル(却下)

    • 強気の平均足の終値がEMA20高値を上回っているものの、EMA50の傾きが横ばいまたはマイナスの場合。広範なトレンドとの整合性が不足しているため、このシグナルは却下されます。  

    売りシグナル(承認)

    • 弱気の平均足の終値がEMA20安値を下回っており、EMA50が下降傾向にある場合。前回のHA終値はEMA50を上回っていましたが、現在のバーでそれを下抜けたことで下降モメンタムが確認されます。  

    売りシグナル(却下)

    • 弱気の平均足の終値がEMA20安値を下回っているものの、EMA50の傾きがプラスの場合。より広いトレンドが上昇傾向にあるため、このシグナルは破棄されます。  

    ビジュアルとアラート

    買いシグナルの矢印は緑色(またはライム色)で表示され、シグナルとなったローソク足の高値からArrowOffsetPointsで定義された距離だけ上にプロットされます。一方、売りシグナルの矢印は赤色で表示され、同じオフセット分だけローソク足の安値の下に配置されます。これによりローソク足との重なりを防ぎ、チャートの視認性を維持します。各矢印には「EMA20HA_BUY_」のような特定の接頭辞が付けられ、同一ローソク足上で重複シグナルが発生しないようタイムスタンプが含まれています。有効なシグナルが発生すると、EAは銘柄とシグナルタイプを含むアラートメッセージを生成します。また、トレーダーの設定に応じてプッシュ通知やメール通知へ拡張することも可能です。



    実装

    エキスパートアドバイザー(EA)は、実際の取引環境とストラテジーテスター環境の両方で安定して動作するように設計されており、どちらの環境においても同一のロジックが保証されます。そのアーキテクチャは、初期化、インジケータ管理、シグナル解析、視覚的出力といった機能を、それぞれ独立したモジュールに分割しています。このモジュール構造により、デバッグの容易性が向上し、全体の可読性も高まります。また、各コンポーネントは実行時の状況に応じて動的に適応することを目的としています。

    下の図は、このEAのワークフローを示したものです。初期化から平均足の計算、EMAフィルタリング、シグナル検証、矢印の描画、そしてアラート生成までの一連の流れを示しています。  

    インジケーターの初期化

    起動時に、このシステムは分析に使用する3本のEMAのインジケーターハンドルを取得します。各ハンドルは正常に生成されたことが確認されてから、処理が継続されます。

    handleEMA50  = iMA(_Symbol, WorkTF, 50, 0, MODE_EMA, PRICE_CLOSE);
    handleEMA20H = iMA(_Symbol, WorkTF, 20, 0, MODE_EMA, PRICE_HIGH);
    handleEMA20L = iMA(_Symbol, WorkTF, 20, 0, MODE_EMA, PRICE_LOW);

    ハンドルのチェックは、不完全な読み込みによってテスト結果が歪むことを防ぐうえで重要です。いずれかの呼び出しが失敗した場合、EAは INIT_FAILEDを返して終了し、不完全なデータに基づく計算が実行されないようにします。これらのハンドルは、初期化解除時にIndicatorRelease()を使用して解放され、システムリソースを適切に確保します。

    • 各ローソク足は個別にチェックされます。

    if(handleEMA50 == INVALID_HANDLE || handleEMA20H == INVALID_HANDLE || handleEMA20L == INVALID_HANDLE)
       return(INIT_FAILED);

    • 終了時にはハンドルが解放されます。

    IndicatorRelease(handleEMA50);
    IndicatorRelease(handleEMA20H);
    IndicatorRelease(handleEMA20L);

    デュアルモードのローソク足処理

    組み込みの平均足インジケーターは、ストラテジーテスター環境では必ずしも正しく描画されない場合があるため、このEAでは冗長な描画メカニズムを備えています。組み込みインジケーターの呼び出しが正常に成功した場合は、そのバッファをデータ取得に使用します。

    double haOpen = (prevHAopen + prevHAclose) / 2.0;
    double haClose = (open[i] + high[i] + low[i] + close[i]) / 4.0;
    double haHigh = MathMax(high[i], MathMax(haOpen, haClose));
    double haLow  = MathMin(low[i],  MathMin(haOpen, haClose));

    組み込みインジケーターの呼び出しが失敗した場合、またはストラテジーテスター環境が検出された場合には、カスタム関数によって平均足の計算式を用いて各ローソク足が手動で構築されます。これらのローソク足は、チャート上に矩形オブジェクトとして描画され、その色はローソク足の方向に対応しています。このデュアルモード方式により、両方の環境において同一の視覚情報と分析結果が表示されることが保証されます。

    ObjectCreate(0, name, OBJ_RECTANGLE, 0, t1, haHigh, t2, haLow);
    ObjectSetInteger(0, name, OBJPROP_COLOR, (haClose > haOpen) ? clrLime : clrRed);

    チャートオブジェクトの管理

    すべてのチャートオブジェクト(矢印、矩形、ラベル)は厳密な命名規則に従って管理されます。それぞれのオブジェクトは、その役割およびシグナルの種類を示す事前定義された接頭辞を付けて作成されます。

    string arrowName = "EMA20HA_BUY_" + IntegerToString(TimeCurrent());

    DeleteObjectsByPrefix()のような関数を使用することで、他のチャート要素に影響を与えることなく、期限切れまたは不要になったオブジェクトを選択的に削除できます。

    DeleteObjectsByPrefix("EMA20HA_", OBJ_ARROW);

    このような体系的な管理により、長時間のテストセッション中でもチャートの乱雑化を防ぎ、新しいシグナルが常に明確に視認できる状態が維持されます。

    シグナル制御と重複排除

    このエンジンでは、同一ローソク足に対して重複したアラートや描画が発生しないよう、タイムスタンプによる追跡機構を採用しています。各シグナルイベントは発生時刻とタイプを記録し、次回の判定時には現在の条件と保存された値を比較したうえで新規シグナルを生成します。

    if(lastSignalTime == Time[0] && lastSignalType == currentSignal)
       return; // skip duplicate

    一致が確認された場合、その処理はスキップされます。この軽量な制御により、急激な値動きやシミュレーション中の高速更新時でも、過剰な描画や通知の発生を防ぎます。

    トレンド検証ルーチン

    各ティック処理時に、EAは現在および過去のEMA50値を計算し、全体的なトレンド方向(傾き)を判断します。この評価は短期的なチェックよりも先に実行され、主トレンドに逆行するシグナルを事前に除外します。処理の順序は以下の通りです。

    • EMA50の傾きを評価し、トレンドコンテキストを定義する
    • HAおよびEMA20データを取得し、短期的な圧力を評価する
    • 条件を統合してシグナルを承認または拒否する

    bool trendBull = ema50_current > ema50_previous;
    bool trendBear = ema50_current < ema50_previous;

    この多層的な評価構造は前述の「メカニクス」セクションと一致しており、一貫性と計算効率の両方を確保します。

    可視化管理

    有効なシグナルが確定した後、グラフィカル要素は各ローソク足につき1回のみ描画されます。矢印は事前定義されたオフセットを用いて配置されるため、チャート上での視認性が維持されます。また、オブジェクト名には銘柄名およびローソク足の時刻が含まれ、一意性が確保されます。

    double arrowPrice = High[0] + (ArrowOffsetPoints * _Point);
    ObjectCreate(0, arrowName, OBJ_ARROW, 0, Time[0], arrowPrice);
    ObjectSetInteger(0, arrowName, OBJPROP_COLOR, clrLime);

    平均足の手動描画が使用されている場合、それらは新しいバーが形成されたときのみ更新され、処理負荷が抑制されます。この応答性と効率性のバランスにより、複数銘柄を同時監視する場合でもインターフェースの可読性が維持されます。

    DeleteObjectsByPrefix("EMA20HA_", OBJ_ARROW);

    リソース処理と終了ルーチン

    初期化解除時には、すべてのインジケーターハンドルが解放され、EAのプレフィックスを持つすべてのオブジェクトが削除されます。これにより、長時間の運用で発生し得るメモリ使用量の蓄積が防止されます。設計思想は明確であり、実行中はインジケーターが計算処理を担い、EA終了後はチャートを軽量な状態に保つことを目的としています。

    IndicatorRelease(handleEMA50);
    IndicatorRelease(handleEMA20H);
    IndicatorRelease(handleEMA20L);
    DeleteObjectsByPrefix("EMA20HA_", OBJ_ARROW);
    DeleteObjectsByPrefix("EMA20HA_", OBJ_RECTANGLE);



    主要機能の内訳

     

    上図は、EAの内部処理フローを示しています。確定バーの検出およびバッファ処理から始まり、EMAによるトレンド検証を経て、最終的なシグナル発火、矢印の描画、そしてアラート生成へと至る一連の流れを表しています。 

    OnInit():初期化ルーチン

    初期化関数は、コアとなるインジケーターのセットアップおよびチャート環境の準備を担当します。EAの読み込み時に、3つのインジケーターハンドルが作成されます。すなわち、終値に基づくEMA50が1つ、さらに高値および安値に基づいて計算されるEMA20がそれぞれ1つずつです。各ハンドルは正常に生成されたかどうかが検証され、不正なハンドルは計算エラーや実行時例外の原因となる可能性があります。成功ステータスを返す前に、前回の実行で残存しているチャートオブジェクトも削除され、シグナルおよびビジュアル要素がクリーンな状態から開始されることが保証されます。

    int OnInit()
    {
       // Load EMA indicators
       handleEMA50  = iMA(_Symbol, WorkTF, 50, 0, MODE_EMA, PRICE_CLOSE);
       handleEMA20H = iMA(_Symbol, WorkTF, 20, 0, MODE_EMA, PRICE_HIGH);
       handleEMA20L = iMA(_Symbol, WorkTF, 20, 0, MODE_EMA, PRICE_LOW);
    
       // Check handles
       if(handleEMA50 == INVALID_HANDLE || handleEMA20H == INVALID_HANDLE || handleEMA20L == INVALID_HANDLE)
       {
          Print("Failed to create EMA handles");
          return(INIT_FAILED);
       }
    
       // Remove any old objects from chart
       DeleteObjectsByPrefix("EMA20HA_", OBJ_ARROW);
       DeleteObjectsByPrefix("EMA20HA_", OBJ_RECTANGLE);
    
       return(INIT_SUCCEEDED);
    }

    OnTick():メイン実行ループ

    この関数は各マーケットティックごとに実行され、データ更新、取引条件の検証、およびシグナル出力の描画処理を担当します。処理はまず、現在および直前のEMA50の値を取得し、あわせて最新のEMA20高値およびEMA20安値の値を取得します。これらのデータポイントを用いて現在の平均足ローソク足構造を生成し、さらにEMA50の傾きを比較することで、優勢なトレンド方向を判定します。最後に、専用の条件関数を用いて買いおよび売りシグナルを評価し、条件が満たされた場合には視覚的な出力をトリガーします。

    void OnTick()
    {
       // Get latest indicator values
       double ema50_current = CopyBufferValue(handleEMA50, 0);
       double ema50_previous = CopyBufferValue(handleEMA50, 1);
       double ema20_high = CopyBufferValue(handleEMA20H, 0);
       double ema20_low  = CopyBufferValue(handleEMA20L, 0);
    
       // Compute current Heikin-Ashi candle
       HA_Candle ha = GetHeikinAshiCandle(0);
    
       // Validate trends
       bool trendBull = ema50_current > ema50_previous;
       bool trendBear = ema50_current < ema50_previous;
    
       // Signal detection
       if(IsBuySignal(ha, ema20_high, ema50_current, trendBull))
          PlaceSignalArrow(true);
       
       if(IsSellSignal(ha, ema20_low, ema50_current, trendBear))
          PlaceSignalArrow(false);
    }

    GetHeikinAshiCandle():HA計算ユーティリティ

    このヘルパー関数は、履歴上の任意のシフトに対して平滑化ローソク足データを生成します。平均足の終値(HA Close)は、元のOHLC値の平均として算出され、その後、平均足の始値(HA Open)は前の平均足の始値と終値の平均として計算されます。高値および安値は、平滑化された値と実際の価格の極値を比較することによって決定されます。また、平均足の終値と始値の関係に基づいて、そのローソク足が強気か弱気かを示すブール値フラグが設定されます。

    HA_Candle GetHeikinAshiCandle(int shift)
    {
       HA_Candle ha;
       ha.close = (Open[shift] + High[shift] + Low[shift] + Close[shift]) / 4.0;
       double prev_ha_open = (Open[shift+1] + Close[shift+1]) / 2.0;
       ha.open  = (prev_ha_open + ha.close) / 2.0;
       ha.high  = MathMax(High[shift], MathMax(ha.open, ha.close));
       ha.low   = MathMin(Low[shift], MathMin(ha.open, ha.close));
       ha.isBull = ha.close > ha.open;
       return(ha);
    }

    IsBuySignal():買い条件チェック

    買いシグナル関数は、現在の平均足がロングトレードのすべての条件を満たしているかを評価します。強気のローソク足であること、終値がEMA20高値を上回っていること、EMA50を上回っていること、さらにEMA50のトレンド傾きが正であることを確認します。これらの条件のいずれかが満たされない場合はfalseを返し、すべて満たされた場合は有効な買いセットアップとしてtrueを返します。

    bool IsBuySignal(HA_Candle ha, double ema20_high, double ema50, bool trendBull)
    {
       if(!ha.isBull) return(false);
       if(ha.close <= ema20_high) return(false);
       if(ha.close <= ema50) return(false);
       if(!trendBull) return(false);
       return(true);
    }

    PlaceSignalArrow():ビジュアル出力

    有効な売買シグナルのチャート描画を担当します。買いの場合はローソク足の高値の上に、売りの場合は安値の下にオフセットを加えて矢印の位置を計算し、取引種別に応じて色を設定したうえでオブジェクトを生成します。また、タイムスタンプをオブジェクト名に埋め込むことで、シグナルの一意性を確保します。

    void PlaceSignalArrow(bool isBuy)
    {
       double price = isBuy ? (High[0] + ArrowOffsetPoints * _Point) : (Low[0] - ArrowOffsetPoints * _Point);
       string name  = isBuy ? "EMA20HA_BUY_" + IntegerToString(Time[0]) : "EMA20HA_SELL_" + IntegerToString(Time[0]);
       int color    = isBuy ? clrLime : clrRed;
    
       ObjectCreate(0, name, OBJ_ARROW, 0, Time[0], price);
       ObjectSetInteger(0, name, OBJPROP_COLOR, color);
    }

    DeleteObjectsByPrefix():チャートのクリーンアップ

    チャートの乱雑化を防ぎ、リソースを適切に管理するため、このユーティリティ関数は指定されたプレフィックスで始まるすべてのチャートオブジェクトを削除します。対象となるオブジェクトタイプに一致するもののみが削除されます。初期化およびデインストール時に呼び出され、常にクリーンな作業環境を維持します。

    void DeleteObjectsByPrefix(string prefix, ENUM_OBJECT type)
    {
       for(int i = ObjectsTotal()-1; i >= 0; i--)
       {
          string name = ObjectName(i);
          if(StringFind(name, prefix) == 0 && ObjectType(name) == type)
             ObjectDelete(0, name);
       }
    }


    導入ガイド

    この戦略を実装するには、.mq5ソースファイルをターミナルのExpertsフォルダにコピーし、MetaEditor上でF7キーを押してコンパイルします。コンパイルが正常に完了したら、任意の銘柄および時間足のチャートを開き、ナビゲータのエキスパートアドバイザ(EA)パネルからEAをチャートへドラッグ&ドロップします。その後、シグナル処理を有効にするためにアルゴリズム取引が有効化されていることを確認します。

    下のGIFは、MetaEditorでEAを作成し、コンパイルしてMetaTraderで使用可能にするまでの手順を示しています。 

    実行前に、選択した時間足に対して十分な履歴データが取得されていることを確認してください。平均足およびEMAの計算には完全な時系列データが必要です。EAをチャートに適用した後は[エキスパート]タブを確認し、初期化成功メッセージが表示されていれば準備完了です。

    代表的なパラメータには以下が含まれます。

    input ENUM_TIMEFRAMES WorkTF = PERIOD_M15;
    input int ArrowOffsetPoints  = 50;
    input bool EnableAlerts      = true;

    これらのパラメータは、それぞれ時間足の選択、矢印表示位置のオフセット、アラート動作を制御します。ボラティリティやチャートの視認性に応じて適宜調整してください。安定性の観点から、ライブ運用前にはストラテジーテスターのビジュアルモードでテストをおこなうことが推奨されます。パフォーマンスと描画結果が確認できた後、デモ口座またはライブ口座に同じ設定を適用します。 

    EAをコンパイルしてチャートに適用した後は、ライブチャートまたはストラテジーテスターで動作確認が可能です。通常MetaTraderの標準平均足インジケーターを使用している場合でも、バックテスト時にはそれをチャートに追加する必要はありません。このEAはテスト中に独自の平均足を計算し、チャート上に直接描画します。これにより、組み込みインジケーターの有無に関係なく、同一の平均足構造が表示されます。より明確にするため、以下の2種類のテストを実行できます。  

    • 組み込み平均足を無効にしたバックテストでは、EAによって生成された平均足のみが表示されます。
    input bool UseBuiltInHA = false; 
    • 組み込み平均足を有効にしたバックテストでは、チャート上に両方が表示されますが、シグナル判定に使用されるのはEA側の平均足です。
    input bool UseBuiltInHA = true;   

    この設定により、表示されている平均足がプラットフォーム標準ではなく、EA内部計算によるものであることを確認できます。 



    テスト

    初期のバックテストおよびデモ/ライブ環境での観察結果から、平均足EMAフュージョン手法は異なる市場環境下でも一貫した挙動を示すことが確認されました。多層フィルター設計により、シグナルはより選択的になり、短期的なボラティリティよりも持続的な価格変動に沿う傾向が見られます。 視覚的な出力により、チャート上でシグナル条件を容易に検証できます。

    デモ口座におけるライブチャートの結果

    ビジュアルバックテストモードでは、CandleSmoothing EMA Engine.mq5が独自の平均足平滑化ローソク足をチャート上に直接描画します。これはプラットフォーム標準の平均足インジケーターには依存していません。これらのローソク足は、EMA20の高値・安値バンドおよびEMA50のトレンドフィルターとともに表示されるため、全体的な市場構造を一目で把握しやすくなります。

    トレードセットアップが確認されると、インジケーターはチャート上に矢印を描画します。緑の矢印は買いシグナル、赤の矢印は売りシグナルを示します。矢印はローソク足の上下にわずかにオフセットして配置されるため、視認性が確保されます。また、すべてのシグナルは[エキスパート]タブにも出力され、銘柄、時刻、および売買方向が記録されます。これにより、チャート上のシグナルと実際の計算ロジックを照合することが可能になります。このH1バックテストの例では、多層フィルターによって多くの偽シグナルが除去されていることが確認できます。その結果、取引回数は減少しますが、より信頼性が高く、現在の市場モメンタムに整合したエントリーが実現されています。

    バックテストおよびライブ運用の両方において、市場環境の変化に応じてシグナル頻度が調整されることが確認されました。強いトレンド相場では、価格が短期EMA20チャネルをブレイクし、EMA50の傾きが方向性を確認した場合にのみシグナルが発生します。これにより、弱い逆張り的な戻し局面での不要なトレードが回避されます。アラートはバー確定直後に即時出力され、矢印は各シグナルにつき1回のみ描画され、重複は発生しません。これにより、確定バー処理ロジックおよび lastSignalType による重複防止機構が正常に機能していることが確認されます。総合的に見ると、このEAはコモディティ、シンセティック指数、FXペアなど幅広い銘柄において安定した動作を示しています。



    結論

    Candle Smoothing EMA Signal EAの開発および初期テストの結果から、複数のフィルターを組み合わせることで、平均足単体戦略に見られる多くの弱点を改善できることが示されました。実際のテストではEMA20の高値と安値のバンドおよびEMA50のトレンドフィルターを組み合わせることで、シグナル数は減少するものの、より品質が高く市場全体の方向性と一貫性のあるエントリーが得られました。

    バックテスト、デモ環境およびライブ環境のいずれにおいても、本EAはノイズによる反転シグナルや誤シグナルの明確な減少を示しました。テストは複数の銘柄および時間足で実施されており、銘柄、期間、ティックモデル、スプレッド設定などの詳細は再現性を確保するためバックテストセクションに記載されています。

    本EAは自動売買システムや資金管理システムではなく、シグナル確認を目的としたツールとして設計されています。バー確定時にチャート上へ矢印表示、EMAオーバーレイおよびアラートを提供し、裁量取引の判断を補助します。ユーザーは各自で検証をおこない、適切なリスク管理を適用する必要があります。過去のパフォーマンスは将来の結果を保証するものではありません。

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

    添付されたファイル |
    ラリー・ウィリアムズの『市場の秘密』(第6回):市場変動を利用したボラティリティブレイクアウトの測定 ラリー・ウィリアムズの『市場の秘密』(第6回):市場変動を利用したボラティリティブレイクアウトの測定
    MQL5を用いてラリー・ウィリアムズのボラティリティブレイクアウト型エキスパートアドバイザーを設計および実装する方法を解説します。スイングレンジの測定、エントリーレベルの算出、リスクベースのポジションサイジング、さらに実際の市場データを用いたバックテストまでを網羅します。
    トレンド強度の最適化:方向と強さに沿った取引戦略 トレンド強度の最適化:方向と強さに沿った取引戦略
    短期および長期の分析を組み合わせ、全体的なトレンドとその強さに基づいて取引判断および執行をおこなう、トレンドフォロー型のエキスパートアドバイザー(EA)です。本記事では、忍耐力と規律を備え、集中力を維持しながら、トレンドの強さと方向に一致する場合にのみ取引を実行し、特にトレンドに逆らう取引や頻繁なバイアス変更を避け、テイクプロフィットに到達するまでポジションを保持できるトレーダー向けに設計されたEAについて詳しく解説します。
    エラー 146 (「トレードコンテキスト ビジー」) と、その対処方法 エラー 146 (「トレードコンテキスト ビジー」) と、その対処方法
    この記事では、MT4において複数のEAの衝突をさける方法を扱います。ターミナルの操作、MQL4の基本的な使い方がわかる人にとって、役に立つでしょう。
    初心者からエキスパートへ:市場の不規則性への対処 初心者からエキスパートへ:市場の不規則性への対処
    市場のルールは常に変化しており、かつて有効だった原則も、時間の経過とともにその効力を徐々に失っていきます。過去に機能していたものが、現在では一貫して機能しなくなることがあります。本記事では、このような市場の不確実性に対応するために、「確率レンジ(ゾーン)」という考え方に焦点を当てます。さらに、MQL5を用いて、特に値動きが不安定な相場環境でも機能するアルゴリズムの構築方法を解説していきます。ディスカッションにぜひご参加ください。