English Русский
preview
初心者からエキスパートへ:市場の不規則性への対処

初心者からエキスパートへ:市場の不規則性への対処

MetaTrader 5 |
21 0
Clemence Benjamin
Clemence Benjamin

内容

  1. はじめに
  2. 実装
  3. テスト
  4. 結論
  5. 重要な学び
  6. 添付ファイル


はじめに

多くの初心者トレーダーは、学習の初期段階でサポートとレジスタンスの概念に触れます。これは、この考え方が広く普及しており、書籍やオンライン教材でも頻繁に取り上げられているためです。もちろん、これは重要な基礎知識です。しかし、固定的なサポートやレジスタンスラインに依存しすぎると、市場構造が変化した際に対応できず、結果として多くのトレーダーが市場から退場することになります。

市場は本質的に動的なものです。かつて有効だった価格レベルも、ボラティリティの変化や構造の乱れによって、その信頼性を失うことがあります。そこで本記事では、従来の「固定ライン」ではなく、動的に変化するサポートやレジスタンスゾーンを特定するアルゴリズム的アプローチを紹介します。この手法により、静的な分析を、継続的に適応するルールベースのシステムへと進化させることが可能になります。

さらに、時系列データを処理するコンピュータの強みを活かし、ゾーンはティックごとに再計算され、更新されます。その結果、急速に変化する市場環境にも柔軟に対応できる、完全に動的なフレームワークが実現されます。

問題の正当性

サポートやレジスタンスを単一の水平線として扱う手法は、整った相場では機能することもあります。しかし、ボラティリティが高く不規則な市場や転換局面では、しばしば通用しません。その結果として、ストップロスに早期にかかってしまったり、注文が適切に約定しなかったり、あるいはセットアップの有効性に対する不確実性から意思決定が遅れたりする状況が頻繁に発生します。

本記事で提案する解決策は、サポートとレジスタンスを単一の価格水準としてではなく、確率的なゾーンとして再定義することにあります。これらのゾーンは、価格が反応する可能性が統計的に高い領域を表しており、それによって注文が約定する確率が高まり、感情的な迷いが軽減され、長期的なドローダウンリスクの低減にもつながります。

また、RSIのようなオシレーターによる確認がなくても、ゾーン算出に用いられる集約ロジックそのものが、信頼性を高める役割を果たします。次のサブセクションでは、このアプローチの概念的基盤を説明し、その後の実装セクションでMQL5を用いて具体的に形にしていきます。

確率ゾーンの概念を理解する

私の多くの研究と同様に、このアイデアも、手動トレーディングで用いられる概念をアルゴリズムへと落とし込むことから始まりました。開発プロセスは多くの場合、MetaTrader 5のチャート上での視覚的分析からスタートし、繰り返し発生する問題を特定したうえで、それがMQL5のアルゴリズム機能によって解決可能かを検討します。

プライスアクションを分析していると、教科書的に整ったセットアップよりも、不規則で方向感の乏しい相場環境がより頻繁に出現することが分かります。ここで重要な疑問が生じます。市場がほとんど「完璧な」機会を提供しないのであれば、それを待つ時間をどのように短縮できるのか、ということです。

長時間の待機が必ずしも報われるとは限らず、多くの場合、取引機会は有効化された時点ですでに遅れていることがあります。この問題に対処するためには、価格を一点ではなくレンジとして捉える仕組みが必要です。これにより、より有利な位置から市場に参加できるようになり、反応の遅れを回避できます。また、このアプローチは、口座資本に対するリスク管理の精度向上にも寄与します。

従来、サポートおよびレジスタンスは、複数の価格反応を平均化することで単一のレベルとして定義されてきました。しかし、その平均値の外側では、無視できないスパイクが発生することがあります。これらのスパイクはゾーンの幅の形成に寄与し、市場の不規則性の主要な要因ともなっています。この現象は、機関投資家の活動や流動性の吸収と関連付けられることがあります。しかしその平均線の外側では、価格はしばしば無視できないスパイクを生成します。

大口参加者の具体的な行動は明確ではありませんが、その結果として現れる非対称な価格構造は観察可能であり、トレーダーの判断を難しくする要因となります。本記事で提示するアプローチは、こうした不完全性を排除するのではなく、前提として受け入れることで分析の信頼性を高めることを目的としています。

