MQL5均线交叉EA优化:提升EA交易效率
MQL5均线交叉EA代码优化
本文将对您提供的MQL5均线交叉EA代码进行优化,以提升其交易效率。
优化建议
-
减少重复计算: 在OnTick函数中,获取均线值的代码被重复调用了两次。建议将其提取到函数外部,在OnInit函数中进行计算,然后在OnTick函数中直接使用这些值。
-
减少循环次数: 在检查当前是否有持仓的循环中,可以使用m_position.SelectByTicket函数直接选择指定的持仓,而不是遍历所有持仓。
-
减少函数调用: 在RefreshRates函数中,可以直接使用m_symbol.Ask()和m_symbol.Bid()刷新行情数据,而不需要调用m_symbol.RefreshRates()函数。
-
减少不必要的返回语句: 在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]);}//+-----------------------------------------------------------------
原文地址: https://www.cveoy.top/t/topic/lao7 著作权归作者所有。请勿转载和采集!