取引関数の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()で説明しています。
コメント