English Русский 中文 Español Deutsch Português
preview
知っておくべきMQL5ウィザードのテクニック(第44回):ATR (Average True Range)テクニカル指標

知っておくべきMQL5ウィザードのテクニック(第44回):ATR (Average True Range)テクニカル指標

MetaTrader 5テスター |
591 0
Stephen Njuki
Stephen Njuki

はじめに

Average True Rangeは、一般的で人気のあるボラティリティ指標であり、特に外国為替トレーダーにとっては、ボリュームデータの代わりとして最も近い存在と言えるでしょう。このインジケーターは、価格バーの範囲を追跡することを目的として開発され、バー内で発生する価格変動も見逃さないよう設計されています。その結果、エントリーシグナルのフィルタリングだけでなく、ポジションサイズの決定においても重要なガイドとして利用され、業界で広く支持されています。この記事では、これまでのインジケーターに関する記事と同様に、ATRをさまざまなパターンに分解して調査します。ただし、今回の主な違いとして、カスタムシグナルクラスに加えて、ウィザードで組み立てられたエキスパートアドバイザー(EA)のカスタム資金管理クラスを活用し、より幅広いパターンを検討します。

その前に、前回取り上げたインジケーターであるADXを簡単にまとめます。


ADX反転

ADXのパターン6は、顕著なトレンドが終了する際に、ADXのメインバッファが低下することで特徴づけられる反転を指します。ここで簡単にADXをおさらいすると、ADXはトレンドの強さを測定するインジケーターです。オシレーターのメインバッファが急上昇またはスパイクを示す場合、そのトレンドの強さが高いことを意味します。また、DI+およびDI-という2つの補助バッファも存在し、それぞれ価格上昇と価格下落の強さを数値化します。

強気のシグナルは、長期間続いた強い弱気トレンドの後に、ADXのメインバッファが50を超える高い水準から2~3本の価格バーの間で4未満にまで急低下することで示されます。この理論的根拠は、ADXがトレンドの強さを測定するため、現在のトレンドが弱まっており、反転(この場合は強気トレンド)が近づいていることを示唆するというものです。反対に、弱気のシグナルは、長期間続いた強い強気トレンドが、ADXのメインバッファで同様の急低下(高水準から40未満への低下)を示す場合に発生します。これらのパターンを、シグナルクラスで次のように実装しています。

//+------------------------------------------------------------------+
//| Check for Pattern 6.                                             |
//+------------------------------------------------------------------+
bool CSignalADX::IsPattern_6(ENUM_POSITION_TYPE T)
{  if(Base(X()+3) >= 50 && Base(X()) <= 40)
   {  if(T == POSITION_TYPE_BUY && Close(StartIndex()) > Close(StartIndex() + m_ma_period))
      {  return(true);
      }
      else if(T == POSITION_TYPE_SELL && Close(StartIndex()) < Close(StartIndex() + m_ma_period))
      {  return(true);
      }
   }
   return(false);
}

「Patterns Used」入力パラメータに整数値64を割り当てて、このパターンのみをテストすると、次の結果が得られます。

adx_r6


ADXとサポート/レジスタンスのブレイク

パターン7は、検討中のADXパターンの8番目であり、最後から2番目にあたります。このパターンは、ADXのメインバッファにおけるスパイク(急上昇)と、サポートラインまたはレジスタンスラインの突破(ブレイクスルー)を組み合わせたものです。しかし、サポートラインおよびレジスタンスラインの解釈は、手動取引よりもプログラムコードで表現する方が複雑なため、それを補完する二次的な指標としてボリンジャーバンドを活用します。このアプローチについては、RSIやボリンジャーバンドに関する最近の記事で取り上げた他の回避策も参考になります。必要に応じて、それらを再確認し、本記事の内容を拡張する際に役立ててください。

サポートとレジスタンスのブレイクアウトは、ボリンジャーバンドインジケーターの下限または上限を価格が突破することで簡単に定義されます。したがって、強気シグナルは、ADXのメインバッファが25を超えて上昇し、価格がボリンジャーバンドの上限を突き抜けることで示されます。一方で、弱気シグナルは、ADXが同様に上昇し、価格がボリンジャーバンドの下限を下回ることで示されます。これをMQL5では以下のように実装しています。

