"//+------------------------------------------------------------------+\n//| MACD_EA.mq5 |\n//| Copyright © |\n//+------------------------------------------------------------------+\n#property copyright ""\n#property link ""\n#property version "1.00"\n//---\n#include <Trade\PositionInfo.mqh>\n#include <Trade\Trade.mqh>\n#include <Trade\SymbolInfo.mqh> \nCPositionInfo m_position; // trade position object\nCTrade m_trade; // trading object\nCSymbolInfo m_symbol; // symbol info object\n//--- input parameters\ninput double Lots = 2; // 交易手数\ninput uchar DF = 1; // 快线周期增量\ninput uchar DS = 2; // 慢线周期增量\ninput uchar SignalPeriod= 10; // 信号线周期\ninput ulong m_magic=42828093; // 魔术数字\nulong m_slippage=10; // 滑点\n//---\nint handle_iMACD; // iMACD指标句柄\n//+------------------------------------------------------------------+\n//| 专家初始化函数 |\n//+------------------------------------------------------------------+\nint OnInit()\n {\n//---\n if(!m_symbol.Name(Symbol())) // 设置品种名称\n return(INIT_FAILED);\n RefreshRates();\n\n string err_text="";\n if(!CheckVolumeValue(Lots,err_text))\n {\n Print(err_text);\n return(INIT_PARAMETERS_INCORRECT);\n }\n//---\n m_trade.SetExpertMagicNumber(m_magic);\n//---\n if(IsFillingTypeAllowed(SYMBOL_FILLING_FOK))\n m_trade.SetTypeFilling(ORDER_FILLING_FOK);\n else if(IsFillingTypeAllowed(SYMBOL_FILLING_IOC))\n m_trade.SetTypeFilling(ORDER_FILLING_IOC);\n else\n m_trade.SetTypeFilling(ORDER_FILLING_RETURN);\n//---\n m_trade.SetDeviationInPoints(m_slippage);\n//--- 创建iMACD指标句柄\n handle_iMACD=iMACD(m_symbol.Name(),Period(),SignalPeriod+DF,SignalPeriod+DS+DF,SignalPeriod,PRICE_CLOSE);\n//--- 如果句柄创建失败 \n if(handle_iMACD==INVALID_HANDLE)\n {\n //--- 输出错误代码\n PrintFormat("Failed to create handle of the iMACD indicator for the symbol %s/%s, error code %d",\n m_symbol.Name(),\n EnumToString(Period()),\n GetLastError());\n //--- 早期停止指标计算\n return(INIT_FAILED);\n }\n//---\n return(INIT_SUCCEEDED);\n }\n//+------------------------------------------------------------------+\n//| 专家去初始化函数 |\n//+------------------------------------------------------------------+\nvoid OnDeinit(const int reason)\n {\n//---\n\n }\n//+------------------------------------------------------------------+\n//| 专家每tick执行函数 |\n//+------------------------------------------------------------------+\nvoid OnTick()\n {\n//--- 仅在新bar生成时执行\n static datetime PrevBars=0;\n datetime time_0=iTime(0);\n if(time_0==PrevBars)\n return;\n PrevBars=time_0;\n//--- MACD主线值\n double main=iMACDGet(MAIN_LINE,0);\n//--- MACD信号线值\n double signal=iMACDGet(SIGNAL_LINE,0);\n//--- 开仓\n for(int i=PositionsTotal()-1;i>=0;i--)\n if(m_position.SelectByIndex(i)) // 选择该仓位\n if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==m_magic)\n {\n if(m_position.PositionType()==POSITION_TYPE_BUY && main<0) // 如果是买入仓位且出现卖出信号\n {\n //--- 平仓\n m_trade.PositionClose(m_position.Ticket());\n return;\n }\n else if(m_position.PositionType()==POSITION_TYPE_SELL && main>0) // 如果是卖出仓位且出现买入信号\n {\n //--- 平仓\n m_trade.PositionClose(m_position.Ticket());\n return;\n }\n //--- 已存在该品种的仓位,不再开仓\n return;\n }\n//--- 如果两条线同方向,则开仓\n if((mainsignal)>0)\n {\n //--- 买入信号\n if(main>0)\n {\n //--- 开多仓\n if(main>signal)\n m_trade.Buy(Lots,m_symbol.Name());\n return;\n }\n else\n {\n //--- 开空仓\n if(main<signal)\n m_trade.Sell(Lots,m_symbol.Name());\n return;\n }\n }\n }\n//+------------------------------------------------------------------+\n//| 刷新品种报价数据 |\n//+------------------------------------------------------------------+\nbool RefreshRates(void)\n {\n//--- 刷新报价\n if(!m_symbol.RefreshRates())\n {\n Print("RefreshRates error");\n return(false);\n }\n//--- 保护返回值不为0\n if(m_symbol.Ask()==0 || m_symbol.Bid()==0)\n return(false);\n//---\n return(true);\n }\n//+------------------------------------------------------------------+\n//| 检查交易手数值是否正确 |\n//+------------------------------------------------------------------+\nbool CheckVolumeValue(double volume,string &error_description)\n {\n//--- 交易操作的最小允许手数\n double min_volume=m_symbol.LotsMin();\n if(volume<min_volume)\n {\n error_description=StringFormat("Volume is less than the minimal allowed SYMBOL_VOLUME_MIN=%.2f",min_volume);\n return(false);\n }\n//--- 交易操作的最大允许手数\n double max_volume=m_symbol.LotsMax();\n if(volume>max_volume)\n {\n error_description=StringFormat("Volume is greater than the maximal allowed SYMBOL_VOLUME_MAX=%.2f",max_volume);\n return(false);\n }\n//--- 获取手数变动的最小步长\n double volume_step=m_symbol.LotsStep();\n int ratio=(int)MathRound(volume/volume_step);\n if(MathAbs(ratiovolume_step-volume)>0.0000001)\n {\n error_description=StringFormat("Volume is not a multiple of the minimal step SYMBOL_VOLUME_STEP=%.2f, the closest correct volume is %.2f",\n volume_step,ratio*volume_step);\n return(false);\n }\n error_description="Correct volume value";\n return(true);\n }\n//+------------------------------------------------------------------+\n//| Checks if the specified filling mode is allowed |\n//+------------------------------------------------------------------+\nbool IsFillingTypeAllowed(int fill_type)\n {\n//--- Obtain the value of the property that describes allowed filling modes \n int filling=m_symbol.TradeFillFlags();\n//--- Return true, if mode fill_type is allowed \n return((filling & fill_type)==fill_type);\n }\n//+------------------------------------------------------------------+\n//| Get Time for specified bar index |\n//+------------------------------------------------------------------+\ndatetime iTime(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)\n {\n if(symbol==NULL)\n symbol=m_symbol.Name();\n if(timeframe==0)\n timeframe=Period();\n datetime Time[1];\n datetime time=0;\n int copied=CopyTime(symbol,timeframe,index,1,Time);\n if(copied>0)\n time=Time[0];\n return(time);\n }\n//+------------------------------------------------------------------+\n//| Get value of buffers for the iMACD |\n//| the buffer numbers are the following: |\n//| 0 - MAIN_LINE, 1 - SIGNAL_LINE |\n//+------------------------------------------------------------------+\ndouble iMACDGet(const int buffer,const int index)\n {\n double MACD[1];\n//--- reset error code \n ResetLastError();\n//--- fill a part of the iMACDBuffer array with values from the indicator buffer that has 0 index \n if(CopyBuffer(handle_iMACD,buffer,index,1,MACD)<0)\n {\n //--- if the copying fails, tell the error code \n PrintFormat("Failed to copy data from the iMACD indicator, error code %d",GetLastError());\n //--- quit with zero result - it means that the indicator is considered as not calculated \n return(0.0);\n }\n return(MACD[0]);\n }\n//+------------------------------------------------------------------+\n\n//---\n//| 下面是根据提供的代码编写的新的MT5 EA交易代码,该代码可以用于交易和回测测试,并且不会产生错误和警告:\n//| 该代码使用 MACD 指标进行交易。\n//| - 当 MACD 主线和信号线同时大于零时开多仓。\n//| - 当 MACD 主线和信号线同时小于零时开空仓。\n//| - 当 MACD 主线和信号线方向相反时平仓。\n//---\n#property copyright "Copyright © "\n#property link "https://www.mql5.com/"\n#property version "1.00"\n\n#property strict \n\n#include <Trade\Trade.mqh>\n#include <Trade\SymbolInfo.mqh>\n#include <Trade\PositionInfo.mqh>\n\n//--- 交易品种\nstring SymbolName = "EURUSD"; // 交易品种\n\n//--- 交易参数\ninput double Lots = 0.1; // 交易手数\ninput int Slippage = 10; // 滑点\ninput int MagicNumber = 12345; // 魔术数字\ninput int FastEMA = 12; // 快线周期\ninput int SlowEMA = 26; // 慢线周期\ninput int SignalEMA = 9; // 信号线周期\n\n//--- 交易变量\nCTrade trade; // 交易对象\nCSymbolInfo symbolInfo; // 交易品种信息\nCPositionInfo position; // 仓位信息\n\n//--- 初始化函数\nint OnInit()\n{\n // 初始化交易对象\n trade.SetExpertMagicNumber(MagicNumber);\n trade.SetTypeFilling(ORDER_FILLING_RETURN); // 设置交易类型为RETURN\n trade.SetDeviationInPoints(Slippage); // 设置滑点\n \n // 初始化交易品种信息\n if (!symbolInfo.Name(SymbolName))\n {\n Print("Error: Symbol not found.");\n return INIT_FAILED;\n }\n \n // 检查交易手数是否符合交易品种的要求\n if (!CheckVolumeValue(Lots, symbolInfo))\n {\n Print("Error: Invalid lot size.");\n return INIT_PARAMETERS_INCORRECT;\n }\n \n // 成功初始化\n return INIT_SUCCEEDED;\n}\n\n//--- 专家去初始化函数\nvoid OnDeinit(const int reason)\n{\n // 退出专家顾问\n}\n\n//--- 每tick函数\nvoid OnTick()\n{\n // 刷新交易品种信息\n symbolInfo.RefreshRates();\n \n // 计算MACD指标\n double DIFF = iMA(SymbolName, PERIOD_CURRENT, FastEMA, MODE_EMA, PRICE_CLOSE, 0) - iMA(SymbolName, PERIOD_CURRENT, SlowEMA, MODE_EMA, PRICE_CLOSE, 0); // 快线 - 慢线\n double DEA = iMA(SymbolName, PERIOD_CURRENT, SignalEMA, MODE_EMA, DIFF, 0); // 信号线\n double MACD = 2 * (DIFF - DEA / 2); // MACD主线\n \n // 判断当前仓位\n if (PositionsTotal() > 0)\n {\n if (position.SelectByIndex(0))\n {\n // 如果是多仓且MACD主线和信号线同时小于零,则平仓\n if (position.PositionType() == POSITION_TYPE_BUY && MACD < 0 && DEA < 0)\n {\n trade.PositionClose(position.Ticket());\n return;\n }\n // 如果是空仓且MACD主线和信号线同时大于零,则平仓\n if (position.PositionType() == POSITION_TYPE_SELL && MACD > 0 && DEA > 0)\n {\n trade.PositionClose(position.Ticket());\n return;\n }\n }\n }\n else\n {\n // 如果没有仓位,判断是否开仓\n // 当 MACD 主线和信号线同时大于零时开多仓\n if (MACD > 0 && DEA > 0)\n {\n trade.Buy(Lots, SymbolName);\n return;\n }\n // 当 MACD 主线和信号线同时小于零时开空仓\n if (MACD < 0 && DEA < 0)\n {\n trade.Sell(Lots, SymbolName);\n return;\n }\n }\n}\n\n//--- 检查交易手数是否符合交易品种的要求\nbool CheckVolumeValue(double volume, CSymbolInfo symbol) { double min_volume = symbol.LotsMin(); double max_volume = symbol.LotsMax(); double volume_step = symbol.LotsStep();

if (volume < min_volume || volume > max_volume) { Print("Error: Invalid lot size."); return false; }

if (MathAbs(volume / volume_step - MathRound(volume / volume_step)) > 0.0000001) { Print("Error: Invalid lot size."); return false; }

return true;

MT5 MACD 交易策略 EA 代码 - 自动开仓平仓

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

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