MQL4言語はC言語のような古い言語です。また数年前からMT4がアップデートされそれに伴い多少変更され、昔のコード異なることがあります。
カスタム・インジケータをMQL4言語を使って作ることが可能です。
直近の時間足で高値をコメントで表示させるインジケータです。
カスタム・インジケータ
MetaEditorでプログラムを作りたいのですが、現状ではMQL5で記述してMT4で使うという微妙な段階にあります。MQL5が新しいのでそちらを導入すればいいのですが、実際に使われているのはMT4なのでMQL5そのままでは動かないこともあるようで、いずれ解消されるでしょうけれど。
初期設定
プロパティ設定:
インジケータなのでチャート上に表示する。表示するため値を入れるバッファーが必要、それを色をつけて線で表示というような設定です。
- ローソク足のチャート上に表示
- 計算と表示用バッファー
- グラフィックス表示用バッファー
- 表示方法
- 表示色
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// ローソク足のチャート上に表示 #property indicator_chart_window // 使用する計算と表示用の時系列バッファー #property indicator_buffers 1 // グラフィックス表示用のバッファー #property indicator_plots 1 // ライン表示 #property indicator_type1 DRAW_LINE // プロットの色 #property indicator_color1 Red |
グローバル変数:
次に具体的なインジケータのバッファー名を配列で決めます。 小数点を使うのでdouble型で宣言
1 2 |
// インジケータの描画用バッファ double ExtLineBuffer[]; |
OnInit():初期化
起動時に1度だけ実行する箇所です。ここで必要な初期化をします。先に宣言したバッファを表示用に使うため SetIndexBuffer を使い、引数にINDICATOR_DATA を指定します。
1 2 3 4 5 6 7 |
int OnInit() { // Buffer配列を表示用として設定 SetIndexBuffer(0,ExtLineBuffer,INDICATOR_DATA); return(INIT_SUCCEEDED); } |
OnCalculate():
次にプログラムの本体となる部分で、OnCalculateは価格の変化 (Tick) 毎に呼び出されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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[]) { // ... return rates_total; } |
- rates_total
- チャートのバー(ロウソク足)の総数で最初は画面バー総数です。
- 価格の変化 (Tick) で呼び出さると+1になります。
- prev_calculated
- 計算済みのバー数です。
- 最初は0
- 計算を始めて全て計算を終えた時にはrates_totalと同じ
- バーが追加されると rates_totalは1つ増えます。
- &time[], &open[], &high[], &low[], &close[]
- それぞれのバーにおける時間、始値、高値、安値、終値が配列で収まっている。
- 要素の0は最新なのでチャート上は右端
- バーが増えると要素が+1シフトする
- tick_volume
- Tickの更新回数
- volume
- Fxでは使用されていません
- spread
- MT4では使用されていません
OnCalculate()
OnCalculate()のパラメーターを使って
Barが追加されると1度だけ計算する設定を作ってみます
これを追加していきます
1 2 3 4 5 6 7 |
int limit = rates_total - prev_calculated; for(int i = limit - 1; i >= 0; i--){ // 計算 ... return rates_total; } |
Print()を使ってLogを取って挙動を確認してみましょう
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
// 様々な設定 // ... //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit(){ // ... return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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[]) { Print("rates_total=" + IntegerToString(rates_total)); Print("prev_calculated=" + IntegerToString(prev_calculated)); Print("Bars=" + IntegerToString(Bars)); // バーの数を取得 int limit = rates_total - prev_calculated; Print("limit=" + IntegerToString(limit)); // main loop for(int i = limit - 1; i >= 0; i--){ if(i==0) Print("i=0"); // ... } Print("return: rates_total=" + IntegerToString(rates_total)); Print("---------"); return rates_total; } |
Logの結果は、以下のようになりました
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
20:54:00.870 TestIndicator GBPUSD,M1: --------- 20:54:00.870 TestIndicator GBPUSD,M1: return: rates_total=2049 20:54:00.870 TestIndicator GBPUSD,M1: limit=0 20:54:00.870 TestIndicator GBPUSD,M1: Bars=2049 20:54:00.870 TestIndicator GBPUSD,M1: prev_calculated=2049 20:54:00.870 TestIndicator GBPUSD,M1: rates_total=2049 20:54:00.260 TestIndicator GBPUSD,M1: --------- 20:54:00.260 TestIndicator GBPUSD,M1: return: rates_total=2049 20:54:00.260 TestIndicator GBPUSD,M1: i=0 20:54:00.260 TestIndicator GBPUSD,M1: limit=1 20:54:00.260 TestIndicator GBPUSD,M1: Bars=2049 20:54:00.260 TestIndicator GBPUSD,M1: prev_calculated=2048 20:54:00.260 TestIndicator GBPUSD,M1: rates_total=2049 20:53:59.085 TestIndicator GBPUSD,M1: --------- 20:53:59.085 TestIndicator GBPUSD,M1: return: rates_total=2048 20:53:59.085 TestIndicator GBPUSD,M1: limit=0 20:53:59.085 TestIndicator GBPUSD,M1: Bars=2048 20:53:59.085 TestIndicator GBPUSD,M1: prev_calculated=2048 20:53:59.085 TestIndicator GBPUSD,M1: rates_total=2048 20:53:58.958 TestIndicator GBPUSD,M1: --------- ... 20:53:51.957 TestIndicator GBPUSD,M1: return: rates_total=2048 20:53:51.957 TestIndicator GBPUSD,M1: limit=0 20:53:51.957 TestIndicator GBPUSD,M1: Bars=2048 20:53:51.957 TestIndicator GBPUSD,M1: prev_calculated=2048 20:53:51.957 TestIndicator GBPUSD,M1: rates_total=2048 20:53:51.222 TestIndicator GBPUSD,M1: --------- 20:53:51.222 TestIndicator GBPUSD,M1: return: rates_total=2048 20:53:51.222 TestIndicator GBPUSD,M1: limit=0 20:53:51.222 TestIndicator GBPUSD,M1: Bars=2048 20:53:51.222 TestIndicator GBPUSD,M1: prev_calculated=2048 20:53:51.222 TestIndicator GBPUSD,M1: rates_total=2048 20:53:50.954 TestIndicator GBPUSD,M1: --------- 20:53:50.954 TestIndicator GBPUSD,M1: return: rates_total=2048 20:53:50.954 TestIndicator GBPUSD,M1: i=0 20:53:50.947 TestIndicator GBPUSD,M1: limit=2048 20:53:50.947 TestIndicator GBPUSD,M1: Bars=2048 20:53:50.947 TestIndicator GBPUSD,M1: prev_calculated=0 20:53:50.947 TestIndicator GBPUSD,M1: rates_total=2048 20:53:50.945 TestIndicator GBPUSD,M1: initialized |
時系列的には下から上に流れています
初期の動きは
rates_total=2048 // 総数
prev_calculated=0 // 計算をしていない状態
limit=2048 // rates_total – prev_calculated なので総数と同じ
i=0 // for()分のmain loopで計算をして、i=0で終わる
次にTickが来ると OnCalculate() が呼ばれるが
prev_calculated=2048 の総数と同じなので何もしない
1分足なので、20:53が20:54になるタイミング、
つまりBarが追加され
rates_total=2049
となり
limit=1でmain loopの計算を1度だけ行う
…
という挙動となります
Comment 高値表示
簡単な文字を表示するためにCommentを使ってみます。下のように文字は「” “」でくくり、数字はそのままで、「,」で区切ります。
1 |
Comment("最新高値= ",high[0]); |
これを使ってOnCalculateで引っ張ってくる最新の高値を表示してみましょう。
ラインを描画しないので必要ないものもありますのでコメントアウト
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
//+------------------------------------------------------------------+ // PriceHigh_01.mq4 //+------------------------------------------------------------------+ //---- the indicator will be plotted in the main window #property indicator_chart_window //---- one buffer will be used for the calculations and plot of the indicator //#property indicator_buffers 1 //---- only one graphic plot is used //#property indicator_plots 1 //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit(){ return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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[]) { Comment("最新高値= ",high[0]); return rates_total; } |
MT4に設定
実際にMT4に設定してみましょう。
MT4の「ファイル」から「データフォルダを開く」を選択
「MQL4」フォルダ
「indicators」を選択
EAはExpertsに入れますがインジケータはindicatorsに入れます。
そのフォルダに拡張子をmq4として保存します。
一旦、MT4を終了して再起動するとex4ファイルがコンパイルされ生成されています。
ナビゲータにインジケータが表示されているのでそれをチャートにドラッグアンドドロップで起動させます。
コメントで1つ前の時間足での高値が表示されます。
また、簡単にインジケータをプログラム無しである程度作れるものもあります
[PR]
インジケーターつくーる
EAを作るオンラインセミナー
実際にEAを作ろうとするとプログラミング以外にFX特有のやり方を知っておかないと失敗します。
失敗はイコール損失です。
EAに関する本もありますが、このようなオンラインセミナーもあります。
プログラミングがある程度分かる
FXの裁量はできるが自動化したい
などのトレーダーに向いているでしょう
EA開発者の必読書:
ケビン・ダービーが3桁のリターンをたたき出すトレードシステム開発の秘訣を伝授
[PR]
システムトレード 検証と実践 ──自動売買の再現性と許容リスク