指标名称:EMA距离 [color=rgba(0, 0, 0, 0.9)]
版本:MT4 ver. 2.01(指标)
EMA距离是一个简单而有效的交易系统,旨在通过价格与 24 EMA(指数移动平均线)的交互捕捉交易机会。该系统适用于主流货币对,支持多时间周期(1小时、4小时和日线图)。它既可以用作短线剥头皮交易,也可以用于长期趋势交易。
这里提供的是多品种多周期信号展示,可自定义品种。
交易规则
该系统的核心在于两条简单规则:
回调反弹规则:
突破回测规则:
当价格位于 24 EMA 以下并向上移动,若价格突破 24 EMA 且收盘在其上方,再次回测 24 EMA 时设置买入限价单。同理,若价格突破 24 EMA 向下,则设置卖出限价单。
止损设置
止损规则基于突破回测规则:
注意事项
参数:
部分代码展示:
//+------------------------------------------------------------------+//| EMA距离.mq4 |//| Copyright © 2009-2024, www.QChaos.com |//| https://www.qchaos.com/ |//+------------------------------------------------------------------+#property copyright "Copyright © 量化混沌, www.qchaos.com"#property link "https://www.qchaos.com"#property version "2.01"#define DATE "2025.01.19"#property indicator_chart_window
extern bool ShowCurrentPairOnly = false; // 是否只显示当前货币对extern string PairsToTrade = "AUDCAD,AUDCHF,AUDJPY,AUDNZD,AUDUSD,CADCHF,CADJPY,CHFJPY,EURAUD,EURCAD,EURGBP,EURJPY,EURUSD,EURNZD,GBPAUD,GBPCAD,GBPJPY,GBPUSD,NZDUSD,NZDJPY,USDCAD,USDCHF,USDJPY,XAGUSD,XAUUSD"; // 交易的货币对列表extern string PeriodsToTrade = "H1,H4,D1";//,W1,MN"; // 可交易的时间框架(H1:1小时,H4:4小时,D1:日线)extern int MaPeriod=24; // 均线周期(默认24)int BufferPips =10; // 设置缓冲点数
extern int MaMethod=MODE_EMA; // 均线类型,默认EMA(指数移动平均)extern string mame="Method: 0=sma; 1=ema; 2=smma; 3=lwma"; // 可选的均线类型说明extern int MaShift=0; // 均线的偏移量extern int MaAppliedPrice=0; // 应用价格的类型extern string maap="Applied price: 0=Close; 1=Open; 2=High"; // 均线应用的价格类型:收盘价、开盘价、最高价extern string maap1="3=Low; 4=Median; 5=Typical; 6=Weighted"; // 其他应用价格类型
extern color colorCodeAboveBand=DodgerBlue; // 当价格高于带状线时的颜色(默认DodgerBlue)extern color colorCodeBelowBand=Red; // 当价格低于带状线时的颜色(默认Red)extern color colorCodeAboveMA=Aqua; // 当价格高于均线时的颜色(默认Aqua)extern color colorCodeBelowMA=Gold; // 当价格低于均线时的颜色(默认Gold)extern color colorCodeNoSignal=Gray; // 没有信号时的颜色(默认Gray)
extern string pdi="----Pair display inputs----"; // 货币对显示的输入提示extern int FontSize=14; // 字体大小(默认14)extern color FontColour=Yellow; // 字体颜色(默认Yellow)extern string Font_Font = "Arial"; // 字体类型(默认Arial)extern string Font_Bold = "Arial Black"; // 加粗字体类型(默认Arial Black)extern double DisplayStarts_X=5; // 显示位置,距离右上角的横向距离(默认5)extern double DisplayStarts_Y=15; // 显示位置,距离右上角的纵向距离(默认15)extern string UniqueID="qchaos001"; // 唯一标识符
// 货币对提取相关变量int NoOfPairs; // 用户输入的货币对数量int NoOfPeriods; // 用户输入的时间周期数量string TradePair[]; // 存储用户选择的交易货币对string TradePeriod[]; // 存储用户选择的交易时间周期int TradePeriodTF[]; // 存储用户选择的交易时间周期对应的整数值double TradeTrendDiffs[][5]; // 存储货币对与均线的差值color Trend[][5]; // 存储货币对趋势颜色color TrendColor[5]; // 存储趋势颜色bool AlertSent[]; // 用于标记是否已发送警报
#define NOSIGNAL 0 // 没有信号#define ABOVEMA 1 // 价格高于均线#define BELOWMA 2 // 价格低于均线#define ABOVEBAND 3 // 价格高于带状线#define BELOWBAND 4 // 价格低于带状线int WindowNo = 0; // 窗口编号string objPrefix ; // 本指标绘制的所有对象前缀string buff_str ; // 存储绘制对象的缓冲字符串// 定义了一个数组用于不同市场的点值乘数int pipMult,pipMultTab[]= {1,10,1,10,1,10,100}; // 用于将点数转换为点的倍数// 定义均线的类型数组,分别为SMA、EMA、SMMA、LWMAstring _type[]= {"SMA","EMA","SMMA","LWMA"};//+------------------------------------------------------------------+// 初始化函数int init()//+------------------------------------------------------------------+ { int i, j; objPrefix = UniqueID+":"+WindowExpertName(); // 设置对象前缀
// pipMult = pipMultTab[Digits];// pip = Point * pipMult; // 设置不同趋势状态的颜色 TrendColor[NOSIGNAL] = colorCodeNoSignal; TrendColor[ABOVEBAND]= colorCodeAboveBand; TrendColor[BELOWBAND]= colorCodeBelowBand; TrendColor[ABOVEMA] = colorCodeAboveMA; TrendColor[BELOWMA] = colorCodeBelowMA;
// 如果不只显示当前货币对 if(!ShowCurrentPairOnly) { // 提取用户交易的货币对 NoOfPairs = StringFindCount(PairsToTrade,",")+1; // 计算货币对的数量 ArrayResize(TradePair, NoOfPairs); // 调整数组大小 string AddChar = StringSubstr(Symbol(),6,4); // 获取货币对的后四个字符 StrPairToStringArray(PairsToTrade, TradePair, AddChar); // 将货币对字符串转为数组 } else { // 只填充当前图表的货币对 NoOfPairs = 1; ArrayResize(TradePair, NoOfPairs); TradePair[0] = Symbol(); // 当前图表的货币对 }
// 提取用户选择的时间周期 NoOfPeriods = StringFindCount(PeriodsToTrade, ",")+1; ArrayResize(TradePeriod, NoOfPeriods); // 调整数组大小 ArrayResize(TradePeriodTF, NoOfPeriods); // 调整周期类型数组大小 StrToStringArray(PeriodsToTrade, TradePeriod); // 将时间周期字符串转换为数组
// 转换时间周期为数字格式 for(j=0; j<NoOfPeriods; j++) { TradePeriodTF[j] = StrToTF(TradePeriod[j]); // 将时间周期转换为MT4支持的数值 }
// 初始化趋势和差异数组 ArrayResize(Trend, NoOfPairs); ArrayInitialize(Trend, NOSIGNAL); ArrayResize(TradeTrendDiffs, NoOfPairs); ArrayInitialize(TradeTrendDiffs, 0);
return(0); // 返回初始化成功 }// End init()
//+------------------------------------------------------------------+// 去初始化函数int deinit()//+------------------------------------------------------------------+ { Comment(""); // 清除当前屏幕上的评论 RemoveObjects(objPrefix); // 删除所有绘制的对象 return(0); // 返回去初始化成功 }
//+------------------------------------------------------------------+// 每个周期开始时执行的函数int start()//+------------------------------------------------------------------+ { GetPairTrends(TradeTrendDiffs, Trend); // 获取每个货币对的趋势 PrintPairTrends(); // 打印货币对的趋势信息 }
//+------------------------------------------------------------------+// 删除指定前缀的所有对象void RemoveObjects(string Pref)//+------------------------------------------------------------------+ { int i; string objname = "";
// 遍历所有对象并删除具有指定前缀的对象 for(i = ObjectsTotal(); i >= 0; i--) { objname = ObjectName(i); if(StringFind(objname, Pref, 0) > -1) ObjectDelete(objname); // 删除对象 } return(0); // 删除完成 } // End void RemoveObjects(string Pref)
//+------------------------------------------------------------------+// 计算子串出现次数int StringFindCount(string str, string str2)//+------------------------------------------------------------------+ { int c = 0; // 遍历字符串,计算子串出现的次数 for(int i=0; i<StringLen(str); i++) if(StringSubstr(str,i,StringLen(str2)) == str2) c++; return(c); // 返回子串出现的次数 } // End int StringFindCount(string str, string str2)
//+------------------------------------------------------------------+// 将货币对字符串转换为数组void StrPairToStringArray(string str, string &a[], string p_suffix, string delim=",")//+------------------------------------------------------------------+ { int z1=-1, z2=0; // 遍历并分割字符串,将每个货币对存入数组 for(int i=0; i<ArraySize(a); i++) { z2 = StringFind(str,delim,z1+1); // 查找分隔符的位置 a = StringSubstr(str,z1+1,z2-z1-1) + p_suffix; // 将每个货币对与后缀拼接 if(z2 >= StringLen(str)-1) break; z1 = z2; } return(0); // 完成转换 }
//+------------------------------------------------------------------+// 将字符串按分隔符分割为数组void StrToStringArray(string str, string &a[], string delim=",")//+------------------------------------------------------------------+ { int z1=-1, z2=0; // 遍历并分割字符串,将每个部分存入数组 for(int i=0; i<ArraySize(a); i++) { z2 = StringFind(str,delim,z1+1); // 查找分隔符的位置 a = StringSubstr(str,z1+1,z2-z1-1); // 存入数组 if(z2 >= StringLen(str)-1) break; z1 = z2; } return(0); // 完成转换 }
//+------------------------------------------------------------------+// 将时间周期字符串转换为MT4的数值int StrToTF(string str)//+------------------------------------------------------------------+ { str = StringUpper(str); // 转换为大写 str = StringTrimLeft(str); // 去掉左侧空格 str = StringTrimRight(str); // 去掉右侧空格
// 根据不同时间周期返回对应的数字值 if(str == "M1") return(1); if(str == "M5") return(5); if(str == "M15") return(15); if(str == "M30") return(30); if(str == "H1") return(60); if(str == "H4") return(240); if(str == "D1") return(1440); if(str == "W1") return(10080); if(str == "MN") return(43200); return(0); // 返回0表示无效周期 }
//+------------------------------------------------------------------+// 将字符串中的小写字母转换为大写字母string StringUpper(string str)//+------------------------------------------------------------------+ { string outstr = ""; string lower = "abcdefghijklmnopqrstuvwxyz"; string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // 遍历字符串中的每个字符 for(int i=0; i<StringLen(str); i++) { int t1 = StringFind(lower,StringSubstr(str,i,1),0); // 查找小写字母的位置 if(t1 >=0) outstr = outstr + StringSubstr(upper,t1,1); // 转换为大写 else outstr = outstr + StringSubstr(str,i,1); // 保留原字符 } return(outstr); // 返回转换后的字符串 }
//+------------------------------------------------------------------+// 获取每个货币对的趋势数据//+------------------------------------------------------------------+void GetPairTrends(double &diffs[][], int &trend[][])//+------------------------------------------------------------------+ { int i, j; double diff;
for(i=0; i<NoOfPairs; i++) { for(j=0; j<NoOfPeriods; j++) { trend[j] = NOSIGNAL;
int digits=MarketInfo(TradePair,MODE_DIGITS); double point = MarketInfo(TradePair,MODE_POINT); double pip = point * pipMultTab[digits]; diff = (iClose(TradePair, TradePeriodTF[j], 0) - iMA(TradePair, TradePeriodTF[j], MaPeriod, MaShift, MaMethod, MaAppliedPrice, 0))/pip; diffs[j] = diff;
if(diff > 0) { if(diff > BufferPips) { trend[j] = ABOVEBAND; } else { trend[j] = ABOVEMA; } } else { if(diff < -BufferPips) { trend[j] = BELOWBAND; } else { trend[j] = BELOWMA; } } } //End for(j=0; j<NoOfPeriods; j++) } //End for(i=0; i<NoOfPairs; i++) return(0);
}
复制代码