English Русский Deutsch
preview
プライスアクション分析ツールキットの開発(第61回):3スイング検証による構造的傾斜トレンドラインブレイクアウト

プライスアクション分析ツールキットの開発(第61回):3スイング検証による構造的傾斜トレンドラインブレイクアウト

MetaTrader 5 |
22 0
Christian Benjamin
Christian Benjamin

内容


はじめに

前回の記事では、傾斜トレンドラインを実用的な市場方向の分析手法として描画するための、体系的なアプローチを構築しました。これは、市場の方向性を理解し、価格が変化する市場構造の中でどのように動いているかを把握するための方法です。 有効性が確認されたスイングポイントを基準にトレンドラインを引くことで、分析を直接的な市場構造に基づいたものにし、裁量的なライン配置を排除しつつ一貫性を高めることができます。

本記事では、その基盤をさらに発展させ、傾斜トレンドラインをブレイクアウトシグナルの生成フレームワークへ拡張した、強化版の分析ツールを紹介します。トレンドラインブレイクアウトは、プライスアクショントレードにおいて最も重要かつ広く利用されている戦略の一つです。これは、蓄積された市場の圧力が解放され、方向性を持った値動きへ移行する瞬間を示すためです。このアプローチでは、システムがトレーダーに代わって市場構造の分析を実行します。有効なトレンドラインを体系的に検出し、意味のあるブレイクのみをシグナルとして通知することで、トレンドラインブレイクアウト手法をより明確で規律ある、そして実行しやすいものにします。

このツールは、MQL5プログラミング言語を使用して開発されています。 以降のセクションでは、まず戦略のロジックを説明し、その後、その構造をどのようにMQL5コードへ変換するかを解説します。さらに、テスト内容と確認された結果を検証したうえで、最後に総括として考察をまとめます。



戦略の概要

トレンドラインブレイクアウトは、プライスアクショントレードで最も早い段階から紹介されてきた概念の一つであり、方向性の判断、市場構造の理解、そしてモメンタム形成を把握するための基礎的なツールです。しかし時間の経過とともに、多くのトレーダーは、精密な分析を約束する一方で不要なノイズを増やす、より複雑な戦略を追求する中で、こうした基本原則から離れていくことがあります。その結果、過剰分析や一貫性のないトレード判断につながることも少なくありません。本アプローチでは、複雑さを追加するのではなく、明確な構造ルールと規律ある実行を中心に、トレンドラインブレイクアウトを捉え直します。将来何が起こるかを予測するのではなく、価格が現在どのような動きをしているかという客観的な事実に焦点を当てます。

動的なサポートとレジスタンスとしてのトレンドライン

トレンドラインは、サポートとレジスタンスを構造的に表したものです。多くのトレーダーは、水平方向のサポートラインやレジスタンスラインに馴染みがあります。これらは、過去に市場が何度も反応した価格帯に引かれるラインです。こうした水平ラインは、価格が比較的固定された範囲内で往復するレンジ相場や保ち合い局面において、特に有効に機能します。

図1:保ち合い相場における水平サポートとレジスタンス

図1では、レンジ相場における水平サポートとレジスタンスを示しています。丸で囲まれた部分は、同じ価格水準で繰り返し発生している価格反応を示しており、これらのゾーンがテクニカル上重要であることを確認できます。このような環境では、価格は横方向へ推移し、一定の範囲内で上下するため、サポートとレジスタンスは比較的固定された状態を維持します。しかし、保ち合いは一時的な状態です。価格がトレンドへ移行すると、上昇トレンドでは高値切り上げと安値切り上げ、下降トレンドでは高値切り下げと安値切り下げを形成し始めます。このような状況では、サポートとレジスタンスは固定されたものではなくなり、方向性を持つ圧力に合わせて変化し、価格とともに進化していきます。

傾斜トレンドラインは、この動的な動きをスイングポイント同士を結ぶことで表現します。上昇トレンドでは、上昇するスイング安値を結ぶことで、買い圧力が継続的に入る領域を示す動的サポートラインになります。下降トレンドでは、下降するスイング高値を結ぶことで、売り圧力が繰り返し発生する領域を示す動的レジスタンスラインになります。トレンドラインは単なる価格水準を示すだけではありません。トレンドの角度、強さ、継続性も表現するため、単独の水平価格帯を見るよりも、価格が時間の経過とともにどのように推移しているかをより明確に把握できます。

傾斜トレンドラインブレイクアウトの例

図2:強気の傾斜トレンドラインブレイクアウト

