English Русский Deutsch
preview
初心者からエキスパートへ:流動性ベースの取引戦略の構築

初心者からエキスパートへ:流動性ベースの取引戦略の構築

MetaTrader 5 |
24 2
Clemence Benjamin
Clemence Benjamin

内容

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

 

はじめに

本記事では、流動性ゾーンに基づいたエキスパートアドバイザー(EA)のモデリングに焦点を当てます。これまでの議論では、これらのゾーンの特定および検証に注力してきましたが、良好な結果が得られました。しかし、依然として重要な課題が一つ残っています。それは取引プロセスの自動化です。これを実現するためには、戦略をMQL5で実行可能なロジックへと変換し、堅牢な注文執行およびリスク管理ルールを組み込む必要があります。

まずは戦略の考え方を明確に理解することが重要です。ロジックが十分に定義された段階で、コード実装へと進みます。

戦略の理解

これまでの分析により、流動性ゾーンはしばしば1本のローソク足として表現できることが分かっています。このローソク足は通常、価格が一時的に停滞または保ち合いを形成した後に出現し、時間をかけて形成された流動性や下位足での流動性を内包しています。この挙動こそが、本研究で扱う市場構造モデルを形成する主要因となっています。

分かりやすさと実装の容易さのため、本アプローチでは意図的に簡略化されたモデルを採用しています。複雑なマルチバー構造に依存するのではなく、最小限の価格情報のみを用いて条件を定義します。これにより、戦略のコアメカニクスに集中でき、コード実装および検証も容易になります。

この戦略の目的は、識別された流動性構造(図1)へと価格が戻ってリテストする動きを利用し、その領域からポジションを構築することです。そして最終的には、セットアップが強気の場合は直近の高値、弱気の場合は直近の安値をターゲットとします。リテストという概念は本モデルの中心的要素ですが、同時にこの考え方が広く研究され一般化されている点にも注意が必要です。その結果、これらの水準はますます市場操作の影響を受けやすくなっています。より大きな資本力を持つ市場参加者は、明確な境界を一時的に突破させることでストップロスを誘発し、弱いポジションを市場から排除した上で、本来の方向へと動かすことがあります。 

図1:スイングB-Cによる流動性ゾーンへのリテスト

このため、リスク管理は後付けの要素として扱うことはできません。戦略設計とアルゴリズム実装の両方において不可欠な構成要素でなければなりません。EAがどのようにリスクを定義し、ストップロスを配置し、エクスポージャーを管理するかは、どのように有効な取引セットアップを識別するかと同様に重要です。

また、すべてのセットアップが成功するわけではないという点も理解しておく必要があります。単一の取引が利益を保証することはありません。むしろパフォーマンスは、勝ちと負けの積み重ねによって時間をかけて形成されます。そして最終的に重要となるのは、十分なサンプル数に基づく累積結果であり、それが戦略の収益性を決定します。

この基礎を踏まえ、次のセクションでは戦略をMQL5コードへと変換する作業に進みます。実装後には、実際の市場環境に近い条件下でその挙動をテストおよび評価していきます。



実装

取引ロジックを実装する前に、MetaEditorのMQL5ウィザードを使用して新しいEAプロジェクトを作成します。このウィザードは、イベントハンドラおよびプレースホルダーコードを含むデフォルトテンプレートを自動生成します。本記事では、その自動生成されたロジックをすべて削除し、以下に示すメタデータセクションのみを残します。

以下がコードです。

//+------------------------------------------------------------------+
//|                            Single_Candle_Liquidity_Trader.mq5    |
//|                                Copyright 2025, Clemence Benjamin |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Clemence Benjamin"
#property link      "https://www.mql5.com"
#property version   "1.00"

これにより、以降のセクションで展開される実装プロセスにおいて、段階的に戦略を構築していくという理解に集中できます。構造に慣れるためにも手動でコードを入力することが望ましいですが、利便性のため、記事末尾の添付ファイルとして完全なソースコードも提供されています。

