【超入門】MQL5 EA講座 第91回「待機注文を削除する関数を実装する」

MQL5でEA作ろう講座


前回は、待機注文を修正するメンバ関数ChangePending関数」をOriginalCTradeクラスに追加する模様を解説しました。

今回は、待機注文を削除する関数を実装していきます。

スポンサーリンク
スポンサーリンク

待機注文を削除する関数「DeletePending」を宣言する

例によって、まずはOriginalCTradeクラスにまずはメンバ関数を宣言します。

関数名は「DeletePending」とします。

EA(自動売買プログラム)のメインプログラムで呼び出す事を目的としているので、アクセスレベルpublicになります。

publicセクションであればどこでも良いのですが、前回作ったChangePending関数の下あたりに、宣言を行います。

//待機注文を修正する
  bool ChangePending(ulong parTicket, double parPrice, double parStop, double parProfit, datetime parExpiration = 0);
  //待機注文を削除する
  bool DeletePending(ulong parTicket);

クラスアクセスレベルについては↓の記事をご参照ください。

DeletePending関数の仮引数と戻り値について

DeletePending関数引数戻り値は以下の通りです。

  //待機注文を削除する
  bool DeletePending(ulong parTicket);

parTicketには待機注文オーダー番号が記述される想定になっています。

MQL5ではオーダー番号ポジション番号約定番号(ディール番号)という概念が存在します。

それぞれの違いについては各用語のアンカーテキストリンクから該当の記事をご参照ください。

DeletePending関数の処理実装記述について

DeletePending関数の処理実装記述は以下の通りです。

//待機注文を削除する
bool OriginalCTrade::DeletePending(ulong parTicket)
{  //インスタンスのリセット
	ZeroMemory(request);
	ZeroMemory(result);
	
	//各種メンバ変数への値代入
	request.action = TRADE_ACTION_REMOVE;
	request.order = parTicket;
	
	// リトライ回数とリターンコードを格納する変数を宣言
	int retryCount = 0;//再試行回数を格納する
	int checkCode = 0;//リターンコードを格納する
	
	do 
	{  //待機注文の削除注文を出す。
		bool sent = OrderSend(request,result);
		//注文結果を返す
		checkCode = ReturnCodeCheck(result.retcode);
		//約定成功の場合do-whileループを抜ける
		if(checkCode == CHECK_RETCODE_OK) break;
		//再試行しても解決しないエラーの場合
		else if(checkCode == CHECK_RETCODE_ERROR)
		{  //リターンコードを取得
			string errDesc = TradeServerReturnCodeDescription(result.retcode);
			//アラートを発出
			Alert("待機注文削除エラー: エラー内容 ",result.retcode," - ",errDesc);
			//ログの出力
			TradeLog();
			break;//ループを抜ける
		}
		else
		{
			Print("サーバーエラーを検知。 再試行中...");
			//次の処理までの待機
			Sleep(RETRY_MILLISECONDS);
			//再試行回数をカウントする変数をインクリメントする
			retryCount++;
		}
	}
	while(retryCount < RETRY_LIMIT);
	
	if(retryCount >= RETRY_LIMIT)
	{
		string errDesc = TradeServerReturnCodeDescription(result.retcode);
		Alert("再注文上限回数に達しました: エラー内容  ",result.retcode," - ",errDesc);
	}
	
	string errDesc = TradeServerReturnCodeDescription(result.retcode);
	Print("待機注文削除エラー #",parTicket,": ",
	result.retcode," - ",errDesc);
	
	if(checkCode == CHECK_RETCODE_OK) 
	{
		Comment("待機注文 ",parTicket," 削除されました");
		return(true);
	}
	else return(false);
}

講座記事を順番に見ている方には、もはや説明不要の記述が増えてきたかもしれませんが、この記事だけスポット的に見ることもあるかと思うので、例によって順番にコードの記述を見ていきましょう。

処理実装記述その1:-インスタンスのリセット~各種メンバ変数への値代入-

MqlTradeRequest構造体MqlTradeResult構造体インスタンスをリセット~各種メンバ変数への値代入というお決まりの流れです。これまでの講座記事では

第72回「ポジションオープン関数を実装する」第76回「SLとTPを設定する関数をクラスに追加する」第85回「ポジションを決済する関数を作る」第90回「待機注文を修正する関数を実装する」