以下の図は、この概念の中核を示しています。一般にノイズや市場操作と見なされがちな外側のスパイクも、実際にはゾーン定義の重要な構成要素であり、アルゴリズムはそれらを無視するのではなく、市場の関心領域の境界を特定するために利用します。

サポートゾーンとレジスタンスゾーン

 図1: 過去の価格分析からの考察

この概念を明確にするために、USDJPYのH1(1時間足)を用い、意図的に過去の価格データへスクロールして分析をおこないました。これはリアルタイム取引ではなく、純粋に構造分析を目的としたものです。実際の執行による影響を排除した状態で、時間の経過とともにサポートおよびレジスタンス付近で価格がどのように振る舞うかを観察しました。

過去のローソク足を遡ることで、リアルタイムでは見落とされがちな繰り返しの反応を客観的に捉え、パターンを特定することが可能になります。

1. 極端な価格拒否のマーク

チャート履歴を確認する中で、まず極端な価格変動に着目しました。

上側の境界では、「エクストリームレジスタンス」と呼ぶラインを引きました。このレベルは、上方向への極端なスパイクが繰り返し拒否された高値領域を示しています。たとえば点Bでは、価格はこの領域まで急騰した直後に反転しています。価格が一時的に到達することはあっても、持続的に滞在することはありませんでした。これは、この領域が正確なエントリーポイントではなく、市場が受け入れる上限として機能していることを示しています。

下側の境界では「エクストリームサポート」を設定しました。点Aでは価格が急落した後、強い買い圧力によって反発しています。このような深い下方向へのスパイクは頻繁ではありませんが、発生した場合には構造上の下限を定義する役割を果たしています。

2. 平均的な反応レベルの特定

次に、履歴データの分析を継続し、強い反応が見られた価格帯だけでなく、最も頻繁に反応が発生した領域を特定しました。

まず、d、e、fといった複数の反応ポイントを集約し、平均的なレジスタンスを設定しました。 価格はエクストリームレジスタンスに達することもありましたが、この平均レベル付近で繰り返し停滞または反転していることが確認できます。

同様に、g、h、i、j といったポイントでの反発を基に、平均的なサポートを特定しました。このレベルはエクストリームサポートよりもはるかに多くテストされており、需要の中心領域として機能しています。

この分析から明らかになるのは、市場は単一の価格市場は単一の価格ではなく、一定の値幅を持つ領域として反応しているという点です。

ゾーン構造の理解

4本のラインが揃うと、構造は自然に把握できるようになります。

平均レジスタンスとエクストリームレジスタンスの間では、価格が頻繁にスパイクし、反発し、保ち合いを形成しています。同様の挙動は、平均サポートとエクストリームサポートの間でも確認できます。これらの領域は理論的に設定されたものではなく、過去の繰り返し挙動に基づいて形成されたサポートおよびレジスタンスのゾーンです。

一般に「ダマシ(フェイクブレイクアウト)」と呼ばれる動きの多くは、実際にはこれらのゾーンの外縁をテストしているに過ぎません。平均値と極値を特定した後、それらをゾーンへと変換しました。ここでこのアイデアは実用的な形になります。4本のラインとして扱うのではなく、それらの間の領域を矩形として可視化することで、実際の挙動がより明確になります。下の図2を参照してください。

SゾーンとRゾーンのマーキング

図2:塗りつぶし矩形で示されたサポートおよびレジスタンスの確率ゾーン

この矩形内での価格推移を観察すると、いくつかの重要な特徴が確認できます。価格は必ずしもエクストリームレジスタンスに到達する必要はなく、d、e、f付近のようにゾーン内部で反応するケースが多く見られます。一方で、Bのようにゾーンの奥深くまでスパイクする場合もありますが、これらは短期間で否定される傾向があります。

アルゴリズム版では:

  1. 平均値および極値の境界を計算します。
  2. 矩形を用いてゾーンを動的に描画します。
  3. 単一ラインではなく、ゾーン内部での価格挙動を評価します。
  4. ゾーン内でのインタラクションに基づき、エントリー、アラート、シグナルを生成します。

