「MFT」マルチタイムフレーム相場分析!!!【プログラム解説】WhereTrend

どうも、あっちゃんっす!

前回の記事ではマルチタイムフレーム分析とは何ぞやという初心者・中級者の方へ向けて記事を書かせてもらったっす!あっちゃんが作成したインジケータを無料でプレゼントする予定になってるっすけど、どうやって配ろうか鋭意検討中っすのでもう少し待っていて欲しいっす!

今回は僕が作成したインジケータWhereTrendのソースを一気大公開し、解説するっす!プログラミングをするうえで初級と言っていいコードなので、まずはこのインジケータを作れるようになれるように関数なども一緒に乗せておいたっす!

前回の記事をマルチタイムフレーム分析とは何か理解していない方はこちらから前回の記事を読んでみて欲しいっす!

またデモ口座やMT4のインストールがまだの人は記事を書いているのでそちらを参考にして欲しいっす!

マルチタイムフレーム分析をMQLプログラミングで簡略化

ここまで、マルチタイムフレーム分析は重要だと書いて来たっすけど、基準足が短くなればなるほどエントリーの回数が増えるため、その都度複数の時間を分析するのは正直言って面倒くさいっす!

チャートが複数あると見なくては行けない箇所が増えて判断ミスの原因にもなるっす!人間の脳は同時に複数の処理をすることはできないっすからね!

そこで、MQLを使ってマルチタイムフレーム分析できないか考えたっす!

このインジケーターは一つのチャートで複数の時間足の相場の方向性が一目で分かるように設計したっす!

では、実際に作っている過程と機能について紹介するっす!MQLを使える様になればシグナルを維持ってオリジナルのツールを作れるようになるっす!

【オリジナルインジケーター】WhereTrend

このインジケーターは単純移動平均線を用いた相場の方向性を確認する為のインジケーターとなっています。ロウソク足も含めて全てが上昇相場の時はオブジェクトが青色に点灯し、逆に下落相場の時は赤色に点灯します。どちらでもない、いわゆるレンジの状態では黄色に点灯するように設計しています。

パラメータの設定

パラメータの設定はパラメータ入力画面に直接入力することでメタエディタを起動してコードを編集しなくてもインジケータ反映してくれる為の設定です。

  • 短期期間:数値を設定することで2本の移動平均線の期間を設定することができます。
  • 長期期間:数値を設定することで2本の移動平均線の期間を設定することができます。
  • トレンド判断基準:相場の方向を判断する指標を決めることができます。
    • 1.単純移動平均線
    • 2.指数移動平均線
  • 超長期:1番右にあるオブジェクトの基準時間を決めることができます。
  • 長期:右から2番目にあるオブジェクトの基準時間を決めることができます。
  • 中期:左から2番目にあるオブジェクトの基準時間を決めることができます。
  • 短期:1番左にあるオブジェクトの基準時間を決めることができます。

【MQL実践】WhereTrendの作成

実際にWereTrendをMQLを使って作成してみるっす!

このインジケータが作れれば簡単なサインインジケータが作れるようになるっすよ!

【MFTインジケータ】WhereTrendの言語化

【言語化】とは実際にコードを書き始める前に作ろうとしているものを言葉で説明できるようにするための工程です。今回はマルチタイムフレーム分析をするためのサインインジケータとなるための処理を言語化していくっす!

  1. チャートにインジケータを表示するタイミングで四角形のオブジェクト作成する
    • 場所はチャートの左下
    • 色は白
  2. ティックが動くたびに相場の方向を表す色を変更する
    1. 上昇相場の判定
      • ロウソク足>移動平均線短期>移動平均線短期
      • 上昇相場は青
    2. 下落相場の判定
      • ロウソク足<移動平均線短期<移動平均線短期
      • 下落相場は赤
    3. レンジ相場上記以外は黄
  3. インジケータを削除するタイミングで作成したオブジェクトを消します

【MFTインジケータ】WhereTrendの構成要素

  1. 図形オブジェクト
  2. ラベル
  3. 単純移動平均線
  4. 指数移動平均線
  5. ロウソク足の終値

仕様するものはそこまで難しくなく上の5つが理解していれば作れるインジケータになってます。

OnInit・deinit

【OnInit】はインジケータやEAがチャートに表示される一番最初に一度だけ流れるイベント関数です。

【deinit】はインジケータやEAがチャートから削除されるときに流れるイベント関数です。

図形・ラベルオブジェクト

条件のサインが揃ったら目で見てわかるようにするために今回はオブジェクトを表示してみます。

