古典的な戦略を再構築する(第18回):ローソク足パターンの探索
ローソク足パターンは長年にわたり、プロのトレーダーが金融市場での取引判断をおこない、投資家の心理を測るために使用されてきました。これらのパターンは時として有効で、信頼できる結果をもたらすこともあります。しかし、市場の状況やレジームによっては機能しないことも知られています。本記事では、利用可能なローソク足パターンを探求し、その古典的解釈の限界を克服するためにアルゴリズム的な改善が可能かどうかを検討します。
今日の議論では、一般に包み線と呼ばれるパターンに焦点を当てます。実務者にとって、信頼できるローソク足パターンを見つけることは容易ではありません。最初に直面する問題として、多くの異なるローソク足パターンが存在するため、どのパターンを追跡するか選択するのが困難です。 さらに厄介なのは、この探索空間は手作業でしか検証できないことです。つまり、実務者はアルゴリズム内で、自分が想定する特定のローソク足パターンを記述するルールや条件を手作業で定義する必要があります。
既存のローソク足パターンは非常に多く、手作業で探索することは、コミュニティの新規メンバーや経験の浅いメンバーにとっては非常に負担の大きい作業となります。この記事では、よく知られたローソク足パターンを改善するための実践的なガイドを提供します。今回取り上げる包み線パターンは、多くのトレーダーにとって、市場におけるブレイクアウトの前兆として認識されています。これらのローソク足パターンは、ポジションの偏りを示すことが多く、そのため市場の一方向への強いブレイクアウトの可能性を示唆します。
本連載の記事のほとんどでは、主にAI主導の取引戦略やテクニカル指標をシグナル生成の主要手段として取り上げています。ローソク足パターンをアルゴリズムの意思決定要素として活用する機会はほとんど取り上げていません。その理由は複数ありますが、ローソク足パターンをトレーディング戦略に組み込むことが難しいいくつかの理由を挙げます。
まず、ローソク足パターンによって定義される探索空間は非常に広大です。存在するパターンは非常に多く、それぞれが異なる形状を取り得ます。ローソク足パターンは毎回同じ形状を取るわけではないため、この空間を探索し、新しいパターンを考案することは手作業でおこなわなければならず、アルゴリズム的に探索するのは非常に困難です。
さらに、同じパターンであっても結果が毎回異なる場合があります。そのため、ローソク足パターンは必ずしも堅牢ではないと議論されることがあります。同じパターンの出現ごとに結果が異なるため、市場の意図する方向性を完全に示すものではありません。
古典戦略の視覚化
それでは、取引戦略の古典的な実装を可視化していきます。通常、包み線は、あるローソク足の始値がその前のローソク足の終値より大きく、終値はその逆である場合に定義されます。包み線は古典的にはほとんどの場合2本のローソク足で構成されるパターンとされています。このパターンはエントリーシグナルとして機能し、低時間足では通常使用されません。今回のコード例では、戦略を日足で実装します。図1では、EURUSDペアにおける包み線パターンを例としてハイライトしています。

図1:古典的包み線パターンの識別
正しく識別された場合、このローソク足パターンの後には、通常、予測された方向への強い価格変動が続きます。図2では読者向けにその様子を可視化しています。これが、取引の現場でこのパターンが人気である理由の一つです。
しかしながら、後ほど示すように、このアルゴリズムをコードとして実装する際にはいくつかの課題が生じます。まず、この古典的戦略のベースライン版を用いてアプリケーションのベースライン性能を確立しました。その後、この古典的バージョンにいくつかの改良を加えることで、市場のノイズをより多く除去でき、取引回数を抑えながらもより高い収益性を実現することができました。これは、よりノイズの多いパターンで必要だった取引数よりも少ない取引で達成できた成果です。