図2では、有効性が確認されたスイングポイントから構築された、強気の傾斜トレンドラインブレイクアウトを示しています。丸で囲まれた部分は、下降傾斜トレンドラインを構築するために使用されたスイングポイントです。このラインは、下降トレンド中に動的レジスタンスとして機能しています。価格がこのラインへ繰り返し接触することで、その有効性が確認されます。ブレイクアウトは、価格が傾斜トレンドラインを明確に上抜けた場合にのみ認識されます。これは、売り圧力が弱まり、市場の主導権が変化していることを示します。

この例は、スイング検出、トレンドライン構築、ブレイクアウト確認が組み合わさることで、戦略内で明確なルールベースのシグナルを生成できることを示しています。 

トレンドラインブレイクアウトの重要性

傾斜トレンドラインは、トレンド市場における変化するサポートとレジスタンスを表します。価格が確立されたトレンドラインを明確に突破した場合、そのトレンドを維持していた方向性の圧力が弱まっていることを示します。このようなブレイクは、反転、より深い調整、または反対方向への加速など、市場動向の大きな変化に先行することがあります。

実際のトレンドラインブレイクアウト取引における問題は、概念そのものではなく、どのようにブレイクを判断するかにあります。多くの失敗するセットアップは、構造的な根拠を持たないトレンドラインや、一時的な価格侵入を有効なブレイクとして判断することから発生します。このような早すぎるシグナルはノイズを増やし、タイミングを悪化させ、一貫性を損ないます。これを防ぐため、この戦略では厳格な構築ルールと確認ルールを採用します。トレンドラインは明確なスイング構造から作成されなければならず、ブレイクアウトは価格がラインに単純に接触したり、一時的に突き抜けたりした場合ではなく、ラインの片側から反対側へ明確にクロスした場合のみ認識されます。

さらに信頼性を高めるため、トレンドラインは3つのスイングポイントを使用して検証されます。幾何学的には2点があればラインを定義できます。しかし、2点だけでは価格がそのラインに対して有意な反応を示している証明にはなりません。3つ目のスイングポイントが加わることで、同じ傾斜水準で価格が繰り返し反応していることが確認されます。この条件によって偶然一致したラインを排除し、実際の市場構造上意味を持つトレンドラインだけをブレイクアウト分析の対象にできます。

図3:3スイングによるトレンドライン検証

この図では、3つ目のスイングが同じ傾斜構造上で価格が繰り返し反応していることを示し、トレンドラインの有効性を確認する役割を説明しています。

戦略ロジックとシグナル生成

このツールでは、トレンドラインは検証済みのスイングポイントだけを使用して厳密に構築されます。これにより、各ラインが実際の市場動向を反映するようになります。さらに、同じトレンドラインに対して複数回のスイング接触を要求することで、その有効性を確認してからシグナル生成に利用します。

有効な傾斜トレンドラインが確立された後、以下の条件でシグナルを生成します。

  • 買いシグナル:価格が検証済みの傾斜レジスタンストレンドラインを明確に上抜ける
  • 売りシグナル:価格が検証済みの傾斜サポートトレンドラインを明確に下抜ける

ブレイクアウトの確認には、単純な接触判定ではなく価格のクロス判定ロジックを使用します。これによりノイズを抑制し、誤ったシグナルを減らします。スイング検出、トレンドライン構築、ブレイクアウト検証を体系的に処理することで、この分析は裁量的なライン配置から解放され、一貫した判断を維持しながら、純粋なプライスアクションの原則に沿ったものになります。

次のセクションでは、この構造をどのようにMQL5へ実装するかを解説します。スイング検出、トレンドライン検証、ブレイクアウト確認を、統一されたワークフローとして管理するコードへの変換方法を示します。



MQL5での実装

このセクションでは、戦略ロジックをどのようにMQL5の実装へ変換するかを解説します。コードは、スイング検出、トレンドライン検証、ブレイクアウト確認をそれぞれ担当するモジュール構造として整理されています。これにより、ロジックを明確に保ちながら、後から機能を拡張しやすい設計になっています。以下の実装手順を確認しながら、各要素がどのように組み合わされて動作するのかを見ていきます。

入力パラメータの設定