わかるようにするだけならアラートを出し耳で知らせたりメールを送って伝える方法もあります。

int OnInit(){

   ObjectCreate(0,"LTime",OBJ_RECTANGLE_LABEL,0,0,0); 
   ObjectSetInteger(0,"LTime",OBJPROP_XSIZE,20);
   ObjectSetInteger(0,"LTime",OBJPROP_YSIZE,20);
   ObjectSetInteger(0,"LTime",OBJPROP_BGCOLOR,clrWhite);   
   ObjectSetInteger(0,"LTime",OBJPROP_CORNER,CORNER_RIGHT_LOWER);
   ObjectSetInteger(0,"LTime",OBJPROP_XDISTANCE,30);
   ObjectSetInteger(0,"LTime",OBJPROP_YDISTANCE,30);
      
   return(INIT_SUCCEEDED);
}

void deinit(){
   ObjectDelete("LTime");
}

※作成したオブジェクトはインジケータを削除したタイミングで一緒に消してあげないとチャートに残り続けるので作成したオブジェクトは【deinit】の中で【ObjectDelete】を使ってオブジェクトを削除しましょう。

四角形の図形を表示したい場合【ObjectCreate】を使います。

コードの3行目は四角形の図形を作成しており、12行目で文字を表示させるためのラベルを置いています。

ObjectCreate

【ObjectCreate】は水平線や図形、文字などのオブジェクトを作成することのできる関数です。

引数のオブジェクトの型を変更することで図形や線、文字をチャートに書くことができます。

bool  ObjectCreate(
  long        chart_id,     // ①チャート識別子
  string      obj_name,     // ②オブジェクトの名
  ENUM_OBJECT obj_type,     // ③オブジェクトの型
  sub_window   nwin,        // ④ウィンドウインデックス
  datetime    time1,        // ⑤1番目のアンカーポイントの時間
  double      price1,       // ⑥1番目のアンカーポイントの価格
  ...
  datetime    timeN=0,      // ⑦N番目のアンカーポイントの時間
  double      priceN=0,     // ⑧N番目のアンカーポイントの価格
  );

今回は四角形とラベルを使用したいため『③オブジェクトの型』に四角形を表示させるための『OBJ_RECTANGLE_LABEL』を使用しています。

ObjectSetInteger

【ObjectSetInteger】は【ObjectCreate】で作成したオブジェクトの位置や大きさといった設定を変更する関数です。

修飾子無し

bool  ObjectSetInteger(
  long                            chart_id,     // ①チャート識別子
  string                          obj_name,     // ②オブジェクト名
  ENUM_OBJECT_PROPERTY_INTEGER    prop_id,      // ③プロパティ
  long                            prop_value    // ④値
  );

修飾子有り

bool  ObjectSetInteger(
  long                            chart_id,        // ❶チャート識別子
  string                          obj_name,        // ❷オブジェクト名
  ENUM_OBJECT_PROPERTY_INTEGER    prop_id,         // ❸プロパティ
  int                             prop_modifier,   // ❹修飾子
  long                            prop_value       // ❺値
  );

今回はオブジェクトを表示させたい場所を変更したいので『③プロパティ』には下記を使います

  • OBJPROP_CORNER:オブジェクトをチャートのどの位置に表示させるか設定するプロパティ
  • OBJPROP_XDISTANCE:【OBJPROP_CORNER】で決めた場所からX軸に距離を移動させるプロパティ
  • OBJPROP_YDISTANCE:【OBJPROP_CORNER】で決めた場所からY軸に距離を移動させるプロパティ
  • OBJPROP_XSIZE:【ObjectCreate】で作成したオブジェクトの横幅を決めるプロパティ
  • OBJPROP_YSIZE:【ObjectCreate】で作成したオブジェクトの縦幅を決めるプロパティ
  • OBJPROP_BGCOLOR:オブジェクトの背景色を決めるプロパティ

OBJPROP_CORNER

【OBJPROP_CORNER】はチャートのどの位置にオブジェクトを配置するか決める為の引数です。

  • CORNER_LEFT_UPPER:チャートの左上を中心とします
  • CORNER_LEFT_LOWER:チャートの左下を中心とします
  • CORNER_RIGHT_LOWER:チャートの右下を中心とします
  • CORNER_RIGHT_UPPER:チャートの右上を中心とします

【OBJPROP_CORNER】を使用できるオブジェクトは下記のオブジェクトになります。

  • ラベル
  • ボタン
  • ビットマップラベル
  • 長方形ラベル
  • エディット