この例は履歴データに基づいていますが、MQL5で実装すれば、ロジック自体はそのままリアルタイム処理に適用可能です。ゾーンを定義してマーキングした後、同じ履歴区間で時間を進め、価格がこれらのゾーンに再び接触した際の挙動を観察しました。この過程では、構造の変更やゾーンの再描画はおこなっていません。価格が境界に再到達した際の反応をそのまま追跡しています。このステップは重要です。ゾーンは反発だけでなく、ブレイクアウトも説明できなければならないためです。

レジスタンスゾーンのブレイクアウト

図3:ゾーンブレイクアウト

図3では、価格がレジスタンスゾーンに接近した際、複数回にわたり上抜けを試みていますが、初期段階ではいずれもゾーン内部で失速しています。この挙動は圧縮状態を示しており、即座に拒否されているのではなく、ゾーン内で売り圧力が徐々に吸収されていることを意味します。

これらの試行は単なるフェイクではなく、ゾーン内で圧力が蓄積されるプロセスとして解釈できます。ゾーンは即時に価格を拒否するものではなく、いずれかの注文が枯渇するまで価格を内包する領域です。

最終的に、価格はレジスタンスゾーンを明確に上抜けました(図中の丸印部分)。これは単なるヒゲ抜けではなく、ゾーン上限を明確に超えてクローズする強い上昇ローソクによるブレイクアウトでした。

特に重要なのは、このブレイクアウトが初回接触ではなく、ゾーン内での十分な滞在と相互作用の後に発生している点です。これは、ゾーンが注文吸収と参加者の意図の顕在化という役割を果たしたことを示しています。

ゾーンを用いることでブレイクアウトが明確になる理由

単一のレジスタンスラインのみを使用していた場合、この値動きは解釈が難しく、フェイクブレイクアウトなのか、それとも実際のブレイクアウトなのかが判別しにくくなっていた可能性があります。

これに対して、レジスタンスをゾーンとして捉えることで、ブレイクアウトは明確になります。

  • 価格がレジスタンス領域全体を完全に上抜けている
  • 過去に反転していた範囲を超えてモメンタムが拡大している
  • 市場構造がレンジからトレンド継続へと明確に移行している

本記事で学ぶ内容と構築するもの

以降のセクションでは、概念から実装へと移行します。具体的には、以下をおこないます。

  1. アルゴリズムの分解:スイングポイントの特定、タッチのクラスタリング、動的な平均値および極値レベルの算出ロジックを詳細に分解します。
  2. MQL5インジケーターの作成:これらの確率ゾーンをリアルタイムでチャート上に描画するコードを実装し、サポートとレジスタンスが視覚的に明確に区別されるようにします。
  3. 取引システムへの統合:これらのアルゴリズムゾーンを基盤として高確率シグナルを生成する方法を示し、可視化から実行への応用へとつなげます。


実装

過去データの分析を通じて、確率ベースのサポートおよびレジスタンスゾーンの概念的な基盤を確立したので、ここからは実装段階へと移行します。このセクションでは、これまで手動でおこなっていた観察プロセスを、構造化され再現可能で、かつリアルタイムで動作するMQL5インジケーターへと変換します。

ここでの目的は価格を予測することではなく、市場の挙動を観察し、それを集約して可視化することにあります。各ステップは、チャート上で行っていた手動分析を、プラットフォーム上で客観的かつ継続的に実行するための設計に基づいています。

1. 構造基盤とユーザー設定

堅牢なMQL5インジケーターは、明確なプロパティ定義と調整可能な入力パラメータから始まります。これによりインジケーターの挙動を定義し、トレーダーが異なる銘柄や時間足に適応できるようになります。

#property copyright "Copyright 2025, Clemence Benjamin."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   4

//--- Input Parameters (Optimized for M5)
input int    LookBackPeriod   = 150;    // Bars to analyze
input int    SwingSensitivity = 5;      // Swing detection (3-10)
input int    ZonePadding      = 20;     // Zone padding in points
input color  SupportColor     = clrRoyalBlue;   // Support zone color
input color  ResistanceColor  = clrCrimson;     // Resistance zone color
input bool   ShowZoneLabels   = true;   // Show zone labels

