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

投稿日

更新日

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

はじめに

ここでは、GUIでストップ狩りを回避するラインを実装します。
GitHubにソースを公開しました。細かい修正は、こちらをご覧下さい。
GitHub : KEG_Qiita_EA
GitHub : KEG_Qiita_EA 差分
前回までの記事を理解しているのが前提です。
【MQL4 : MT4】GUI で ストップ狩りを回避するライン を実装した EA を作る。③
作成手順としては、以下の通りです。

  1. ComboBoxにライン作成Listを追加
  2. 2本のライン作成処理
  3. GUIを拡張(横スクロールできる予定)
  4. ライン情報( pips, 損益, RR )を表示
  5. 仕掛けに対して、ラインで決済できる処理
  6. 細かい修正etc...
    今回は、6. 細かい修正etc... を実装します。
    本当に細かいところは、GitHubにてご確認ください。
    ※ネーミングセンスはありません。なるだけ分かりやすくしているつもりです!
    いろいろと初心者な為、至らない部分もありますが、宜しくお願いします。
    フォルダ構造のアドバイスなどを頂けると助かります。
  • Experts/
    • Sample/
      • Common/
        • CMD.mqh     
        • Common.mqh   
      • Plugin/        
        • ExitCurrency.mqh  
        • LineOrder.mqh
      • KEG_Order.mq4
      • AppWindow.mqh
      • Event.mqh

実行結果

Screenshot_5.png

細かい修正etc...

KEG_Order.mq4

KEG_Order.mq4
void OnTimer()
{
   LineOrder.check();
   
   if( b_check0 )
      LineOrder.getLine( str_lineName0 );
   else if( AppWindow.m_labelPips0.Text() != "" )
      LineOrder.reset( str_lineName0 );
      
   if( b_check1 )
      LineOrder.getLine( str_lineName1 );
   else if( AppWindow.m_labelPips1.Text() != "" )
      LineOrder.reset( str_lineName1 );      
   
   LineOrder.exitCheck();
}

KEG_Order.mq4 の ソースコード詳細

毎秒実行するコードを出来るだけ少なくしたつもりです。
ラインの有無をチェックし、
あったら、ラインの情報取得。
ない 且つ Labelに文字があったら、文字を消します。
else if( AppWindow.m_labelPips0.Text() != "" )


Event.mqh

Event.mqh
bool CEvent::btnLine( const int id, const long lparam, const double dparam, const string sparam )
{
   if( id == 1000 && ( !b_lineCreate0 || !b_lineCreate1 ) ) // 1000ってなに。。。w
   {
      if( StringFind( sparam, "btnLine0", 4 ) != -1 )
         b_lineCreate0 = true;
      if( StringFind( sparam, "btnLine1", 4 ) != -1 )
         b_lineCreate1 = true;   
   }
   if( id == CHARTEVENT_CLICK )
   {
      if( b_lineCreate0 )
         if( !LineOrder.create( str_lineName0, dparam ) )
            CMD.Error( "LineOrder : Create0" );
         else
            b_lineCreate0 = false;
      
      if( b_lineCreate1 )
         if( !LineOrder.create( str_lineName1, dparam ) )
            CMD.Error( "LineOrder : Create1" );
         else
            b_lineCreate1 = false;
   }
   
   
   return true;
}

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

if( id == 1000 && ( !b_lineCreate0 || !b_lineCreate1 ) )
onChartEventの id の 1000ってなんの定数?w
恐らく、マウスクリックを離したときだけど、何も見てないから確信がもてない。。。


LineOrder.mqh

LineOrder.mqh
#include "../Common/Common.mqh"
class CLineOrder
{
   public:
      bool  check();
      bool  exitCheck();
      bool  getLine( string str_lineName );
      
      bool  create( string str_name, double d_param );
      bool  reCreate( string str_name, int i_type );
      
