4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Last updated at Posted at 2020-03-21

23/09/22追記
note購入者はDMして下されば続きが読めます!
https://note.com/iceseeds/n/nfdae2c5ac2ef

はじめに

ここでは、GUIでストップ狩りを回避するラインを実装します。

前回までの記事を理解しているのが前提です。
【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を拡張(横スクロールできる予定 を実装します。

YoutubeでLive配信しながら作ってます。
https://www.youtube.com/channel/UCcTw_iVgpLfrep9f94KxwLg?sub_confirmation=1
チャンネル登録お願いします:relaxed:
Twitterでは毎日呟いています。
https://twitter.com/IceSeed_bz
フォローお願いします:relaxed:
お疲れ様。:eye::eye:

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?