C
MQL4
MT4
Dialog
3
どのような問題がありますか?

投稿日

更新日

【MQL4 : MT4】GUI で ストップ狩りを回避するライン を実装した EA を作る。① 【Dialog】

はじめに

ここでは、GUIでストップ狩りを回避するラインを実装します。
GitHubにソースを公開しました。細かい修正は、こちらをご覧下さい。
GitHub : KEG_Qiita_EA
GitHub : 差分
差分が見れない場合があります。
この記事の最終確認にお使いください。
前回までの記事を理解しているのが前提です。
【MQL4 : MT4】GUI で 全決済、個別決済 を実装した EA を作る。
作成手順としては、以下の通りです。

  1. ComboBoxにライン作成Listを追加
  2. 2本のライン作成処理
  3. GUIを拡張(横スクロールできる予定)
  4. ライン情報( pips, 損益, RR )を表示
  5. 仕掛けに対して、ラインで決済できる処理
  6. 細かい修正etc...
    今回は、1 と 2 を実装します。
    既存のファイルは、ほとんど修正がありません。
    また、今後も様々な機能を追加していく予定なので、
    Errorなどを別ファイルに分けました。
    ※ネーミングセンスはありません。なるだけ分かりやすくしているつもりです!
    いろいろと初心者な為、至らない部分もありますが、宜しくお願いします。
    フォルダ構造のアドバイスなどを頂けると助かります。
  • Experts/
    • Sample/
      • Common/
        • CMD.mqh     ←コマンドファイル。エラー、時間取得 ( new )
        • Common.mqh   ←変数ファイル? ( new )
      • Plugin/        
        • ExitCurrency.mqh  
        • LineOrder.mqh   ←今回のメインファイルです。( new )
      • guiwindow.mq4
      • AppWindow.mqh
      • Event.mqh

実行結果

Screenshot_3.png
LineOrderを選択し、Pushをすると、2本のラインが表示されます。

Commonフォルダ

CMD.mqh

CMD.mqh
#include <stderror.mqh>    // --- 1
#include <stdlib.mqh>
class CCMD
{
   public:
      string   GetTimes();
      void     Error( string str_place );
};
string CCMD::GetTimes()    //  --- 2
{
   MqlDateTime times ;
   TimeToStruct( TimeLocal(), times );
   
   return (string)times.year + (string)times.mon + (string)times.day + (string)times.hour + (string)times.min + (string)times.sec;
}
void CCMD::Error( string str_place )   // --- 3
{
   if( GetLastError() != ERR_NO_ERROR && ERR_OBJECT_ALREADY_EXISTS )
      Alert( "Place : " + str_place + "\nErrorCode : " + (string)GetLastError() + "\nDetails : " + ErrorDescription( GetLastError() ) );
}

CMD.mqh の ソースコード詳細

1. Include文

エラーメッセージを詳しく表示させるための標準ファイルです。

CMD.mqh
#include <stderror.mqh>
#include <stdlib.mqh>

2. GetTimes関数

現在時刻を取得するための関数です。

CMD.mqh
string CCMD::GetTimes()
{
   MqlDateTime times ;
   TimeToStruct( TimeLocal(), times );
   return (string)times.year + (string)times.mon + (string)times.day + (string)times.hour + (string)times.min + (string)times.sec;
}

今回は、オブジェクトの名前に使用します。
戻り値の例「20203212213」
MqlDateTime times ;
datetime型で現在時刻を取得します。
TimeToStruct( TimeLocal(), times );
datetime型の値をMqlDateTime構造体変数に変換してます。

2. Error関数

Errorを表示させる関数です。

CMD.mqh
void CCMD::Error( string str_place )
{
   if( GetLastError() != ERR_NO_ERROR && ERR_OBJECT_ALREADY_EXISTS )
      Alert( "Place : " + str_place + "\nErrorCode : " + (string)GetLastError() + "\nDetails : " + ErrorDescription( GetLastError() ) );
}

引数で、エラー箇所を受け取ります。
if( GetLastError() != ERR_NO_ERROR && ERR_OBJECT_ALREADY_EXISTS )
不明なエラー 且つ 既に存在してるオブジェクト なら
エラー場所、エラーコード、エラー内容 を表示します。


Common.mqh

Common.mqh
#include "../AppWindow.mqh"
#include "CMD.mqh"
#include "../Plugin/ExitCurrency.mqh"
#include "../Plugin/LineOrder.mqh"
CPanelDialog   AppWindow;
CCMD           CMD;
CExitCurrency  ExitCurrency;
CLineOrder     LineOrder;

Common.mqh の ソースコード詳細

今後追加する際は、ここにinclude文を書きこみます。
このファイルは、ためしでやってみたので、
使い勝手が悪かったら、改造するかもです。
なにかいいアイデアがあれば教えてください。

2本のラインを!

AppWindow.mqh

修正部分の周辺のみ記載します。

AppWindow.mqh
~略~
bool CPanelDialog::CreateCombCreate()
{
   int widths = ClientAreaWidth() / 5;
   int x1 = 0;
   int y1 = ClientAreaHeight() - 20;
   int x2 = widths * 4;
   int y2 = ClientAreaHeight();
   
   if( !m_combCreate.Create( m_chart_id, m_name + "comboCreate", m_subwin, x1, y1, x2, y2 ) ) return false;
   m_combCreate.AddItem( "All Exit", 0 );
   m_combCreate.AddItem( "This Exit", 1 );
   m_combCreate.AddItem( "Line Order", 2 );           // --- 1
   
   if( !Add( m_combCreate ) ) return false;
   
   return true;
}
~略~