      bool  reset( string str_lineName );
  private:
      bool  exit( int i_ticket );
};
~
略
~
bool  CLineOrder::reset( string str_lineName )    // --- 1
{
   if( str_lineName == str_lineName0 )
   {
      AppWindow.m_labelPips0.Text( "" );
      AppWindow.m_labelProfit0.Text( "" );
   }else if( str_lineName == str_lineName1 ) 
   {
      AppWindow.m_labelPips1.Text( "" );
      AppWindow.m_labelProfit1.Text( "" );
   }
   
   
   return true;
}
bool CLineOrder::create( string str_name, double d_param )    // --- 2
{
   int      i_sub;
   datetime dt_x;
   double   d_y;
   ChartXYToTimePrice( ChartID(), 0, (int)d_param, i_sub, dt_x, d_y );
   
   if( !ObjectCreate( str_name, OBJ_HLINE, 0, Time[0], NormalizeDouble( d_y, Digits() ) ) ) 
      return false;
   ObjectSet( str_name, OBJPROP_STYLE, STYLE_DASHDOTDOT );
   ObjectSet( str_name, OBJPROP_COLOR, clrRed );
   ObjectSet( str_name, OBJPROP_HIDDEN, true );
   ObjectSet( str_name, OBJPROP_SELECTED, true );
   
   
   return true;
}
bool CLineOrder::reCreate( string str_name, int i_type )      // --- 3
{
   double d_line = ObjectGet( str_name, OBJPROP_PRICE1 );
   ObjectDelete( ChartID(), str_name );
   
   string   str_type;
   color    c_line;
   
   if( i_type == 0 )
   {
      if( d_line > Close[0] )
      {
         str_type = "LongProfit";
         c_line = clrRoyalBlue;
      }else{
         str_type = "LongLoss";
         c_line = clrDeepPink;
      }
   }else{
      if( d_line < Close[0] )
      {
         str_type = "SellProfit";
         c_line = clrRoyalBlue;
      }else{
         str_type = "SellLoss";
         c_line = clrDeepPink;
      }
   }
   
   if( !OrderSelect( OrdersTotal() - 1, SELECT_BY_POS, MODE_TRADES ) )
   {
      return false;
   }else{
      string str_exName = "KEG_" + Symbol() + "_" + (string)OrderTicket() + "_" + str_type;
      if( !ObjectCreate( ChartID(), str_exName, OBJ_HLINE, 0, 0, d_line ) ) 
         return false;
      ObjectSet( str_exName, OBJPROP_WIDTH, 2 );
      ObjectSet( str_exName, OBJPROP_COLOR, c_line );
      ObjectSet( str_exName, OBJPROP_HIDDEN, true );
      ObjectSet( str_exName, OBJPROP_SELECTED, true );
   }
   
   
   return true;
}
bool CLineOrder::getLine( string str_lineName )     // --- 4
{
   double DigitsValue = MathPow( 10, Digits() - 1 );
   
   double d_line     = ObjectGet( str_lineName, OBJPROP_PRICE1 );
   double d_pips     = ( d_line - Close[0] ) * DigitsValue;
   double d_profit   = ( d_pips * (double)AppWindow.m_editLots.Text() ) * 1000;
   
   if( str_lineName == str_lineName0 )
   {
      AppWindow.m_labelPips0.Text( DoubleToString( d_pips, 0 ) + " pips" );
      AppWindow.m_labelProfit0.Text( DoubleToString( d_profit, 0 ) + " yen" );
   }else if( str_lineName == str_lineName1 ) 
   {
      AppWindow.m_labelPips1.Text( DoubleToString( d_pips, 0 ) + " pips" );
      AppWindow.m_labelProfit1.Text( DoubleToString( d_profit, 0 ) + " yen" );
   }
   return true;
}
~
略
~

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

1. reset関数

ラインがなかったら、Labelの表示を消します。

bool  CLineOrder::reset( string str_lineName )
{
   if( str_lineName == str_lineName0 )
   {
      AppWindow.m_labelPips0.Text( "" );
      AppWindow.m_labelProfit0.Text( "" );
   }else if( str_lineName == str_lineName1 ) 
   {
      AppWindow.m_labelPips1.Text( "" );
      AppWindow.m_labelProfit1.Text( "" );
   }
   
   
   return true;
}

2. create関数

bool CLineOrder::create( string str_name, double d_param )
{
   int      i_sub;
   datetime dt_x;
   double   d_y;
   ChartXYToTimePrice( ChartID(), 0, (int)d_param, i_sub, dt_x, d_y );
   
   if( !ObjectCreate( str_name, OBJ_HLINE, 0, Time[0], NormalizeDouble( d_y, Digits() ) ) ) 
      return false;
   ObjectSet( str_name, OBJPROP_STYLE, STYLE_DASHDOTDOT );
   ObjectSet( str_name, OBJPROP_COLOR, clrRed );
   ObjectSet( str_name, OBJPROP_HIDDEN, true );
   ObjectSet( str_name, OBJPROP_SELECTED, true );
   
   
   return true;
}