//--- Buffers
double SupportHighBuffer[];
double SupportLowBuffer[];
double ResistanceHighBuffer[];
double ResistanceLowBuffer[];

設計上のポイントは次のとおりです。

  1. チャートウィンドウへの描画:インジケーターは価格チャート(indicator_chart_window)上に直接描画され、即時の視覚的コンテキストを提供します。
  2. 感度の設定可能性:SwingSensitivityLookBackPeriodといったパラメータにより、スキャルピング(M1〜M5)からスイングトレード(H1〜H4)まで柔軟に対応できます。
  3. 4つのデータバッファ:2つのゾーンそれぞれの境界を保持するために4つのバッファを使用します。必要に応じて破線の境界ラインを描画可能ですが、主な可視化はチャートオブジェクトでおこないます。

2. コア市場構造検出:スイングポイントアルゴリズム

ゾーンの精度は、重要な転換点であるスイングポイントをどれだけ正確に検出できるかに依存します。実装では、各バーを前後のバーと比較するシンプルな手法を用いて、局所的な高値と安値を特定します。

//+------------------------------------------------------------------+
//| Simple swing high detection                                      |
//+------------------------------------------------------------------+
bool IsSwingHighSimple(int index, int period, const double& high[])
{
   if(index < period || index >= ArraySize(high)-period)
      return false;
   
   double currentHigh = high[index];
   
   for(int i=1; i<=period; i++)
   {
      if(currentHigh <= high[index-i] || currentHigh <= high[index+i])
         return false;
   }
   return true;
}

//+------------------------------------------------------------------+
//| Simple swing low detection                                       |
//+------------------------------------------------------------------+
bool IsSwingLowSimple(int index, int period, const double& low[])
{
   if(index < period || index >= ArraySize(low)-period)
      return false;
   
   double currentLow = low[index];
   
   for(int i=1; i<=period; i++)
   {
      if(currentLow >= low[index-i] || currentLow >= low[index+i])
         return false;
   }
   return true;
}

これらの関数は、局所極値検出手法を実装しています。たとえばSwingSensitivityを5に設定した場合、あるバーがスイングハイと認識されるのは、その前後5本のバーよりも高い場合に限られます。この条件により、ノイズを抑えつつ、意味のある価格変動のみを抽出できます。

3. ゾーン計算エンジン:点から確率レンジへ

このシステムの中核は、離散的なスイングポイントを連続的なゾーンへと変換する処理にあります。この段階では、有効なスイングポイントを収集し、その範囲を特定したうえで、ゾーンとして適切な幅を持たせます。

//+------------------------------------------------------------------+
//| Find support and resistance zones                                |
//+------------------------------------------------------------------+
void FindZones(const double& high[], const double& low[], 
               double& supportHigh, double& supportLow,
               double& resistanceHigh, double& resistanceLow)
{
   double supportLevels[], resistanceLevels[];
   ArrayResize(supportLevels, 0);
   ArrayResize(resistanceLevels, 0);
   
   int limit = MathMin(ArraySize(high), LookBackPeriod);
   
   // Find swing points
   for(int i=SwingSensitivity; i<limit-SwingSensitivity; i++)
   {
      if(IsSwingLowSimple(i, SwingSensitivity, low))
      {
         ArrayResize(supportLevels, ArraySize(supportLevels)+1);
         supportLevels[ArraySize(supportLevels)-1] = low[i];
      }
      
      if(IsSwingHighSimple(i, SwingSensitivity, high))
      {
         ArrayResize(resistanceLevels, ArraySize(resistanceLevels)+1);
         resistanceLevels[ArraySize(resistanceLevels)-1] = high[i];
      }
   }
   
   // Calculate support zone
   if(ArraySize(supportLevels) > 0)
   {
      // Find the most recent significant support
      supportHigh = 0;
      supportLow = DBL_MAX;
      
      for(int i=0; i<ArraySize(supportLevels); i++)
      {
         if(supportLevels[i] > supportHigh) supportHigh = supportLevels[i];
         if(supportLevels[i] < supportLow) supportLow = supportLevels[i];
      }
      
      // Adjust for zone
      double zonePadding = ZonePadding * _Point;
      supportHigh += zonePadding * 2;  // Add padding above
      supportLow -= zonePadding;       // Add padding below
   }
   // ... similar logic for resistance zone
}