//+------------------------------------------------------------------+
//| Check for Pattern 7.                                             |
//+------------------------------------------------------------------+
bool CSignalADX::IsPattern_7(ENUM_POSITION_TYPE T)
{  if(Base(X()+2) < 25 && Base(X()) > 25)
   {  if(T == POSITION_TYPE_BUY && Close(StartIndex()) >= Upper(StartIndex()))
      {  return(true);
      }
      else if(T == POSITION_TYPE_SELL && Close(StartIndex()) <= Lower(StartIndex()))
      {  return(true);
      }
   }
   return(false);
}

「Patterns Used」入力パラメータを128に設定して、このパターンのみを使用するウィザードで組み立てられたEAをテストすると、次の結果が得られます。

adx_r7


ADXとRSIの確認

最後のパターン8は、ADXと、これまでに説明したRSIというインジケーターを組み合わせたものです。ADXはトレンドを測定する指標であり、一方のRSIは主に買われすぎや売られすぎのポイントを示すため、ADXの観点からこれら2つを組み合わせる場合には、トレンドの終焉ではなく、上昇トレンドや主要トレンドの進行に注目する必要があります。このため、70/30の閾値に達することよりも、RSIが50レベルを交差するポイントに焦点を当てます。

その結果、強気シグナルは、RSIが50未満から50を超える方向に交差し、かつADXのメインバッファが25未満から25を超える方向に上昇する場合に示されます。これに対して、弱気シグナルは、RSIが50レベルを超えてからその下に下落し、さらにADX値が再び25を超える方向に上昇する場合に示されます。これをMQL5では以下のように実装しています。

//+------------------------------------------------------------------+
//| Check for Pattern 8.                                             |
//+------------------------------------------------------------------+
bool CSignalADX::IsPattern_8(ENUM_POSITION_TYPE T)
{  if(Base(X()+1) < 25 && Base(X()) > 25)
   {  if(T == POSITION_TYPE_BUY && RSI(StartIndex()) > 50 && RSI(StartIndex() + 1) < 50)
      {  return(true);
      }
      else if(T == POSITION_TYPE_SELL && RSI(StartIndex()) < 50 && RSI(StartIndex() + 1) > 50)
      {  return(true);
      }
   }
   return(false);
}

「Patterns Used」入力整数を256に割り当てて、このパターンだけをテストすると、次の結果が得られます。

adx_r8


理想的なADXパターンの最適化

ウィザードで組み立てられたEAについては、この記事の最後に添付されているコードを使用する方法について、こちらこちらのガイド記事で詳しく説明しています。このEAは、これまで検討してきたすべてのADXパターンを使用する場合にも対応可能ですが、それぞれ異なる重み付けを適用する必要があります。ただし、前にも述べたように、このアプローチは必ずしも理想的とは言えません。その理由は、異なるパターンが互いに打ち消し合う傾向があるため、最適化の実行結果が「曲線適合」されたものになりやすいからです。このような結果は、サンプル外データでパフォーマンスを再現するのが難しくなることが多いです。以上を踏まえた上で、これまでに検討してきた9つのADXパターンを組み合わせた際のテスト結果をいくつか以下に示します。

adx_r_all

adx_c_all


ATR

上記ですでに紹介したATRオシレーターは、ボラティリティを測定する指標です。特にボリュームデータが不足している外国為替トレーダーにとって、ATRは非常に重要な役割を果たします。それでは、ATRのパターンについても見てみましょう。その中には、一般的なカスタムシグナルクラス以外でも活用可能なものがあります。


ボラティリティブレイクアウトシグナル

現在のATR値が直近の平均値を大幅に上回る場合、ボラティリティのブレイクアウトを示唆している可能性があります。これに基づく取引戦略では、ATRの急上昇時にブレイクアウトの方向にポジションを取ることが推奨され、市場がその方向に大きな価格変動を起こす可能性が高いと判断します。また、移動平均やMACDなどの補助指標を使用して、取引方向をより明確にすることも可能です。これをMQL5では以下のように実装しています。

//+------------------------------------------------------------------+
//| Check for Pattern 0.                                             |
//+------------------------------------------------------------------+
bool CSignalATR::IsPattern_0(ENUM_POSITION_TYPE T)
{  if(ATR(X()) > ATR(X() + 1) && ATR(X() + 1) > ATR(X() + 2) && ATR(X() + 2) > ATR(X() + 3))
   {  if(T == POSITION_TYPE_BUY && Close(X()) > Close(X() + 1) && Close(X() + 1) > Close(X() + 2) && Close(X() + 2) > Close(X() + 3))
      {  return(true);
      }
      else if(T == POSITION_TYPE_SELL && Close(X()) < Close(X() + 1) && Close(X() + 1) < Close(X() + 2) && Close(X() + 2) < Close(X() + 3))
      {  return(true);
      }
   }
   return(false);
}

