MT4程序在MT5上运行:通用MT4与MT5指标函数的设计与实现

本文介绍了如何设计通用的MT4和MT5指标,包括指标句柄结构体模板,如MACD、RSI、AC、MA和Stochastic的参数结构,以及如何通过CreateHandleMA和iMACaching/iMAMQL4函数实现在两种平台上的通用指标计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MT4指标与MT5指标的区别

  • MT4指标可以通过输入参数直接返回指标值,而MT5需要生成指标句柄,然后通过句柄获取指标值。
  • MT5指标使用向对MT4指标来说不不便利,但性能更高。
  • MT4的指标与MT5在对方的平台上都无法使用。

设计通用MT4与MT5指标的意义

  • 用户自定义指标,可以同时运行在MT4与MT5上,可开发跨平台技术指标。
  • 用户开发其中一个平台开发的EA程序,指标部分的调用也可同时运行在另一个平台上。
  • 深度理解和学习MT4与MT5的差别和联系,加深对开发的理解。

通用技术指标的实现思想

  • 以MQL4指标函数作为模板,并在指标函数名字后面增加MQL4的后缀,因MQL4的指标访问更便利并兼顾MQL5指标的性能。
  • 由于MT5指标函数在使用前,需要在OnInit函数中进行初始化获取句柄,所以我们需要创建一个保存指标句柄的结构体。
  • 每类MT5指标句柄都保存在指标句柄结构体数组中,同类指标单参数不同,则句柄不同。

指标句柄和参数的结构体模板

  • 结构设置两个变量:m_handle用来保存指标句柄的值,m_inputs用来保存指标的参数,模板设计可兼容所有指标。
  • 重载==运算符用于判断参数是否相对,重载=运算符用于指标参数复制。
  • GetHandle()函数可读取指标的句柄值。
//+------------------------------------------------------------------+
//| 指标句柄结构体模板                                               |
//+------------------------------------------------------------------+
template <typename T>
struct STRUCT_IND_HANDLE
{
    private:
        int     m_handle;   // 指标句柄
        T       m_inputs;   // 指标参数
    public:
        STRUCT_IND_HANDLE() : m_handle(INVALID_HANDLE) { }
        bool    operator==(const T &inputs) const { return (m_inputs == inputs); }
        void    operator=(const T &inputs) {m_inputs=inputs; }
        int     GetHandle() { return((m_handle!=INVALID_HANDLE) ? m_handle : (m_handle=m_inputs.GetHandle())); }
};
//+------------------------------------------------------------------+
//| 获取指标句柄                                                     |
//+------------------------------------------------------------------+
    template<typename T>
int GetHandle(STRUCT_IND_HANDLE<T> &arr_handle[], const T &inputs, bool is_created=false)
{
    const int size = ArraySize(arr_handle);
    //
    for (int i=0; i<size; i++)
    {
        if (arr_handle[i]==inputs) return (arr_handle[i].GetHandle());
    }
    // 创建指标句柄只可以在OnInit函数数,否者出现Stack overflow
    if (is_created)
    {
        ArrayResize(arr_handle, size+1);
        arr_handle[size] = inputs;
        return (arr_handle[size].GetHandle());
    }
    else
        return (INVALID_HANDLE);
}

创建多个指标参数结构体

  • MACD 指标参数结构体
  • RSI 指标参数结构体
  • AC 指标参数结构体
  • MA 指标参数结构体
  • Stochastic 指标参数结构体
