2時間足(H2)と15分足(M15)の移動平均(MA)を使用して反転指標を構築することは可能です。このような指標は、短期(M15)と中期(H2)のトレンドの変化を捉え、価格の反転ポイントを特定するために役立ちます。以下に、MQL5でこの反転指標を構築する手順を初心者向けに段階的に解説し、サンプルコードを提供します。また、ユーザーの前の質問(ボリンジャーバンド2σ超え+MAクロス)との関連性を考慮し、反転指標をEAの注文条件に組み込む方法も示します。
【免責事項】私は投資アドバイザーではありません。投資判断はご自身で行い、必要に応じてファイナンシャルアドバイザーに相談してください。この記事は自身の勉強を目的としており、EAの動作保証や生じた損失に対しても一切の責任を負いません。
反転指標の構築コンセプト目的:
- 2時間足の移動平均(例:20期間SMA)と15分足の移動平均(例:20期間SMA)を使用し、価格の反転ポイントを特定。
- 反転指標の例:
- ゴールデンクロス/デッドクロス:M15の短期MAがH2の長期MAを上抜け(買いシグナル)または下抜け(売りシグナル)。
- 価格とMAの関係:価格がH2のMAを大きく乖離した後、M15のMAがH2のMAに近づく動きを反転シグナルとする。
- トレンド確認:H2のMAで中期トレンドを把握し、M15のMAで短期的な反転を検出。
仮定(必要に応じて修正可能):
- 2時間足MA(H2_MA):20期間単純移動平均(SMA)。
- 15分足MA(M15_MA):20期間単純移動平均(SMA)。
- 反転シグナル:
- 買い:M15_MAがH2_MAを上抜け、かつ価格がH2_MAに近づく(例:H2_MAから一定範囲内)。
- 売り:M15_MAがH2_MAを下抜け、かつ価格がH2_MAに近づく。
- 前の質問のボリンジャーバンド(BB)2σ条件をオプションとして統合可能。
注意:
- 「反転指標」の具体的な定義が曖昧な場合(例:MAクロス以外の条件、特定の閾値など)、詳細を教えていただければコードを調整します。
- 以下では、M15_MAがH2_MAをクロスする基本的な反転指標を構築し、EAに組み込みます。
ステップ1: 必要な知識
- マルチタイムフレーム(MTF)データ:
- MQL5のiMA()関数で異なる時間足(H2、M15)のMAを取得。
- CopyBuffer()でインジケーターデータを時間足ごとに取得。
- 価格データ:
- SymbolInfoDouble()でBid/Ask価格を取得。
- 注文送信:
- OrderSend()で買い/売り注文を送信。
- ポジション管理:
- PositionsTotal()でポジション数を制限。
- デバッグ:
- Print()やComment()でMA値やシグナルを確認。
ステップ2: 反転指標のサンプルコード(EA)以下のコードは、H2とM15のMAクロスを基にした反転指標をEAに組み込んだものです。前の質問のBB 2σ条件もオプションで追加可能(コメントで示します)。
mql5
//+------------------------------------------------------------------+
//| 入力パラメータ |
//+------------------------------------------------------------------+
input int maH2Period = 20; // H2移動平均期間
input int maM15Period = 20; // M15移動平均期間
input double lotSize = 0.1; // ロットサイズ
input int slPoints = 50; // ストップロス(ポイント)
input int tpPoints = 100; // テイクプロフィット(ポイント)
input bool useBBFilter = false; // ボリンジャーバンドフィルターを使用するか
input int bbPeriod = 20; // BB期間(M15)
input double bbDeviation = 2.0; // BB標準偏差(2σ)
// グローバル変数
int handleMaH2, handleMaM15, handleBB;
//+------------------------------------------------------------------+
//| EA初期化 |
//+------------------------------------------------------------------+
void OnInit() {
// インジケーターハンドルの作成
handleMaH2 = iMA(_Symbol, PERIOD_H2, maH2Period, 0, MODE_SMA, PRICE_CLOSE);
handleMaM15 = iMA(_Symbol, PERIOD_M15, maM15Period, 0, MODE_SMA, PRICE_CLOSE);
if(useBBFilter) {
handleBB = iBands(_Symbol, PERIOD_M15, bbPeriod, 0, bbDeviation, PRICE_CLOSE);
}
// ハンドル作成のエラーチェック
if(handleMaH2 == INVALID_HANDLE || handleMaM15 == INVALID_HANDLE ||
(useBBFilter && handleBB == INVALID_HANDLE)) {
Print("インジケーターハンドル作成に失敗");
ExpertRemove();
}
Print("EA初期化完了");
}
//+------------------------------------------------------------------+
//| 新しいティックごとの処理 |
//+------------------------------------------------------------------+
void OnTick() {
// M15チャートでのみ動作(EAがM15チャートに適用されている前提)
if(Period() != PERIOD_M15) return;
// インジケーターデータの取得(最新3本分)
double maH2[], maM15[], bbUpper[], bbLower[];
if(CopyBuffer(handleMaH2, 0, 0, 3, maH2) <= 0 ||
CopyBuffer(handleMaM15, 0, 0, 3, maM15) <= 0) {
Print("データ取得失敗、エラーコード: ", GetLastError());
return;
}
if(useBBFilter && (CopyBuffer(handleBB, UPPER_BAND, 0, 3, bbUpper) <= 0 ||
CopyBuffer(handleBB, LOWER_BAND, 0, 3, bbLower) <= 0)) {
Print("BBデータ取得失敗、エラーコード: ", GetLastError());
return;
}
// 現在価格
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
// ポジション確認(既にポジションがある場合は取引しない)
if(PositionsTotal() > 0) return;
// 買い条件:M15_MAがH2_MAを上抜け
bool buySignal = maM15[1] > maH2[1] && maM15[2] <= maH2[2];
if(useBBFilter) {
buySignal = buySignal && bid < bbLower[1]; // BB下限を下回る
}
if(buySignal) {
double sl = ask - slPoints * _Point;
double tp = ask + tpPoints * _Point;
MqlTradeRequest request = {};
MqlTradeResult result = {};
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = lotSize;
request.type = ORDER_TYPE_BUY;
request.price = ask;
request.sl = sl;
request.tp = tp;
if(OrderSend(request, result)) {
Print("買い注文成功、チケット: ", result.order);
} else {
Print("買い注文失敗、エラーコード: ", GetLastError());
}
}
// 売り条件:M15_MAがH2_MAを下抜け
bool sellSignal = maM15[1] < maH2[1] && maM15[2] >= maH2[2];
if(useBBFilter) {
sellSignal = sellSignal && bid > bbUpper[1]; // BB上限を超える
}
if(sellSignal) {
double sl = bid + slPoints * _Point;
double tp = bid - tpPoints * _Point;
MqlTradeRequest request = {};
MqlTradeResult result = {};
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = lotSize;
request.type = ORDER_TYPE_SELL;
request.price = bid;
request.sl = sl;
request.tp = tp;
if(OrderSend(request, result)) {
Print("売り注文成功、チケット: ", result.order);
} else {
Print("売り注文失敗、エラーコード: ", GetLastError());
}
}
}
//+------------------------------------------------------------------+
//| EA終了処理 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
IndicatorRelease(handleMaH2);
IndicatorRelease(handleMaM15);
if(useBBFilter) IndicatorRelease(handleBB);
Print("EA終了、理由コード: ", reason);
}
ステップ3: コードの解説
- 入力パラメータ:
- maH2Period, maM15Period:H2とM15のMA期間(デフォルト:20)。
- lotSize, slPoints, tpPoints:取引量、SL、TP。
- useBBFilter:BB 2σ条件をオプションで有効化(デフォルト:無効)。
- bbPeriod, bbDeviation:BBの設定(M15チャート用)。
- 初期化(OnInit):
- iMA()でH2とM15のMAハンドルを作成。
- iBands()でBBハンドルを作成(useBBFilterがtrueの場合)。
- ハンドル作成失敗時はEAを終了。
- ティック処理(OnTick):
- M15チャートでのみ動作(Period() != PERIOD_M15で制限)。
- CopyBuffer()でH2_MAとM15_MAを取得(3本分でクロス判定)。
- 買い条件:
- M15_MAがH2_MAを上抜け(maM15[1] > maH2[1] && maM15[2] <= maH2[2])。
- オプション:価格がBB下限を下回る(bid < bbLower[1])。
- 売り条件:
- M15_MAがH2_MAを下抜け(maM15[1] < maH2[1] && maM15[2] >= maH2[2])。
- オプション:価格がBB上限を超える(bid > bbUpper[1])。
- 注文はOrderSend()で送信し、SL/TPを設定。
- 終了処理(OnDeinit):
- インジケーターハンドルを解放。
ステップ4: 反転指標の改良以下の方法で反転指標を強化できます:
- 価格とH2_MAの距離:
- 価格がH2_MAに近づく(例:±50ピップス以内)ことを条件に追加:mql5
double maDiff = MathAbs(bid - maH2[1]); if(buySignal && maDiff < 50 * _Point) { // 買い注文 }
- 価格がH2_MAに近づく(例:±50ピップス以内)ことを条件に追加:mql5
- トレンドフィルター:
- H2_MAの方向(上昇/下降)を確認し、トレンドに沿ったシグナルのみ採用:mql5
bool isH2Uptrend = maH2[1] > maH2[2]; if(buySignal && isH2Uptrend) { // 買い注文 }
- H2_MAの方向(上昇/下降)を確認し、トレンドに沿ったシグナルのみ採用:mql5
- ボリンジャーバンド統合:
- 前の質問のBB 2σ条件を有効化(useBBFilter = true)。
- BBをH2チャートに適用する場合は、iBands()の時間足をPERIOD_H2に変更。
- リスク管理:
- 口座残高に基づくロットサイズ:mql5
double balance = AccountBalance(); double riskAmount = balance * 0.01; // 1%リスク lotSize = riskAmount / (slPoints * SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE));
- 口座残高に基づくロットサイズ:mql5
- 時間フィルター:
- 例:東京時間(8:00-12:00 JST)のみ取引(現在の日時:2025年10月13日21:37 JSTを考慮):mql5
MqlDateTime dt; TimeToStruct(TimeCurrent(), dt); if(dt.hour >= 8 && dt.hour < 12) { // 取引条件をチェック }
- 例:東京時間(8:00-12:00 JST)のみ取引(現在の日時:2025年10月13日21:37 JSTを考慮):mql5
ステップ5: バックテストと最適化
- ストラテジーテスター:
- MT5のストラテジーテスターでEAをテスト(例:USDJPY、M15、2024年データ)。
- パラメータ最適化:
- maH2Period:10-50
- maM15Period:5-30
- bbPeriod(BB使用時):10-30
- 結果分析:
- プロフィットファクター(>1.5)、ドローダウン(<20%)を確認。
- 過剰最適化を避けるため、バックテストとデモ口座テストを比較。
- デモ口座テスト:
- デモ口座で1か月運用し、ログを分析。
ステップ6: デバッグと検証
- ログ出力:mql5
Print("Bid: ", bid, " H2_MA: ", maH2[1], " M15_MA: ", maM15[1], " BB Upper: ", bbUpper[1], " BB Lower: ", bbLower[1]);
- チャートコメント:mql5
Comment("H2_MA: ", maH2[1], "\nM15_MA: ", maM15[1]);
- エラーチェック:
- OrderSend()の失敗をGetLastError()で確認。
- インジケーターデータの取得エラーをチェック。
ステップ7: 学習リソース
- MQL5公式ドキュメント:
- MQL5コミュニティ:
- 記事「Multi-Timeframe Indicators」(https://www.mql5.com/en/articles)。
- Code Base(https://www.mql5.com/en/code)でMTFのサンプルコード。
- YouTube:
- 「MQL5 Tutorial」チャンネル(英語)や「FX 自動売買 MQL5」動画(日本語)。
- 書籍:
- 「MQL5 Programming for Traders」(無料、MQL5公式)。
ステップ8: 次のアクションと質問対応
- コードの使用:
- 上記コードをMetaEditorにコピーし、M15チャートでコンパイル。
- ストラテジーテスターでテスト(例:USDJPY、M15、2024年)。
- 練習課題:
- 価格とH2_MAの距離(例:50ピップス以内)を条件に追加。
- BB 2σフィルターをH2チャートに適用。
- RSI(例:70以上で売り、30以下で買い)を追加。
- 確認事項:
- 「反転指標」の具体的な定義(例:MAクロス以外の条件、特定の閾値)を教えてください。
- 前の質問のBB 2σ条件を必須で統合する?(現在はオプション)。
- 特定の通貨ペアや時間足向けの調整が必要?
- リスク管理やフィルター(時間帯、ボラティリティ)の追加?
- 問題解決:
- 特定のコード部分(例:MTFデータ取得、注文ロジック)が不明な場合、詳細解説を提供。
- バックテストやデバッグの具体的な手順が必要なら説明。
具体的な質問:
- 「トリガーレベル」(前の質問)や「反転指標」の詳細な条件を教えてください(例:MAの差、価格レベル、追加インジケーター)。
- BB 2σ条件をH2チャートでなくM15チャートで使うか、または他の条件を優先?