この特定のソロパターンをテストし、使用パターンの入力値を「1」に設定した場合、短期間の最適化から得られた好結果の一例として、以下のようなレポートが得られます。最適化は、2022年のEUR/USDペアを対象に、1時間足の時間枠で実施しています。

tar_r0


ブレイクアウト確認のためのATR閾値

ATRはボラティリティを測定する指標であり、ATRを使用したブレイクアウトの確認は非常に重要です。ATRは、指定された期間内の平均的な値幅(高値と安値の差)を算出することで、各新しいバーで価格がどれほど動く傾向があるかをトレーダーに示します。 ブレイクアウトは、価格が事前に定義されたサポートまたはレジスタンスレベルを超える動きとして発生します。したがって、ATRはボラティリティの閾値を活用してブレイクアウトの正確性を確認し、偽のブレイクアウトをフィルタリングする役割を果たします。

ブレイクアウトにおける一般的な課題として、価格が一時的にレベルを突破してもすぐに戻るケースがあります。この問題を解決するために、ATR閾値を補完的に活用することで、価格がサポートやレジスタンスレベルをATR値に基づいた特定の割合(例えば1.5倍や2倍)上回る、または下回る場合にブレイクアウトを有効と判断することができます。 例えば、ATRが20ピップスの場合、サポートまたはレジスタンスレベルを超えて20ピップスの1.5倍、つまり30ピップス以上動いた場合に、本当のモメンタムの変化を示していると判断できます。このようなATRの適用は非常に敏感な反応を示すため、市場のスピードや戦略に応じて異なる設定が必要です。短期取引やボラティリティの高い市場では、通常の14期間ではなく、ATRの期間を短く(例えば7や10に設定)することで適応性が向上します。 一方で、スイングトレードのような中長期取引では、14や20といった長めのATR期間を採用することで、ノイズを減らし、安定したブレイクアウト確認シグナルを提供できます。

しかし、MQL5での実装では、絶対的なATR値と価格変動を追跡する、やや異なるアプローチを採用しています。特定の方向での価格変動が、最適化されたATR閾値を超える場合、その方向に新しいシグナルがトリガーされます。このロジックを以下のコードで実装します。

//+------------------------------------------------------------------+
//| Check for Pattern 1.                                             |
//+------------------------------------------------------------------+
bool CSignalATR::IsPattern_1(ENUM_POSITION_TYPE T)
{  if(ATR(X()) >= m_threshold_points*m_symbol.Point())
   {  if(T == POSITION_TYPE_BUY && Close(X()) > Close(X() + 1) && Close(X() + 1) > Close(X() + 2) && Close(X() + 2) > Close(X() + 3))
      {  return(true);
      }
      else if(T == POSITION_TYPE_SELL && Close(X()) < Close(X() + 1) && Close(X() + 1) < Close(X() + 2) && Close(X() + 2) < Close(X() + 3))
      {  return(true);
      }
   }
   return(false);
}

このパターンのみを使用した最適化のテスト実行では、次の結果が得られます。

tar_r1


エグジットシグナルとしてのATR

ATR(平均真の範囲)は、市場のボラティリティを測定するため、現在の市場状況に応じて動的なエグジットポイントを決定する非常に効果的なツールです。固定されたpip数やポイントに基づくエグジット戦略とは異なり、ATRを基準としたエグジットは市場のボラティリティに適応します。これにより、任意の閾値ではなく、意味のある価格レベルでポジションを終了できるようになります。たとえば、ATR値が突然増加する場合、これは重要な市場イベント(例:FRBの議事録発表など)や潜在的なトレンド反転の兆候を示している可能性があります。こうした場合、トレーダーはATRが特定の閾値を超えたタイミングでポジションを終了することで、トレンドの枯渇や反転のリスクを軽減できます。この差し迫った反転自体がシグナルとして機能するのです。

スイングトレーダーは、さらにATRを活用してポジションのエグジットポイントを調整できます。たとえば、最近のスイング高値や安値にATRの倍数を加算または減算することで、主要な価格レベルでポジションを終了させることが可能です。このアプローチは、平均的な価格変動を考慮に入れることで、重要な反転ポイント付近で合理的なエグジットを提供します。 こうしたATRベースのエグジット戦略を採用することで、特にボラティリティが急上昇し反転や統合フェーズが迫っている際に、不利な状況や不必要なドローダウンへのリスクを減少させることができます。