OBJPROP_XDISTANCE・OBJPROP_YDISTANCE

【OBJPROP_XDISTANCE】は【OBJPROP_CORNER】で決めた位置から横軸(pixel)へ移動するための設定です。

【OBJPROP_YDISTANCE】は【OBJPROP_CORNER】で決めた位置から縦軸(pixel)へ移動するための設定です。

start

【start】はティックが動くたびに流れるイベント関数です。

int start(){

   double LMA,SMA;
   SMA =iMA(0,0,20,0,MODE_SMA,PRICE_CLOSE,0);
   LMA =iMA(0,0,80,0,MODE_SMA,PRICE_CLOSE,0);
   
   if(Close[0]>LMA){   
      if(Close[0]>SMA){
         ObjectSetInteger(0,"LTime",OBJPROP_BGCOLOR,clrBlue);
      }else if(Close[0]<=SMA){
         ObjectSetInteger(0,"LTime",OBJPROP_BGCOLOR,clrYellow);
      }      
   }else{   
      if(Close[0]<SMA){
         ObjectSetInteger(0,"LTime",OBJPROP_BGCOLOR,clrRed);
      }else if(Close[0]>=SMA){
         ObjectSetInteger(0,"LTime",OBJPROP_BGCOLOR,clrYellow);
      }
   }   
   return(0);
}
Close[N]:終値

【Close】は[]の中に数値を入れることで対応した時間の終値を取得できます。数値は0が現在となり数値が増えるごとに過去へ遡っていきます。

  • Close[0]:現在のバーの終値
  • Close[1]:1本前のバーの終値
  • Close[N]:N本前のバーの終値

iMA:移動平均線
double  iMA(
   string          symbol,       // ①通貨ペア
   int             time,         // ②時間軸
   int             period,       // ③MAの平均期間
   int             ma_shift,     // ④MAシフト
   ENUM_MA_METHOD  ma_method,    // ⑤MAの平均化メソッド
   int            applied_price,// ⑥適用価格
   int            shift         // ⑦シフト
   );

『③MAの平均期間』を変更することで移動平均線の期間を変更することができます。

『⑤MAの平均化メソッド』を「ID」または「値」へ変更することで移動平均線の種類を変更することができます。

  • 『単純移動平均』:0:MODE_SMA
  • 『指数移動平均』:1:MODE_EMA
  • 『平滑移動平均』:2:MODE_SMMA
  • 『加重移動平均』:3:MODE_LWMA
条件分岐:if-else

条件分岐の【if-else文】はプログラミングを行う際に必ず通る道なのでしっかりと理解を深めましょう!

日常の中で例を挙げて説明します。

例)あなたは「りんご」を買いたいとします。お財布の中に100円入っており、スーパーへ行くと「りんご」が100円でした。あなたは「りんご」を買うことができますか?

答えは『買うことができるです』

では、「りんご」が120円だったらどうでしょうか?『買うことができない』ですね。

これが条件分岐になります。

コードで書くと以下のようになります。

if(🍎==100円){
 1つ買う
}else{
 買えない
}

【if】とは英語で『もし』にあたり【else】は『そうでないと』という意味になります。

ですので「もし、🍎が100円ならりんごを1つ買い、そうでないなら買わない」という意味になります。

【if文】単体でも使用可能です。その場合、条件を満たしたら【if文】の処理を行います。

また、複数条件がある場合は【if文】【else if文】【else文】を使用します。

if(🍎==100円){
 1つ買う
}else if(🍎==50円){
 2つ買う
}else{
 買えない
}

上記の場合「もし、🍎が100円ならりんごを1つ買い、🍎が50円ならりんごを2つ買い、そうでないなら買わない」という意味になります。

前半部分は【if】と【else】は同じですが【else if】が入ることにより、りんごを2つ買えるようになりました。

コードの解説

コード解説の為に再度コードを載せておきます

ここまで書ければ、表示中のチャートにインジケータを表示することができます。

int start(){

   double LMA,SMA;  
   SMA =iMA(0,0,20,0,MODE_SMA,PRICE_CLOSE,0);
   LMA =iMA(0,0,80,0,MODE_SMA,PRICE_CLOSE,0);
   
   if(Close[0]>LMA){      
      if(Close[0]>SMA){
         ObjectSetInteger(0,"LTime",OBJPROP_BGCOLOR,clrBlue);
      }else if(Close[0]<SMA){
         ObjectSetInteger(0,"LTime",OBJPROP_BGCOLOR,clrYellow);
      }      
   }else if(Close[0]<=LMA){
      if(Close[0]<SMA){
         ObjectSetInteger(0,"LTime",OBJPROP_BGCOLOR,clrRed);
      }else if(Close[0]>SMA){
         ObjectSetInteger(0,"LTime",OBJPROP_BGCOLOR,clrYellow);
      }
   }
   
   return(0);
}