EAのメタデータと入力が定義された後、すべての注文執行を担当する取引ライブラリをインクルードします。低レベルの取引関数を直接扱うのではなく、より安全で構造化されたインターフェースを提供するCTradeクラスを利用します。

以下がコードです。

#include <Trade/Trade.mqh>

CTrade trade;

単一のグローバルCTradeオブジェクトを宣言することで、指値注文、ストップロス、テイクプロフィット、マジックナンバー設定といったすべての取引操作を一元化し、コードの可読性と保守性を向上させます。

入力パラメータと戦略制御の宣言

実行ロジックを書く前に、まず入力パラメータを定義します。これは意図的なステップです。入力はEAの外部挙動を定義し、ソースコードを変更することなく戦略を調整できるようにします。これにより、戦略ロジックとユーザー制御を分離しており、これはプロフェッショナルなEA設計における重要な原則です。

以下がコードです。 

input double LotSize             = 0.10;
input int    MaxSpreadPoints     = 30;
input bool   AllowBuy            = true;
input bool   AllowSell           = true;
input double RatioMultiplier     = 3.0;
input double SL_Offset_Points    = 20;
input int    PendingExpiryHours  = 24;
input ulong  MagicNumber         = 777333;

ここでは、それぞれのパラメータを明確な役割とともに定義しています。

  1. LotSizeは、各指値注文における固定ロットサイズを制御します。これによりリスクサイズを予測可能にし、現時点では動的ロット計算を避けています。
  2. MaxSpreadPointsは、不利な流動性環境(ニュース時やロールオーバー時など)での注文を防ぐために導入されています。
  3. AllowBuyおよびAllowSellは方向フィルターとして機能し、ロジックを変更することなく片方向の取引を無効化できます。
  4. RatioMultiplierは本戦略のコア構造制御であり、インパルス足がベース足に対してどの程度大きい必要があるかを決定し、流動性圧縮検出の感度を調整します。
  5. SL_Offset_Pointsは、ストップロスを意図的に流動性ゾーンの外側へ配置するために使用され、短期的な操作やストップ狩りを減少させます。
  6. PendingExpiryHoursは時間的リスク管理です。この時間内に価格が流動性ゾーンへ戻らない場合、そのセットアップは無効とみなされます。
  7. MagicNumberは、このEAによって生成されたすべての注文とポジションを識別するための一意の識別子であり、同一口座上で他ストラテジーと混在しても明確に分離されます。

このように入力を構造化することで、EAは柔軟でテスト可能かつユーザーフレンドリーになりつつ、内部ロジックの整合性が維持されます。

グローバル変数の宣言

次に、ティック間で状態を保持するためのグローバル変数を定義します。本戦略では、グローバル状態は意図的に最小限に抑えています。

以下がコードです。

datetime lastBarTime = 0;

この変数は、新しいローソク足の開始を検出するためにのみ使用されます。自動取引システムにおいて実行頻度を制御することは極めて重要であり、重複エントリーやバックテストの不整合を防ぎます。

新しいローソク足の検出

すべての取引ロジックの評価前に、「1本の足につき1回の実行」というルールを強制します。これにより、ティック頻度に関係なく、確定足ごとに1回のみEAが反応するようになります。

以下がコードです。

bool IsNewBar()
{
   datetime currentBar = iTime(_Symbol, _Period, 0);
   if(currentBar != lastBarTime)
   {
      lastBarTime = currentBar;
      return true;
   }
   return false;
}

ここでは現在のローソク足のタイムスタンプと直前に処理したローソク足を比較します。新しい足が形成された場合、その時間を更新し処理を許可します。

この仕組みにより以下が保証されます。

  • ノンリペイントロジック
  • 安定したストラテジーテスター挙動
  • 予測可能な注文タイミング

ローソク足レンジの計測

本戦略の中心はローソク足の実体ではなくレンジベースの比較です。そのため、各ローソク足の高値・安値レンジを返すヘルパー関数を導入します。