さらに、レンジ相場(ボラティリティが低い相場)ではATR値が低い傾向にあります。しかし、ATRが突然上昇した場合、それは市場のブレイクアウトやボラティリティの急増を示唆している可能性があります。この場合、レンジ相場内でポジションを保有しているトレーダーは、このATRの上昇をエグジットシグナルとして活用することができます。ここでの重要なルールは、低ボラティリティの状況での早すぎるエグジットを避けることです。これにより、不安定で横ばいの市場に閉じ込められるリスクを回避し、取引における有利なリスク/リターン比率を維持することができます。ただし、MQL5での実装においては、カスタムシグナルクラスを作成してエントリポイントを探すことを目的としているため、やや単純化されています。このパターン2を以下のようにコーディングしています。

//+------------------------------------------------------------------+
//| Check for Pattern 2.                                             |
//+------------------------------------------------------------------+
bool CSignalATR::IsPattern_2(ENUM_POSITION_TYPE T)
{  if(ATR(X()) >= 2.0 * m_threshold_points*m_symbol.Point())
   {  if(T == POSITION_TYPE_SELL && Close(X()) > Close(X() + 1) && Close(X() + 1) > Close(X() + 2) && Close(X() + 2) > Close(X() + 3))
      {  return(true);
      }
      else if(T == POSITION_TYPE_BUY && Close(X()) < Close(X() + 1) && Close(X() + 1) < Close(X() + 2) && Close(X() + 2) < Close(X() + 3))
      {  return(true);
      }
   }
   return(false);
}

ここで提案しているアプローチは、ATR値が最適化された閾値の2倍以上に達してしまった場合にトレンドの反転をシグナルとするものです。しかし、この方法がATRを活用する最善のアプローチというわけではありません。読者の皆さんもお気づきのとおり、私たちはこれまでに、エグジット戦略をより効率的に活用する「より興味深い」方法についても言及してきました。ただし、従来通り、付属のソースコードを編集することで、別のアプローチを試すことが可能です。参考までに、EUR/CHFペアを対象とした簡易的なテストを2022年のデータを用い、1時間足で最適化を実行しました。この短期間の最適化から得られたレポートは以下の通りです。

atr_r2


ボラティリティ収縮シグナル

ATRの収縮は、ボラティリティの拡大、すなわち嵐の前の静けさに備えるためのシグナルとしても機能します。通常、ボラティリティが低い期間は、価格の急騰やボラティリティの急増の前に発生します。一部のトレーダーは、ATRの収縮を監視して、ブレイクアウトが発生する可能性が高い時期を予測し、今後の動きに備えるために位置を取ります。このような収縮の後にATRが突然上昇すると、多くの場合、ブレイクアウトが発生したことを強く示唆します。したがって、トレーダーはATRの収縮を利用して、ボラティリティが再び拡大し始めたタイミングで取引を開始し、トレンドに乗ることができます。

ATR収縮のもう一つの利点は、時間制限付きの出口戦略です。 一部のトレーダーは一定期間後にポジションを終了することがあり、そのため、ATRを使用して停滞しているポジションをいつクローズするかを判断することが非常に有効です。ATRが低い、または時間の経過とともに減少している場合、それは勢いの減少を示しており、ポジションを保持しても大きな動きが期待できないため、ポジションを終了するのが理にかなっています。 トレンドフォロー戦略では、ATRの収縮も有効です。 強いトレンドの中で収縮が始まると、トレンドの勢いが失われ、統合が始まる可能性があることを示唆します。この場合、トレンドフォロワーにとっては、反転に備えたり、利益を確定したりする良いタイミングとなります。トレンドトレーダーにとっては、一時的な撤退は理にかなっているかもしれません。

スイングトレーダーにとって、ATRの収縮は価格が統合フェーズに入り、動きが停滞していることを示唆しており、この時点でポジションを解消し、横ばいの動きに巻き込まれないようにするべきです。逆に、収縮が終わると、スイングトレーダーはボラティリティが再び拡大し始めた時点でエントリーポイントを探し始めます。また、スイングトレーダーはATR収縮を使ってレンジ相場を特定し、レンジ内でサポートで買い、レジスタンスで売る戦略を取ることができます。ブレイクアウトやブレイクダウンが発生するまでこのようにレンジ取引をおこないます。