図2:過去のパフォーマンスから合理的な信頼度を得られるパターン
本連載全体では、5種類のユニークなローソク足パターンを探索していきます。しかし、今回はまず包み線のパターンのみに焦点を当てます。ほとんどのアプリケーションと同様に、まずはシステム定数を定義し、両方のテストで同じロットサイズを使用することを保証します。
//+------------------------------------------------------------------+ //| Candle Stick Patterns.mq5 | //| Copyright 2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" //+------------------------------------------------------------------+ //| This application attempts to reliably use different candlestick | //| patterns. The application will employ the following: | //| | //| 1) Engulfing Candle | //| 2) Momentum Candle | //| 3) Doji Candle | //| 4) Shooting Star Candle | //| 5) Hammer Candle | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| System constants | //+------------------------------------------------------------------+ #define LOT_SIZE SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN)
取引ライブラリをインポートします。
//+------------------------------------------------------------------+ //| Trading libraries | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh> CTrade Trade;
次に、必要なテクニカル指標を読み込みます。このアプリケーションでは、ATRを使用して、ストップロスおよびテイクプロフィットのレベルを定義します。
//+------------------------------------------------------------------+ //| Indicators | //+------------------------------------------------------------------+ int atr_handler; double atr[];
ほとんどのアプリケーションと同様に、いくつかのグローバル変数が必要です。これらは時間の経過や価格水準の変化を追跡する役割を果たします。
//+------------------------------------------------------------------+ //| Global variables | //+------------------------------------------------------------------+ MqlDateTime time_stamp,current_time; double bid,ask;
アプリケーションを初期化する際に、タイムスタンプパラメータとATRを設定します。
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Set the time TimeLocal(time_stamp); atr_handler = iATR(Symbol(),PERIOD_CURRENT,14); //--- return(INIT_SUCCEEDED); }
アプリケーションの終了時には、以前に使用していたインジケーターに関連付けられたメモリを解放します。
//+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- IndicatorRelease(atr_handler); }
新しい価格データを受信するたびに、システムはまず現在時刻を更新し、現在の日付と保存されているタイムスタンプに不一致がないかを確認します。初期化以降最初のティックの場合、タイムスタンプは依然として初期値のままです。新しい日が検出された場合、タイムスタンプを更新した後、市場データをリフレッシュします。これにはATRバッファの読み取り値や現在のBidおよびAsk価格も含まれます。
ポジションがない場合、アルゴリズムは包み線のパターンを検出します。通常、このパターンは、現在形成中のローソク足と前日のローソク足の2本のローソク足で構成されます。そのため、iOpenおよびiCloseは現在のローソク足と前日のローソク足を参照するようにそれぞれ0と1でインデックス化されます。
強気の包み線は、現在のローソク足の始値が前日の終値より下で、現在の終値が前日の始値を上回った場合に識別されます。この条件により、前日のローソク足を完全に包み込む形のローソク足が形成されます。逆の条件が弱気の包み線パターンを定義します。
これらのルールによりエントリーシグナルが生成され、テイクプロフィットレベルはATRの1.5倍間隔で設定され、リスクリワードレシオ1:1を維持します。
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- Update the current time TimeLocal(current_time); //--- Check if a new candle has fully formed if(time_stamp.day != current_time.day) { //--- Update the time TimeLocal(time_stamp); //--- A new candle has formed //--- Update the ATR reading CopyBuffer(atr_handler,0,0,1,atr); ask = SymbolInfoDouble(Symbol(),SYMBOL_ASK); bid = SymbolInfoDouble(Symbol(),SYMBOL_BID); //--- First check if we have no open positions if(PositionsTotal() == 0) { //--- Then check for a trade //--- Check for a bullish engulfing candle stick pattern if((iOpen(Symbol(),PERIOD_D1,0)<iClose(Symbol(),PERIOD_D1,1)) && (iClose(Symbol(),PERIOD_D1,0)>iOpen(Symbol(),PERIOD_D1,1))) { //--- Then, enter long positions Trade.Buy(LOT_SIZE,Symbol(),ask,(ask - (atr[0]*1.5)),(ask + (atr[0]*1.5))); } //--- Otherwise we may check for bearish engulfing candlestick pattern if((iOpen(Symbol(),PERIOD_D1,0)>iClose(Symbol(),PERIOD_D1,1)) && (iClose(Symbol(),PERIOD_D1,0)<iOpen(Symbol(),PERIOD_D1,1))) { //--- Then, enter long positions Trade.Sell(LOT_SIZE,Symbol(),ask,(ask + (atr[0]*1.5)),(ask - (atr[0]*1.5))); } } } //--- Otherwise, the current candle has not fully formed } //+------------------------------------------------------------------+
アプリケーションの終了時には、定義したマクロを解除します。
//+------------------------------------------------------------------+ //| System definitions | //+------------------------------------------------------------------+ #undef LOT_SIZE
アプリケーションのベンチマーク版のバックテスト期間を設定します。今回は2023年から2025年までの2年間のデータを使用します。

図3:古典的なローソク足パターンのベンチマーク版のテスト
初期のパフォーマンス結果は有望です。包み線パターンにはある程度の信頼性があることが示唆されます。2年間で合計純利益127.64ドルを生み出し、取引数は115回でした。これは55.7%の勝率で達成され、ロングとショートのエントリーも健全に分布しています。以前の議論でも触れましたが、統計モデルからこれほど対称的な取引分布を得るのは非常に困難でした(リンクはこちら)。

図4:古典的セットアップから得られた統計結果
元のローソク足パターンバージョンは、利益率が堅実で長期的に上昇傾向のあるエクイティカーブを生み出しました。これは、この戦略をさらに改良する価値があることを示すさらなる信頼性を示しています。