//+------------------------------------------------------------------+
//| MACD 指标参数结构体                                              |
//+------------------------------------------------------------------+
struct STRUCT_MACD_PARAMS
{
    private:
        string             m_symbol;
        ENUM_TIMEFRAMES    m_tf;
        int                m_fast_ema_period;
        int                m_slow_ema_period;
        int                m_signal_period;
        ENUM_APPLIED_PRICE m_applied_price;
    public:
        STRUCT_MACD_PARAMS() { }
        //+------------------------------------------------------------------+
        //| A constructor with an initialization list                        |
        //+------------------------------------------------------------------+
        STRUCT_MACD_PARAMS(const string  &symbol,
                const ENUM_TIMEFRAMES    &tf,
                const int                &fast_ema_period,
                const int                &slow_ema_period,
                const int                &signal_period,
                const ENUM_APPLIED_PRICE &applied_price) : m_symbol((symbol==NULL||symbol=="") ? Symbol() : symbol),
            m_tf(tf),
            m_fast_ema_period(fast_ema_period),
            m_slow_ema_period(slow_ema_period),
            m_signal_period(signal_period),
            m_applied_price(applied_price) { }
        //
        int GetHandle(void) const { return (iMACD(m_symbol, m_tf, m_fast_ema_period, m_slow_ema_period, m_signal_period, m_applied_price)); }
        //+------------------------------------------------------------------+
        //| Operation Overloading "=="                                       |
        //+------------------------------------------------------------------+
        bool operator==(const STRUCT_MACD_PARAMS &inputs) const
        {
            return (m_symbol==inputs.m_symbol
                    && m_tf==inputs.m_tf
                    && m_fast_ema_period==inputs.m_fast_ema_period
                    && m_slow_ema_period == inputs.m_slow_ema_period 
                    && m_signal_period == inputs.m_signal_period
                    && m_applied_price==inputs.m_applied_price);
        }
};
//+------------------------------------------------------------------+
//| RSI 指标参数结构体                                               |
//+------------------------------------------------------------------+
struct STRUCT_RSI_PARAMS
{
    private:
        string             m_symbol;
        ENUM_TIMEFRAMES    m_tf;
        int                m_ma_period;
        ENUM_APPLIED_PRICE m_applied_price;
    public:
        STRUCT_RSI_PARAMS() { }
        //+------------------------------------------------------------------+
        //| A constructor with an initialization list                        |
        //+------------------------------------------------------------------+
        STRUCT_RSI_PARAMS(const string  &symbol,
                const ENUM_TIMEFRAMES    &tf,
                const int                &ma_period,
                const ENUM_APPLIED_PRICE &applied_price) : m_symbol((symbol==NULL||symbol=="") ? Symbol() : symbol),
            m_tf(tf),
            m_ma_period(ma_period),
            m_applied_price(applied_price) { }
        //
        int GetHandle(void) const { return (iRSI(m_symbol, m_tf, m_ma_period, m_applied_price)); }
        //+------------------------------------------------------------------+
        //| Operation Overloading "=="                                       |
        //+------------------------------------------------------------------+
        bool operator==(const STRUCT_RSI_PARAMS &inputs) const
        {
            return (m_symbol==inputs.m_symbol
                    && m_tf==inputs.m_tf
                    && m_ma_period==inputs.m_ma_period
                    && m_applied_price==inputs.m_applied_price);
        }
};
//+------------------------------------------------------------------+
//| AC指标结构体参数                                                 |
//+------------------------------------------------------------------+
struct STRUCT_AC_PARAMS
{
    private:
        string             m_symbol;
        ENUM_TIMEFRAMES    m_tf;
    public:
        STRUCT_AC_PARAMS() { }
        //+------------------------------------------------------------------+
        //| A constructor with an initialization list                        |
        //+------------------------------------------------------------------+
        STRUCT_AC_PARAMS(const string &symbol,
                const ENUM_TIMEFRAMES &tf) : m_symbol((symbol==NULL||symbol=="") ? Symbol() : symbol),
            m_tf(tf) { }
        //
        int GetHandle(void) const { return iAC(m_symbol, m_tf); }
        //+------------------------------------------------------------------+
        //| Operation Overloading "=="                                       |
        //+------------------------------------------------------------------+
        bool operator==(const STRUCT_AC_PARAMS &inputs) const
        {
            return (m_symbol==inputs.m_symbol
                    && m_tf==inputs.m_tf);
        }
};
//+------------------------------------------------------------------+
//| MA指标结构体参数                                                 |
//+------------------------------------------------------------------+
struct STRUCT_MA_PARAMS
{
    private:
        string             m_symbol;              // symbol name 
        ENUM_TIMEFRAMES    m_tf;                  // timeframe 
        int                m_ma_period;           // averaging period 
        int                m_ma_shift;            // horizontal shift 
        ENUM_MA_METHOD     m_ma_method;           // smoothing type 
        ENUM_APPLIED_PRICE m_applied_price;       // type of price 
    public:
        STRUCT_MA_PARAMS() { }
        //+------------------------------------------------------------------+
        //| A constructor with an initialization list                        |
        //+------------------------------------------------------------------+
        STRUCT_MA_PARAMS(const string &symbol,
                const ENUM_TIMEFRAMES &tf,
                const int &ma_period,
                const int &ma_shift,
                const ENUM_MA_METHOD &ma_method,
                const ENUM_APPLIED_PRICE &applied_price
                ) : m_symbol((symbol==NULL||symbol=="") ? Symbol() : symbol),
            m_tf(tf),
            m_ma_period(ma_period),
            m_ma_shift(ma_shift),
            m_ma_method(ma_method),
            m_applied_price(applied_price) { }
        //
        int GetHandle(void) const { return iMA(m_symbol, m_tf, m_ma_period, m_ma_shift, m_ma_method, m_applied_price); }
        //+------------------------------------------------------------------+
        //| Operation Overloading "=="                                       |
        //+------------------------------------------------------------------+
        bool operator==(const STRUCT_MA_PARAMS &inputs) const
        {
            return (m_symbol==inputs.m_symbol
                    && m_tf==inputs.m_tf
                    && m_ma_period==inputs.m_ma_period
                    && m_ma_shift==inputs.m_ma_shift
                    && m_ma_method==inputs.m_ma_method
                    && m_applied_price==inputs.m_applied_price);
        }
};
//+------------------------------------------------------------------+
//| Struct Stochastic                                                |
//+------------------------------------------------------------------+
struct STRUCT_STOCH_PARAMS
{
    private:
        string             m_symbol;              // 交易品种名称  
        ENUM_TIMEFRAMES    m_tf;                  // K线时间框架
        int                m_Kperiod;             // K线周期 (用于计算的柱数) 
        int                m_Dperiod;             // D线周期 (开始平滑周期) 
        int                m_slowing;             // 最终平滑 
        ENUM_MA_METHOD     m_ma_method;           // 平滑类型 
        ENUM_STO_PRICE     m_price_field;         // 随机计算法 
    public:
        STRUCT_STOCH_PARAMS() { }
        //+------------------------------------------------------------------+
        //| A constructor with an initialization list                        |
        //+------------------------------------------------------------------+
        STRUCT_STOCH_PARAMS(const string &symbol,
                const ENUM_TIMEFRAMES &tf,
                const int &Kperiod,
                const int &Dperiod,
                const int &slowing,
                const ENUM_MA_METHOD &ma_method,
                const ENUM_STO_PRICE &price_field
                ) : m_symbol((symbol==NULL||symbol=="") ? Symbol() : symbol),
            m_tf(tf),
            m_Kperiod(Kperiod),
            m_Dperiod(Dperiod),
            m_slowing(slowing),
            m_ma_method(ma_method),
            m_price_field(price_field) { }
        //
        int GetHandle(void) const { return ::iStochastic(m_symbol, m_tf, m_Kperiod, m_Dperiod, m_slowing, m_ma_method, m_price_field); }
        //+------------------------------------------------------------------+
        //| Operation Overloading "=="                                       |
        //+------------------------------------------------------------------+
        bool operator==(const STRUCT_STOCH_PARAMS &inputs) const
        {
            return (m_symbol==inputs.m_symbol
                    && m_tf==inputs.m_tf
                    && m_Kperiod==inputs.m_Kperiod
                    && m_Dperiod==inputs.m_Dperiod
                    && m_slowing==inputs.m_slowing
                    && m_ma_method==inputs.m_ma_method
                    && m_price_field==inputs.m_price_field);
        }
};