また、特に不透明な外国為替市場において、ATRの収縮は取引量の減少と同時に発生することが多く、これは市場参加者が優柔不断であることを示していることが多いです。取引量が増加し、ATRが再び拡大すると、新たな流動性が市場に流入し、ブレイクアウトの可能性が高くなることを示唆します。ATRの収縮とそれに続く取引量の急増を組み合わせることで、ボラティリティ拡大のタイミングでエントリーを狙うブレイクアウトトレーダーにとって、重要な確認となります。 この記事では、ATR収縮をエントリーシグナルとして使用し、反転の兆しを捉える方法を紹介します。これらの保留中の反転は、予測される価格の方向を定義します。例えば、ATRが下降トレンドの後に減少した場合、反発が予想され、強気のシグナルとして解釈します。一方、ATRの収縮が強気相場の終わりに発生した場合、これは弱気のシグナルと見なすことができます。この効果を実現するコードを以下に示します。

//+------------------------------------------------------------------+
//| Check for Pattern 3.                                             |
//+------------------------------------------------------------------+
bool CSignalATR::IsPattern_3(ENUM_POSITION_TYPE T)
{  if(ATR(X()) < ATR(X() + 1) && ATR(X() + 1) < ATR(X() + 2) && ATR(X() + 2) < ATR(X() + 3))
   {  if(T == POSITION_TYPE_SELL && Close(X() + 3) > Close(X() + 4) && Close(X() + 4) > Close(X() + 5) && Close(X() + 5) > Close(X() + 6))
      {  return(true);
      }
      else if(T == POSITION_TYPE_BUY && Close(X() + 3) < Close(X() + 4) && Close(X() + 4) < Close(X() + 5) && Close(X() + 5) < Close(X() + 6))
      {  return(true);
      }
   }
   return(false);
}

「Patterns Used」入力パラメータを8として、パターン3のみを使用する最適化結果の一部をテスト実行すると、次の結果が得られます。

atr_r3


ATRチャネル(ATRバンド)

ATRチャネル(ATRバンドとも呼ばれる)は、ATRの倍数を使用して、価格の上下にプロットされる動的なボラティリティベースのバンドです。ボリンジャーバンドと同様に、価格の周りにチャネルを作成し、この特定のケースでは市場のボラティリティを反映するのに役立ちます。

これらのバンドは、価格変動に基づいて拡大および縮小し、トレーダーに対して、特定の期間内に価格が平均からどの程度変動するかの感覚を提供します。また、上限バンドと下限バンドはそれぞれ、動的なサポートおよびレジスタンスレベルとして機能します。価格はこれらのバンド内で変動する傾向があり、これらの「レベル」に触れたり突破したりすると、潜在的な反転や継続のシグナルが生成される可能性があります。静的なサポートやレジスタンスレベルとは異なり、これらのバンドは市場の状況に応じて動的に変化するため、より敏感に反応します。

したがって、これらのバンドから得られるシグナルは、価格が上部のATRバンドを突破すると強気のトレンドや買い圧力の高まりを示し、下部のATRバンドを下回ると弱気のトレンドや売り圧力を示唆します。手動で取引するトレーダーは、これらのバンドを物理的にプロットするカスタムインジケーターを実装する必要がありますが、私たちの場合はウィザードで組み立てたEA(新規読者向けのガイドはこちらこちら)を使用しているため、この点について心配する必要はありません。取引プロセスを自動化しているため、価格移動平均とATRの二つのインジケーターから得られるデータを取得し、それらを合計して新しいバーごとにバンドを定義することができます。MQL5では次のようにパターンを実装します。

//+------------------------------------------------------------------+
//| Check for Pattern 4.                                             |
//+------------------------------------------------------------------+
bool CSignalATR::IsPattern_4(ENUM_POSITION_TYPE T)
{  if(T == POSITION_TYPE_BUY && Close(X()) > MA(X()) + 2.0 * ATR(X()))
   {  return(true);
   }
   else if(T == POSITION_TYPE_SELL && Close(X()) < MA(X()) - 2.0 * ATR(X()))
   {  return(true);
   }
   return(false);
}

