23/09/22追記
note購入者はDMして下されば続きが読めます!
https://note.com/iceseeds/n/nfdae2c5ac2ef
はじめに
ここでは、GUIでストップ狩りを回避するラインを実装します。
前回までの記事を理解しているのが前提です。
【MQL4 : MT4】GUI で 全決済、個別決済 を実装した EA を作る。
作成手順としては、以下の通りです。
- ComboBoxにライン作成Listを追加
- 2本のライン作成処理
- GUIを拡張(横スクロールできる予定)
- ライン情報( pips, 損益, RR )を表示
- 仕掛けに対して、ラインで決済できる処理
- 細かい修正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
- Common/
- Sample/
実行結果
LineOrderを選択し、Pushをすると、2本のラインが表示されます。
Commonフォルダ
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文
エラーメッセージを詳しく表示させるための標準ファイルです。
#include <stderror.mqh>
#include <stdlib.mqh>
2. GetTimes関数
現在時刻を取得するための関数です。
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を表示させる関数です。
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
#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
修正部分の周辺のみ記載します。
~略~
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を追加しました。
m_combCreate.AddItem( "Line Order", 2 );
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を呼び出します。
引数には、水平ラインの名前が被らない様に、現在時刻を入れてます。
if( !LineOrder.lineOrder( CMD.GetTimes() ) )
CMD.Error( "LineOrder" );
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関数を使って、水平ラインを作成しています。
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
チャンネル登録お願いします
Twitterでは毎日呟いています。
https://twitter.com/IceSeed_bz
フォローお願いします
お疲れ様。