EAでは、まずトレード環境や分析スタイルに合わせて動作をカスタマイズできるよう、包括的な入力パラメータを定義します。これらのパラメータには、スイング検出に関する設定が含まれます。たとえば、過去何本のバーを確認するかを指定するSwingLookbackや、最小スイングサイズを設定するMinSwingSize があります。最小スイングサイズは、ATRを基準に設定することも、固定値として設定することも可能です。また、動的なスイングサイズ調整のためにATRフィルタを使用するかどうかをUseATRFilteringで選択できます。さらに、チャート上にスイングポイントやラベルを表示するかどうかも設定できます(ShowSwingPoints:スイングポイントの表示設定、ShowSwingLabels:スイングラベルの表示設定)。トレンドライン関連の設定では、レジスタンストレンドラインを描画するかどうかを指定するDrawResistanceLine、サポートトレンドラインを描画するかどうかを指定するDrawSupportLine、これらのラインをチャート右端まで延長するかどうかを設定するExtendToRightEdge、そしてラインが有効と判断されるために必要な最小接触回数を指定するMinTouchPointsRequiredなどを設定できます。

input int    SwingLookback = 5;
input double MinSwingSize = 0.0003;
input bool   UseATRFiltering = true;
input bool   ShowSwingPoints = true;
input bool   ShowSwingLabels = false;

input bool   DrawResistanceLine = true;
input bool   DrawSupportLine = true;
input bool   ExtendToRightEdge = true;
input int    MinTouchPointsRequired = 3;

input double ThirdSwingToleranceATR = 0.15;
input bool   RequireThirdSwingAfterAnchor2 = true;

input bool   EnableBreakoutSignals = true;
input bool   BreakoutUseClose = true;
input int    BreakoutBufferPoints = 5;
input bool   AlertOnBreakout = false;
input bool   PermanentArrows = true;

input color  BullArrowColor = clrLimeGreen;
input color  BearArrowColor = clrRed;

3つ目のスイングポイントを使用してトレンドラインを検証するために、ATRを基準とした許容範囲を設定するThirdSwingToleranceATRや、信頼性を高めるために3つ目のスイングが2つ目のアンカーポイントより後に発生する必要があるかを指定するRequireThirdSwingAfterAnchor2などのパラメータが用意されています。ブレイクアウト検出に関する設定では、シグナル機能を有効または無効にするEnableBreakoutSignals、終値を基準に検出するか、ローソク足のヒゲを基準に検出するかを選択するBreakoutUseClose、確認用としてトレンドラインを超える必要があるポイント幅を設定するBreakoutBufferPoints、アラートを有効にするかどうかを指定するAlertOnBreakout、そしてチャート上に永続的な視覚矢印を配置するかどうかを設定するPermanentArrowsなどがあります。さらに、色、ライン幅、ラインスタイル、矢印サイズなどの表示カスタマイズ項目も用意されており、チャート表示を好みに合わせて調整できます。

グローバル変数とデータ構造体

このロジックを実現するために、実装では少数のグローバル変数とデータ構造体を管理します。ATR用のインジケーターハンドル(atrHandle)が初期化され、最新のATR値を保持する変数(currentATR)が用意されます。また、スイングポイントを保持するための配列(significantHighs、significantLows)と、ブレイクアウト情報を格納するための配列(breakoutsArray)が作成されます。

int    atrHandle = INVALID_HANDLE;
double currentATR = 0.0001;

struct SwingPoint
{
   datetime          time;
   double            price;
   int               barIndex;
   double            size;
   bool              isHigh;
   int               order;
};

struct BreakoutInfo
{
   datetime          time;
   double            price;
   bool              isBullish;
   string            lineType;  // "RES" or "SUP"
   int               touchCount;
};

2つの構造体が定義されています。1つ目のSwingPointは、時間、価格、バーインデックス、サイズ、高値または安値であるかどうか、そして順序などの情報を保持します。2つ目のBreakoutInfoは、確認された各ブレイクアウトについて、タイムスタンプ、価格、ラインタイプ、接触回数を記録します。

SwingPoint significantHighs[10], significantLows[10];
BreakoutInfo breakoutsArray[];
int breakoutsCount = 0;

これらの構造体によってデータを論理的に整理できるため、スイングポイントの処理、トレンドラインの検証、ブレイクアウトイベントの記録を体系的に実行できます。

ユーティリティ関数

ユーティリティ関数は、分析処理の中心となるロジックを支える重要な処理を提供します。DeleteObjectsByPrefixは、チャート上をスキャンして指定されたプレフィックスを持つすべてのオブジェクトを削除します。これにより、新しいトレンドラインやポイントを再描画する前に、古い表示要素を整理できます。BreakoutBufferPriceとThirdSwingTolerancePriceは、それぞれポイント数とATRを基準にバッファ範囲を計算します。これらの値は、ブレイクアウト確認や、スイングポイントとトレンドラインとの距離判定に使用されます。

