「MT4で引いた水平線の価格をEAで取得しようとしたら、なぜか0になる…」
「トレンドラインは取れるのに、水平線だけ取得できないのはなぜ?」
そんな疑問を持った方向けに、MQL4でトレンドライン・水平線の価格を正しく取得する方法を解説します。
本記事では、ObjectGetValueByShift()が水平線では使えない理由と、 ObjectGet()を使った正しい取得方法を、サンプルEA付きで実務目線でまとめています。
- MT4のトレンドライン・水平線をEA(MQL4)で扱う基本的な考え方
ObjectGetValueByShift()で取得できる値/できない値の違い- 水平線の価格が 0になる原因 とその仕組み
ObjectGet()を使って水平線の価格を正しく取得する方法- トレンドラインと水平線の取得方法の違いと実装時の注意点
- 検証用EAサンプルコードと取得結果の確認方法
なぜ水平線はObjectGetValueByShift()で取得できないのか
まず、トレンドラインの価格帯を取得する場合、ObjectGetValueByShift()で取得する事ができます。
同じように水平線もObjectGetValueByShift()で取得できるのでは?と思ってやってみましたが、0になってうまく取得できませんでした。
ここで結論からお伝えすると、
以下にサンプルソースを交えて解説します。
トレンドラインと水平線の価格を取得できるか検証してみる
単純にトレンドラインと水平線を引き、その価格帯をObjectGetValueByShift()とObjectGet()の両方で取得し操作履歴に出力するEAを作っています。
以下サンプルソースです。
//+------------------------------------------------------------------+
//| test.mq4 |
//| Copyright 2020, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
// エントリー関数
void OnTick()
{
//トレンドラインを引く(斜め線)
ObjectDelete(0,"T_LINE");
ObjectCreate(0,"T_LINE",OBJ_TREND,0,Time[40],Close[40],Time[10],Close[10]);
ObjectSetInteger(0,"T_LINE",OBJPROP_COLOR,clrYellow);
ObjectSetInteger(0,"T_LINE",OBJPROP_STYLE,STYLE_SOLID);
ObjectSetInteger(0,"T_LINE",OBJPROP_WIDTH,2);
ObjectSetInteger(0,"T_LINE",OBJPROP_RAY_RIGHT,true);
//水平線を引く
ObjectDelete(0,"H_LINE");
ObjectCreate(0,"H_LINE",OBJ_HLINE,0,0,iLow(NULL, 0, 0));
ObjectSetInteger(0,"H_LINE",OBJPROP_COLOR,clrRed);
ObjectSetInteger(0,"H_LINE",OBJPROP_STYLE,STYLE_DOT);
ObjectSetInteger(0,"H_LINE",OBJPROP_WIDTH,2);
//各オブジェクトの値を取得する
double Sh_T = ObjectGetValueByShift("T_LINE", 0);
double OG_T = ObjectGet("T_LINE",OBJPROP_PRICE1);
double Sh_H = ObjectGetValueByShift("H_LINE", 0);
double OG_H = ObjectGet("H_LINE",OBJPROP_PRICE1);
Print("トレンドライン①" + Sh_T);
Print("トレンドライン②" + OG_T);
Print("水平ライン①" + Sh_H);
Print("水平ライン②" + OG_H);
}
サンプルのEAをビジュアルモード等で実行し操作履歴の画像下段の赤枠(水平ライン①)を見てください。

この部分はObjectGetValueByShift()で水平線の値を取得していますが、前述したように0になっている事がわかります。
ソースコードの解説と結果
ソース解説
では先ほどのトレンドラインと水平線を引くサンプルソースの解説です。
まずトレンドラインと水平線は以下の箇所で引いています。
//トレンドラインを引く(斜め線)
ObjectDelete(0,"T_LINE");
ObjectCreate(0,"T_LINE",OBJ_TREND,0,Time[40],Close[40],Time[10],Close[10]);
ObjectSetInteger(0,"T_LINE",OBJPROP_COLOR,clrYellow);
ObjectSetInteger(0,"T_LINE",OBJPROP_STYLE,STYLE_SOLID);
ObjectSetInteger(0,"T_LINE",OBJPROP_WIDTH,2);
ObjectSetInteger(0,"T_LINE",OBJPROP_RAY_RIGHT,true);
//水平線を引く
ObjectDelete(0,"H_LINE");
ObjectCreate(0,"H_LINE",OBJ_HLINE,0,0,iLow(NULL, 0, 0));
ObjectSetInteger(0,"H_LINE",OBJPROP_COLOR,clrRed);
ObjectSetInteger(0,"H_LINE",OBJPROP_STYLE,STYLE_DOT);
ObjectSetInteger(0,"H_LINE",OBJPROP_WIDTH,2);続いてトレンドラインと水平線の価格帯を取得する箇所です。
//各オブジェクトの値を取得する
double Sh_T = ObjectGetValueByShift("T_LINE", 0);
double OG_T = ObjectGet("T_LINE",OBJPROP_PRICE1);
double Sh_H = ObjectGetValueByShift("H_LINE", 0);
double OG_H = ObjectGet("H_LINE",OBJPROP_PRICE1);ObjectGetValueByShift()とObjectGet()を使っています。
最後は出力箇所です。
Print("トレンドライン①" + Sh_T);
Print("トレンドライン②" + OG_T);
Print("水平ライン①" + Sh_H);
Print("水平ライン②" + OG_H);結果