実装の詳細:

  • 動的配列管理:ArrayResize()を用いて、固定メモリを事前確保することなく効率的にスイングポイントを収集します。
  • 非対称パディング戦略:サポートゾーンには上方向に大きめの余白 (zonePadding * 2)を設定し、レジスタンスゾーンには下方向により大きな余白を設定します。これは、反転前に価格がオーバーシュートしやすいという市場特性を反映しています。
  • 境界チェック:DBL_MAXおよびゼロ初期化により、スイングポイントが存在しない場合などのエッジケースにも堅牢に対応します。

4. 可視化システム:明確なゾーン描画

取引ツールは、情報を即座にかつ明確に伝える必要があります。本描画システムでは、複数の視覚レイヤーを用いて確率ゾーンを直感的に表現します。

//+------------------------------------------------------------------+
//| Draw support and resistance zones                                |
//+------------------------------------------------------------------+
void DrawZones(double supHigh, double supLow, double resHigh, double resLow)
{
   string name;
   datetime startTime = iTime(_Symbol, _Period, LookBackPeriod);
   datetime endTime = TimeCurrent();
   
   // Delete old objects first
   ObjectsDeleteAll(0, "SZone");
   ObjectsDeleteAll(0, "RZone");
   // ... additional cleanup
   
   // Only draw if we have valid values
   if(supHigh > 0 && supLow > 0 && supHigh > supLow)
   {
      // Draw support zone (filled rectangle)
      name = "SZone_Rect";
      ObjectCreate(0, name, OBJ_RECTANGLE, 0, startTime, supHigh, endTime, supLow);
      ObjectSetInteger(0, name, OBJPROP_COLOR, SupportColor);
      ObjectSetInteger(0, name, OBJPROP_BGCOLOR, SupportColor);
      ObjectSetInteger(0, name, OBJPROP_FILL, true);
      ObjectSetInteger(0, name, OBJPROP_BACK, true);
      ObjectSetInteger(0, name, OBJPROP_WIDTH, 0);
      
      // Draw support average line (middle of zone)
      name = "SZone_Avg";
      ObjectCreate(0, name, OBJ_HLINE, 0, 0, (supHigh + supLow) / 2);
      ObjectSetInteger(0, name, OBJPROP_COLOR, clrWhite);
      ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);
      ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);
      
      // ... boundary lines and labels
   }
   // ... similar drawing for resistance zone
}

視覚階層設計:

  • 一次層:塗りつぶし矩形(OBJPROP_BACK=true)により、プライスアクションを妨げずにゾーンを背景表示します。
  • 二次層:白色の実線(太さ2px)で、最も反応確率の高いポイントを示します。
  • 三次層:色付きの破線(太さ1px)でゾーンの境界を定義します。
  • 情報層:任意でテキストラベルやチャート隅のステータス表示を追加します。

5. リアルタイム処理エンジン:OnCalculate関数

OnCalculate()関数はインジケーターの中心となる処理であり、新しい価格データが到着するたびに実行されます。これにより、ゾーンは常に最新の市場状況に基づいて更新されます。

//+------------------------------------------------------------------+
//| Indicator iteration function                                     |
//+------------------------------------------------------------------+
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 we have enough data
   if(rates_total < LookBackPeriod + SwingSensitivity * 2)
      return(0);
   
   // Set arrays as series
   ArraySetAsSeries(high, true);
   ArraySetAsSeries(low, true);
   
   // Find zones
   double supHigh, supLow, resHigh, resLow;
   FindZones(high, low, supHigh, supLow, resHigh, resLow);
   
   // Fill buffers
   int limit = MathMin(rates_total, LookBackPeriod);
   for(int i=0; i<limit; i++)
   {
      SupportHighBuffer[i] = supHigh;
      SupportLowBuffer[i] = supLow;
      ResistanceHighBuffer[i] = resHigh;
      ResistanceLowBuffer[i] = resLow;
   }
   
   // Draw zones on chart
   DrawZones(supHigh, supLow, resHigh, resLow);
   
   // Also publish to global variables for EA access
   if(supHigh > 0 && supLow > 0 && resHigh > 0 && resLow > 0)
   {
      GlobalVariableSet("GLOBAL_SUPPORT_HIGH", supHigh);
      GlobalVariableSet("GLOBAL_SUPPORT_LOW", supLow);
      // ... additional global variables
      GlobalVariableSet("GLOBAL_ZONES_TIME", TimeCurrent());
   }
   
   return(rates_total);
}