创建通用的MT4与MT5指标方法

  • 以iMA指标为例:创建三个函数如下:
  • CreateHandleMA 用来创建指标句柄,并保存在句柄数组中,相同参数的指标只创建一次。
  • iMACaching 包装MT5的iMA指标,参数中不需要传入句柄。
  • iMAMQL4 以MQL4的指标为原型,可同时运行在MT4上和MT5上,实现通用指标。

创建通用的MT4与MT5指标的代码实现,以MA为例,其他指标类似

// 通用MT4与MT5的 iMA指标
//bool   CreateHandleMA(string symbol, ENUM_TIMEFRAMES tf, int ma_period, int ma_shift, ENUM_MA_METHOD ma_method, ENUM_APPLIED_PRICE applied_price);
//double iMACaching(string symbol, ENUM_TIMEFRAMES tf, int ma_period, int ma_shift, ENUM_MA_METHOD ma_method, ENUM_APPLIED_PRICE applied_price, int shift)
//double iMAMQL4(string symbol, int tf, int ma_period, int ma_shift, int method, int price, int shift);

// MA 指标句柄数组,在MT5中保存所有MA指标函数的句柄,参数不同句柄不同
STRUCT_IND_HANDLE<STRUCT_MA_PARAMS> g_HANDLES_MA[];
//+------------------------------------------------------------------+
//| 创建MA指标句柄                                                  |
//+------------------------------------------------------------------+
bool CreateHandleMA(string symbol, ENUM_TIMEFRAMES tf, int ma_period, int ma_shift, ENUM_MA_METHOD ma_method, ENUM_APPLIED_PRICE applied_price)
{
    //---
    const STRUCT_MA_PARAMS Inputs(symbol,tf,ma_period,ma_shift,ma_method,applied_price);
    int handle = GetHandle(g_HANDLES_MA, Inputs, true);
    //
    if (handle == INVALID_HANDLE)
    {
        Print(__FUNCTION__,": Invalid Handle error=",GetLastError());
        return (false);
    }
    else
        return (true);
}
//+------------------------------------------------------------------+
//| iMA function in MQL4 notation                                    |
//+------------------------------------------------------------------+
double iMACaching(string symbol, ENUM_TIMEFRAMES tf, int ma_period, int ma_shift, ENUM_MA_METHOD ma_method, ENUM_APPLIED_PRICE applied_price, int shift)
{
    double result=NaN;
    //
    const STRUCT_MA_PARAMS Inputs(symbol, tf, ma_period, ma_shift, ma_method, applied_price);
    int handle = GetHandle(g_HANDLES_MA, Inputs, false);
    //---
    if (handle == INVALID_HANDLE)
    {
        Print(__FUNCTION__,": Invalid handle error=",GetLastError());
        return (result);
    }
    double val[1];
    int copied = CopyBuffer(handle, 0, shift, 1, val);
    if (copied > 0)
        result = val[0];
    else
        Print(__FUNCTION__, ": CopyBuffer error=", GetLastError());
    return (result);
}
// iMA 计算移动平均线指标并返回其值
// 通用 MA 指标,在MT4与MT5下皆可运行
double iMAMQL4(string symbol, int tf, int ma_period, int ma_shift, int method, int price, int shift) export
{
#ifdef __MQL5__
    ENUM_TIMEFRAMES timeframe = TFMigrate(tf);
    ENUM_MA_METHOD ma_method = MethodMigrate(method);
    ENUM_APPLIED_PRICE applied_price = PriceMigrate(price);
    return iMACaching(symbol, timeframe, ma_period, ma_shift, ma_method, applied_price, shift);
#else
    return iMA(symbol, tf, ma_period, ma_shift, method, price, shift);
#endif
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迈达量化

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值