このようなバンドは、ボリンジャーバンドやケルトナーチャネルなどの他のインジケーターと併用することで、ブレイクアウトが十分に重要であることを確認し、偽のブレイクアウトをフィルタリングするなどの追加的な役割を果たすことができます。ATRチャネルのその他の用途は、前述の内容と重複する部分もありますが、それでも触れておく価値があります。ATRチャネルは、トレンドの強さと方向を識別するのに非常に役立ちます。価格が一貫してATRバンドの上限付近で動く場合、強い強気トレンドを示唆します。同様に、価格が下限バンドに沿って動いている場合は、強い弱気トレンドを示していることがわかります。このトレンドの発見は、大きな時間枠で急激に変動する市場において特に有効です。逆に、価格がATRバンドを突破するのに苦労したり、フォロースルーなく頻繁にバンドに触れたりする場合、それはトレンドの枯渇や勢いの減退を示唆する可能性があります。

また、トレーダーは特にレンジ相場において、ATRバンドを使って平均回帰の機会を見つけることができます。価格が上限または下限のバンドに触れると、資産が過剰に買われているか、過剰に売られていることを示しており、平均価格への反転が起こる可能性が高まります。 したがって、検討する時間枠によりますが、価格が上限または下限のATRバンドを突破せずに反発する場合、それはトレーダーに利益確定やポジションの反転のサインを示すことになります。

ボラティリティベースでテイクプロフィットを設定する際、これらのバンドは動的なレベルを提供します。ATRバンドのすぐ外側にテイクプロフィットを設定すると、通常の市場ノイズによって利益を失うことなく、価格がバンド内で変動する余地を確保できます。これは、カスタムシグナルクラスを使用しているため、パターン4の実装では考慮されませんでしたが、別のウィザードで組み立てたEAのカスタムトレーリングクラスでは機能する可能性があります。テストランは、上記で使用した設定と同様に、EUR CHF、1時間足、2022年で最適化スティントを実施した結果、次のようになりました。

atr_r4

次に、これらすべてのシグナルを1つにまとめ、さまざまな重みを使用して最適化を実行すると、好ましい最適化実行の1つから次のテスト実行が得られます。

atr_r_all

atr_c_all


トレーリングクラスにおけるATR

ATRを使用してEAのエントリーシグナルやエグジットシグナルを生成する方法については、以前検討しましたが、これは必ずしもその主な目的や使用方法ではありません。主にATRはストップの配置や、最大でもポジションサイズの決定に使用されます。そのため、これらの機能を、MQL5ウィザードを介してEA内で組み立てられるカスタムクラスの中でどのように利用するかを見ていきます。

ここでは、実装をシンプルに保ち、トレーリングストップレベルを定義するために、単純にベンチマークをATRの倍数だけ増加させる方法を採用します。このベンチマークには、3つの形式があります。生の価格、移動平均価格、およびSARインジケーターの価格レベルです。それぞれが独自のパターンを提供し、これをインデックス0、1、2で管理し、以下のようにコーディングします。

//+------------------------------------------------------------------+
//| Check for Pattern 0.                                             |
//+------------------------------------------------------------------+
void CTrailingATR::IsPattern_0(double &Price, ENUM_POSITION_TYPE T)
{  if(T == POSITION_TYPE_BUY)
   {  Price -= (m_stop_level * ATR(StartIndex()));
   }
   else if(T == POSITION_TYPE_SELL)
   {  Price += (m_stop_level * ATR(StartIndex()));
   }
}
//+------------------------------------------------------------------+
//| Check for Pattern 1.                                             |
//+------------------------------------------------------------------+
void CTrailingATR::IsPattern_1(double &Price, ENUM_POSITION_TYPE T)
{  if(T == POSITION_TYPE_BUY)
   {  Price = (MA(StartIndex()) - (m_stop_level * ATR(StartIndex())));
   }
   else if(T == POSITION_TYPE_SELL)
   {  Price = (MA(StartIndex()) + (m_stop_level * ATR(StartIndex())));
   }
}
//+------------------------------------------------------------------+
//| Check for Pattern 2.                                             |
//+------------------------------------------------------------------+
void CTrailingATR::IsPattern_2(double &Price, ENUM_POSITION_TYPE T)
{  if(T == POSITION_TYPE_BUY && SAR(StartIndex()) < Low(StartIndex()))
   {  Price = (SAR(StartIndex()) - (m_stop_level * ATR(StartIndex())));
   }
   else if(T == POSITION_TYPE_SELL && SAR(StartIndex()) > High(StartIndex()))
   {  Price = (SAR(StartIndex()) + (m_stop_level * ATR(StartIndex())));
   }
}

