ホーム » ソース共通化 » 取引関数 » OrderSend() – 取引関数

OrderSend() – 取引関数

取引関数

取引関数OrderSend()について、MQL4とMQL5のソースコード共通化する方法を説明しています。

関数定義

MQL4の定義

int  OrderSend( 
   string   symbol,              // symbol 
   int      cmd,                 // operation 
   double   volume,              // volume 
   double   price,               // price 
   int      slippage,            // slippage 
   double   stoploss,            // stop loss 
   double   takeprofit,          // take profit 
   string   comment=NULL,        // comment 
   int      magic=0,             // magic number 
   datetime expiration=0,        // pending order expiration 
   color    arrow_color=clrNONE  // color 
   );

MQL5の定義

bool  OrderSend( 
   MqlTradeRequest&  request,      // 問の構造体 
   MqlTradeResult&   result        // 答えの構造体 
  );

EAでは使用頻度が高い関数ですが、MQL5では取引関数の仕様は大きく変更されてOrderSend()の引数が大幅に変更されています。
その為、MQL5でMQL4の関数を使えるように定義をすることで対応します。

共通化方法

ソース共通化

対処方法

共通化するためにMQL4の関数をMQL5で使えるように定義をします。
#ifdef __MQL5__ ~ #endifを使用することでMQL5のコンパイルにのみ有効となります。
MQL4の場合は「__MQL4__」を使用しますが、今回使用していないためMQL4は既存で組み込まれた定義済み変数が利用されます。
後述する使用例でポジションの決済を行うので、OrderClose()についても定義しています。

#ifdef __MQL5__
#define OP_BUY				((int)0)
#define OP_SELL				((int)1)
#define OP_BUYLIMIT			((int)2)
#define OP_SELLLIMIT		((int)3)
#define OP_BUYSTOP			((int)4)
#define OP_SELLSTOP			((int)5)

///////////////////////////////////////////////////////////////////////////////
// 約定ポジションをクローズする
bool OrderClose(int iTicket, double dLots, double dPrice, int iSlippage, color arrow_color = clrNONE)
{
	bool bResult = false;
	bResult = PositionSelectByTicket(iTicket);
	if (bResult) {
		MqlTradeRequest mqlRequest = {};
		MqlTradeResult mqlResult = {};
		ZeroMemory(mqlResult);
		ZeroMemory(mqlResult);
		mqlRequest.action		= TRADE_ACTION_DEAL;						// 取引操作タイプ
		mqlRequest.position		= iTicket;									// ポジションチケット
		mqlRequest.symbol		= PositionGetString(POSITION_SYMBOL);		// シンボル
		mqlRequest.volume		= dLots;									// ポジションボリューム
		mqlRequest.deviation	= iSlippage;								// 価格からの許容偏差
		mqlRequest.type			= (ENUM_ORDER_TYPE)PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY ? ORDER_TYPE_SELL : ORDER_TYPE_BUY;		// ポジションのType
		mqlRequest.magic		= 0;										// ポジションのMagicNumber
		long lMode = SymbolInfoInteger(mqlRequest.symbol, SYMBOL_FILLING_MODE);
		mqlRequest.type_filling	= SYMBOL_FILLING_IOC == lMode ? ORDER_FILLING_IOC : ORDER_FILLING_FOK;
		if (OrderSend(mqlRequest, mqlResult)) {
			bResult = true;
		} else {
			bResult = false;
		}
	}
	return bResult;
}
///////////////////////////////////////////////////////////////////////////////
// MQL5のオーダータイプに変換する
ENUM_ORDER_TYPE GetOrderType(int iOrderType)
{
	ENUM_ORDER_TYPE OrderTypeTbl [] = {
		ORDER_TYPE_BUY,
		ORDER_TYPE_SELL,
		ORDER_TYPE_BUY_LIMIT,
		ORDER_TYPE_SELL_LIMIT,
		ORDER_TYPE_BUY_STOP,
		ORDER_TYPE_SELL_STOP,
		ORDER_TYPE_BUY_STOP_LIMIT,
		ORDER_TYPE_SELL_STOP_LIMIT,
		ORDER_TYPE_CLOSE_BY,
	};
	return OrderTypeTbl[iOrderType];
}
///////////////////////////////////////////////////////////////////////////////
// オーダーによりポジションをオープンする
int OrderSend(string strSymbol, int iOrderType, double dLots, double dPrice, int iSlippage, 
				double dSL, double dTP, string strComment, int iMagicNumber, datetime dtExpiration, color clOrder)
{
	int iResult = -1;
	MqlTradeRequest mqlRequest = {};
	MqlTradeResult mqlResult = {};
	ZeroMemory(mqlRequest);
	ZeroMemory(mqlResult);
	if (OP_BUY == iOrderType || OP_SELL == iOrderType) {
		mqlRequest.action	= TRADE_ACTION_DEAL;
	} else {
		mqlRequest.action	= TRADE_ACTION_PENDING;
	}
	mqlRequest.symbol		= strSymbol;
	mqlRequest.volume		= dLots;
	mqlRequest.type			= GetOrderType(iOrderType);
	mqlRequest.price		= dPrice;
	mqlRequest.sl			= NormalizeDouble(dSL, (int)SymbolInfoInteger(strSymbol, SYMBOL_DIGITS));
	mqlRequest.tp			= NormalizeDouble(dTP, (int)SymbolInfoInteger(strSymbol, SYMBOL_DIGITS));
	mqlRequest.price		= dPrice;
	mqlRequest.deviation	= iSlippage;
	mqlRequest.magic		= iMagicNumber;
	mqlRequest.comment		= strComment;
	long lMode = SymbolInfoInteger(strSymbol, SYMBOL_FILLING_MODE);
	mqlRequest.type_filling	= SYMBOL_FILLING_IOC == lMode ? ORDER_FILLING_IOC : ORDER_FILLING_FOK;
	bool bResult =  OrderSend(mqlRequest, mqlResult);
	if (bResult) {
		iResult = (int)mqlResult.order;
	} else {
	    iResult = -1;
	}
	return iResult;
}
#endif

OrderSend()の引数が、INPUTとOUTPUT(結果)の構造体を2つ指定するだけになっています。
MQL4形式のOrderSend()で指定された引数を、MQL5形式のOrderSend()の引数形式に設定して呼出しを行います。
予約注文についても、actionメンバへの設定値を変えることで動作を変更しています。

使用例

OrderClose()で説明しています。

コメント

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