処理の最適化:

  • 効率的な配列処理:ArraySetAsSeries(true) により、インデックス0を最新バーとして扱い、アクセス効率を最適化します。
  • バッファの活用:主な可視化はチャートオブジェクトでおこないますが、インジケーターバッファを埋めることで、バックテストや他機能との統合を可能にします。
  • グローバル変数連携:GlobalVariableSet()を用いて計算済みゾーンを保存することで、エキスパートアドバイザー(EA)からプログラム的にアクセス可能なインターフェースを提供し、自動売買への応用を実現します。

6. システム統合とクリーンアップ

実運用を前提としたMQL5開発では、リソース管理が重要です。OnInitとOnDeinitを適切に実装することで、インジケーターの初期化と初期化解除処理を確実におこないます。

//+------------------------------------------------------------------+
//| Indicator initialization function                                |
//+------------------------------------------------------------------+
int OnInit()
{
   // Set buffer properties
   SetIndexBuffer(0, SupportHighBuffer, INDICATOR_DATA);
   // ... buffer setup for all four buffers
   
   // Set plotting properties
   PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE);
   PlotIndexSetInteger(0, PLOT_LINE_STYLE, STYLE_DASH);
   PlotIndexSetInteger(0, PLOT_LINE_COLOR, SupportColor);
   // ... similar setup for other plots
   
   IndicatorSetString(INDICATOR_SHORTNAME, "Dynamic S/R Zones");
   IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Indicator deinitialization function                              |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Clean up all objects
   ObjectsDeleteAll(0, "SZone");
   ObjectsDeleteAll(0, "RZone");
   ObjectsDeleteAll(0, "Sup");
   ObjectsDeleteAll(0, "Res");
   ObjectsDeleteAll(0, "ZoneInfo");
   
   // Clean up global variables
   GlobalVariableDel("GLOBAL_SUPPORT_HIGH");
   // ... delete all related global variables
}

リソース管理戦略:

  • OnInit()による設定:OnInit()関数では、すべてのインジケーター設定を単一かつ整理された関数内で適切に構成します。
  • 徹底的なクリーンアップ処理:OnDeinit()関数では、インジケーターによって作成されたすべてのチャートオブジェクトおよびグローバル変数を確実に削除します。これにより、インジケーター削除後に発生し得るチャート上のオブジェクト残留やメモリリークを防止します。


テスト

今回開発したインジケーターの興味深い点の一つは、MetaTrader 5 ストラテジーテスター上で直接評価できることです。この機能により、ロジックの検証をライブチャート上での視覚的および裁量的観察に依存するだけでなく、統制された履歴環境における構造的テストとして実施できます。リアルタイム環境とシミュレーション環境の両方で同一の計算ロジックおよび描画処理が実行されることを保証することで、客観的な検証が可能になります。

インジケーターはリアルタイムでテストされ、新しい価格データが追加されるにつれてサポート/レジスタンスの確率ゾーンがどのように変化するかを観察しました。同時に、MetaTrader 5ストラテジーテスターを用いて履歴データをリプレイし、過去の価格がこれらのゾーンとどのように相互作用していたかを分析しました。このデュアルモードテストにより、ゾーンが後付けではなく、価格進行に応じて動的に更新されていることを確認できます。

履歴テストの結果からは、価格が識別されたゾーンを尊重しながら推移している様子が明確に確認できます。価格の反応として見られる一時的な停止、反発、そして短期的な保ち合いは、ハイライトされた領域付近で繰り返し発生しており、これにより検出されたサポートおよびレジスタンスレンジの妥当性が強化されています。また、この挙動はテストした異なる期間やセグメントにおいて一貫して観察されており、ロジックの頑健性に対する信頼性をさらに強化しています。

テスト

図4:ストラテジーテスターでインジケーターを視覚的にテストする