void DeleteObjectsByPrefix(const string prefix)
{
   int total = ObjectsTotal(0, -1, -1);
   for(int i = total - 1; i >= 0; i--)
   {
      string name = ObjectName(0, i, -1, -1);
      if(StringLen(name) >= StringLen(prefix) && StringSubstr(name, 0, StringLen(prefix)) == prefix)
         ObjectDelete(0, name);
   }
}

LinePriceAtTimeは、指定した時間におけるトレンドライン上の補間価格を計算します。これは、傾斜したラインを視覚化し、その有効性を検証するための基本的な処理になります。

double LinePriceAtTime(const SwingPoint &a, const SwingPoint &b, datetime t)
{
   double dt = (double)(b.time - a.time);
   if(dt == 0.0)
      return a.price;
   double slope = (b.price - a.price) / dt;
   return a.price + slope * (double)(t - a.time);
}

ThirdSwingConfirms関数は、3つ目のスイングポイント(高値または安値)がトレンドラインの許容範囲内に位置しているかを確認し、そのトレンドラインの有効性を検証します。DrawPermanentArrowは、ブレイクアウトが発生した位置に視覚的な矢印マーカーを作成します。強気または弱気のブレイクアウトを示し、そのイベント情報をbreakoutsArrayへ保存します。RedrawPermanentArrowsは、保存されているブレイクアウトデータを順番に処理して矢印を再描画し、表示状態を維持します。OnInit、OnDeinit、OnTick関数は、初期化、終了処理、更新処理を管理します。これらの処理には、ATR値の更新、古いオブジェクトの削除、新しいローソク足ごとの分析処理の実行などが含まれます。

bool ThirdSwingConfirms(const SwingPoint &a, const SwingPoint &b, const SwingPoint &c)
{
   double lp = LinePriceAtTime(a, b, c.time);
   return (MathAbs(c.price - lp) <= ThirdSwingTolerancePrice());
}

スイングポイントの検出

FindSignificantSwings関数は、直近のバーを体系的にスキャンし、有効なスイングハイとスイングローを検出します。この関数では、範囲外参照を防ぐため、SwingLookback分のオフセットを考慮した位置からバーの確認を開始します。各バーについて、高値が周囲のバーより高いかどうかを確認し、スイングハイを検出します。同様に、安値が周囲のバーより低いかどうかを確認することで、スイングローを判定します。その後、高値と安値の差からスイングサイズを計算し、それを最小サイズの条件と比較します。この最小サイズは、ATRを基準にすることも、固定値として設定することもできます。条件を満たしたスイングポイントは、時間、価格、バーインデックス、サイズ、種類などの情報とともに、それぞれ対応する配列へ保存されます。この処理によって、トレンドラインの描画対象となるのは重要なスイングポイントのみとなり、小さな価格変動によるノイズを除外できます。

void FindSignificantSwings(const MqlRates &rates[], int totalBars,
                           SwingPoint &highs[], int &highCount,
                           SwingPoint &lows[], int &lowCount)
{
   highCount = 0;
   lowCount  = 0;

   double minSize = UseATRFiltering ? (currentATR * 0.8) : MinSwingSize;

   for(int i = SwingLookback; i < totalBars - SwingLookback; i++)
   {
      // Swing high detection
      bool isSwingHigh = true;
      double currentHigh = rates[i].high;
      for(int j = 1; j <= SwingLookback; j++)
      {
         if(rates[i-j].high >= currentHigh || rates[i+j].high >= currentHigh)
         {
            isSwingHigh = false;
            break;
         }
      }
      if(isSwingHigh)
      {
         // Save swing high info
         ...
      }

      // Swing low detection
      bool isSwingLow = true;
      double currentLow = rates[i].low;
      for(int j = 1; j <= SwingLookback; j++)
      {
         if(rates[i-j].low <= currentLow || rates[i+j].low <= currentLow)
         {
            isSwingLow = false;
            break;
         }
      }
      if(isSwingLow)
      {
         // Save swing low info
         ...
      }
   }
}

スイング順序の割り当て

スイングポイントが検出された後、AssignSwingOrder関数は、それぞれのタイムスタンプを基準に、古いものから新しいものへ時系列順に並べ替えます。この順序付けは重要です。トレンドラインは、特定のスイングポイントを順番に結ぶことで描画されるためです。並べ替えが完了すると、各スイングポイントには順序番号が割り当てられます。最も古いスイングポイントを1番として、以降のポイントへ順番に番号を付けていきます。この番号による管理により、トレンドライン構築や検証で使用するポイントを一貫して選択できるようになります。特に、時間の経過とともに複数のスイングポイントを分析する場合に、この順序情報が重要な役割を果たします。