などでも解説してきた記述です。

//インスタンスのリセット
	ZeroMemory(request);
	ZeroMemory(result);
	
	//各種メンバ変数への値代入
	request.action = TRADE_ACTION_REMOVE;
	request.order = parTicket;

待機注文の削除にあたって必要なMqlTradeRequest構造体メンバ変数は、.action.orderのみです。

新規成行注文、新規待機注文、現有ポジションのSLTP変更、待機注文修正などに比べるとシンプルですね。

取引の種類を設定する.actionには、待機注文を削除する定数TRADE_ACTION_REMOVE代入します。

request.order はオーダー番号を格納するメンバ変数なので、オーダー番号が記述される想定の引数「parTicket」の値を代入します。

インスタンスについては、↓の記事をご参照ください。

処理実装記述その2-リトライ回数とリターンコードを格納する変数を宣言する-

リトライ回数とリターンコードを格納する変数を宣言します。

<参照リンク>

第72回「ポジションオープン関数を実装する」

// リトライ回数とリターンコードを格納する変数を宣言
	int retryCount = 0;//再試行回数を格納する
	int checkCode = 0;//リターンコードを格納する

処理実装記述その3-do-while文の中に発注回路を組み込んでいく-

他の注文関数と同様にdo-while文を使って、待機注文の削除に関する発注回路を記述していきます。

do 
	{  //待機注文の削除注文を出す。
		bool sent = OrderSend(request,result);
		//注文結果を返す
		checkCode = ReturnCodeCheck(result.retcode);
		//約定成功の場合do-whileループを抜ける
		if(checkCode == CHECK_RETCODE_OK) break;
		//再試行しても解決しないエラーの場合
		else if(checkCode == CHECK_RETCODE_ERROR)
		{  //リターンコードを取得
			string errDesc = TradeServerReturnCodeDescription(result.retcode);
			//アラートを発出
			Alert("待機注文削除エラー: エラー内容 ",result.retcode," - ",errDesc);
			//ログの出力
			TradeLog();
			break;//ループを抜ける
		}
		else
		{
			Print("サーバーエラーを検知。 再試行中...");
			//次の処理までの待機
			Sleep(RETRY_MILLISECONDS);
			//再試行回数をカウントする変数をインクリメントする
			retryCount++;
		}
	}
	while(retryCount < RETRY_LIMIT);

OrderSend関数待機注文の削除注文を出す

ReturnCodeCheck関数で注文結果の次を行動を規定する。

「約定が成功した場合」「再試行しても解決しないエラーの場合」「再試行すれば解決する可能性のあるエラーの場合」という3つをif文 else文で条件分岐させ処理を切り分けていきます。

TradeServerReturnCodeDescription関数については→コチラをご覧ください。

ReturnCodeCheck関数戻り値であるデータ型ENUM_CHECK_RETCODE」については→コチラをご覧ください。

do-while構文については、→の記事をご覧ください。第39回「do-while文について」

インクリメントについては↓をご覧ください。

インクリメントとデクリメント(Increment,Decrement)

breakについては→コチラをご覧ください。

Alert関数については→コチラをご覧ください。

処理実装記述その4-再注文試行が上限回数に達した場合の記述-

if(retryCount >= RETRY_LIMIT)
	{
		string errDesc = TradeServerReturnCodeDescription(result.retcode);
		Alert("再注文上限回数に達しました: エラー内容  ",result.retcode," - ",errDesc);
	}

if(retryCount >= RETRY_LIMIT)

という記述は↑再注文試行回数が#define命令で設定した定数RETRY_LIMITの数を上回っている事を意味します。

TradeServerReturnCodeDescription関数リターンコードを獲得後、変数「errDesc」に格納→Alert関数変数に格納された内容を発出します。

処理実装記述その5:結果をPrint関数でログ出力

string errDesc = TradeServerReturnCodeDescription(result.retcode);
	Print("待機注文削除エラー #",parTicket,": ",
	result.retcode," - ",errDesc);

待機注文削除の結果をPrint関数でログ出力します。この処理は、待機注文の削除が成功した場合でも、失敗した場合でも行います。

処理実装記述その6:戻り値を返して終了