以下がコードです。

double CandleRange(int index)
{
   return MathAbs(iHigh(_Symbol,_Period,index) -
                   iLow(_Symbol,_Period,index));
}

この処理を関数として分離することで可読性が向上し、EA全体で一貫したロジックとして再利用できます。

買いセットアップのためのマルチレベル流動性エントリー

単一価格でのエントリーではなく、ベース足のレンジ全体にわたって指値注文を分散配置します。これは市場における流動性吸収の挙動をモデル化したものです。

以下がコードです。

void PlaceBuyLimits(double highB, double lowB, double sl, double tp, datetime expiry)
{
   double mid = (highB + lowB) / 2.0;

   trade.BuyLimit(LotSize, highB, _Symbol, sl, tp, ORDER_TIME_SPECIFIED, expiry);
   trade.BuyLimit(LotSize, mid,   _Symbol, sl, tp, ORDER_TIME_SPECIFIED, expiry);
   trade.BuyLimit(LotSize, lowB,  _Symbol, sl, tp, ORDER_TIME_SPECIFIED, expiry);
}

ベース足の高値、中値、安値で注文することで、以下が実現されます。

  • 平均エントリー価格の改善
  • 完璧なタイミング依存の低減
  • 浅いリトレースでも部分約定を獲得

売りセットアップのマルチレベル流動性エントリー

弱気相場に対しても同様のロジックを適用します。

以下がコードです。

void PlaceSellLimits(double highB, double lowB, double sl, double tp, datetime expiry)
{
   double mid = (highB + lowB) / 2.0;

   trade.SellLimit(LotSize, highB, _Symbol, sl, tp, ORDER_TIME_SPECIFIED, expiry);
   trade.SellLimit(LotSize, mid,   _Symbol, sl, tp, ORDER_TIME_SPECIFIED, expiry);
   trade.SellLimit(LotSize, lowB,  _Symbol, sl, tp, ORDER_TIME_SPECIFIED, expiry);
}

この対称性により、両方向で一貫した挙動が保証され、検証および最適化が容易になります。

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

すべての戦略ロジックはOnTick()関数内で統合されます。ここで条件判定、リスクチェック、注文がおこなわれます。

以下がコードです。 