最適化とテスト実行は、上記のようにパターンごとに実施できますが、簡潔さを重視して、異なる重み付けで全てのパターンの使用を最適化する1回の実行のみをおこないます。その結果は以下の通りです。

atr_t_all

atr_c_t_all


マネーマネジメントにおけるATR

ストップロスギャップはポジションサイズを設定する際に有用です。その理由は、ポジションを保有している場合、取引が不利になった場合にそのポジションで発生する最大損失を制限するのがストップロスであるという考え方に基づいています。したがって、ストップロスギャップのティック値を測定することによって、その時点でフリーマージンの設定されたパーセンテージを超えないポジションサイズをロット単位で算出することができます。

ストップロスレベルと最大リスク率を設定すれば、理論的には損失を抑えるロット数を算出できます。これは理論的な話であり、ストップロスは価格を保証するものではないためです。ストップロスは、その価格が実際に利用可能である場合にのみ発動されます。これが理由で、2015年1月はCHFトレーダーにとって非常に厳しい月となりました。では、最善の保険は何でしょうか。それは、最小限かつ責任を持ったポジションサイズです。もし、上記で説明したように3つの異なるストップロスメソッドを採用した場合、カスタムマネーマネジメントクラスに3つの並列パターンを実装する方法は次のようになります。

//+------------------------------------------------------------------+
//| Getting lot size for open long position.                         |
//+------------------------------------------------------------------+
double CMoneyATR::CheckOpenLong(double price, double sl)
{  if(m_symbol == NULL)
      return(0.0);
//--- select lot size
   double lot;
   if(price == 0.0)
      lot = m_account.MaxLotCheck(m_symbol.Name(), ORDER_TYPE_BUY, m_symbol.Ask(), m_percent);
   else
      lot = m_account.MaxLotCheck(m_symbol.Name(), ORDER_TYPE_BUY, price, m_percent);
//---
   double result  = 0.0, results = 0.0;
   price =m_symbol.Bid();
//--- if the model 0 is used and "ATR-Based Stop Loss"
   if(((m_patterns_usage & 0x01) != 0))
   {  IsPattern_0(price, POSITION_TYPE_BUY);
      result += m_pattern_0 * price;
      results += m_pattern_0;
   }
//--- if the model 1 is used and "ATR-MA-Channel Stop Loss"
   if(((m_patterns_usage & 0x02) != 0))
   {  IsPattern_1(price, POSITION_TYPE_BUY);
      result += m_pattern_1 * price;
      results += m_pattern_1;
   }
//--- if the model 2 is used and "ATR-SAR-Channel Stop Loss"
   if(((m_patterns_usage & 0x04) != 0))
   {  IsPattern_2(price, POSITION_TYPE_BUY);
      result += m_pattern_2 * price;
      results += m_pattern_2;
   }
//---
   if(results > 0)
   {  result /= results;
      double _risk = (fabs(m_symbol.Bid()-result)/m_symbol.Point())*(m_symbol.TickSize()/m_symbol.Point())*m_symbol.TickValue();
      _risk /= m_account.FreeMargin();
      _risk *= 100.0;
      double _risk_lots = m_percent/_risk;// where m_percent is also max risk
      lot = fmin(2.0*lot, fmax(_risk_lots, m_symbol.LotsMin()));
   }
//--- return trading volume
   return(Optimize(lot));
}
//+------------------------------------------------------------------+
//| Getting lot size for open short position.                        |
//+------------------------------------------------------------------+
double CMoneyATR::CheckOpenShort(double price, double sl)
{  if(m_symbol == NULL)
      return(0.0);
//--- select lot size
   double lot;
//---
   if(price == 0.0)
      lot = m_account.MaxLotCheck(m_symbol.Name(), ORDER_TYPE_SELL, m_symbol.Bid(), m_percent);
   else
      lot = m_account.MaxLotCheck(m_symbol.Name(), ORDER_TYPE_SELL, price, m_percent);
//---
   double result  = 0.0, results = 0.0;
   price =m_symbol.Ask();
//--- if the model 0 is used and "ATR-Based Stop Loss"
   if(((m_patterns_usage & 0x01) != 0))
   {  IsPattern_0(price, POSITION_TYPE_SELL);
      result += m_pattern_0 * price;
      results += m_pattern_0;
   }
//--- if the model 1 is used and "ATR-MA-Channel Stop Loss"
   if(((m_patterns_usage & 0x02) != 0))
   {  IsPattern_1(price, POSITION_TYPE_SELL);
      result += m_pattern_1 * price;
      results += m_pattern_1;
   }
//--- if the model 2 is used and "ATR-SAR-Channel Stop Loss"
   if(((m_patterns_usage & 0x04) != 0))
   {  IsPattern_2(price, POSITION_TYPE_SELL);
      result += m_pattern_2 * price;
      results += m_pattern_2;
   }
//---
   if(results > 0)
   {  result /= results;
      double _risk = (fabs(result-m_symbol.Ask())/m_symbol.Point())*(m_symbol.TickSize()/m_symbol.Point())*m_symbol.TickValue();
      _risk /= m_account.FreeMargin();
      _risk *= 100.0;
      double _risk_lots = m_percent/_risk;// where m_percent is also max risk
      lot = fmin(2.0*lot, fmax(_risk_lots, m_symbol.LotsMin()));
   }
//--- return trading volume
   return(Optimize(lot));
}