前述した通り水平ライン①(ObjectGetValueByShift()側)は0になり、水平ライン②(ObjectGet()側)は正確に水平線を引いた値を取得出来ている事がわかります。
不思議ですが、水平線はObjectGet()で取得しようという事ですね!
また、トレンドライン①(ObjectGetValueByShift()側)は最新のローソク足上のトレンドラインの値になっている事がわかります。
そしてトレンドライン②(ObjectGet()側)はトレンドラインの始点の値になっている事がわかります。中々面白いですね!
ちなみにトレンドラインは、『ObjectGetValueByShift(“T_LINE”, 0);』の箇所を変えてあげるとバーシフトにちなんだトレンドラインの値を取得する事が可能です。
- ObjectGetValueByShift(“T_LINE”, 1); ➡133.887
- ObjectGetValueByShift(“T_LINE”, 2); ➡133.869
- ObjectGetValueByShift(“T_LINE”, 3); ➡133.851
- ObjectGetValueByShift(“T_LINE”, 4); ➡133.833
- ObjectGetValueByShift(“T_LINE”, 5); ➡133.815
このように取得したトレンドラインの価格は、実際のEAロジックにも応用可能です。
ZigZagと組み合わせて相場の流れを読む具体的なEAサンプルについては、以下の記事で詳しく解説しています。
❓ トレンドライン・水平線の価格取得に関するよくある質問【MQL4 FAQ】
💬 ObjectGet / ObjectGetValueByShift の違いや、水平線が0になる原因についてよくある疑問をまとめました。
ObjectGetValueByShift()は時間軸を持つオブジェクト専用の関数であり、時間情報を持たない水平線(OBJ_HLINE)では正しい価格を取得できないため0が返ります。
水平線(OBJ_HLINE)の価格を取得する場合は、ObjectGet()を使ってOBJPROP_PRICE1の値を取得する必要があります。
トレンドラインは時間と価格の2点を持つオブジェクトですが、水平線は価格のみを持つオブジェクトのため、対応する取得関数が異なります。
ObjectGet()で取得したトレンドラインの価格は、トレンドラインの始点(PRICE1)の価格になります。
トレンドラインの現在足や過去足に対応した価格を取得する場合は、ObjectGetValueByShift()を使用してバーシフトを指定する必要があります。
水平線は時間軸を持たないため、ObjectGetValueByShift()を使って価格を取得することはできません。常にObjectGet()を使用する必要があります。
まとめ|トレンドラインと水平線の正しい価格取得方法
以上が、『トレンドラインと水平線の価格帯の取得方法』です。
水平線の価格帯を取得する場合はObjectGet()を使用し、トレンドラインの価格帯を取得する場合はObjectGetValueByShift()を取得するという事がわかりました。
トレンドライン系の処理は以下の記事にも記載していますので良ければ参考にしてみてください。
✅ 今回のロジックをベースにしたEAサンプルも多数公開中
今回紹介したようなEAの売買ロジック・考え方をベースに、
当サイトではさまざまなFX自動売買EAのサンプルコードを公開しています。
ロジックの違いや設計の考え方を比較しながら、
自分に合ったEA構成を探したい方はぜひチェックしてみてください。
📊 EA運用・検証フェーズに進みたい方へ
今回のような仕組みを理解したうえで、
「実際にどのEAが安定しているのか」、「検証データではどんな差が出ているのか」
を確認したい方は、以下の記事も参考になります。
EA開発初心者向けに、今後も実践的に使えるMQL4関数や実装例を紹介していきます。
気になる機能やロジックがあれば、用途別に整理した関連記事もぜひあわせてご覧ください。











コメント