図5:ベンチマーク戦略によって生成されたエクイティカーブは長期的な上昇傾向を示す
再設計戦略の可視化
慎重に検討した結果、いくつかの改善点が見えてきました。
最初の改善点は、2本のローソク足を始値と終値だけで比較するのではなく、ヒゲの高値と安値も考慮するということです。これによりノイズを除去し、十分な取引量によってトレンドや強い方向性の動きを支えられる、より顕著なローソク足を際立たせることができます。
2つ目の改善点は技術的なもので、MetaTrader5上でのバックテストの動作に関連します。MetaTrader5で自動売買ロボットをバックテストする際、シミュレーションでは各ローソク足の開始時刻(午前0時)から処理が開始されます。そのため、日足の確定足の始値、高値、安値、終値に依存するロジックは、その時点では有効になりません。MQL5の観点からは、パターンを3本のローソク足構造として扱うほうが実用的です。新しい日が始まるたびに、前日とその前の日のローソク足の情報を参照する方法です。
実務上の例として、週の初めの月曜日には、前週の金曜日のローソク足が木曜日のローソク足を包み込んでいたかを確認します。この情報を基に月曜日の取引判断を行います。月曜日のローソク足は市場オープン時にまだ形成中のため、月曜日のローソク足が金曜日のローソク足を包むかどうかを判断するのは適切ではありません。この理由に基づき、改良されたパターンを開発しました(図6参照)。

図6:改良版ローソク足パターンの識別
予備テストの結果は有望で、戦略の有効性を示唆しました。しかし、最終的にはデータが物語ることになります。

図7:提案したローソク足パターンから得られた予備結果は有望である
取引アプリケーションもこれに応じて更新しました。エントリー条件を始値と終値だけでなく、ローソク足のヒゲも確認する形に修正しました。また、始値の利用方法も改善しました。終値と直接比較するのではなく、過去2日間の動きを評価します。包み線の動きの中で始値が上昇していれば強気、下降していれば弱気と判断します。
//--- Then check for a trade //--- Check for a bullish engulfing candle stick pattern if((iLow(Symbol(),PERIOD_D1,1)<iLow(Symbol(),PERIOD_D1,2)) && (iHigh(Symbol(),PERIOD_D1,1)>iHigh(Symbol(),PERIOD_D1,2)) && (iOpen(Symbol(),PERIOD_D1,1)>iOpen(Symbol(),PERIOD_D1,2))) { //--- Then, enter long positions Trade.Buy(LOT_SIZE,Symbol(),ask,(ask - (atr[0]*1.5)),(ask + (atr[0]*1.5))); } //--- Otherwise we may check for bearish engulfing candlestick pattern if((iLow(Symbol(),PERIOD_D1,1)<iLow(Symbol(),PERIOD_D1,2)) && (iHigh(Symbol(),PERIOD_D1,1)>iHigh(Symbol(),PERIOD_D1,2)) && (iOpen(Symbol(),PERIOD_D1,1)<iOpen(Symbol(),PERIOD_D1,2))) { //--- Then, enter long positions Trade.Sell(LOT_SIZE,Symbol(),ask,(ask + (atr[0]*1.5)),(ask - (atr[0]*1.5))); }
同じテスト期間で再実行したところ、改善された結果が得られました。

図8:改良版アプリケーションのテスト準備完了
総純利益は126ドルから160ドルに増加し、取引回数は減少しました。これは、資本のより効率的な使用を示しています。以前のバージョンでは、包み線の識別において不要なリスクが導入されていたことが示唆されます。興味深いことに、利益の出た取引の割合はおおむね55%で変わらず、両戦略が同じローソク足概念のバリエーションであることを考えると合理的です。

図9:改良版取引アプリケーションから得られた詳細結果
最後に、改良版パターンのエクイティカーブを分析すると、オリジナル戦略では達成できなかった新高値への明確なブレイクアウトが観察されました。

図10:改良版取引戦略によって生成されたエクイティカーブ
結論
本記事では、一般的な包み線パターンを、MQL5プラットフォームに適した形で効果的に適用する方法を示しました。ローソク足パターンは古典的な形でも実務上の価値を持ち、適切な改良を加えることで、より堅牢かつ資本効率の高い戦略にできることを示しています。
また、これらのパターンをATRインジケーターと組み合わせることで、リスク管理を向上させる方法も示しました。ローソク足パターン単体ではリスク管理機能を内蔵していないため、ATRを活用することにより、より安全に取引判断をおこなうことが可能です。次回の議論では、5種類のローソク足パターンシリーズの2つ目のパターンをさらに改良する予定です。
| ファイル名 | ファイルの説明 |
|---|---|
| Candle Stick Benchmark.mq5 | 主要業績評価指標を確立するために設計されたアプリケーションのベンチマークバージョン |
| Candle Stick Patterns.mq5 | これまでのパフォーマンスレベルを上回るように作成された、改良版アプリケーション |
MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/20223
警告: これらの資料についてのすべての権利はMetaQuotes Ltd.が保有しています。これらの資料の全部または一部の複製や再プリントは禁じられています。
この記事はサイトのユーザーによって執筆されたものであり、著者の個人的な見解を反映しています。MetaQuotes Ltdは、提示された情報の正確性や、記載されているソリューション、戦略、または推奨事項の使用によって生じたいかなる結果についても責任を負いません。
MQL5での取引戦略の自動化(第39回):信頼区間とダッシュボードを備えた統計的平均回帰
ダイナミックマルチペアEAの形成(第5回):スキャルピングとスイングトレードの切替設計
エラー 146 (「トレードコンテキスト ビジー」) と、その対処方法
MQL5における市場ポジショニング戦略の体系(第2回): Nvidia向けマルチパターンのビット単位学習
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索