void AssignSwingOrder(SwingPoint &swings[], int count)
{
   if(count <= 0)
      return;
   // Sorting by time ascending
   for(int i = 0; i < count-1; i++)
   {
      for(int j = i+1; j < count; j++)
      {
         if(swings[i].time > swings[j].time)
         {
            SwingPoint tmp = swings[i];
            swings[i] = swings[j];
            swings[j] = tmp;
         }
      }
   }
   for(int i = 0; i < count; i++)
      swings[i].order = i + 1;
}

スイングポイントの描画

DrawSwingPoints関数は、検出されたスイングハイとスイングローをチャート上に表示します。各スイングハイまたはスイングローに対して、対応する時間と価格位置に矢印オブジェクトを作成します。高値にはOBJ_ARROW_THUMB_DOWN、安値にはOBJ_ARROW_THUMB_UPが使用されます。視認性を高めるため、色、幅、アンカーポイントなどの表示プロパティが設定されます。また、有効化されている場合は、「H1」や「L1」などのラベルもスイングポイント付近に表示されます。これらのラベルは、ローソク足と重ならないようにATRを基準として少し離れた位置に配置されます。これらの視覚的なマーカーによって、トレーダーは重要なスイングポイントを容易に認識でき、プライスアクションの構造をより明確に理解できます。

void DrawSwingPoints(const SwingPoint &highs[], int highCount,
                     const SwingPoint &lows[], int lowCount)
{
   for(int i = 0; i < highCount; i++)
   {
      string pointName = TL_PREFIX + "H_" + IntegerToString(highs[i].order);
      if(ObjectFind(0, pointName) < 0)
         ObjectCreate(0, pointName, OBJ_ARROW_THUMB_DOWN, 0, highs[i].time, highs[i].price);
      else
         ObjectMove(0, pointName, 0, highs[i].time, highs[i].price);
      ObjectSetInteger(0, pointName, OBJPROP_COLOR,  SwingHighColor);
      ObjectSetInteger(0, pointName, OBJPROP_WIDTH,  2);
      ObjectSetInteger(0, pointName, OBJPROP_ANCHOR, AnchorPoint);
      ObjectSetInteger(0, pointName, OBJPROP_BACK,   false);
      // Labels if enabled
      if(ShowSwingLabels)
      {
         ...
      }
   }
   // Similar for lows
}

最適なレジスタンスラインとサポートラインの検出

FindBestResistanceLine3関数とFindBestSupportLine3関数は、事前に検出されたスイングポイントを分析し、最も重要なレジスタンスラインとサポートラインを選択します。これらの関数は、スイングポイントの組み合わせを体系的に調査し、下降するレジスタンスパターン(古い高値が新しい高値より高い状態)または上昇するサポートパターン(古い安値が新しい安値より低い状態)を確認します。各組み合わせについて、候補となるトレンドラインの傾きを計算し、設定された乖離許容範囲内でラインに接触・交差するローソク足の数をカウントします。さらに、ThirdSwingConfirms関数を使用して、3つ目のスイングポイントが存在し、そのトレンドラインの有効性を確認しているかどうかも検証します。各候補ラインには、接触回数、ラインからの乖離、時間的な新しさ(どれだけ最近形成されたラインか)、そして3つ目のスイングによる確認の有無に基づいてスコアが付けられます。最も高いスコアを獲得したラインが、最も重要なトレンドラインとして選択されます。これらは、現在のチャート環境において最も強いレジスタンスまたはサポート水準を示します。

void FindBestResistanceLine3(const SwingPoint &highs[], int highCount,
                             const MqlRates &rates[], int totalBars,
                             SwingPoint &bestAnchor1, SwingPoint &bestAnchor2, SwingPoint &bestAnchor3,
                             int &bestTouchCount, double &bestScore)
{
   ...
   for(int a = 0; a < highCount-1; a++)
   {
      for(int b = a+1; b < highCount; b++)
      {
         if(!(pts[a].price > pts[b].price))
            continue;
         ...
         // Count touches and confirm third swing
         ...
         // Calculate score and update best line
      }
   }
}

トレンドラインの描画

DrawTrendline3関数は、選択されたスイングポイントを結ぶトレンドラインオブジェクトを作成または更新します。この関数では、レジスタンスラインまたはサポートラインの種類に応じてトレンドラインへ一意の名前を設定し、色、幅、スタイル、延長設定などの表示プロパティをユーザーの設定に従って適用します。トレンドラインは最初の2つのアンカーポイント間に描画されます。また、検証に使用されたスイングポイント数を示すラベルが3つ目のスイングポイント付近に配置され、視認性を高めるために少し垂直方向へオフセットされます。この視覚的な表示によって、トレーダーは複数のスイングによって検証された傾斜サポート・レジスタンスラインを確認でき、ブレイクアウトの可能性を分析するための市場背景を把握できます。