AppWindo.mqh の ソースコード詳細

1. AddItem

ラインを表示するItemを追加しました。

AppWindow.mqh
m_combCreate.AddItem( "Line Order", 2 );

Event.mqh

修正部分の周辺のみ記載します。

Event.mqh
#include "Common/Common.mqh"
~略~
bool CEvent::combSelect( const int id, const long lparam, const double dparam, const string sparam )
{
   if( ( StringFind( sparam, "btnComb", 4 ) != -1 ) && id == CHARTEVENT_OBJECT_CLICK ) 
   {
      switch( (int)AppWindow.m_combCreate.Value() )
      {
         case 0: // to All Exit
            if( !ExitCurrency.exit() )
               CMD.Error( "combSelect : All Exit" );
            break;
         case 1: // to This Exit
            if( !ExitCurrency.exit( Symbol() ) )
               CMD.Error( "combSelect : This Exit" );
            break;
         case 2: // to Line Order
            if( !LineOrder.lineOrder( CMD.GetTimes() ) )    // --- 2
               CMD.Error( "LineOrder" );
            break;
         default:
            Alert( "not select" );
      }
   }
   
   return true;
}
~略~

Event.mqh の ソースコード詳細

2. combBoxでのswitch文

前回同様、LineOrderを2番に設定したので、その際にLineOrderを呼び出します。
引数には、水平ラインの名前が被らない様に、現在時刻を入れてます。

Event.mqh
if( !LineOrder.lineOrder( CMD.GetTimes() ) )
   CMD.Error( "LineOrder" );

LineOrder.mqh

今回のメインです。
このシリーズは長丁場になりそうなので、無駄なコードがあるかもしれません。
最後の修正で、綺麗にしますのでご了承ください。

LineOrder.mqh
class CLineOrder
{
   public:
      bool  lineOrder( string str_name );
      bool  check();
   
   private:
      bool create( string str_name );
};
/* MEMO いらないんじゃない? ....いや使いそうかも??? */ 
bool CLineOrder::lineOrder( string str_name )
{
   if( !create( str_name ) )  return false;
   
   return true;
}
bool CLineOrder::create( string str_name )      // --- 3
{
   if( !ObjectCreate( str_name + "LineOrder0", OBJ_HLINE, 0, Time[0], Close[5] ) ) return false;
   
   if( !ObjectCreate( str_name + "LineOrder1", OBJ_HLINE, 0, Time[0], Close[10] ) ) return false;
   
   
   return true;
}
/* TODO ObjectFindで、特定の文字列が含まれていたら。。。
      全Objectを検索対象にする。
*/
bool CLineOrder::check()
{
   if( ObjectFind( ChartID(), "LineOrder0" ) )  return false;
   if( ObjectFind( ChartID(), "LineOrder1" ) )  return false;
      
   return true;
}

LineOrder.mqh の ソースコード詳細

3. ObjectCreate関数

ObjectCreate関数を使って、水平ラインを作成しています。

AppWindow.mqh
if( !ObjectCreate( str_name + "LineOrder0", OBJ_HLINE, 0, Time[0], Close[5] ) ) return false;
if( !ObjectCreate( str_name + "LineOrder1", OBJ_HLINE, 0, Time[0], Close[10] ) ) return false;

オブジェクトの名前が被らない且つLineOrderで作ったラインだよって印を付けるために、LineOrder0,1 と追加しました。
ObjectCreate( ラインの名前, オブジェクトの種類, ウィンド, 作成位置の時間( X軸 ), 作成位置の価格( Y軸 )
水平ラインなので、作成位置の価格( Y軸 ) に適当な価格を入れてます。

さいごに

今回は、1, 2. 2本のライン作成を実装しました。
次回は、3. GUIを拡張(横スクロールできる予定 を実装します。
GitHubにソースを公開しました。細かい修正は、こちらをご覧下さい。
2年振りぐらいなので、いろいろと覚えてなかった。。。
GitHub : KEG_Qiita_EA
GitHub : 差分
※差分が見れない場合があります。この記事の最終確認にお使いください。
YoutubeでLive配信しながら作ってます。
https://www.youtube.com/channel/UCcTw_iVgpLfrep9f94KxwLg?sub_confirmation=1
チャンネル登録お願いします:relaxed:
Twitterでは毎日呟いています。
https://twitter.com/IceSeed_bz
フォローお願いします:relaxed:
お疲れ様。:eye::eye:

新規登録して、もっと便利にQiitaを使ってみよう

  1. ユーザーやタグをフォローできます
  2. 便利な情報をストックできます
  3. 記事の編集提案をすることができます
ログインすると使える機能について
IceSeed
何か始めようとして取りあえず作った。 youtube :【https://www.youtube.com/channel/UCcTw_iVgpLfrep9f94KxwLg?sub_confirmation=1】

コメント

この記事にコメントはありません。
あなたもコメントしてみませんか :)
新規登録
すでにアカウントを持っている方はログイン
3
どのような問題がありますか?
新規登録して、Qiitaをもっと便利に使ってみませんか

この機能を利用するにはログインする必要があります。ログインするとさらに下記の機能が使えます。

  1. ユーザーやタグのフォロー機能であなたにマッチした記事をお届け
  2. ストック機能で便利な情報を後から効率的に読み返せる
新規登録ログイン
ストックするカテゴリー