初心者からエキスパートへ:イントラデイ戦略の自動化
内容
はじめに
日中取引とは、同じ取引日のうちに新規建てと決済をおこなう取引を指します。簡単に言えば、長期投資や翌日までポジションを保有することには関心がありません。その代わりに、数分から数時間程度の短期間の市場変動を捉えることを目的とします。
日中取引は高速な環境でおこなわれるため、トレーダーには一貫した意思決定が求められます。感情による遅れやためらいは、エントリー機会の損失、早すぎる決済、または反応の遅れにつながることがあります。ここで自動化が強力な役割を果たします。
広く使用されている日中取引の概念の1つに、移動平均反発があります。トレンド市場では、価格はトレンド方向へ継続する前に、動的な平均線へ引き戻されることがよくあります。移動平均は、上昇トレンドでは動的サポートとして、下降トレンドでは動的レジスタンスとして機能します。
さまざまな期間の中でも、50期間移動平均は機関投資家の基準として広く利用されています。MA10やMA20のようにノイズが多いほど速くなく、MA200のように遅すぎることもありません。反応性と構造のバランスを取っています。このバランスにより、日中取引の枠組みでは理想的な指標になります。
この記事ではMA50を中心に扱いますが、最終的なシステムでは移動平均期間をカスタマイズできるようにします。この柔軟性により、異なる時間足や取引スタイルへ適応できます。
概念調査および市場観察
コードを書く前に、手動によるチャートの振り返り調査を実施しました。これは、多くの開発者が省略する重要な工程です。過去のチャートをローソク足ごとに手動でスクロールしながら、MA50付近での実際の値動きを観察します。
そこで発見したことは重要です。単一で固定された反発パターンは存在しません。
時には、反発は明確なピンバーとして現れます。ヒゲがMA50を貫通する、または正確にMA50付近に位置した後、価格が反発し、トレンド方向へ強く終値を形成します。
また別の場合では、反発は典型的な反転構造として形成されます。
- 上昇トレンド中のMA50周辺でのダブルボトム
- 下降トレンド中のMA50周辺でのダブルトップ
- MAレベルで形成される包み足
- MA接触後に発生するインサイドバーのブレイクアウト
いくつかのケースでは、価格が移動平均をわずかにブレイクし、小さな構造を形成した後、その後もう一度試しに戻ってきて、その後継続するという2段階のリテストを形成します。
この多様性は重要なことを示しています。反発は単一のローソク足パターンではなく、複数の値動きの特徴がまとまって現れる現象です
したがって、自動化では過度に固定的な条件にするべきではありません。単一のピンバー条件だけをコード化すると、多くの有効な反発を見逃します。包み足ロジックだけを実装すると、構造的なリテストを無視することになります
そのため、戦略では1つのローソク足形成に焦点を当てるのではなく、「反応」という考え方を抽象化する必要があります。
繰り返し反発確率の観測
手動調査から、もう1つの重要な発見がありました。トレンド中に価格が以前MA50で反発していた場合、次回その価格が移動平均へ戻った際には、反応する確率が高くなる傾向があります。
言い換えると、トレンド中に価格が一度MA50からきれいに反発した場合、次に価格がその移動平均へ戻ってきたとき、市場参加者は再びその水準を守ろうとする可能性が高くなります。
これは保証されたものではありません。あくまで確率的なものです。しかし、確率こそがトレードの基盤です。
この繰り返される防衛行動は、コンテキストフィルタを導入できることを示しています。
- MA50が最近サポートまたはレジスタンスとして機能したか
- 以前の反応は強かったか
- トレンドはまだ維持されているか
以下の図(図1および図2)は、これらの考え方を視覚的に示しています。

図1:EMA50周辺でのダブルボトム形成、2段階目のリテスト動作、および以前の反発が発生した場合の高い確率