void DrawTrendline3(const SwingPoint &anchor1, const SwingPoint &anchor2, const SwingPoint &anchor3,
                    bool isResistance, int touchCount)
{
   string lineName  = TL_PREFIX + (isResistance ? "RESISTANCE" : "SUPPORT");
   string labelName = TL_PREFIX + (isResistance ? "RES_LABEL"  : "SUP_LABEL");

   if(ObjectFind(0, lineName) < 0)
   {
      ObjectCreate(0, lineName, OBJ_TREND, 0,
                   anchor1.time, anchor1.price,
                   anchor2.time, anchor2.price);
   }
   else
   {
      ObjectMove(0, lineName, 0, anchor1.time, anchor1.price);
      ObjectMove(0, lineName, 1, anchor2.time, anchor2.price);
   }

   ObjectSetInteger(0, lineName, OBJPROP_COLOR,     lineColor);
   ObjectSetInteger(0, lineName, OBJPROP_WIDTH,     LineWidth);
   ObjectSetInteger(0, lineName, OBJPROP_STYLE,     LineStyle);
   ObjectSetInteger(0, lineName, OBJPROP_RAY_RIGHT, ExtendToRightEdge);
   ObjectSetInteger(0, lineName, OBJPROP_BACK,      false);

   // Label near 3rd swing
   ...
}

ブレイクアウト確認(傾斜ライン用クロス判定ロジック)

CheckBreakouts関数は、直近のローソク足を監視し、価格がレジスタンストレンドラインを上抜ける、またはサポートトレンドラインを下抜けるタイミングを検出します。これは、ブレイクアウト発生の可能性を示す重要なイベントになります。この関数では、直近2本の確定ローソク足におけるトレンドライン上の想定価格を計算し、実際の終値またはローソク足のヒゲ価格と比較します。その際、誤ったシグナルを防ぐために設定されたバッファ範囲も考慮されます。価格がレジスタンスラインを上抜けた場合は強気ブレイクアウト、サポートラインを下抜けた場合は弱気ブレイクアウトとして判定されます。また、そのバーですでにブレイクアウトが記録されていないことを確認したうえで、イベント情報を保存し、永続的な矢印を描画し、必要に応じてアラートメッセージを送信します。システムはタイムスタンプを追跡することで、1つのバーにつき各方向1回のみブレイクアウトを認識するよう管理しています。これにより、同じイベントに対して複数のシグナルが発生することを防ぎます。

void CheckBreakouts(const MqlRates &rates[],
                    bool haveRes, const SwingPoint &resA, const SwingPoint &resB, int resTouches,
                    bool haveSup, const SwingPoint &supA, const SwingPoint &supB, int supTouches)
{
   ...
   if(haveRes)
   {
      double line1 = LinePriceAtTime(resA, resB, t1);
      double line2 = LinePriceAtTime(resA, resB, t2);
      double p1 = BreakoutUseClose ? rates[1].close : rates[1].high;
      double p2 = BreakoutUseClose ? rates[2].close : rates[2].high;
      bool crossedUp = (p2 <= line2 + buf) && (p1 > line1 + buf);
      if(crossedUp && t1 != g_lastBuyBarTime)
      {
         g_lastBuyBarTime = t1;
         // Draw arrow and alert
      }
   }
   // Similar for support line
}

チャートイベント処理とメインループ

OnChartEvent関数は、必要に応じて手動操作やホットキーによる制御を追加できるように用意されていますが、この実装ではプレースホルダーとして存在しており、処理内容は空になっています。主な実行処理はOnTick関数でおこなわれます。この関数は、価格ティックが発生するたびに実行されます。最初に、バーのタイムスタンプを比較して新しいローソク足が形成されたかどうかを確認します。新しいバーが形成された場合、ATR値を更新し、既存のトレンドラインオブジェクトを削除した後、DrawMostSignificantTrendlinesを通じてメイン分析処理を開始します。この処理では、スイングポイントの検出、最適なレジスタンスラインとサポートラインの選択、トレンドラインの描画、そしてブレイクアウト確認が順番に実行されます。確認済みのブレイクアウトについては、永続的な矢印が再描画され、チャート上に最新のテクニカル状況が反映されます。この継続的な処理によって、EAは変化する市場環境に動的に対応し、適切なタイミングでシグナルを提供できます。

