MQL5均线交叉EA代码优化

本文将对您提供的MQL5均线交叉EA代码进行优化,以提升其交易效率。

优化建议

  1. 减少重复计算: 在OnTick函数中,获取均线值的代码被重复调用了两次。建议将其提取到函数外部,在OnInit函数中进行计算,然后在OnTick函数中直接使用这些值。

  2. 减少循环次数: 在检查当前是否有持仓的循环中,可以使用m_position.SelectByTicket函数直接选择指定的持仓,而不是遍历所有持仓。

  3. 减少函数调用: 在RefreshRates函数中,可以直接使用m_symbol.Ask()和m_symbol.Bid()刷新行情数据,而不需要调用m_symbol.RefreshRates()函数。

  4. 减少不必要的返回语句: 在OnTick函数中,可以将买入和卖出的交易操作放在同一个if-else语句中,避免使用多个return语句。

优化后的代码cpp//+------------------------------------------------------------------+//| MovingAverageCrossoverEA.mq5 |//| Created by ChatGPT |//+------------------------------------------------------------------+#property copyright 'Created by ChatGPT'#property link 'https://www.example.com'#property version '1.000'//---#include <Trade\PositionInfo.mqh>#include <Trade\Trade.mqh>#include <Trade\SymbolInfo.mqh> CPositionInfo m_position; // trade position objectCTrade m_trade; // trading objectCSymbolInfo m_symbol; // symbol info object//--- input parametersinput double Lots = 2; // 交易手数input int FastMA = 10; // 快速均线周期input int SlowMA = 30; // 慢速均线周期input ulong m_magic=42828093; // 魔术数字ulong m_slippage=10; // 滑点//---int handle_fastMA; // 快速均线指标句柄int handle_slowMA; // 慢速均线指标句柄double fastMA; // 快速均线值double slowMA; // 慢速均线值

//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+int OnInit(){ //--- if(!m_symbol.Name(Symbol())) // 设置交易品种名称 return(INIT_FAILED); RefreshRates();

string err_text='';    if(!CheckVolumeValue(Lots,err_text))    {        Print(err_text);        return(INIT_PARAMETERS_INCORRECT);    }

//---    m_trade.SetExpertMagicNumber(m_magic);

if(IsFillingTypeAllowed(SYMBOL_FILLING_FOK))        m_trade.SetTypeFilling(ORDER_FILLING_FOK);    else if(IsFillingTypeAllowed(SYMBOL_FILLING_IOC))        m_trade.SetTypeFilling(ORDER_FILLING_IOC);    else        m_trade.SetTypeFilling(ORDER_FILLING_RETURN);

m_trade.SetDeviationInPoints(m_slippage);

//--- 创建快速均线指标句柄    handle_fastMA = iMA(m_symbol.Name(), Period(), FastMA, 0, MODE_SMA, PRICE_CLOSE);    //--- 创建慢速均线指标句柄    handle_slowMA = iMA(m_symbol.Name(), Period(), SlowMA, 0, MODE_SMA, PRICE_CLOSE);

//--- 检查指标句柄是否创建成功    if(handle_fastMA == INVALID_HANDLE || handle_slowMA == INVALID_HANDLE)    {        Print('Failed to create moving average indicators for the symbol ', m_symbol.Name());        return(INIT_FAILED);    }

//--- 获取均线值    fastMA = iMA(m_symbol.Name(), Period(), FastMA, 0, MODE_SMA, PRICE_CLOSE);    slowMA = iMA(m_symbol.Name(), Period(), SlowMA, 0, MODE_SMA, PRICE_CLOSE);

return(INIT_SUCCEEDED);}//+------------------------------------------------------------------+//|  Expert deinitialization function                                |//+------------------------------------------------------------------+void OnDeinit(const int reason){    //---}//+------------------------------------------------------------------+//|  Expert tick function                                            |//+------------------------------------------------------------------+void OnTick(){    //--- 仅在新K线生成时进行交易    static datetime PrevBars=0;    datetime time_0=iTime(0);    if(time_0==PrevBars)        return;    PrevBars=time_0;