変数の定義

3:変数を利用するために最初に使用する変数を定義する必要があります。今回は移動平均の値を変数として使いたいので、小数点を利用できる【double型】を使います。

変数というのは「物を入れるための箱」だと思ってください。また、【double】【int】【string】【bool】というのは入れる物によって変わってきます。宅配便で送る時にはるシールがイメージとしてわかりやすいのではないでしょうか?「要冷蔵」だったり「割れ物注意」と取り扱いはたくさんあると思います。

【string[文字]】の中に【int[整数]】を入れることは可能ですが、【if文】などで条件ごとに処理をする際に違う形式のものが入っていると想定と違う動きをするので十分に気を付けてください。

4:【double[浮動小数点]】SMAという箱の中にMAの値を代入します。
 【iMA】は移動平均の値を取得するための関数となっています。
  引数1:「0」は現在表示中のチャートの通貨ペア
  引数2:「0」は現在表示中のチャートの時間軸
  引数3:「20」は20本分の平均値
  引数4:「0」MAシフトはしない
  引数5:「MODE_SMA」は単純移動平均
  引数6:「PRICE_CLOSE」は終値で移動平均を計算
  引数7:「0」現在の時間足で移動平均を計算

5:期間を「80」にしている以外、4行目と同様です。

上昇相場の条件

7:『現在の値』が『期間80単純移動平均』より大きい場合に8~12行の処理を実行する

 8:『現在の値』が『期間20単純移動平均』より大きい場合に9行目の処理を実行する
  9:初期値で設定したオブジェクトの色を「青」に変更する

 10:『現在の値』が『期間20単純移動平均』より小さい場合に11行目の処理を実行する
  11:初期値で設定したオブジェクトの色を「黄」に変更する

13:7行目の条件に合わなかった場合に14~18行目の処理を実行する

 13:『現在の値』が『期間20単純移動平均』より小さい場合に14行目の処理を実行する
  14:初期値で設定したオブジェクトの色を「赤」に変更する

 15:『現在の値』が『期間20単純移動平均』より大きい場合に16行目の処理を実行する
  16:初期値で設定したオブジェクトの色を「黄」に変更する

マルチタイムフレームカスタマイズ

このままでもインジケータとして使えるには使えるのですが、もう少し利便性を上げるために任意の時間足と移動平均の種類をプロパティ画面で選択できるようにコードをカスタマイズします。

//+------------------------------------------------------------------+
//|                                            WhereTrend-Simple.mq4 |
//|                                      https://mqlprogramming.net/ |
//+------------------------------------------------------------------+  
#property link      "https://mqlprogramming.net/"
#property version   "1.00"

#property strict  //日本語化
#property indicator_chart_window

input string SP;//★★★★★★★★★★★★★★★★★★
input int STerm = 20; //短期期間
input int LTerm = 80; //長期期間
input string SP0;//★★★★★★★★★★★★★★★★★★

//リスト表示
enum PT_Type{
                     PT_SMA=0,//1.単純移動平均
                     PT_EMA=1,//2.指数移動平均
                     PT_GMMA=2,//3.平滑移動平均
                     PT_SEMA=3,//4.加重移動平均
                     };
extern PT_Type Type_PT1; //トレンド判断基準
int MAType_PT = 0 ;
enum Time_Zone{
                     PT_TNone=0,//チャート時間
                     PT_month=43200,//月
                     PT_week=10080,//週
                     PT_day=1440,//日
                     PT_H4=240,//4時間
                     PT_H1=60,//1時間
                     PT_M30=30,//30分
                     PT_M15=15,//15分
                     PT_M5=5,//5分
                     PT_M1=1,//1分
                     };

extern Time_Zone Time_Zone1; //判定基準時間

int OnInit(){
   MAType_PT = Type_PT1;
   ObjectCreate(0,"LTime",OBJ_RECTANGLE_LABEL,0,0,0); 
   ObjectSetInteger(0,"LTime",OBJPROP_XSIZE,20);
   ObjectSetInteger(0,"LTime",OBJPROP_YSIZE,20);
   ObjectSetInteger(0,"LTime",OBJPROP_BGCOLOR,clrWhite);   
   ObjectSetInteger(0,"LTime",OBJPROP_CORNER,CORNER_RIGHT_LOWER);
   ObjectSetInteger(0,"LTime",OBJPROP_XDISTANCE,30);
   ObjectSetInteger(0,"LTime",OBJPROP_YDISTANCE,30);

   return(INIT_SUCCEEDED);
}