図2:弱気EMA50反発
実装
ここでは、研究内容を構造へ変換します。
最初のステップはトレンド判定です。
- 価格がMA50より上 → 強気バイアス
- 価格がMA50より下 → 弱気バイアス
2つ目のステップでは、ローソク足の動きを使用してEMAとの相互作用を検出します。
- 強気の相互作用:ローソク足がEMAを貫通し、EMAより上で終値を形成する
- 弱気の相互作用:ローソク足がEMAを貫通し、EMAより下で終値を形成する
これにより、正確な価格距離への依存をなくし、動作を優先したコアエンジンを構築します。
3つ目のステップは反応の確認です。柔軟な条件には以下が含まれます。
- EMA接触後の強気または弱気の終値
- リテスト後の小さなスイング高値/安値のブレイク
- 実体サイズ比を超えるピンバーによる拒否反応
- 初期反応後の2段階目の確認
4つ目のステップは繰り返される防衛フィルタです。過去の反発イベントを追跡し、最近EMAがサポートまたはレジスタンスとして機能していた場合、より高確率のエントリーを許可します。
MQL5での実装には以下が含まれます。
- iMA()を使用したMAハンドルの作成
- 過去のEMA値取得のためのCopyBuffer()の使用
- OHLCローソク足構造の分析
- フラグによる過去反発イベントの追跡
- CTradeクラスを使用した取引実行
モジュール化されたコンポーネントには以下が含まれます。
- CheckTrend()
- CheckEMAInteraction()
- CheckReaction()
- CheckPreviousBounce()
- ExecuteTrade()
- ManageRisk()
将来的な拡張モジュールには以下を含めることができます。
- 複数時間足の確認
- ATRベースの動的ストップ
- ブレークイーブン自動化
- トレーリングストップロジック
詳細なコード解説
このセクションでは、エキスパートアドバイザー(EA)を1行ごと、またはセクションごとに説明します。何を宣言するのか、なぜ宣言するのか、そして各構造ブロックが全体のアーキテクチャにどのように貢献するのかを説明します。この説明は、MetaTrader 5ターミナルがプログラムを処理する流れに沿って、初期化から実行まで自然な順序で進みます。
1. Property宣言とTradeオブジェクトファイルの最上部では、メタデータを定義し、厳格なコンパイルルールを適用します。
以下を宣言します。- #property strictで最新のMQL5構文基準を適用
- #property versionでEAの進化を追跡
- #property descriptionでプログラムの目的を記録
その直後に、Tradeライブラリをインクルードし、CTradeオブジェクトをインスタンス化します。このオブジェクトは、買い注文や売り注文など、すべての取引操作を処理します。手動で取引リクエストを構築する代わりに、標準化されたCTradeクラスを使用することで、より整理された実行処理を実現します。
#property strict #property version "2.00" #property description "EMA 50 Bounce EA using Candle Interaction Logic" #include <Trade/Trade.mqh> CTrade trade;このセクションでは、環境を構築し、取引インターフェースを準備します。
2. 入力パラメータ:ユーザー設定層
次に、すべての入力パラメータを宣言します。これらは、ソースコードを編集せずにユーザーが戦略動作を変更できる外部変数です。
入力は論理的なカテゴリに分けます。
移動平均構成
以下を宣言します。
- EMA期間(InpMAPeriod)
- 適用価格タイプ(InpPrice)
input int InpMAPeriod = 50; input ENUM_APPLIED_PRICE InpPrice = PRICE_CLOSE;
これにより、必要に応じてEMA50以外の期間にも戦略を柔軟に対応できます。
リスクおよびポジション管理
以下を宣言します。
- 固定ロットサイズ(InpLotSize)
- オプションの割合リスクモード(UseRiskPercent)
- リスク割合値(RiskPercent)
input double InpLotSize = 0.10; input bool UseRiskPercent = false; input double RiskPercent = 1.0;この2つのリスク管理方式により、固定ロットまたは資金ベースの動的リスク管理のどちらかを使用できます。
停止および目標パラメータ
ポイント単位でストップロスとテイクプロフィット距離を宣言します。
input int StopLossPoints = 300; input int TakeProfitPoints = 600;これらの値は、後で_Pointを使用して価格オフセットへ変換されます。
オプションの動作フィルタ
次に、切り替え可能なロジックコンポーネントを宣言します。
input bool UseTolerance = false; input int TolerancePoints = 50; input bool RequireSecondLeg = false; input bool UsePinBarFilter = false; input bool UseDoubleStructure = false;これらのフラグにより、コアEMA相互作用ロジックを変更せずに戦略を拡張できます。
これで設定層が完成します。
3. グローバル変数
EAのライフサイクル全体で使用するグローバル変数を宣言します。
int maHandle; double maBuffer[]; bool previousBounceDetected = false;
- maHandleはiMA()から返されるインジケータハンドルを保存します。
- maBuffer[]はインジケータバッファからコピーされたEMA値を保存します。
- previousBounceDetectedは、コンテキスト拡張(繰り返される防衛ロジック)のために予約されています。
4. 初期化:OnInit()
EAが読み込まれると、最初にOnInit()が実行されます。
ここでEMAインジケータハンドルを作成します。
以下を指定します。- Symbol
- Timeframe
- Period
- Shift (0)
- Mode (MODE_EMA)
- Applied price
ハンドル作成に失敗した場合、INIT_FAILEDを返します。
その後、配列をSeries形式に設定します。
ArraySetAsSeries(maBuffer,true);
これによりインデックスが逆順になり、[0]が現在のローソク足を表すようになります。これはMQL5の時系列処理と一致します。
int OnInit() { maHandle = iMA(_Symbol,_Period,InpMAPeriod,0,MODE_EMA,InpPrice); if(maHandle == INVALID_HANDLE) return(INIT_FAILED); ArraySetAsSeries(maBuffer,true); return(INIT_SUCCEEDED); }初期化により、インジケータインフラが準備されます。
5. 初期化解除:OnDeinit()
EAが削除されると、インジケータハンドルを解放します。
void OnDeinit(const int reason) { if(maHandle != INVALID_HANDLE) IndicatorRelease(maHandle); }これによりメモリリークを防ぎ、適切なリソース解放をおこないます。
6. メイン実行ループ:OnTick()
OnTick()はすべてのティックで実行されます。
ただし、意図的に新しいバーの場合のみロジックを実行します。
if(!IsNewBar()) return;これにより、ローソク足内部のノイズと過剰なトリガーを防ぎます。
次に、EMAデータをコピーします。
if(CopyBuffer(maHandle,0,0,3,maBuffer) <= 0) return;
処理を継続する前に、有効なデータ取得を確認します。
次に、重複ポジションを防ぎます。
if(PositionSelect(_Symbol)) return;
最後に、コアロジックを呼び出します。
CheckForSetup();
完全なブロック:
void OnTick() { if(!IsNewBar()) return; if(CopyBuffer(maHandle,0,0,3,maBuffer) <= 0) return; if(PositionSelect(_Symbol)) return; CheckForSetup(); }
7. コアロジック:CheckForSetup()
この関数には動作ベースのエンジンが含まれています。
まずEMAとOHLC値を取得します。
double ema = maBuffer[1]; double open1 = iOpen(_Symbol,_Period,1); double close1 = iClose(_Symbol,_Period,1); double high1 = iHigh(_Symbol,_Period,1); double low1 = iLow(_Symbol,_Period,1);
前のローソク足終値を使用してトレンドバイアスを判定します。
bool bullishTrend = close2 > ema; bool bearishTrend = close2 < ema;
次に、システムの中心となるEMA相互作用を定義します。
bool bullishInteraction = (low1 < ema && close1 > ema); bool bearishInteraction = (high1 > ema && close1 < ema);
これにより、固定された近接条件ではなく、拒否反応を基準にしたロジックになります。
オプションフィルタは条件付きで適用されます。
- 許容範囲ソフトフィルタ
- 2段階目の要件
- ピンバーフィルタ
- 二重構造フィルタ
最終判断:
if(bullishTrend && bullishInteraction) ExecuteTrade(ORDER_TYPE_BUY); if(bearishTrend && bearishInteraction) ExecuteTrade(ORDER_TYPE_SELL);この段階的なアプローチにより、構造を優先した実行が可能になります。
8. ピンバー検出
実体とヒゲのサイズを計算します。
double body = MathAbs(close-open); double lowerWick = MathMin(open,close) - low;以下を条件として設定します。
- ヒゲが実体の2倍以上
- 方向性のある終値確認
return (lowerWick > body*2 && close > open);この機械的な定義により、主観性を排除します。
9. 二重構造検出
スイングポイントを比較します。
return (MathAbs(low1 - low3) <= 20*_Point);これは、後で拡張可能な簡易構造モデルです。
10. 取引実行
ExecuteTrade()では以下をおこないます。
- Bid/Ask価格を取得する
- ロットサイズを計算する(固定またはリスクベース)
- SLとTPのオフセットを計算する
Buyの例:
sl = price - StopLossPoints*_Point; tp = price + TakeProfitPoints*_Point; trade.Buy(lot,_Symbol,price,sl,tp,"EMA50 OHLC Buy");
Sellも同じロジックで対称的に処理します。
この分離により、実行処理をシグナルロジックから独立させています。
11. リスクベースのロット計算以下を計算します。
- 口座残高
- 金銭的リスク
- ティックの値
- ティックのサイズ
- ロットあたりの損失
double lot = riskMoney/lossPerLot;ブローカーのボリュームステップに合わせてロットを正規化し、最小ロット制限を適用します。
これにより、現実的でブローカー準拠の注文実行を保証します。12. 新規バー検出
最後に、IsNewBar()によってシグナルの安定性を確保します。
static datetime lastBar=0; datetime current=iTime(_Symbol,_Period,0);
時間が変化した場合、新しいバーとして検出します。
これにより、1本のローソク足内で複数回トリガーされることを防ぎます
テスト
ここでは、理論的な構造が実際に観測可能な市場動作と結び付きます。この研究では、主な検証方法としてMetaTrader 5ストラテジーテスター内でのビジュアルテストを使用します。目的は、すぐに統計的な最適化をおこなうことではなく、構造の確認です。つまり、EAが実際の過去価格データと相互作用した際に、設計通りに動作することを確認します。
リプレイ時に可能な限り高い精度を得るため、「リアルティックに基づいた全ティック」モデリングモードを使用します。この戦略はEMAとのローソク足の相互作用、特に貫通してから終値を形成する動作に依存しているため、正確なイントラバーのモデリングが重要です。低品質なモデリングでは、拒否反応の動作が歪められ、シグナル形成方法について誤った解釈を生む可能性があります。
ビジュアルテスト中は、動作の正確性だけに注目します。シミュレーションが進行する中で、各取引をチャート上で直接確認します。エントリーが有効なEMA相互作用の後にのみ発生していることを確認します。つまり、ローソク足がEMAを貫通し、現在のトレンド方向へ戻って終値を形成する必要があります。また、反応ロジックが有効なセットアップごとに正確に1回だけ発動し、同じバーで重複シグナルが生成されないことを確認します。2段階オプションが有効な場合は、追加確認を適切に待機してからポジションを実行することを確認します。

