{{tag>mql5 mql4 ctrade}}
====== MQL5 標準ライブラリのラッパークラスを作ろう 4 (CTrade 編) ======
前回までの記事は以下を参照。
* [[:metatrader:mql:csymbolinfo_wrapper|]]
* [[:metatrader:mql:caccountinfo_wrapper|]]
* [[:metatrader:mql:cpositioninfo_wrapper|]]
今回は最終回。[[https://www.mql5.com/ja/docs/standardlibrary/tradeclasses/ctrade|CTrade]] のラッパークラス。\\
ここまでつくれば EA が売買処理を行うのに必要最低限の機能は揃う。
===== ラップしたメソッド =====
* SetExpertMagicNumber
* SetDeviationInPoints
* SetMarginMode
* PositionOpen
* PositionClose
===== ラッパークラス ClTradeHelper 完成! =====
MQL5 版のコードはこれまでと同様に ''CTrade'' の対応メソッドを呼び出しているだけである。\\
MQL4 版のコードはすべて独自実装している。\\
=== コード ===
//+------------------------------------------------------------------+
//| TradeHelper.mqh |
//+------------------------------------------------------------------+
#ifndef _TRADEHELPER_MQH_
#define _TRADEHELPER_MQH_
//+------------------------------------------------------------------+
//| インクルード |
//+------------------------------------------------------------------+
#ifdef _MQL4
#include
#else // _MQL4
#include
#endif // _MQL4
//+------------------------------------------------------------------+
//| マクロ |
//+------------------------------------------------------------------+
#define LOG_ERROR(msg) PrintFormat("[ERROR] (@%s %s() line:%d): %s", __FILE__, __FUNCTION__, __LINE__, msg)
//+------------------------------------------------------------------+
//| ClTradeHelperクラス |
//+------------------------------------------------------------------+
class ClTradeHelper : public CObject
{
public:
ClTradeHelper(void);
virtual ~ClTradeHelper(void);
void SetExpertMagicNumber(const ulong magic);
void SetDeviationInPoints(const ulong deviation);
void SetMarginMode(void);
bool PositionOpen(const string symbol, const ENUM_ORDER_TYPE order_type, const double volume,
const double price, const double sl, const double tp, const string comment = "");
bool PositionClose(const ulong ticket, const ulong deviation = ULONG_MAX);
protected:
#ifdef _MQL4
ulong l_magic; // マジックナンバー
ulong l_deviation; // 許容スリッページ
#else // _MQL4
CTrade l_Trade; // シンボル情報
#endif // _MQL4
};
//+------------------------------------------------------------------+
//| コンストラクター |
//+------------------------------------------------------------------+
ClTradeHelper::ClTradeHelper(void)
{
#ifdef _MQL4
l_magic = 0;
l_deviation = 10;
#else
#endif
}
//+------------------------------------------------------------------+
//| デストラクター |
//+------------------------------------------------------------------+
ClTradeHelper::~ClTradeHelper(void)
{
}
//+------------------------------------------------------------------+
//| マジックナンバーの設定 |
//+------------------------------------------------------------------+
void ClTradeHelper::SetExpertMagicNumber(const ulong magic)
{
#ifdef _MQL4
l_magic = magic;
#else
l_Trade.SetExpertMagicNumber(magic);
#endif
}
//+------------------------------------------------------------------+
//| 許容スリッページの設定 |
//+------------------------------------------------------------------+
void ClTradeHelper::SetDeviationInPoints(const ulong deviation)
{
#ifdef _MQL4
l_deviation = deviation;
#else
l_Trade.SetDeviationInPoints(deviation);
#endif
}
//+------------------------------------------------------------------+
//| マージンモードの設定 |
//+------------------------------------------------------------------+
void ClTradeHelper::SetMarginMode(void)
{
#ifdef _MQL4
// no op
#else
l_Trade.SetMarginMode();
#endif
}
//+------------------------------------------------------------------+
//| 成り行き注文(新規) |
//+------------------------------------------------------------------+
bool ClTradeHelper::PositionOpen(const string symbol, const ENUM_ORDER_TYPE order_type, const double volume,
const double price, const double sl, const double tp, const string comment/*=""*/)
{
#ifdef _MQL4
int ticket = -1;
int error = 0;
if(order_type == ORDER_TYPE_BUY || order_type == ORDER_TYPE_BUY_LIMIT || order_type == ORDER_TYPE_BUY_STOP)
{
ResetLastError();
ticket = OrderSend(symbol, order_type, volume, price, (int)l_deviation, sl, tp, comment, (int)l_magic, 0, Red);
if(ticket == -1)
{
error = GetLastError();
LOG_ERROR(StringFormat("Error OrderSend(); ErrorCode=%d;", error));
return(false);
}
return(true);
}
else if(order_type == ORDER_TYPE_SELL || order_type == ORDER_TYPE_SELL_LIMIT || order_type == ORDER_TYPE_SELL_STOP)
{
ResetLastError();
ticket = OrderSend(symbol, order_type, volume, price, (int)l_deviation, sl, tp, comment, (int)l_magic, 0, Blue);
if(ticket == -1)
{
error = GetLastError();
LOG_ERROR(StringFormat("Error OrderSend(); ErrorCode=%d;", error));
return(false);
}
return(true);
}
else
{
LOG_ERROR("Error unknown trade operation.");
return(false);
}
#else
return(l_Trade.PositionOpen(symbol, order_type, volume, price, sl, tp, comment));
#endif
}
//+------------------------------------------------------------------+
//| 成り行き注文(決済) |
//+------------------------------------------------------------------+
bool ClTradeHelper::PositionClose(const ulong ticket, const ulong deviation/*=ULONG_MAX*/)
{
#ifdef _MQL4
int slippage = deviation == ULONG_MAX ? (int)l_deviation : (int)deviation;
int error = 0;
ResetLastError();
if(!OrderSelect((int)ticket, SELECT_BY_TICKET))
{
error = GetLastError();
LOG_ERROR(StringFormat("Error OrderSelect(); ErrorCode=%d;", error));
return(false);
}
ResetLastError();
bool result = OrderClose((int)ticket, OrderLots(), OrderClosePrice(), slippage, Yellow);
if(result)
{
return(true);
}
else
{
error = GetLastError();
LOG_ERROR(StringFormat("Error OrderClose(); ErrorCode=%d;", error));
return(false);
}
#else
return(l_Trade.PositionClose(ticket, deviation));
#endif
}
#endif // _TRADEHELPER_MQH_
//+------------------------------------------------------------------+
=== 使用例 ===
MQL4 のソースをビルドするときはソースに #define _MQL4 を定義することに留意する。
//+------------------------------------------------------------------+
//| Sample.mq4 |
//+------------------------------------------------------------------+
#property strict
#property copyright ""
#property version "1.0"
// MQL4用ソースを使用
#define _MQL4
// インクルード
#include "SymbolInfoHelper.mqh"
#include "TradeInfoHelper.mqh"
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
ClSymbolInfoHelper symbolInfo;
if(!symbolInfo.Name(Symbol()))
{
Print("Error initializing symbol.");
return(INIT_FAILED);
}
if(!symbolInfo.RefreshRates())
{
Print("Error initializing symbol.");
return(INIT_FAILED);
}
int magic = 1234;
ulong slippage = 10;
ClTradeHelper tradeHelper;
tradeHelper.SetExpertMagicNumber(magic); // マジックナンバー
tradeHelper.SetDeviationInPoints(slippage); // 許容スリッページ
tradeHelper.SetMarginMode();
if(tradeHelper.PositionOpen(symbolInfo.Name(), ORDER_TYPE_BUY, 0.10, symbolInfo.Ask(), 0, 0, ""))
{
Print("成り行き買い成功");
}
else
{
Print("成り行き買い失敗");
}
return(INIT_SUCCEEDED);
}
// (以下、略)