MQL5で既存の内蔵インジケーター(例:移動平均(MA)やボリンジャーバンド(BB))をチャートに表示させると、売買タイミングやEAの動作を視覚的に確認でき、トレーディング戦略の理解やデバッグが容易になります。前の質問で扱った「2時間足(H2)と15分足(M15)の移動平均(MA)クロスを売買タイミングの指標とし、ボリンジャーバンド(BB)2σ超えをオプション条件とするEA」に、既存の内蔵インジケーター(H2_MA、M15_MA、BB)をチャートに表示する機能を追加することは可能です。以下の回答では、以下のポイントを踏まえて解説とコードを提供します:
【免責事項】私は投資アドバイザーではありません。投資判断はご自身で行い、必要に応じてファイナンシャルアドバイザーに相談してください。この記事は自身の勉強を目的としており、EAの動作保証や生じた損失に対しても一切の責任を負いません。
- 既存インジケーターの表示:
- MT5の内蔵インジケーター(iMA, iBands)をチャートに表示。
- H2_MAをM15チャートにマルチタイムフレーム(MTF)で表示。
- M15_MAとBB(オプション)をM15チャートに表示。
- 視覚的メリット:
- MAクロスやBB 2σ超えのタイミングを視覚的に確認。
- EAの売買シグナルが正しいか直感的に把握。
- EAとの統合:
- 前のコード(H2/M15 MAクロス、BB 2σ、ATRベースSL、RR/BBベースTP、トレーリングストップ)をベースに、インジケーター表示を追加。
- 自動計算の維持:
- インジケーター表示は視覚化専用で、EAの売買ロジックは内部計算で処理。
ステップ1: 視覚的メリットと実現方法視覚的メリット
- 売買タイミングの確認:
- H2_MAとM15_MAのクロスポイントをチャートで視覚化し、EAの買い/売りシグナルが正確か確認。
- BB 2σの上下限と価格の関係を視覚化し、価格が2σを超えたタイミングを把握。
- デバッグの容易さ:
- インジケーターが表示されることで、コードの誤り(例:誤ったMA値やクロス判定)を発見しやすくなる。
- 戦略の理解:
- トレーダーにとって、MAクロスやBBの動きを視覚的に追うことで、戦略の意図を直感的に理解可能。
実現方法
- MT5内蔵インジケーターの表示:
- IndicatorCreate()関数を使用して、M15チャートにH2_MA、M15_MA、BBを表示。
- iMAとiBandsのハンドルを作成し、チャートに追加。
- マルチタイムフレーム(MTF)対応:
- H2_MAをM15チャートに表示するため、IndicatorCreate()でPERIOD_H2を指定。
- EAとの分離:
- インジケーター表示は視覚化専用で、EAの売買ロジックはCopyBuffer()で内部計算。
- インジケーターを別ウィンドウやチャート上にオーバーレイ表示。
ステップ2: サンプルコード(インジケーター表示+EA)以下のコードは、前のEA(H2/M15 MAクロス、BB 2σオプション、ATRベースSL、RR/BBベースTP、トレーリングストップ)に、H2_MA、M15_MA、BBをチャートに表示する機能を追加したものです。インジケーターはM15チャートに表示され、H2_MAはMTFで描画されます。
mql5
//+------------------------------------------------------------------+
//| 入力パラメータ |
//+------------------------------------------------------------------+
input int maH2Period = 20; // H2移動平均期間
input int maM15Period = 20; // M15移動平均期間
input bool useBBFilter = false; // BB 2σフィルターを使用
input int bbPeriod = 20; // ボリンジャーバンド期間(M15)
input double bbDeviation = 2.0; // BB標準偏差(2σ)
input double lotSize = 0.1; // ロットサイズ
input int atrPeriod = 14; // ATR期間
input double atrMultiplier = 2.0; // ATR倍率(SL用)
input double riskRewardRatio = 2.0; // リスクリワードレシオ(TP用)
input bool useBBTP = true; // BBをTPに使用
input bool useTrailingStop = true; // トレーリングストップ使用
input int trailingStart = 20; // トレーリング開始(ポイント)
input int trailingStep = 10; // トレーリングステップ(ポイント)
input bool displayIndicators = true; // インジケーターをチャートに表示
// グローバル変数
int handleMaH2, handleMaM15, handleBB, handleATR;
//+------------------------------------------------------------------+
//| 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);
handleATR = iATR(_Symbol, PERIOD_M15, atrPeriod);
if(useBBFilter || useBBTP) {
handleBB = iBands(_Symbol, PERIOD_M15, bbPeriod, 0, bbDeviation, PRICE_CLOSE);
}
// ハンドル作成のエラーチェック
if(handleMaH2 == INVALID_HANDLE || handleMaM15 == INVALID_HANDLE ||
handleATR == INVALID_HANDLE || ((useBBFilter || useBBTP) && handleBB == INVALID_HANDLE)) {
Print("インジケーターハンドル作成に失敗");
ExpertRemove();
}
// インジケーターをチャートに表示(displayIndicatorsがtrueの場合)
if(displayIndicators) {
// H2_MAを表示(MTF)
int subWindow = 0; // メインウィンドウ
if(!IndicatorCreate(_Symbol, PERIOD_M15, IND_MA, 0, maH2Period, 0, MODE_SMA, PRICE_CLOSE)) {
Print("H2_MA表示失敗、エラーコード: ", GetLastError());
}
// M15_MAを表示
if(!IndicatorCreate(_Symbol, PERIOD_M15, IND_MA, 0, maM15Period, 0, MODE_SMA, PRICE_CLOSE)) {
Print("M15_MA表示失敗、エラーコード: ", GetLastError());
}
// BBを表示(useBBFilterまたはuseBBTPがtrueの場合)
if(useBBFilter || useBBTP) {
if(!IndicatorCreate(_Symbol, PERIOD_M15, IND_BANDS, 0, bbPeriod, 0, bbDeviation, PRICE_CLOSE)) {
Print("BB表示失敗、エラーコード: ", GetLastError());
}
}
}
Print("EA初期化完了");
}
//+------------------------------------------------------------------+
//| 新しいティックごとの処理 |
//+------------------------------------------------------------------+
void OnTick() {
// M15チャートでのみ動作
if(Period() != PERIOD_M15) return;
// インジケーターデータの取得(最新3本分)
double maH2[], maM15[], bbUpper[], bbLower[], atr[];
if(CopyBuffer(handleMaH2, 0, 0, 3, maH2) <= 0 ||
CopyBuffer(handleMaM15, 0, 0, 3, maM15) <= 0 ||
CopyBuffer(handleATR, 0, 0, 3, atr) <= 0) {
Print("データ取得失敗、エラーコード: ", GetLastError());
return;
}
if((useBBFilter || useBBTP) &&
(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) {
if(useTrailingStop) TrailStop();
return;
}
// SL(ATRベース)とTPの計算
double slDistance = atr[1] * atrMultiplier; // ATRベースのSL
double tpDistance = slDistance * riskRewardRatio; // RRベースのTP
// 買い条件:M15_MAがH2_MAを上抜け(+BB下限フィルター)
bool buySignal = maM15[1] > maH2[1] && maM15[2] <= maH2[2];
if(useBBFilter) buySignal = buySignal && bid < bbLower[1];
if(buySignal) {
double sl = ask - slDistance;
double tp = useBBTP ? bbUpper[1] : ask + tpDistance;
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, " SL: ", sl, " TP: ", tp);
} else {
Print("買い注文失敗、エラーコード: ", GetLastError());
}
}
// 売り条件:M15_MAがH2_MAを下抜け(+BB上限フィルター)
bool sellSignal = maM15[1] < maH2[1] && maM15[2] >= maH2[2];
if(useBBFilter) sellSignal = sellSignal && bid > bbUpper[1];
if(sellSignal) {
double sl = bid + slDistance;
double tp = useBBTP ? bbLower[1] : bid - tpDistance;
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, " SL: ", sl, " TP: ", tp);
} else {
Print("売り注文失敗、エラーコード: ", GetLastError());
}
}
}
//+------------------------------------------------------------------+
//| トレーリングストップ |
//+------------------------------------------------------------------+
void TrailStop() {
for(int i = 0; i < PositionsTotal(); i++) {
ulong ticket = PositionGetTicket(i);
if(PositionSelectByTicket(ticket) && PositionGetString(POSITION_SYMBOL) == _Symbol) {
double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double sl = PositionGetDouble(POSITION_SL);
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) {
if(currentPrice - openPrice > trailingStart * _Point) {
double newSL = currentPrice - trailingStep * _Point;
if(newSL > sl) {
PositionModify(ticket, newSL, PositionGetDouble(POSITION_TP));
Print("買いポジションSL更新、チケット: ", ticket, " 新SL: ", newSL);
}
}
} else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) {
if(openPrice - currentPrice > trailingStart * _Point) {
double newSL = currentPrice + trailingStep * _Point;
if(newSL < sl || sl == 0) {
PositionModify(ticket, newSL, PositionGetDouble(POSITION_TP));
Print("売りポジションSL更新、チケット: ", ticket, " 新SL: ", newSL);
}
}
}
}
}
}
//+------------------------------------------------------------------+
//| EA終了処理 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
IndicatorRelease(handleMaH2);
IndicatorRelease(handleMaM15);
IndicatorRelease(handleATR);
if(useBBFilter || useBBTP) IndicatorRelease(handleBB);
Print("EA終了、理由コード: ", reason);
}
ステップ3: コードの解説
- 入力パラメータ:
- maH2Period, maM15Period:H2/M15のMA期間(デフォルト:20)。
- useBBFilter, bbPeriod, bbDeviation:BBフィルターのON/OFFと設定。
- lotSize, atrPeriod, atrMultiplier, riskRewardRatio, useBBTP:TP/SL設定。
- useTrailingStop, trailingStart, trailingStep:トレーリングストップ。
- displayIndicators:インジケーター表示のON/OFF(デフォルト:true)。
- 初期化(OnInit):
- 内部計算用:iMA, iATR, iBandsでハンドルを作成(EAのロジック用)。
- チャート表示用(displayIndicators=trueの場合):
- IndicatorCreate()でH2_MA(PERIOD_H2)、M15_MA、BBをM15チャートに追加。
- H2_MAはMTFで表示(M15チャート上にH2データ)。
- エラーチェックで表示失敗をログ出力。
- ティック処理(OnTick):
- M15チャート専用(Period() != PERIOD_M15で制限)。
- CopyBuffer()でH2_MA、M15_MA、ATR、BB(必要な場合)のデータを取得。
- 買い条件:M15_MAがH2_MAを上抜け+BB下限(オプション)。
- 売り条件:M15_MAがH2_MAを下抜け+BB上限(オプション)。
- SL:ATR×atrMultiplier。
- TP:useBBTPがtrueならBB上限/下限、falseならSL×riskRewardRatio。
- ポジションがある場合はTrailStop()を呼び出し。
- トレーリングストップ(TrailStop):
- 利益がtrailingStart(20ピップス)に達したら、SLをtrailingStep(10ピップス)ずつ更新。
- 終了処理(OnDeinit):
- 内部計算用のインジケーターハンドルを解放。
- チャート表示用のインジケーターは自動的にクリアされる。
ステップ4: インジケーター表示の視覚的効果
- H2_MA(MTF):
- M15チャート上でH2の20期間SMAが滑らかな線で表示され、中期トレンドを視覚化。
- M15_MAとのクロスポイントが明確にわかる。
- M15_MA:
- M15チャートに20期間SMAを表示し、短期トレンドを追跡。
- BB(オプション):
- M15のBB(2σ)を表示し、価格が上下限を超えるタイミングを視覚化。
- メリット:
- 売買シグナル(例:M15_MAがH2_MAを上抜け+BB下限)の発生箇所をチャートで確認。
- 誤ったシグナルやデータ取得エラーを視覚的に発見可能。
注意:
- IndicatorCreate()はMT5の内蔵インジケーターを直接チャートに追加しますが、カスタマイズ(色、スタイル)は限定的。詳細なカスタム表示が必要なら、別途カスタムインジケーターを作成(後述)。
- 表示はM15チャートに適用されるため、EAをM15チャートに設定してください。
ステップ5: カスタムインジケーターの代替案もし内蔵インジケーターの表示(色やスタイル)が物足りない場合、MQL5でカスタムインジケーターを作成し、H2_MA、M15_MA、BBを自由にカスタマイズできます。以下は簡単なカスタムインジケーターの例(別ファイルとして保存):
mql5
//+------------------------------------------------------------------+
//| カスタムインジケーター:H2/M15 MAとBB |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots 3
#property indicator_label1 "H2_MA"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_label2 "M15_MA"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_label3 "BB_Upper"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrGreen
#property indicator_label4 "BB_Lower"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrGreen
// 入力パラメータ
input int maH2Period = 20; // H2移動平均期間
input int maM15Period = 20; // M15移動平均期間
input int bbPeriod = 20; // BB期間
input double bbDeviation = 2.0; // BB標準偏差
// バッファ
double bufferH2MA[], bufferM15MA[], bufferBBUpper[], bufferBBLower[];
int handleMaH2, handleMaM15, handleBB;
//+------------------------------------------------------------------+
//| 初期化 |
//+------------------------------------------------------------------+
void OnInit() {
SetIndexBuffer(0, bufferH2MA, INDICATOR_DATA);
SetIndexBuffer(1, bufferM15MA, INDICATOR_DATA);
SetIndexBuffer(2, bufferBBUpper, INDICATOR_DATA);
SetIndexBuffer(3, bufferBBLower, INDICATOR_DATA);
handleMaH2 = iMA(_Symbol, PERIOD_H2, maH2Period, 0, MODE_SMA, PRICE_CLOSE);
handleMaM15 = iMA(_Symbol, PERIOD_M15, maM15Period, 0, MODE_SMA, PRICE_CLOSE);
handleBB = iBands(_Symbol, PERIOD_M15, bbPeriod, 0, bbDeviation, PRICE_CLOSE);
}
//+------------------------------------------------------------------+
//| 計算 |
//+------------------------------------------------------------------+
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[]) {
// データ取得
double tempH2MA[], tempM15MA[], tempBBUpper[], tempBBLower[];
if(CopyBuffer(handleMaH2, 0, 0, rates_total, tempH2MA) <= 0 ||
CopyBuffer(handleMaM15, 0, 0, rates_total, tempM15MA) <= 0 ||
CopyBuffer(handleBB, UPPER_BAND, 0, rates_total, tempBBUpper) <= 0 ||
CopyBuffer(handleBB, LOWER_BAND, 0, rates_total, tempBBLower) <= 0) {
Print("データ取得失敗、エラーコード: ", GetLastError());
return(0);
}
// バッファにコピー
for(int i = 0; i < rates_total; i++) {
bufferH2MA[i] = tempH2MA[i];
bufferM15MA[i] = tempM15MA[i];
bufferBBUpper[i] = tempBBUpper[i];
bufferBBLower[i] = tempBBLower[i];
}
return(rates_total);
}
//+------------------------------------------------------------------+
//| 終了処理 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
IndicatorRelease(handleMaH2);
IndicatorRelease(handleMaM15);
IndicatorRelease(handleBB);
}
カスタムインジケーターの使用:
- 上記コードをIndicatorsフォルダに保存(例:Custom_MA_BB.mq5)。
- MetaEditorでコンパイルし、M15チャートに適用。
- EAとは別にチャートに表示され、色やスタイルをカスタマイズ可能。
ステップ6: バックテストと最適化
- ストラテジーテスター:
- EAをM15チャート(例:USDJPY)に適用。
- テスト設定:2024年データ、M15、スプレッド20。
- 最適化パラメータ:
- maH2Period:10-50
- maM15Period:5-30
- atrMultiplier:1.0-3.0
- riskRewardRatio:1.0-3.0
- 結果分析:
- プロフィットファクター(>1.5)、ドローダウン(<20%)。
- インジケーター表示による視覚的確認で、シグナルの正確さを検証。
- デモ口座テスト:
- デモ口座で1か月運用(現在の日時:2025年10月13日21:54 JST)。
- チャートでMAクロスやBB 2σ超えを確認。
ステップ7: デバッグと視覚的検証
- ログ出力:mql5
Print("Bid: ", bid, " H2_MA: ", maH2[1], " M15_MA: ", maM15[1], " BB Upper: ", bbUpper[1], " BB Lower: ", bbLower[1], " ATR: ", atr[1]);
- チャートコメント:mql5
Comment("H2_MA: ", maH2[1], "\nM15_MA: ", maM15[1], "\nSL Distance: ", slDistance);
- 視覚的確認:
- チャート上でH2_MA(青)とM15_MA(赤)のクロスを確認。
- BB(緑)の上下限と価格の関係を視覚化。
- 売買シグナル(例:買い注文時のログ)がチャートのクロスポイントと一致するかチェック。
ステップ8: 学習リソース
- MQL5公式ドキュメント:
- MQL5コミュニティ:
- 記事「How to Create 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公式)。
ステップ9: 次のアクションと質問対応
- コードの使用:
- EAコードをMetaEditorにコピーし、M15チャートでコンパイル。
- displayIndicators=trueで内蔵インジケーターを表示。
- 必要ならカスタムインジケーターコードを別ファイルで適用。
- ストラテジーテスターでテスト(例:USDJPY、M15、2024年)。
- 練習課題:
- インジケーターの色やスタイルをカスタマイズ(カスタムインジケーター使用)。
- シグナル発生時に矢印を表示(カスタムインジケーターにDRAW_ARROWを追加)。
- 時間ベースの利確(例:4時間)を追加。
- 確認事項:
- インジケーター表示:
- 内蔵インジケーターで十分?カスタムインジケーター(色やスタイルのカスタマイズ)が必要?
- 特定の表示(例:シグナル矢印、別ウィンドウ)を希望?
- TP/SL:
- 現在のATRベースSL、RR/BBベースTP、トレーリングストップでOK?
- 他のオリジナルTP/SL(例:高値/安値、MA乖離)を追加?
- BB条件:
- BB 2σフィルターを必須にする?(現在はuseBBFilter=false)。
- BBをH2チャートに変更?
- トリガーレベル(前の質問):
- MAクロス以外の条件(例:MAの差、RSI)を追加?
- 特定の通貨ペアや時間足向けの調整?
- インジケーター表示:
- 問題解決:
- インジケーター表示の設定(例:IndicatorCreateのエラー)が不明なら解説。
- バックテストや視覚的デバッグの手順が必要なら説明。
具体的な質問:
- インジケーター表示のカスタマイズ(例:色、矢印、別ウィンドウ)を希望?
- 特定のTP/SLロジックや追加フィルター(例:RSI、時間帯)を指定?
- どの部分を深掘りしたい?(例:インジケーターのカスタム、コード改良、テスト方法)