if(checkCode == CHECK_RETCODE_OK) 
	{
		Comment("待機注文 ",parTicket," 削除されました");
		return(true);
	}
	else return(false);
}

DeletePending関数戻り値bool型です。待機注文の削除に成功した場合はtrue、失敗した場合はfalseを返すよう設計しています。

returnについては→コチラをご覧ください。

Comment関数については→コチラをご覧ください。

まとめ

今回の記事では、待機注文を削除するメンバ関数DeletePending関数」をOriginalCTradeクラスに追加する模様を解説しました。

※今回の関数はあくまで「待機注文の削除する」為の関数です。いったん待機注文が約定しポジションとして有効化された場合は、この関数を使ってポジションをクローズする事はできません。

ポジションをクローズするする場合は、第85回「ポジションを決済する関数を作る」で作ったClosePosition関数を使います。

DeletePending関数の宣言部分↓は以下の通りです。

  //待機注文を削除する
  bool DeletePending(ulong parTicket);

の処理実装記述部分↓は以下の通りです。

//待機注文を削除する
bool OriginalCTrade::DeletePending(ulong parTicket)
{  //インスタンスのリセット
	ZeroMemory(request);
	ZeroMemory(result);
	
	//各種メンバ変数への値代入
	request.action = TRADE_ACTION_REMOVE;
	request.order = parTicket;
	
	// リトライ回数とリターンコードを格納する変数を宣言
	int retryCount = 0;//再試行回数を格納する
	int checkCode = 0;//リターンコードを格納する
	
	do 
	{  //待機注文の削除注文を出す。
		bool sent = OrderSend(request,result);
		//注文結果を返す
		checkCode = ReturnCodeCheck(result.retcode);
		//約定成功の場合do-whileループを抜ける
		if(checkCode == CHECK_RETCODE_OK) break;
		//再試行しても解決しないエラーの場合
		else if(checkCode == CHECK_RETCODE_ERROR)
		{  //リターンコードを取得
			string errDesc = TradeServerReturnCodeDescription(result.retcode);
			//アラートを発出
			Alert("待機注文削除エラー: エラー内容 ",result.retcode," - ",errDesc);
			//ログの出力
			TradeLog();
			break;//ループを抜ける
		}
		else
		{
			Print("サーバーエラーを検知。 再試行中...");
			//次の処理までの待機
			Sleep(RETRY_MILLISECONDS);
			//再試行回数をカウントする変数をインクリメントする
			retryCount++;
		}
	}
	while(retryCount < RETRY_LIMIT);
	
	if(retryCount >= RETRY_LIMIT)
	{
		string errDesc = TradeServerReturnCodeDescription(result.retcode);
		Alert("再注文上限回数に達しました: エラー内容  ",result.retcode," - ",errDesc);
	}
	
	string errDesc = TradeServerReturnCodeDescription(result.retcode);
	Print("待機注文削除エラー #",parTicket,": ",
	result.retcode," - ",errDesc);
	
	if(checkCode == CHECK_RETCODE_OK) 
	{
		Comment("待機注文 ",parTicket," 削除されました");
		return(true);
	}
	else return(false);
}

今回紹介した現時点(講座記事第91回時点)でのOriginalTrade.mqhファイル全体のコード記述は↓の記事からご確認ください。

講座記事第91回時点でのOriginalTrade.mqhファイル全体のコード記述について

※講座記事第90回時点でのOriginalTrade.mqhファイル全体のコード記述は↓コチラ

講座記事第90回時点でのOriginalTrade.mqhファイル全体のコード記述について

講座記事第87回時点でのOriginalTrade.mqhファイル全体のコード記述は↓コチラ

講座記事第87回時点でのOriginalTrade.mqhファイル全体のコード記述について

第86回第87回第88回第89回第90回、そして今回の第91回の6回にかけて待機注文クラス関数を作ってきました。次回はこれらを利用して待機注文を使ったEA(自動売買プログラム)を作っていきたいと思います。

今回は以上とさせていただきます。

最後までお読みいただきありがとうございました。

【超入門】MQL5 EA講座 第90回「待機注文を修正する関数を実装する」

          →【超入門】MQL5 EA講座 第92回「待機注文クラスを使ってEAを作る」

コメント

タイトルとURLをコピーしました