void OnTick()
{
   if(!IsNewBar())
      return;

最初に新規バー判定をおこないます。新しい足が形成されていない場合は処理を終了します。

スプレッド保護と取引識別

市場構造を評価する前に取引条件を検証します。

以下がコードです。

if(SymbolInfoInteger(_Symbol, SYMBOL_SPREAD) > MaxSpreadPoints)
   return;

trade.SetExpertMagicNumber(MagicNumber);

これにより不利なスプレッド環境でのエントリーを防ぎ、すべての取引をマジックナンバーで一意に識別します。

ローソク足の役割定義

モデルに参加するローソク足を明示的に定義します。

以下がコードです。

int A = 1;   // Impulse candle (closed)
int B = 2;   // Base candle

  • Bはベース足(流動性圧縮)
  • Aはインパルス足(確定済み)

現在形成中の足(インデックス0)は意図的に無視されます。

ローソク足比率フィルタの適用

本戦略の構造的コアです。

以下がコードです。

double rangeA = CandleRange(A);
double rangeB = CandleRange(B);

if(rangeB > rangeA / RatioMultiplier)
   return;

ここではベース足がインパルス足に対して十分に小さいことを要求し、RatioMultiplierによって感度を制御します。

方向性の確認

両ローソク足が同方向であることを確認します。

以下がコードです。

double openA  = iOpen(_Symbol,_Period,A);
double closeA = iClose(_Symbol,_Period,A);
double openB  = iOpen(_Symbol,_Period,B);
double closeB = iClose(_Symbol,_Period,B);

これにより枯渇ではなく、継続的な動きを対象とします。

ストップロスオフセットと注文期限

相場操作やフェイクブレイクを考慮し、ストップロスと時間制御を導入します。

以下がコードです。

double point  = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double offset = SL_Offset_Points * point;

datetime expiry = TimeCurrent() + PendingExpiryHours * 3600;

これら2つのパラメータは連携して、価格面と時間面のリスクを制御します。

強気なセットアップの実行

以下がコードです。

if(AllowBuy && closeA > openA && closeB > openB)
{
   double sl = lowB - offset;
   double tp = highA;

   PlaceBuyLimits(highB, lowB, sl, tp, expiry);
}

買い注文は流動性ゾーン内に配置され、ゾーン外にストップロスを置き、インパルス高値をターゲットとします。

弱気なセットアップの実行

以下がコードです。

if(AllowBuy && closeA > openA && closeB > openB)
{
   double sl = lowB - offset;
   double tp = highA;

   PlaceBuyLimits(highB, lowB, sl, tp, expiry);
}

この論理は強気シナリオを反映しており、構造的な一貫性を維持しています。

この時点で、単一ローソク足ベースの流動性戦略は、パターン検出から注文執行、リスク管理まで完全にモデル化されています。本システムはインジケーターに依存せず、純粋に価格挙動と流動性、そして規律ある執行ロジックのみに基づいて設計されています。

次のセクションでは、テスト手法、パラメータの感度、および結果の解釈について説明します。



テスト

ここでは、MetaTrader 5のストラテジーテスターでEAを実行することで得られた初期テスト結果を示します。プラットフォームに不慣れな読者のために説明すると、まずはナビゲーターウィンドウのExpertsフォルダ内で本プロジェクトに対応するEAを見つけます。見つけたら、そのEAを右クリックし、コンテキストメニューから[Test]を選択します。この操作によりストラテジーテスターが起動し、さまざまな種類のテストを実行できるようになります。

最適化を検討する前に、まず最優先すべき目的は、EAが意図されたストラテジールールどおりに一貫して実行されていることを検証することです。この段階では収益性は問題ではなく、ロジックがコンセプトからコードへ正しく変換されているか、そして注文が設計通りに発注・管理・期限切れ処理されているかを確認することが重要です。この検証ステップが完了して初めて、最適化やパラメータ調整へと進みます。

また、一部の戦略はこの初期段階で失敗することがあります。場合によっては、遺伝的最適化をおこなった後であっても構造的に不健全であり、それ以上の開発に適さないと判明するケースもあります。このような結果を早期に特定することは、時間の節約につながり、不要な過剰最適化を防ぐことにもなります。

以下のスクリーンキャストはストラテジーの動作を示しており、コンセプトモデルが実際に実装として機能していることを確認できます。なお、システムが収益性のあるトレーディングモデルとして成立するためには追加の調整が必要ですが、下に示す最適化結果(グラフ形式)はすでに一定のパフォーマンスが見込める領域を示しています。さらなるフィルタリングと負の結果の排除を通じて改善することで、継続的な開発に対して前向きなシグナルが得られます。

図2:テスト



結論

本記事では、ベース足とインパルス足から構成される単一の流動性ゾーンを利用するパターンを、概念的な取引アイデアからMQL5を用いて完全に自動化された取引モデルへと変換する方法を示しました。完成したEAは、定義されたストラテジールールに従って実行されます。すなわち、指値注文は構造に基づいて配置され、一部の取引は発動して利益確定され、他の取引は損失となり、また一部の注文は約定しないまま終了します。

長期的な履歴テスト(2005年から現在まで)を通じて観察すると、すべての流動性ゾーンが必ずしも価格によって再訪されるわけではないことが分かります。場合によってはリテストが大幅に遅れる、あるいは発生しないこともあります。この挙動に対応するため、設定された時間を超過した場合に未約定の指値注文を自動的に削除する時間ベースの期限切れメカニズムを導入し、古い取引アイデアが市場に残り続けることを防いでいます。

教育的観点から見ると、本研究は抽象的なトレーディング概念を、正確なルールベース実行ロジックへと変換するプロセスを示しています。本EAは学習および研究目的で設計されており、デモ口座での検証が推奨されます。また、セッションフィルターの追加、市場環境フィルターの強化、補助的な分析ツールとの統合など、今後の改善余地も残されています。

総じて本研究は、取引戦略がその条件を明確に定義しプログラム的に表現できる場合、自動化が可能であることを確認するものです。本記事が戦略デザインおよびEA実装の両面において実用的な示唆を提供できれば幸いです。

ご意見やご感想は、下記のコメント欄にお寄せください。

重要な学びと関連資料は、以下のセクションに記載されています。


重要な学び

重要な学び説明
単一ローソク足の流動性流動性は必ずしも複雑なマルチバー構造を必要とせず、単一のローソク足でも有効な流動性ゾーンを定義できる
実体 vs レンジローソク足の実体ではなく高値・安値レンジ全体を測定することで、ボラティリティ収縮をより客観的に評価できる
インパルスベース比率インパルス足とベース足の比率を用いることで、主観的な概念を定量的かつ検証可能なルールへ変換できる
確定足ロジック確定足のみで評価することでリペイントを排除し、バックテストとライブ実行の整合性を確保できる
複数指値エントリー 流動性レンジ内に複数の指値注文を分散することで、約定確率と平均エントリー精度を改善できる
方向性整合ベース足とインパルス足の方向を一致させることでノイズを減らし、継続的なセットアップを強化できる
構造ターゲットインパルス足の極値を利確目標にすることで、恣意的ではない市場構造ベースの出口設計が可能になる
ストップロスバッファストップロスにオフセットを設けることで、流動性スイープや短期操作による早期退出を軽減できる
注文有効期限管理時間経過による無効化を導入することで、古くなったセットアップの市場残存を防げる
サンプルサイズの現実収益性は単発取引ではなく大量サンプルの累積結果で決まる
ルールベースの自動化明確なルールにより裁量を排除し、再現可能な実行モデルを構築できる
実行の規律自動執行は一貫性を保証し、裁量による性能劣化を防ぐ
選択的フィルタリングすべての構造を取引するのではなく、スプレッドやセッション条件などで精度を高める必要がある
戦略検証視覚的テストと最適化は、ロジックの機械的整合性を確認するために不可欠である
反復的開発戦略は一度の実装ではなく、テストと改善の繰り返しで進化する

添付ファイル

ソースファイル名バージョン 説明
Single_Candle_Liquidity_Trader.mq5  1.0Single Candle Liquidity Trader EAの完全実装。ベース足による流動性圧縮の検出、インパルス継続の検証(レンジ比率による)、マルチレベル指値注文の実行、リスク管理、ストップロスオフセット、時間ベースの注文期限切れ機能を含む
目次に戻る

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

添付されたファイル |
最後のコメント | ディスカッションに移動 (2)
Alexander Balandin
Alexander Balandin | 14 3月 2026 において 14:42

こんにちは、 ベンジャミンさん。 あなたのEAをM30で最適化しました(M1では分析していません。TPが小さすぎるため、また私のブローカーが取引の開始を許可していないためです)。第1モードは「実際のティックに基づく各ティック」、 、そして第2モードでは「全ティック」で最適化しました(これは必須です。なぜなら、MT5は第1モードでは現実には存在しない価格の急騰を検知し、そのせいでテスト結果の収益性が非常に高くなってしまうからです!!! - これは現実とは異なります)。残念ながら、最適化後の「全ティック」モードでは、戦略は1件もプラスの結果を出さず、あるいは結果はプラスでも極めて微弱なものに留まりました(一方、第1モードでは全く逆の結果に!! 結果は驚異的です。ロットサイズをバランスに応じて増やす設定にすると、3年間で3000%のリターンを達成し、最大ドローダウンは1%にとどまりました……)。3つの資産(株式、先物ではありません!)を分析しました。 GAZP、VTB、AFLT


追伸:ZONの流動性判定手法(残念ながら記事にはあまり詳しく書かれていませんでしたが)を検討した結果、第2モードでのテストは、貴殿の「手法」による流動性ゾーンの判定に影響を及ぼすべきではないと考えます。

敬具、アレクサンドル。


こんにちは、ベンジャミン。あなたのEAをM30で最適化しました(M1ではTPが小さすぎて、私のブローカーでは取引が許可されないため、分析は行っていません)。 モード1(「実際のティックに基づく毎ティック」)とモード2(「毎ティック」)を使用しました(これは、モード1ではMT5が現実には存在しない価格の急騰を検知し、その結果、テスト上の収益性が非常に高くなってしまうためです!!! — これは現実には当てはまりません)。 残念ながら、最適化後、モード2の「毎ティック」戦略では、プラスの結果が1つも出なかったか、あるいはプラスの結果が出ても非常に、非常に微弱なものにとどまりました(一方、モード1ではその逆でした!! 結果は信じられないほどでした。ロット増加分を含めると、3年間で3000%の利益、最大ドローダウンは1%でした……。3つの資産(先物ではなく株式!)を分析しました。GAZP、VTBR、AFLT


追伸:ゾーンの流動性を決定するあなたの手法を研究した結果(残念ながら、記事にはこれについてほとんど書かれていません)、第2モードでのテストは、あなたの手法による流動性ゾーンの決定に影響を与えるべきではないと考えています。


敬具、アレクサンダー

Alexander P.
Alexander P. | 11 6月 2026 において 10:34

なぜMaxBaseBodyATRとMinExitBodyATRが省略されたのですか?

口座ダイナミクスの追跡:MQL5による残高、エクイティ、含み損益の可視化 口座ダイナミクスの追跡:MQL5による残高、エクイティ、含み損益の可視化
カスタムMT5インジケーターを作成し、全ディール履歴を処理して、開始残高、残高、エクイティ、および含み損益を連続曲線として描画します。このインジケーターはバーごとに更新され、複数銘柄にまたがるポジションを追跡し、ローカルキャッシュを利用することで外部依存を回避します。これを使用することで、エクイティと残高の乖離、実現損益と含み損益の関係、そしてリスクを取ったタイミングを分析できます。
プライスアクション分析ツールキットの開発(第58回):レンジ収縮分析および成熟度分類モジュール プライスアクション分析ツールキットの開発(第58回):レンジ収縮分析および成熟度分類モジュール
前回の記事で紹介した市場状態分類モジュールに続き、本稿ではコンプレッションゾーンの検出および評価をおこなうコアロジックの実装に焦点を当てます。本記事では、価格そのもののプライスアクションのみを用いて市場の持ち合い状態を分析する、レンジ収縮検出および成熟度評価システムをMQL5で実装する方法を解説します。
初心者からエキスパートへ:流動性ゾーンインジケータの開発 初心者からエキスパートへ:流動性ゾーンインジケータの開発
流動性ゾーンの広がりとブレイクアウトレンジの大きさは、リテストが発生する確率に大きな影響を与える重要な変数です。本ディスカッションでは、これらの比率を組み込んだインジケータを開発するための完全なプロセスについて解説します。
MQL5入門(第38回):MQL5のAPIとWebRequest関数の習得(XII) MQL5入門(第38回):MQL5のAPIとWebRequest関数の習得(XII)
MetaTrader 5とBinanceの間に実用的な橋渡しを構築します。WebRequestを使用して30分足のデータ(kline)を取得し、JSONからOHLCおよび時刻データを抽出したうえで、確定済みのローソク足のみを使用して強気の包み足パターンを確認します。その後、クエリ文字列を組み立て、HMAC-SHA256署名を計算し、X-MBX-APIKEYを追加して認証済み注文を送信します。これにより、データ取得から注文執行までを網羅した、分かりやすいエンドツーエンドのEAワークフローを実現できます。