//--- 更新均线值    fastMA = iMA(m_symbol.Name(), Period(), FastMA, 0, MODE_SMA, PRICE_CLOSE);    slowMA = iMA(m_symbol.Name(), Period(), SlowMA, 0, MODE_SMA, PRICE_CLOSE);  

//--- 检查当前是否有持仓    if(m_position.SelectByTicket(m_trade.PositionGetTicket(0)))    {        if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==m_magic)        {            if((m_position.PositionType()==POSITION_TYPE_BUY && fastMA < slowMA) ||               (m_position.PositionType()==POSITION_TYPE_SELL && fastMA > slowMA))            {                //--- 平仓                m_trade.PositionClose(m_position.Ticket());            }        }    }    else     {        //--- 无持仓,根据均线交叉进行交易        if(fastMA > slowMA)        {            //--- 买入            m_trade.Buy(Lots, m_symbol.Name());        }        else if(fastMA < slowMA)        {            //--- 卖出            m_trade.Sell(Lots, m_symbol.Name());        }    }}//+------------------------------------------------------------------+//|  刷新交易品种行情数据                                           |//+------------------------------------------------------------------+bool RefreshRates(void){    //--- 刷新行情数据    if(m_symbol.Ask()==0 || m_symbol.Bid()==0)    {        Print('RefreshRates error');        return(false);    }

return(true);}//+------------------------------------------------------------------+//|  检查交易手数的正确性                                           |//+------------------------------------------------------------------+bool CheckVolumeValue(double volume, string &error_description){    //--- 最小允许交易手数    double min_volume = m_symbol.LotsMin();    if(volume < min_volume)    {        error_description = StringFormat('Volume is less than the minimal allowed SYMBOL_VOLUME_MIN=%.2f', min_volume);        return(false);    }

//--- 最大允许交易手数    double max_volume = m_symbol.LotsMax();    if(volume > max_volume)    {        error_description = StringFormat('Volume is greater than the maximal allowed SYMBOL_VOLUME_MAX=%.2f', max_volume);        return(false);    }

//--- 获取交易手数变动的最小步长    double volume_step = m_symbol.LotsStep();    int ratio = (int)MathRound(volume / volume_step);    if(MathAbs(ratio * volume_step - volume) > 0.0000001)    {        error_description = StringFormat('Volume is not a multiple of the minimal step SYMBOL_VOLUME_STEP=%.2f, the closest correct volume is %.2f',                                     volume_step,ratio * volume_step);        return(false);    }    error_description = 'Correct volume value';    return(true);}//+------------------------------------------------------------------+ //|  检查指定的成交模式是否允许                                     | //+------------------------------------------------------------------+ bool IsFillingTypeAllowed(int fill_type){    int filling = m_symbol.TradeFillFlags();    return((filling & fill_type) == fill_type);}//+------------------------------------------------------------------+ //|  获取指定柱子的时间                                              | //+------------------------------------------------------------------+ datetime iTime(const int index, string symbol=NULL, ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT){    if(symbol == NULL)        symbol = m_symbol.Name();    if(timeframe == 0)        timeframe = Period();    datetime Time[1];    datetime time = 0;    int copied = CopyTime(symbol, timeframe, index, 1, Time);    if(copied > 0)        time = Time[0];    return(time);}//+------------------------------------------------------------------+//|  获取iMA指标缓冲区的值                                           |//|  缓冲区编号如下:                                                |//|   0 - MAIN_LINE, 1 - SIGNAL_LINE                                 |//+------------------------------------------------------------------+double iMAGet(const int buffer, const int index){    double MA[1];    if(CopyBuffer(handle_fastMA, buffer, index, 1, MA) < 0)    {        Print('Failed to copy data from the moving average indicator');        return(0.0);    }    return(MA[0]);}//+-----------------------------------------------------------------
MQL5均线交叉EA优化:提升EA交易效率

原文地址: https://www.cveoy.top/t/topic/lao7 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录