目次

, ,

MQL5 標準ライブラリのラッパークラスを作ろう 4 (CTrade 編)

前回までの記事は以下を参照。

今回は最終回。CTrade のラッパークラス。
ここまでつくれば EA が売買処理を行うのに必要最低限の機能は揃う。

ラップしたメソッド

ラッパークラス ClTradeHelper 完成!

MQL5 版のコードはこれまでと同様に CTrade の対応メソッドを呼び出しているだけである。
MQL4 版のコードはすべて独自実装している。

コード

クリックするとコードが開きます

TradeInfoHelper.mqh
//+------------------------------------------------------------------+
//|                                                  TradeHelper.mqh |
//+------------------------------------------------------------------+
#ifndef _TRADEHELPER_MQH_
#define _TRADEHELPER_MQH_
 
//+------------------------------------------------------------------+
//| インクルード                                                     |
//+------------------------------------------------------------------+
#ifdef _MQL4
#include <Object.mqh>
 
#else  // _MQL4
#include <Trade\Trade.mqh>
 
#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);
}
// (以下、略)