ラインのレイアウトを見やすく変更しました。
ObjectSet( str_name, OBJPROP_STYLE, STYLE_DASHDOTDOT );
スタイルを、ダッシュDDに。
ObjectSet( str_name, OBJPROP_COLOR, clrRed );
からーを赤に。
ObjectSet( str_name, OBJPROP_HIDDEN, true );
表示中のライン等からの非表示に。
ObjectSet( str_name, OBJPROP_SELECTED, true );
ライン生成時、選択された状態に。

2. reCreate関数

2本のラインを同時に生成しましたが、引数をつかって、一つづつに。
また、色をProfitは、赤。Lossを、青にしました。

bool CLineOrder::reCreate( string str_name, int i_type ) 
{
   double d_line = ObjectGet( str_name, OBJPROP_PRICE1 );
   ObjectDelete( ChartID(), str_name );
   
   string   str_type;
   color    c_line;
   
   if( i_type == 0 )
   {
      if( d_line > Close[0] )
      {
         str_type = "LongProfit";
         c_line = clrRoyalBlue;
      }else{
         str_type = "LongLoss";
         c_line = clrDeepPink;
      }
   }else{
      if( d_line < Close[0] )
      {
         str_type = "SellProfit";
         c_line = clrRoyalBlue;
      }else{
         str_type = "SellLoss";
         c_line = clrDeepPink;
      }
   }
   
   if( !OrderSelect( OrdersTotal() - 1, SELECT_BY_POS, MODE_TRADES ) )
   {
      return false;
   }else{
      string str_exName = "KEG_" + Symbol() + "_" + (string)OrderTicket() + "_" + str_type;
      if( !ObjectCreate( ChartID(), str_exName, OBJ_HLINE, 0, 0, d_line ) ) 
         return false;
      ObjectSet( str_exName, OBJPROP_WIDTH, 2 );
      ObjectSet( str_exName, OBJPROP_COLOR, c_line );
      ObjectSet( str_exName, OBJPROP_HIDDEN, true );
      ObjectSet( str_exName, OBJPROP_SELECTED, true );
   }
   
   
   return true;
}

2. getLine関数

こちらも、2本のラインを同時に取得しましたが、引数をつかって、一つづつに。
引数の文字列によって、Labelにセットする場所を変えてます。

bool CLineOrder::getLine( string str_lineName )
{
   double DigitsValue = MathPow( 10, Digits() - 1 );
   
   double d_line     = ObjectGet( str_lineName, OBJPROP_PRICE1 );
   double d_pips     = ( d_line - Close[0] ) * DigitsValue;
   double d_profit   = ( d_pips * (double)AppWindow.m_editLots.Text() ) * 1000;
   
   if( str_lineName == str_lineName0 )
   {
      AppWindow.m_labelPips0.Text( DoubleToString( d_pips, 0 ) + " pips" );
      AppWindow.m_labelProfit0.Text( DoubleToString( d_profit, 0 ) + " yen" );
   }else if( str_lineName == str_lineName1 ) 
   {
      AppWindow.m_labelPips1.Text( DoubleToString( d_pips, 0 ) + " pips" );
      AppWindow.m_labelProfit1.Text( DoubleToString( d_profit, 0 ) + " yen" );
   }
   return true;
}

さいごに

今回は、6. 細かい修正etc... を実装しました。
次回は、Lineタッチで、LineAppにメッセージを送信 を実装する予定です。
今日まで毎日更新をしてきましたが、他に新しい事を始めたので、週1ペースで更新します。
GitHubにソースを公開しました。細かい修正は、こちらをご覧下さい。
2年振りぐらいなので、いろいろと覚えてなかった。。。
GitHub : KEG_Qiita_EA
GitHub : KEG_Qiita_EA 差分
前回のコードは、GitHubにてダウンロードしてください。
当EAを利用し、予期せぬエラーにより利用者が損失した場合、一切責任を持ちません。
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】

コメント

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

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

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