void deinit(){
   ObjectDelete("LTime");
}

int start(){

   double LMA,SMA;
   SMA =iMA(0,Time_Zone1,STerm,0,MAType_PT,PRICE_CLOSE,0);
   LMA =iMA(0,Time_Zone1,LTerm,0,MAType_PT,PRICE_CLOSE,0);
   
   if(Close[0]>LMA){   
      if(Close[0]>SMA){
         ObjectSetInteger(0,"LTime",OBJPROP_BGCOLOR,clrBlue);
      }else if(Close[0]<=SMA){
         ObjectSetInteger(0,"LTime",OBJPROP_BGCOLOR,clrYellow);
      }      
   }else{   
      if(Close[0]<SMA){
         ObjectSetInteger(0,"LTime",OBJPROP_BGCOLOR,clrRed);
      }else if(Close[0]>=SMA){
         ObjectSetInteger(0,"LTime",OBJPROP_BGCOLOR,clrYellow);
      }
   }

   return(0);
}

プロパティ画面をいじれるように【40行目:OnInit】より上を追加し、61行目と62行目のMAの設定引数を変更しました。

12・13行目のように型の宣言の前に【input】または【extern】を書くとプロパティ画面でユーザーが変更入力できるようになります。

17・26行目のように【enum】を使うとリストボックスを作成することが可能です。

41行目で【int:整数型】の変数に17~23行目の移動平均種別『Type_PT1』を入れなおしています。

61・62行目:移動平均の引数変更

  1. 『引数2:期間』に25~38行目で時間足のリストボックスを作成し、プロパティ画面で設定した時間足の数値を入れて自由に時間軸を変更できるようにしています。
  2. 『引数3:期間』に12・13行目でプロパティ画面で設定した数値を入れて自由に期間を変更できるようにしています
  3. 『引数5:移動平均種別』に41行目で『Type_PT1』を入れなおした値を入れ「単純・指数・平滑・加重」を選択できるようにしています。

まとめ

以上が、WhereTrendインジケータの作成方法の概要となってるっす!

関数などの説明も入れて丁寧に説明した分とても長くなってしまったっすけど、今後は時間はかかると思うすけど関数などは用語集にまとめて説明はそちらで行おうと思ってるっす!

【MT4でEA自作しちゃお~】

https://yukifx.web.fc2.com/index.html

参考までにあっちゃんが参考にしているサイトを載せておくのでわからなくなったらここで調べればいいと思うっす!

では、今回の記事のまとめっす!

僕が作成した『WhereTrend』の作り方を実践をまじえて説明したっす!この記事では1つのオブジェクトしか記載してないっすけど、あっちゃんが実際使ってるのは4つ表示できるようにしてマルチタイムフレームにしてるっす!もし、複数個表示させたいって人がいたら説明したところのオブジェクト数とかを増やせばいいっすよ!注意点はオブジェクトの名前は変えないといけないところっす!実際触ってみて試してみるといいっす!

今回の記事を書いていて思ったことっすけど記事の為に素材を作ってブログを書くってものすごく労力がかかるっすね!今後いろいろ工夫して更新頻度上げれるように頑張っていくつもりなので応援よろしくっす!

皆からあっちゃんへ「こんなインジケータ作って欲しい」とか「ここ説明して欲しい」とかあればできる範囲で応えられるようがんばるので連絡ほしいっす!

では次回の記事も楽しみにして欲しいっす!

記事が待てないという人はお金はかかってしまうっすけどトレードで生計を立てている人から直接学ぶと上達が早いっす!あっちゃんの考えっすけど、無料で渡された情報より身銭を切って得た情報の方が元をとってやろうという精神が働き学習スピードが速い気がするっす!

Programming master school分割払い *月/15,000円を12回払いで180,000円

【無料プレゼント】マルチタイムフレーム分析WhereTrend

公式ラインを作成したので友達登録していただければお得な情報やプレゼント情報などをお送りいたします。

また、WhereTrendをご希望の方はチャットより「プレゼント希望」と送ってください。

※返答AIで対応していただいていますので「」や他の文言を入れてしまうとちゃんと動作しない可能性があるので注意してください。

おすすめの記事