void OnTick()
{
   static datetime lastBarTime = 0;
   datetime currentBarTime = iTime(_Symbol, _Period, 0);
   if(currentBarTime == lastBarTime && lastBarTime != 0)
      return;
   lastBarTime = currentBarTime;

   if(UseATRFiltering && atrHandle != INVALID_HANDLE)
   {
      double atrBuffer[1];
      if(CopyBuffer(atrHandle, 0, 0, 1, atrBuffer) > 0)
         currentATR = atrBuffer[0];
   }

   DeleteObjectsByPrefix(TL_PREFIX);
   DrawMostSignificantTrendlines();

   RedrawPermanentArrows();
}

実装後、コードはコンパイルされ、テスト前に正常なビルドが完了していることを確認します。コンパイラから出力されるメッセージは、構造上のフィードバックとして扱われます。これらを参考にしながら、構文、宣言、関数の使用方法などを修正し、エラーなしでコンパイルが完了する状態まで調整します。



テストと結果

ツールのコンパイルが正常に完了した後、次のステップはテストです。テストは実際のチャート上でも実行できますが、最初はリアル口座ではなくデモ口座から開始することを強く推奨します。デモ環境でのテストによって、不必要なリスクを負うことなく、実際の市場環境で戦略がどのように動作するかを観察できます。

リアルタイムチャートでの検証に加えて、MetaTrader 5のストラテジーテスターを使用してツールを評価することもできます。このような過去データを利用した検証は、一般的にバックテストと呼ばれ、過去の市場環境において戦略がどのように動作したかを確認できます。バックテストでは、戦略の強みや弱点、さらにパラメータ調整が必要となる可能性のある部分を発見することもできます。特に、シンボルごとに価格の動き方は異なるため、この検証は重要です。

さらにMetaTrader 5内で最適化することで、より詳細な調整が可能になります。最適化では、入力パラメータを体系的にテストし、パフォーマンス向上の可能性を探ります。ただし、この処理は計算負荷が高くなる場合があり、一般的には高性能なコンピュータを使用することで効率が向上します。

このセクションでは、テスト段階で確認された結果を紹介し、異なる市場環境でツールがどのように動作したか、そして結果から得られた知見について説明します。

1つ目の結果

図4:EURUSDのバックテスト例(1時間足)

図4は、MetaTrader 5のストラテジーテスターでビジュアルモードを使用して取得したバックテスト例です。この例では、ツールが3つの検証済みスイングポイントを結ぶことで、傾斜レジスタンストレンドライン(赤色)を自動的に検出・構築しています。その後、価格が上昇し、トレンドラインを明確に上抜けるブレイクが発生します。このブレイクアウトはツールによって確認され、緑色の上向き矢印によって強気ブレイクアウトとして表示されます。シグナルは、単純な接触や一時的なライン侵入に反応するのではなく、明確な価格クロスが発生した後にのみ生成されます。この例は、過去検証においてツールがどのように動作するかを示しています。トレンドラインは検証済みのスイング構造から生成され、ブレイクアウトシグナルは意味のある条件が成立した場合にのみ表示されます。その結果、プライスアクションの考え方に沿った、明確で規律あるシグナルを提供します。

2つ目の結果

以下の図は、MetaTrader 5のストラテジーテスターでビジュアルモードを使用して取得した、ゴールド(XAUUSD)のH1時間足における2つ目のテスト結果です。ゴールドでは価格変動幅が大きく、相場状況の変化も速いため、このような環境でツールがどのように機能するかを示しています。このテストでは、ツールが検証済みのスイングポイントを基準に、傾斜レジスタンスラインと傾斜サポートラインの両方を自動的に検出しています。

下降する赤色のトレンドラインは、3つの確認済みスイング高値から構築されたレジスタンスを示しています。一方、上昇する青色のトレンドラインは、複数のスイング安値から形成されたサポートを示しています。価格が進行する中で、レジスタンストレンドラインは維持されます。そして、明確な価格反応が発生した時点でブレイクアウト判定が出されます。このツールは、一時的なライン突破やボラティリティによる急激なヒゲの動きに反応するのではなく、傾斜トレンドラインに対する明確な価格クロスを待ってからブレイクアウト条件を評価します。これは、ボラティリティが高く、ダマシのブレイクアウトが発生しやすいゴールドのような金融商品では特に重要です。

図5:XAUUSDのバックテスト例(1時間足)