全体として、テスト結果は良好であり、本インジケーターがサポート/レジスタンスベースの取引戦略において、信頼性の高い基盤を提供することを示唆しています。さらなるフォワードテストおよびパラメータ調整は常に推奨されますが、現時点の結果からも、これらのゾーンが意味のあるものであり、安定性と実用性を備えていることが確認できます。分析用途および取引用途のいずれにおいても有効です。



結論

確率ベースのゾーンを構造化された取引フレームワークの中で用いることで、複雑な市場構造にも十分に対応できます。本記事では、抽象的で手動的に扱われてきたサポートおよびレジスタンスの概念を、どのようにして正確でルールベースのアルゴリズムへと変換できるかを示しました。これにより、裁量的なチャート分析と体系的なインジケーター開発との間にあったギャップを埋めています。

本記事では、概念的な市場構造ロジックから、実際に機能するカスタムインジケーターの完成に至るまで、開発の流れを一通り追いました。その中で、確率ゾーンがどのように導出され、どのように可視化され、さらに履歴データおよびリアルタイムデータを使ってどのように検証されるのかを示しています。

その結果として得られたツールは、サポートおよびレジスタンスの確率ゾーンを明確かつ一貫して特定できるようにし、主観性を抑えつつ、意思決定時の分析に対する確信を高めます。

現時点では、実装に完全な自動売買機能は含まれていませんが、それでも意思決定支援ツールとして十分に実用的です。これらのゾーンを活用することで、トレーダーは他のテクニカルシグナルと組み合わせながら、エントリー位置の精度やリスク管理、さらにはコンフルエンス分析を向上させることができます。

ストラテジーテスターの結果も、このアプローチの堅牢性を裏付けています。市場構造が展開する中で、価格がこれらのゾーンに繰り返し反応することが確認されています。

今後は、ゾーン更新の自動化や、過去の反応に基づく確率的な重み付けの導入、さらに取引実行ロジックの統合を進めていく予定です。こうした拡張により、このインジケーターは単なる分析補助ツールから、エキスパートアドバイザーにも組み込める、完全なルールベースの取引コンポーネントへと発展していきます。

本結論の後では、本記事の主要なポイントを簡潔に整理するとともに、ここで解説したソースコード一式を掲載します。コメント欄での質問やフィードバック、オープンな議論も歓迎します。こうしたやり取りは、アイデアを磨き、実践的な取引手法を発展させていくうえで欠かせないものだからです。

重要な学び

重要な学び 説明
サポートとレジスタンスはゾーンとして扱うことができます。 サポートおよびレジスタンスを単一の水平線ではなく、繰り返されるスイングの相互作用から導かれる価格レンジとして扱います。これにより、トレーダーは確率的な視点で市場を捉えることができ、エントリー、ストップ、ターゲットの意思決定精度が向上します。
スイング構造が市場状況 を決定します。 価格データから直接スイングハイおよびスイングローを検出することで、遅行指標よりも市場構造の重要性を強調します。トレーダーはトレンドの挙動と反応が有効な取引領域をどのように形成するかを理解できます。
MQL5インジケーターは厳格なライフサイクルに従います。 OnInit、OnCalculate、OnDeinitがどのように連携して動作するかを示します。このライフサイクルを理解することで、ライブチャートおよびストラテジーテスターの両方で安定して動作するインジケーターを構築できます。
バッファは戦略の統合を可能にします。 可視化にチャートオブジェクトを使用する場合でも、インジケーターバッファは依然として重要です。EAや他のツールがインジケーターのロジックをプログラム的に利用できるようになります。
グローバル変数はEAとの通信を可能にします。 ゾーン値をグローバル変数として公開することで、インジケーターがEAと市場状況を共有できるようになり、構造分析に基づいた自動売買判断が可能になります。
非対称ゾーンパディングは市場心理を反映します。 サポート上側およびレジスタンス下側により大きなパディングを設定することで、市場が反転前にオーバーシュートする傾向を考慮しています。この技術的調整は実際のトレーダー行動を反映し、ダマシのブレイクアウトを減少させます。
チャートオブジェクトは適切にクリーンアップする必要があります。 ObjectsDeleteAll( ) を接頭辞付きで使用することで、メモリリークやチャートのオブジェクト残留を防止します。この規律ある設計はプロフェッショナルなインジケーター開発と長期的なチャート安定性に不可欠です。
パラメータ最適化には、状況認識が不可欠です。 最適なSwingSensitivityおよびLookBackPeriodは時間足やボラティリティによって変化します。成功するトレーダーは、普遍的な「最適値」を求めるのではなく、市場環境に応じて調整することを学びます。
視覚的階層構造はトレード判断を向上させます。 平均を実線、境界を破線、ゾーンを塗りつぶし矩形として表現することで、情報を即座に直感的に理解できるようになります。この設計アプローチにより、急速な相場環境でも複雑な情報処理が容易になります。
確率ゾーンは感情的な取引を軽減します。
正確な価格ではなく領域として提示することで、「正確なレベルを逃す」という心理的ストレスを減少させ、統計的に意味のある領域内でリスクリワードに集中できるようになります。
モジュール化されたコード構造は拡張性を高めます。 スイング検出、ゾーン計算、可視化を分離することで、ボリューム確認やマルチタイムフレーム分析などの機能追加を、全体を書き直すことなく実装できます。
リアルタイム処理には効率性が求められます。 OnCalculate関数の構造では、データ不足時の早期リターンや適切な配列シリアル処理により、高ボラティリティの低時間足でもインジケーターの応答性を維持します。

