最高値最安値について
特定期間の最高値・最安値をトレード戦略の肝に据えることは多いのではないでしょうか?
ブレイクアウト狙いのトレンドフォローエントリーや、ストップロスエントリーの目安にする
などの戦略は割と一般的かと思います。(個人的にも有用な戦略であると考えています)
※トレンドフォローについては以下の記事も参考になるかと思います。↓
最高値・最安値の取得方法については、いろいろな記述の仕方があるかとは思いますが、
今回は
ArrayMaximum関数、ArrayMinimum関数を使ったやり方
を紹介します。
後日、iHighest関数,iLowest関数を使ったやり方を紹介する予定ですが、この記述は簡易でMQL4利用者にもなじみ深い一方で、
MQL5で頻出する、
インジケータのハンドルを取得→配列の時系列セット→コピー関数による情報の配列コピー
という工程に親和性が高いのは、ArrayMaximum関数、ArrayMinimum関数を使った記述法のような気がするからです。
そんなわけで、今回は
- 直近100本の最高値、最安値の値を取得し、
- ↑を水平線にて描画し、
- 最高値と最安値の差分レンジをコメントに表示
以上の回路を作っていきたいと思います。
最高値と最安値の取得におけるロードマップ
以下の手順でコードを記述していきます
- 高値と安値の差を格納する変数を宣言
- 直近高値、直近安値の取得に必要な変数・配列の宣言
- 配列を時系列にセット
- 高値と安値の情報を配列にコピー
- 最高値・最安値インデックスを取得し、変数に格納
- MqlRates構造体を利用して、最高値・最安値を取得する
- 取得した最高値・最安値を水平線で描画する
高値と安値の差を格納する変数を宣言
これは最高値、最安値を取得するのは無関係なのですが、
チャート上に、最高値と最安値のレンジ幅がどのくらいか、というのをチャート上にコメント表示するために使います。
//高値と安値の差を格納する変数を宣言
double tradingRange=0;
直近高値、直近安値の取得に必要な変数・配列の宣言
HighestCandle,LowestCandleは直近から100本の時系列範囲で、どの時点での足が最高値、最安値だったかを格納するint型の変数です。
例えば、3本前の足が最高値だったら、HighestCandleに「3」が格納される・・・そんな感じです。
※実際の最高値最安値データが格納されるわけではないので注意してください。
High[],Low[]配列は、後述するCopyHigh関数やCopyLow関数を使って、各足ごとの高値、安値情報を格納する配列です。
※あくまで時間足ごとの高値、安値であり最高値・最安値を格納している配列ではない点に注意してください。
//直近高値、直近安値の場所を格納する変数を宣言
int HighestCandle,LowestCandle;
//高値と安値の情報を格納する変数配列を宣言
double High[],Low[];
配列を時系列にセット
最新足から古い時間足に向かってデータが格納されるように配列をセットします。
配列の時系列セットにはArraySetAsSeries関数を用います。
インデックス[0]が一番直近の時間足のデータになります。
//配列を時系列にセット
ArraySetAsSeries(High,true);
ArraySetAsSeries(Low,true);
※ArraySetAsSeries関数については↓をご覧ください。
高値と安値の情報を配列にコピー
高値データはCopyHigh関数、安値データはCopyLow関数を使って、配列にデータをコピーしていきます。
※Copy~関数は、上記以外にも多数種類があります。
詳しくは↓の講座記事で解説しておりますので、ご参照ください。
・MQL5 EA講座 第105回「CopyRates関数以外のCopy関数」
//高値と安値の情報を配列にコピー
CopyHigh(_Symbol,_Period,0,100,High);
CopyLow(_Symbol,_Period,0,100,Low);
最高値・最安値インデックスを取得し、変数に格納
時系列ごとの高値・安値を格納している配列High[]、Low[]のなかから最高値・最安値のインデックスを見つけ出し、変数に格納します。
インデックスの取得にはArrayMaximum関数、ArrayMinimum関数を利用します。
※iHighest関数やiLowest関数はチャートの中から、指定期間高安値インデックスを取得しますが、ArrayMaximum関数やArrayMinimum関数は配列の中から指定期間高安値インデックスを取得する、
という違いがあります。
//高値格納配列の最高値インデックスを格納
HighestCandle=ArrayMaximum(High,0,100);
//安値格納配列の最安値インデックスを格納
LowestCandle=ArrayMinimum(Low,0,100);
MqlRates構造体を利用して、最高値・最安値を取得する
構造体というのは、
MqlRates構造体はMQL5側で事前に定義済みの構造体です。
定義は↓のようになっています。
struct MqlRates
{
datetime time; // 期間開始時間
double open; // 始値
double high; // 期間中の最高値
double low; // 期間中の最安値
double close; // 終値
long tick_volume; // ティックボリューム
int spread; // スプレッド
long real_volume; // 取引高
};
お弁当パックのように、チャート上の様々な情報をいろいろ詰め込めるようになっています。
今回は
PriceInfo[]
という配列で宣言しているので、↓のようなロッカー上に情報を格納できるようになっています。
[0] | [1] | [2] | [3] | |
期間開始時間 | ||||
始値 | ||||
期間中の最高値 | ||||
終値 | ||||
ティックボリューム | ||||
スプレッド | ||||
取引高 |
配列を時系列にセットするのは、高値・安値配列のときと同じですね。
MqlRates構造体のインスタンスに情報を格納するには、CopyRates関数を使います。
これで、MqlRates構造体が定義している情報を使えるようになります。
//MqlRates構造体のインスタンス配列を宣言
MqlRates PriceInfo[];
//配列を時系列にセット
ArraySetAsSeries(PriceInfo,true);
//価格情報をMqlRates構造体インスタンス配列に格納
int Data=CopyRates(_Symbol,_Period,0,Bars(_Symbol,_Period),PriceInfo);
※最後の行、「int Data」でCopyRates関数がコピーした要素数を格納していますが、特にこの後何かに利用したりはしていません。
MqlRates構造体の使い方についてはコチラの記事も参考になるかと思います。↓
取得した最高値・最安値を水平線で描画する
下のソースコードを見ても、ぱっと見ではどれが取得した最高値・最安値かはわからないかもしれません。
最高値=PriceInfo[HighestCandle].high
最安値=PriceInfo[LowestCandle].low
となっています。
- PriceInfoがMqlRates構造体のインスタンスで、各種時系列データを格納している
- [HighestCandle]、[LowestCandle]が最高値・最安値の場所、
- .high、.low で格納している各種時系列データのうち、高値・安値をピックアップする
↑そんな仕組みになっています。
取得した最高値・最安値をもとに各種Object~関数を用いて、水平ラインを描画する記述を書きます。
//オブジェクト生成シークエンス(高値)
ObjectCreate(0,"Line1",OBJ_HLINE,0,0,PriceInfo[HighestCandle].high);
ObjectSetInteger(0,"Line1",OBJPROP_COLOR,clrOrange);
ObjectSetInteger(0,"Line1",OBJPROP_WIDTH,3);
ObjectMove(0,"Line1",0,0,PriceInfo[HighestCandle].high);
//オブジェクト生成シークエンス(安値)
ObjectCreate(0,"Line2",OBJ_HLINE,0,0,PriceInfo[LowestCandle].low);
ObjectSetInteger(0,"Line2",OBJPROP_COLOR,clrOrange);
ObjectSetInteger(0,"Line2",OBJPROP_WIDTH,3);
ObjectMove(0,"Line2",0,0,PriceInfo[LowestCandle].low);
高値と安値の差分を算出し、コメント出力
見やすくするために、改行をしてはいますが、
やっていることは単純に最高値から最安値を引いているだけです。
//高値と安値の差分を算出し、格納
tradingRange=NormalizeDouble(
(PriceInfo[HighestCandle].high
-
PriceInfo[LowestCandle].low
),
_Digits);
Comment("最高値~最安値のレンジ: ",tradingRange);
}
NormalizeDouble関数については↓をご覧ください。
全体のプログラムコード
全体のサンプルコードは以下のようになります。
void OnTick()
{
//高値と安値の差を格納する変数を宣言
double tradingRange=0;
//直近高値、直近安値の場所を格納する変数を宣言
int HighestCandle,LowestCandle;
//高値と安値の情報を格納する変数配列を宣言
double High[],Low[];
//配列を時系列にセット
ArraySetAsSeries(High,true);
ArraySetAsSeries(Low,true);
//高値と安値の情報を配列にコピー
CopyHigh(_Symbol,_Period,0,100,High);
CopyLow(_Symbol,_Period,0,100,Low);
//高値格納配列の最高値インデックスを格納
HighestCandle=ArrayMaximum(High,0,100);
//安値格納配列の最安値インデックスを格納
LowestCandle=ArrayMinimum(Low,0,100);
//MqlRates構造体のインスタンス配列を宣言
MqlRates PriceInfo[];
//配列を時系列にセット
ArraySetAsSeries(PriceInfo,true);
//価格情報をMqlRates構造体インスタンス配列に格納
int Data=CopyRates(_Symbol,_Period,0,Bars(_Symbol,_Period),PriceInfo);
//オブジェクト生成シークエンス(高値)
ObjectCreate(0,"Line1",OBJ_HLINE,0,0,PriceInfo[HighestCandle].high);
ObjectSetInteger(0,"Line1",OBJPROP_COLOR,clrOrange);
ObjectSetInteger(0,"Line1",OBJPROP_WIDTH,3);
ObjectMove(0,"Line1",0,0,PriceInfo[HighestCandle].high);
//オブジェクト生成シークエンス(安値)
ObjectCreate(0,"Line2",OBJ_HLINE,0,0,PriceInfo[LowestCandle].low);
ObjectSetInteger(0,"Line2",OBJPROP_COLOR,clrOrange);
ObjectSetInteger(0,"Line2",OBJPROP_WIDTH,3);
ObjectMove(0,"Line2",0,0,PriceInfo[LowestCandle].low);
//高値と安値の差分を算出し、格納
tradingRange=NormalizeDouble(
(PriceInfo[HighestCandle].high
-
PriceInfo[LowestCandle].low
),
_Digits);
Comment("最高値~最安値のレンジ: ",tradingRange);
}
//+------------------------------------------------------------------+
サンプルコードの挙動は以下のようになります↓
最後までお読みいただきありがとうございました<(_ _)>
※最高値・最安値の取得方法については<MQL5でEAを作ろう講座>でも↓の記事で解説しておりますので、よろしければ参考にしていただければと思います。
・MQL5 EA講座 第106回「最高値と最安値の取得について」
また、最高値・最安値の値を取得する別の方法に興味があれば↓の記事もご覧ください。
コメント