図3:USDJPYでのテスト
この段階では、統計だけでは確認できない市場状況の細かな特徴も観察できます。EMAとの相互作用が本当に市場の拒否反応を示しているか、オプションのピンバーフィルタや二重構造フィルタが論理的に動作しているか、そしてシステムが重要でない価格ノイズに反応していないかを評価します。ビジュアル確認により、アルゴリズムによる抽象化が実際の市場動作へどのように変換されるのかについての理解を深めることができます。
本記事ではビジュアル検証に焦点を当てていますが、今後のステップとして、複数年にわたる統計的バックテスト、複数銘柄での堅牢性テスト、パラメータ最適化などの追加分析が推奨されます。これらの手順は定量的な確認を提供しますが、まずビジュアルテストによって構造ロジックが正しく動作していることを確認した後に実施するべきです。
このフレームワークでは、ビジュアルテストは表面的な工程ではありません。より深い統計評価を開始する前に、EMA相互作用に基づく動作モデルが忠実に実行されていることを保証する重要な検証段階です。
結論
EMA50リテスト戦略は、固定されたローソク足パターンのシステムではなく、行動ベースの反応モデルです。慎重な手動によるチャート振り返り調査と観察を通じて、移動平均線の反発を効果的に取引するシステムを開発し、裁量的な洞察を構造化されたアルゴリズム実行へ変換することに成功しました。これは、行動ベースの自動化が実用的で、イントラデイトレードに適用可能であることを示しています。
EMA50周辺で発生する反発構造は非常に多様です。一部は鋭い拒否反応として現れ、他のものは緩やかな収縮として形成され、さらに継続前に2段階のリテストを示すものもあります。そのため、自動化では固定されたローソク足パターンだけに注目するのではなく、EMAとの行動的な相互作用を捉える必要があります。トレンド判定、EMA相互作用の検出、反応確認ロジック、そして過去の反発による防衛確率の概念を組み合わせることで、このシステムは高確率なEMA50反発を一貫して識別し、実行します。
この議論の構造化された概要に関心がある読者向けに、以下の表では主要なポイントを整理しています。また、添付されたソースファイルには、研究内容と実装リファレンスの両方が含まれています。これらのリソースは、概念的な研究、コーディング構造、そして実践的な応用の間をつなぐものです。
皆様からのご意見、ご感想、ご質問をお待ちしております。コメント欄で皆様の考えや経験を共有していただき、このトレードアプローチのさらなる改善と発展にご協力ください。
重要な学び
| 重要な学び | 説明 |
|---|---|
| 1. コードを書く前に調査する | 自動化の前に、手動によるチャート振り返り調査をおこなうべきです。実際の市場動作を観察せずにコーディングすると、硬直的で非現実的なシステムにつながります。 |
| 2. 形状ではなく動作をコード化する | 市場は固定されたローソク足パターンではなく、行動の集合によって反応します。視覚的な形状を記憶するのではなく、反応ロジック(貫通+終値)を変換します。 |
| 3. トレンドとエントリーを分離する | トレンド判定はエントリーロジックから分離する必要があります。まず方向性バイアスを判断し、その後に相互作用条件を評価します。 |
| 4. インジケータハンドルを正しく使用する | 常にiMA()を使用してインジケータを作成し、CopyBuffer()で値を取得します。適切なハンドル管理により、安定性とパフォーマンスを確保できます。 |
| 5. ローソク足シフトを意識する | シフトインデックスを正しく使用します。インデックス0は形成中のローソク足を示します。早すぎる実行を避けるため、確定したシグナルではインデックス1以上を使用します。 |
| 6. 新しいバーのロジックで実行を制御する | IsNewBar()関数を使用して、イントラバーでの過剰な発動を防ぎ、シグナルの安定性を確保します。 |
| 7. モジュール構造を採用する | CheckTrend()、CheckInteraction()、ExecuteTrade()などの関数にロジックを分離します。モジュール化されたシステムは拡張性が高く、デバッグも容易になります。 |
| 8. オプションフィルタは切り替え可能にする | ピンバーやダブルストラクチャなどの構造フィルタには、ブール型入力を使用します。これにより、コアロジックを書き換えることなく柔軟な検証が可能になります。 |
| 9. 過剰な精度を避ける | 距離ベースの許容範囲はオプションにするべきです。正確な価格一致よりも、行動的な確認の方がより堅牢です。 |
| 10. リスクは設計する | 固定ロットモデルとパーセントリスクモデルの両方を実装します。プロフェッショナルなシステムでは、ストップロス幅に基づいてロットサイズを計算します。 |
| 11. ブローカー制約を正規化する | ロットサイズ計算時には、必ずSYMBOL_VOLUME_STEPとSYMBOL_VOLUME_MINを考慮し、ブローカーの仕様に適合させます。 |
| 12. 重複ポジションを防ぐ | 取引実行前にPositionSelect()を使用し、意図しない複数エントリーの積み重ねを防ぎます。 |
| 13. リソースを適切に管理する | OnDeinit()でインジケータハンドルを解放し、メモリリークを防止してプログラムの整合性を維持します。 |
| 14. 最適化前に構造を検証する | 統計的な最適化を開始する前に、ビジュアルテストによって動作の正確性を確認する必要があります。 |
| 15. シグナルではなくシステムを構築する | プロフェッショナルなEAは、単なるエントリー条件ではありません。構造、状況判断、リスク管理、実行管理、そして検証方法まで含めた総合的なシステムです。 |
添付ファイル
| ファイル名 | 現在のバージョン | 目的と説明 |
|---|---|---|
| EMA50_Bounce_EA.mq5 | 1.00 | EMA50反発戦略を完全に行動ベースで実装したものです。ローソク足のOHLC相互作用ロジックを使用し、ピンバーやダブルトップ/ダブルボトム確認などのオプション構造フィルタを搭載しています。 |
| Walkback_Study_Screenshots.zip | 1.00 | EMA反発の多様性、反応の深さ、2段階リテスト構造を示す手動チャート振り返り調査のスクリーンショット集です。 |
MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/21283
警告: これらの資料についてのすべての権利はMetaQuotes Ltd.が保有しています。これらの資料の全部または一部の複製や再プリントは禁じられています。
この記事はサイトのユーザーによって執筆されたものであり、著者の個人的な見解を反映しています。MetaQuotes Ltdは、提示された情報の正確性や、記載されているソリューション、戦略、または推奨事項の使用によって生じたいかなる結果についても責任を負いません。
MQL5でカスタムインジケータを作成する(第8回):出来高統合によるより深いマーケットプロファイル分析
エラー 146 (「トレードコンテキスト ビジー」) と、その対処方法
MQL5取引ツール(第20回):統計的相関分析と回帰分析を用いたCanvasグラフ作成
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索