添付ファイル

ソースファイル名 バージョン  説明
SRProbabilityZones.mq5 1.0 サポートおよびレジスタンスを静的な水平線としてではなく、確率ベースのゾーンとして動的に計算し、可視化するコアインジケーターです。ユーザーが設定したルックバック期間内でスイングハイおよびスイングローをアルゴリズム的に検出し、それらの価格反応をクラスタリングします。その結果として、チャート上に異なる色の矩形ゾーン(サポートは青、レジスタンスは赤)を描画します。各ゾーンの境界は、価格が反応する可能性のある範囲を示しており、ゾーン内部には高確率反応レベルを示す白色の実線が平均値として描画されます。ティックごとに更新され、計算されたゾーン値をグローバル変数へ出力することで、EAとの統合や自動売買ロジックへの活用を可能にします。

ヒントSRProbabilityZones.mq5 のソースコードをダウンロードした後、MetaEditorでコンパイルし、任意のMetaTrader 5チャートに適用することで、動的なサポート/レジスタンスの確率ゾーンを即座に可視化できます。 

目次に戻る

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

添付されたファイル |
EAのサンプル EAのサンプル
一般的なMACDを使ったEAを例として、MQL4開発の原則を紹介します。
MQL5入門(第34回):MQL5のAPIとWebRequest関数の習得(VIII) MQL5入門(第34回):MQL5のAPIとWebRequest関数の習得(VIII)
MetaTrader 5でインタラクティブなコントロールパネルを作成する方法を学びます。入力フィールド、アクションボタン、テキストを表示するためのラベルを追加する基本について説明します。プロジェクトベースのアプローチを用いて、ユーザーがメッセージを入力し、最終的にAPIからのサーバー応答を表示するパネルを設定する方法を学びます。
エラー 146 (「トレードコンテキスト ビジー」) と、その対処方法 エラー 146 (「トレードコンテキスト ビジー」) と、その対処方法
この記事では、MT4において複数のEAの衝突をさける方法を扱います。ターミナルの操作、MQL4の基本的な使い方がわかる人にとって、役に立つでしょう。
MQL5でカスタムインジケーターを作成する(第4回):デュアルオシレーター搭載Smart WaveTrend Crossover MQL5でカスタムインジケーターを作成する(第4回):デュアルオシレーター搭載Smart WaveTrend Crossover
本記事では、MQL5で「Smart WaveTrend Crossover」と呼ばれるカスタムインジケーターを開発します。このインジケーターは、2つのWaveTrendオシレーターを活用しており、1つはクロスオーバーシグナルの生成、もう1つはトレンドフィルタリングを目的としています。チャネル長、平均期間、移動平均期間といった各種パラメータはカスタマイズ可能です。また、トレンド方向に応じてローソク足を色分け表示し、クロスオーバー時には買いや売りの矢印シグナルを表示します。さらに、トレンド確認の有効化オプションや、色やオフセットなどのビジュアル要素も調整可能です。