このアプローチには、ストップロス価格が利用可能であることに過度に依存するという弱点があるほか、ストップロスギャップが非常に小さい場合には、過度に大きなロットサイズが割り当てられるリスクもあります。したがって、ロット数が余剰証拠金のデフォルトリスクパーセントで得られるロットの2倍を超えないように正規化します。このため、リスクパーセント(m_percent)には2つの目的があります。1つ目は、余剰証拠金の割合としてロット数を購入する場合の上限を定義すること、2つ目は、ストップロスが設定されたレベルにある場合に失う余剰証拠金の名目上の最大パーセントを定義することです。

上記と同様の設定で、最適化結果の中から最良のものを使ってテストを実行したところ、次のような結果が得られました。

atr_m_r_all

atr_m_c_all

もう一度、パターンごとにテストを実行したわけではなく、上記のトレーリングストップと同様に、異なる重みを付けてすべてのパターンを使用するようにEAを最適化しただけです。


結論

前回の記事で検討したADXインジケーターの考察を終え、ATRインジケーターについても開始から完了までを取り上げました。この記事では、ATRに関するさまざまなアイデアや実装が提案されましたが、簡潔さを保つため、コード化やテストはおこなっていません。そのため、読者はこれらのアイデアを自ら実装し、理想的にはさらに多くの銘柄や履歴データを使ってテストをおこない、各自の状況に最適な方法を見つけ出すことができます。

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

添付されたファイル |
MoneyWZ_44.mqh (13.81 KB)
TrailingWZ_44.mqh (11.24 KB)
SignalWZ_44.mqh (15.63 KB)
wz_44_signal.mq5 (7.47 KB)
wz_44_trail.mq5 (8.35 KB)
wz_trail_mm_44.mq5 (9.07 KB)
MQL5経済指標カレンダーを使った取引(第1回):MQL5経済指標カレンダーの機能をマスターする MQL5経済指標カレンダーを使った取引(第1回):MQL5経済指標カレンダーの機能をマスターする
この記事では、まず、MQL5経済指標カレンダーの基本機能を理解し、それを取引に活用する方法を探ります。次に、MQL5で経済指標カレンダーの主要機能を実装し、取引の判断に役立つニュースを取得する方法を説明します。最後に、この情報を活用して取引戦略を効果的に強化する方法を紹介します。
主成分を用いた特徴量選択と次元削減 主成分を用いた特徴量選択と次元削減
この記事では、Luca Puggini氏とSean McLoone氏による論文「Forward Selection Component Analysis: Algorithms and Applications」に基づき、修正版のForward Selection Component Analysis (FSCA)アルゴリズムの実装について詳しく解説します。
リプレイシステムの開発(第55回):コントロールモジュール リプレイシステムの開発(第55回):コントロールモジュール
この記事では、開発中のメッセージシステムに統合できるように、コントロールインジケーターを実装します。それほど難しくはありませんが、このモジュールの初期化について理解しておくべき細かい点がいくつかあります。ここで提示される資料は教育目的のみに使用されます。示された概念を学習し習得する以外の目的での利用は決して想定されていません。
MacOSでのMetaTrader 5 MacOSでのMetaTrader 5
macOS上のMetaTrader 5取引プラットフォーム用の特別なインストーラーを提供します。これは、アプリケーションをネイティブにインストールできる本格的なウィザードです。インストーラーは、システムの識別、最新のWineバージョンのダウンロードとインストール、設定の適用、その後のMetaTraderのインストールまで、すべての手順を自動で実行します。インストールが完了すると、すぐにプラットフォームを使用できます。