このテストから確認できる重要な点は、ツールが手動調整なしでゴールド特有の価格変動へ適応していることです。スイング検出、トレンドライン構築、検証処理は、広い値幅や急激な価格変化が発生する環境でも一貫して動作します。これは、戦略ロジックが特定の銘柄に依存するものではなく、共通した価格構造に基づいていることを示しています。全体として、このテストは異なる市場環境におけるツールの堅牢性を確認するものです。FX通貨ペアで使用される構造ルールは、ゴールドのようなコモディティ市場でも有効であり、過去検証においてトレンドラインブレイクアウトを客観的かつ一貫して検出できます。ただし、すべてのプライスアクションツールと同様に、パフォーマンスは市場環境、時間足の選択、そしてシグナルを解釈する際の規律に左右されます。



結論

本記事では、構造に基づいた傾斜トレンドラインブレイクアウトのアプローチを解説し、プライスアクションの基本原則を、規律あるMQL5分析ツールへどのように変換できるかを示しました。明確な市場構造ルールを適用することで、このツールはトレンドラインブレイクアウト分析において一般的に発生する曖昧さの多くを排除します。

テスト例では、この構造を優先したロジックが、異なる金融商品や市場環境において一貫して機能することが確認されました。市場に合わせてルールを変化させるのではなく、分析はスイング構造と価格の動きに基づいて維持されます。その結果、ブレイクアウトシグナルはチャート上の価格動作から自然に形成されます。

この枠組みによって、トレンドラインブレイクアウトは、主観的な判断や裁量によるライン配置に依存することなく、より簡単に識別、評価、そして規律あるプライスアクション分析へ組み込めるようになります。

このツールは、あくまで分析およびシグナル確認を目的としており、自動売買を目的としたものではありません。実際の資金で使用する前には、過去データによるバックテストやライブデモ口座を利用した十分な検証を強く推奨します。既存のトレード手法と組み合わせて使用することで、規律ある意思決定を補強する追加的な確認手段として機能します。

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

添付されたファイル |
MQL5取引ツール(第17回):ベクトルベースの角丸長方形と三角形を探る MQL5取引ツール(第17回):ベクトルベースの角丸長方形と三角形を探る
MQL5のcanvasを使用して、ベクトルベースの手法で角丸長方形と三角形を描画する方法を解説します。さらに、アンチエイリアス処理を実現するためにスーパーサンプリングを利用します。実装では、スキャンライン塗りつぶし、円弧や接線に対する幾何学的事前計算、そして境界線描画を組み合わせることで、滑らかでカスタマイズ可能な図形を作成します。このアプローチは、今後の取引ツールにおけるモダンなUI要素を構築するための基盤となり、サイズ、角の半径、境界線、透明度などを入力で柔軟に設定できる設計になっています。
ラリー・ウィリアムズの『市場の秘密』(第11回):カスタムインジケータによるスマッシュデー反転の検出 ラリー・ウィリアムズの『市場の秘密』(第11回):カスタムインジケータによるスマッシュデー反転の検出
ラリー・ウィリアムズのスマッシュデー反転ルールを、確認済みセットアップを矢印で表示する実用的なMQL5インジケータへ変換します。バッファのバインド、プロットプロパティの設定、履歴データへのマッピング、そしてOnCalculate内でのリアルタイム更新までを、段階的に解説します。調整可能なルックバックパラメータと見やすいチャート描画により、有効な反転をすばやく検出できる一方で、最終的な売買判断は裁量と市場状況に委ねられます。
エラー 146 (「トレードコンテキスト ビジー」) と、その対処方法 エラー 146 (「トレードコンテキスト ビジー」) と、その対処方法
この記事では、MT4において複数のEAの衝突をさける方法を扱います。ターミナルの操作、MQL4の基本的な使い方がわかる人にとって、役に立つでしょう。
MQL5における二変量コピュラ(第3回):混合コピュラモデルの実装とチューニング MQL5における二変量コピュラ(第3回):混合コピュラモデルの実装とチューニング
MQL5上でネイティブ実装された混合コピュラを用いて、既存のコピュラツールキットを拡張します。Clayton–Frank–GumbelおよびClayton–Student-t–Gumbelの混合モデルを構築し、EMアルゴリズムによってパラメータ推定をおこないます。また、SCAD (Smoothly Clipped Absolute Deviation)とクロスバリデーションを組み合わせることで、モデルのスパース性制御を実現します。提供するスクリプトでは、ハイパーパラメータの調整、情報量基準を用いた混合モデルの比較、学習済みモデルの保存までを実行できます。これらのコンポーネントを利用することで、実務者は非対称なテール依存性を捉え、選択したモデルをインジケータやエキスパートアドバイザー(EA)へ組み込めるようになります。