
使用MQL4和MQL5绘制基于分形指标的趋势线
内容简介表
- 简介
- 1. 输入参数,DeInit()函数及初始化变量声明
- 2. 搜索最近的分形
- 3. 确定分形的价格和时间
- 4. 创建对象并编辑属性重绘趋势线
- 5. 检查历史数据加载情况
- 6. 突破趋势线的信号,推送通知
- 7. 趋势线在交易中的实际应用
- 总结
简介
最近,我一直在考虑如何使用趋势线。如何选择绘制趋势线的点以及绘制的精确度一直是个问题。我决定使用分形来作为基础。
我的主要工作是分析市场,也能花些时间来做交易。你不能仅仅在长时间框架下绘制趋势线,应能够通过极点精确到15分钟图表上。原因是长时间框架上的分形时间并不总是等于M15上的极值点的时间。简而言之,自动化在此能够派上用场。我开始用MQL5编写代码然后移植到MQL4上,因为我需要程序运行于MetaTrader 4。
在本文中,我将以MQL4和MQL5两种语言来呈现问题的解决方案。虽然在本文中对两种语言进行了比较,但并不是为了对比MQL4和MQL5的执行效率。当然我也意识到可能有比我更好的解决方法。本文对使用MQL4或MQL5编写脚本的初学者有帮助,尤其是那些计划使用分形和趋势线的朋友。
1. 输入参数,DeInit()函数及初始化变量声明
我使用如下变量作为参数:
input color Resistance_Color=Red; // 设置阻力线颜色 input ENUM_LINE_STYLE Resistance_Style; // 设置阻力线类型 input int Resistance_Width=1; // 设置阻力线宽度 input color Support_Color=Red; // 设置支撑线颜色 input ENUM_LINE_STYLE Support_Style; // 设置支撑线类型 input int Support_Width=1; // 设置支撑线宽度
这些变量对于MQL4和MQL5都是一样的。
在MQL5中我们得先创建指标:
//--- iFractals 指标句柄 int Fractal; //+------------------------------------------------------------------+ //| EA初始化函数 | //+------------------------------------------------------------------+ int OnInit() { //--- 获取iFractals指标句柄 Fractal=iFractals(Symbol(),PERIOD_D1); //--- return(INIT_SUCCEEDED); }
因为程序将绘制图形对象,那么有必要在EA从图标上移除的同时删除它们。
void OnDeinit(const int reason) { ObjectDelete(0,"TL_Resistance"); ObjectDelete(0,"TL_Support"); }
绘制两条直线(支撑和阻力线)需要四个点。要确定点需要知道时间和价格。
坐标以如下顺序确定:首选,我们找到极点所在K线,找到它我们就能确定极点的价格和时间。
在OnTick()函数中声明变量:
MQL4 |
---|
//--- 声明变量 int n,UpperFractal_1,UpperFractal_2,LowerFractal_1,LowerFractal_2; |
MQL5 |
---|
//--- 声明变量 int n,UpperFractal_1,UpperFractal_2,LowerFractal_1,LowerFractal_2; //--- 声明用于写入iFractal指标值的缓存数组 double FractalDown[],FractalUp[]; double UpFractal_1,UpFractal_2,LowFractal_1,LowFractal_2; |
首先,我仅仅声明了那些用于存储形成分形的K线索引变量。
在MQL4中:
- n - 使用for循环操作符找到最近的分形所需的变量;
- UpperFractal_1, UpperFractal_2, LowerFractal_1, LowerFractal_2 - 这些变量将存储最近的两个极点对应的K线索引,极点即最高或最低价(用来确定分形)
在MQL5中我们引入额外的变量:
- FractalDown[],FractalUp[]; - 声明存储iFractals指标缓存值的double类型数组;
- 接下来,double类型变量: UpFractal_1,UpFractal_2,LowFractal_1,LowFractal_2。它们将存储极点的价格。
2. 搜索最近的分形
要找到形成最近分形的K线,我们使用for循环操作符。
让我们确定最先的两个K线的索引,它们对应第一和第二上分形。
MQL4 |
---|
//--- 找到最近的上分形K线索引 for(n=0; n<(Bars-1);n++) { if(iFractals(NULL,1440,MODE_UPPER,n)!=NULL) break; UpperFractal_1=n+1; } //--- 找到第二近的上分形K线索引 for(n=UpperFractal_1+1; n<(Bars-1);n++) { if(iFractals(NULL,1440,MODE_UPPER,n)!=NULL) break; UpperFractal_2=n+1; } |
MQL5 |
---|
//--- 首先,我们要将分形指标缓存值写入数组 //--- 用缓存值填充数组 CopyBuffer(Fractal,0,TimeCurrent(),Bars(Symbol(),PERIOD_D1),FractalUp); CopyBuffer(Fractal,1,TimeCurrent(),Bars(Symbol(),PERIOD_D1),FractalDown); //--- 索引类似时间序列 ArraySetAsSeries(FractalUp,true); ArraySetAsSeries(FractalDown,true); //--- 接下来我们使用for循环来查找第一个上分形 for(n=0; n<Bars(Symbol(),PERIOD_D1); n++) { //--- 如果值非空,跳出循环体 if(FractalUp[n]!=EMPTY_VALUE) break; } //--- 将第一个分形的价格写入变量 UpFractal_1=FractalUp[n]; //--- 将其索引写入变量 UpperFractal_1=n; //--- 查找第二个上分形 for(n=UpperFractal_1+1; n<Bars(Symbol(),PERIOD_D1); n++) { if(FractalUp[n]!=EMPTY_VALUE) //如果值非空,跳出循环体 break; } //--- 将第二个分形的价格写入变量 UpFractal_2=FractalUp[n]; //--- 将第二个分形的索引写入变量 UpperFractal_2=n; |
在这里我清楚的揭示了MQL5和MQL4的区别 - 使用获取时间序列的函数。
在MQL4中,我立即开始查找形成分形的K线索引,但是在MQL5中我定义了FractalUp[]和FractalDown[]数组来存储上下分形的值,它们通过iFractals指标和CopyBuffer()函数获取。接下来,我使用ArraySetAsSeries()函数将这些数组设置为时间序列。
在MQL4中和仅仅获得分形对应K线的索引,但是在MQL5中我使用CopyBuffer()函数获取分形的索引和其对应的价格。
类似的,我们找到了最近的两个下分形:
MQL4 |
---|
//--- 找到最近的下分K线形索引 for(n=0; n<(Bars-1);n++) { if(iFractals(NULL,1440,MODE_LOWER,n)!=NULL) break; LowerFractal_1=n+1; } //--- 找到第二近的下分形K线索引 for(n=LowerFractal_1+1; n<(Bars-1);n++) { if(iFractals(NULL,1440,MODE_LOWER,n)!=NULL) break; LowerFractal_2=n+1; } |
MQL5 |
---|
//--- 找到下分形的值 //--- 查找最近的下分形 for(n=0; n<Bars(Symbol(),PERIOD_D1); n++) { //--- 如果值非空,跳出循环体 if(FractalDown[n]!=EMPTY_VALUE) break; } //--- 将第一个分形的价格写入变量 LowFractal_1=FractalDown[n]; //--- 将其索引写入变量 LowerFractal_1=n; //--- 查找第二个下分形 for(n=LowerFractal_1+1; n<Bars(Symbol(),PERIOD_D1); n++) { if(FractalDown[n]!=EMPTY_VALUE) break; } //--- 将第二个分形的价格写入变量 LowFractal_2=FractalDown[n]; //--- 将第二个分形的索引写入变量 LowerFractal_2=n; |
如你所见,MQL4和MQL5代码非常类似。只有一些句法上细微的区别。
3. 确定分形的价格和时间
要绘制趋势线,我们需要确定分形的时间和价格。当然,在MQL4中我们可以简单的使用High[]和Low[]预定义时间序列变量,以及iTime()函数,然而我们也需要获取更为精确的坐标来确保绘制趋势线的准确性。
图1-2显示了H4和M15时间框架下极点时间的差别。
图1. H4图表上的极点时间。
图2. M15图表上的极点时间
我得出结论,M15上的极点精度对我来说已经足够。
总的来说,极点确定的原则在MQL4和MQL5上几乎是一样的,但是细节上还是略有差异:
MQL4 | MQL5 |
---|---|
|
|
每一步的代码如下:
MQL4 |
---|
// Step 1. 在大时间框架下确定极点时间: //--- 确定分形的时间 datetime UpFractalTime_1=iTime(NULL, 1440,UpperFractal_1); datetime UpFractalTime_2=iTime(NULL, 1440,UpperFractal_2); datetime LowFractalTime_1=iTime(NULL, 1440,LowerFractal_1); datetime LowFractalTime_2=iTime(NULL, 1440,LowerFractal_2); |
// Step 2. 在较小的时间框架上确定极点所在K线的索引 //--- 在M15上查找分形索引 int UpperFractal_1_m15=iBarShift(NULL, 15, UpFractalTime_1,true); int UpperFractal_2_m15=iBarShift(NULL, 15, UpFractalTime_2,true); int LowerFractal_1_m15=iBarShift(NULL, 15, LowFractalTime_1,true); int LowerFractal_2_m15=iBarShift(NULL, 15, LowFractalTime_2,true); |
// Step 3. 在M15上使用数组查找极点: //--- 使用数组查找极点 //--- 声明i变量用于循环 int i; //--- 1. 首先,查找低值极点 //--- 3.1 查找最近的低值极点 //--- 声明存储K线索引值的数组 int Lower_1_m15[96]; //--- 声明存储价格的数组 double LowerPrice_1_m15[96]; //--- 开始循环: for(i=0;i<=95;i++) { //--- 用K线索引值填充数组 Lower_1_m15[i]=LowerFractal_1_m15-i; //--- 用价格填充数组 LowerPrice_1_m15[i]=iLow(NULL,15,LowerFractal_1_m15-i); } //--- 确定数组中的最低价 int LowestPrice_1_m15=ArrayMinimum(LowerPrice_1_m15,WHOLE_ARRAY,0); //--- 确定数组中最低价对应的K线索引 int LowestBar_1_m15=Lower_1_m15[LowestPrice_1_m15]; //--- 确定最低价K线所在的时间 datetime LowestBarTime_1_m15=iTime(NULL,15,Lower_1_m15[LowestPrice_1_m15]); //--- 3.2 查找第二极值点 int Lower_2_m15[96]; double LowerPrice_2_m15[96]; for(i=0;i<=95;i++) { //--- 用K线索引值填充数组 Lower_2_m15[i]=LowerFractal_2_m15-i; //--- 用价格填充数组 LowerPrice_2_m15[i]=iLow(NULL,15,LowerFractal_2_m15-i); } //--- 确定数组中的最低价 int LowestPrice_2_m15=ArrayMinimum(LowerPrice_2_m15,WHOLE_ARRAY,0); //--- 确定数组中最低价对应的K线索引 int LowestBar_2_m15=Lower_2_m15[LowestPrice_2_m15]; //--- 确定最低价K线所在的时间 datetime LowestBarTime_2_m15=iTime(NULL,15,Lower_2_m15[LowestPrice_2_m15]); //--- 3.3 查找最近的高值极点 int Upper_1_m15[96]; double UpperPrice_1_m15[96]; for(i=0;i<=95;i++) { //--- 用K线索引值填充数组 Upper_1_m15[i]=UpperFractal_1_m15-i; //--- 用价格填充数组 UpperPrice_1_m15[i]=iHigh(NULL,15,UpperFractal_1_m15-i); } //--- 确定数组中的最高价 int HighestPrice_1_m15=ArrayMaximum(UpperPrice_1_m15,WHOLE_ARRAY,0); //--- 确定数组中最高价对应的K线索引 int HighestBar_1_m15=Upper_1_m15[HighestPrice_1_m15]; //--- 确定最高价K线所在的时间 datetime HighestBarTime_1_m15=iTime(NULL,15,Upper_1_m15[HighestPrice_1_m15]); //--- 3.4 查找第二高值极值点 int Upper_2_m15[96]; double UpperPrice_2_m15[96]; for(i=0;i<=95;i++) { //--- 用K线索引值填充数组 Upper_2_m15[i]=UpperFractal_2_m15-i; //--- 用价格填充数组 UpperPrice_2_m15[i]=iHigh(NULL,15,UpperFractal_2_m15-i); } |
MQL5 |
---|
// Step 1. 在大时间框架下确定极点时间: //--- 声明存储较大时间框架下K线对应的时间的数组 datetime UpFractalTime_1[],LowFractalTime_1[],UpFractalTime_2[],LowFractalTime_2[]; //--- 确定较大时间框架下分形的时间 CopyTime(Symbol(),PERIOD_D1,UpperFractal_1,1,UpFractalTime_1); CopyTime(Symbol(),PERIOD_D1,LowerFractal_1,1,LowFractalTime_1); CopyTime(Symbol(),PERIOD_D1,UpperFractal_2,1,UpFractalTime_2); CopyTime(Symbol(),PERIOD_D1,LowerFractal_2,1,LowFractalTime_2); |
// Step 2. 确定下一个日线的开始时间 //--- 确定下一个日线的开始时间(CopyHigh(),CopyLow() 和 CopyTime()的结束时间) datetime UpFractalTime_1_15=UpFractalTime_1[0]+86400; datetime UpFractalTime_2_15=UpFractalTime_2[0]+86400; datetime LowFractalTime_1_15=LowFractalTime_1[0]+86400; datetime LowFractalTime_2_15=LowFractalTime_2[0]+86400; |
// Step 3. 声明和填充15分钟时间框架下的时间和价格数组: //--- 声明存储最大和最小价格值的数组 double High_1_15[],Low_1_15[],High_2_15[],Low_2_15[]; //--- 用CopyHigh() 和 CopyLow() 函数填充数组 CopyHigh(Symbol(),PERIOD_M15,UpFractalTime_1[0],UpFractalTime_1_15,High_1_15); CopyHigh(Symbol(),PERIOD_M15,UpFractalTime_2[0],UpFractalTime_2_15,High_2_15); CopyLow(Symbol(),PERIOD_M15,LowFractalTime_1[0],LowFractalTime_1_15,Low_1_15); CopyLow(Symbol(),PERIOD_M15,LowFractalTime_2[0],LowFractalTime_2_15,Low_2_15); //--- 声明存储对应极点所在K线时间的数组 datetime High_1_15_time[],High_2_15_time[],Low_1_15_time[],Low_2_15_time[]; //--- 填充数组 CopyTime(Symbol(),PERIOD_M15,UpFractalTime_1[0],UpFractalTime_1_15,High_1_15_time); CopyTime(Symbol(),PERIOD_M15,UpFractalTime_2[0],UpFractalTime_2_15,High_2_15_time); CopyTime(Symbol(),PERIOD_M15,LowFractalTime_1[0],LowFractalTime_1_15,Low_1_15_time); CopyTime(Symbol(),PERIOD_M15,LowFractalTime_2[0],LowFractalTime_2_15,Low_2_15_time); |
// Step 4. 查找最低和最高价格,以及极点对应的时间值 //--- 用ArrayMaximum() 和 ArrayMinimum() 函数确定最高和最低价格以及时间 int Max_M15_1=ArrayMaximum(High_1_15,0,96); int Max_M15_2=ArrayMaximum(High_2_15,0,96); int Min_M15_1=ArrayMinimum(Low_1_15,0,96); int Min_M15_2=ArrayMinimum(Low_2_15,0,96); |
最后,我们确定了下面趋势线的坐标:
1. 支撑线:
MQL4 | MQL5 |
---|---|
|
|
2. 对于阻力线:
MQL4 | MQL5 |
---|---|
|
|
4. 创建对象并编辑属性重绘趋势线
现在,当我们知道了直线的坐标后,我们仅仅需要创建图形对象了:
MQL4 |
---|
//--- 创建支撑线 ObjectCreate(0,"TL_Support",OBJ_TREND,0,LowestBarTime_2_m15,LowerPrice_2_m15[LowestPrice_2_m15], LowestBarTime_1_m15,LowerPrice_1_m15[LowestPrice_1_m15]); ObjectSet("TL_Support",OBJPROP_COLOR,Support_Color); ObjectSet("TL_Support",OBJPROP_STYLE,Support_Style); ObjectSet("TL_Support",OBJPROP_WIDTH,Support_Width); //--- 创建阻力线 ObjectCreate(0,"TL_Resistance",OBJ_TREND,0,HighestBarTime_2_m15,UpperPrice_2_m15[HighestPrice_2_m15], HighestBarTime_1_m15,UpperPrice_1_m15[HighestPrice_1_m15]); ObjectSet("TL_Resistance",OBJPROP_COLOR,Resistance_Color); ObjectSet("TL_Resistance",OBJPROP_STYLE,Resistance_Style); ObjectSet("TL_Resistance",OBJPROP_WIDTH,Resistance_Width); |
MQL5 |
---|
//--- 创建支撑线 ObjectCreate(0,"TL_Support",OBJ_TREND,0,Low_2_15_time[Min_M15_2],Low_2_15[Min_M15_2],Low_1_15_time[Min_M15_1],Low_1_15[Min_M15_1]); ObjectSetInteger(0,"TL_Support",OBJPROP_RAY_RIGHT,true); ObjectSetInteger(0,"TL_Support",OBJPROP_COLOR,Support_Color); ObjectSetInteger(0,"TL_Support",OBJPROP_STYLE,Support_Style); ObjectSetInteger(0,"TL_Support",OBJPROP_WIDTH,Support_Width); //--- 创建阻力线 ObjectCreate(0,"TL_Resistance",OBJ_TREND,0,High_2_15_time[Max_M15_2],High_2_15[Max_M15_2],High_1_15_time[Max_M15_1],High_1_15[Max_M15_1]); ObjectSetInteger(0,"TL_Resistance",OBJPROP_RAY_RIGHT,true); ObjectSetInteger(0,"TL_Resistance",OBJPROP_COLOR,Resistance_Color); ObjectSetInteger(0,"TL_Resistance",OBJPROP_STYLE,Resistance_Style); ObjectSetInteger(0,"TL_Resistance",OBJPROP_WIDTH,Resistance_Width); |
至此我创建了需要的线并且基于输入参数确定了他们的参数。
现在我们要绘制趋势线了。
当市场情况发生变化时,例如,当新的极点出现时,我们要将已有的线移除:
MQL4 |
---|
//--- 重绘支撑线 //--- 将支撑线的时间坐标写入变量中 datetime TL_TimeLow2=ObjectGet("TL_Support",OBJPROP_TIME2); datetime TL_TimeLow1=ObjectGet("TL_Support",OBJPROP_TIME1); //--- 如果线的坐标不符合当前坐标 if(TL_TimeLow2!=LowestBarTime_1_m15 && TL_TimeLow1!=LowestBarTime_2_m15) { //--- 移除直线 ObjectDelete(0,"TL_Support"); } //--- 重绘支撑线 //--- 将阻力线的时间坐标写入变量中 datetime TL_TimeUp2=ObjectGet("TL_Resistance",OBJPROP_TIME2); datetime TL_TimeUp1=ObjectGet("TL_Resistance",OBJPROP_TIME1); //--- 如果线的坐标不符合当前坐标 if(TL_TimeUp2!=HighestBarTime_1_m15 && TL_TimeUp1!=HighestBarTime_2_m15) { //--- 移除直线 ObjectDelete(0,"TL_Resistance"); } |
MQL5 |
---|
//--- 重绘支撑线 //--- 将支撑线的时间坐标写入变量中 datetime TL_TimeLow2=(datetime)ObjectGetInteger(0,"TL_Support",OBJPROP_TIME,0); datetime TL_TimeLow1=(datetime)ObjectGetInteger(0,"TL_Support",OBJPROP_TIME,1); //--- 如果线的坐标不符合当前坐标 if(TL_TimeLow2!=Low_2_15_time[Min_M15_2] && TL_TimeLow1!=Low_1_15_time[Min_M15_1]) { //--- 移除直线 ObjectDelete(0,"TL_Support"); } //--- 重绘支撑线 //--- 将阻力线的时间坐标写入变量中 datetime TL_TimeUp2=(datetime)ObjectGetInteger(0,"TL_Resistance",OBJPROP_TIME,0); datetime TL_TimeUp1=(datetime)ObjectGetInteger(0,"TL_Resistance",OBJPROP_TIME,1); //--- 如果线的坐标不符合当前坐标 if(TL_TimeUp2!=High_2_15_time[Max_M15_2] && TL_TimeUp1!=High_1_15_time[Max_M15_1]) { //--- 移除直线 ObjectDelete(0,"TL_Resistance"); } |
5. 检查历史数据加载情况
在测试中我发现这些线并不总是能够正确绘制。
起先我向可能是代码中有bug或者我的解决方案有问题。但是后来我意识到问题是由于较小时间框架如M15上的历史数据加载不完全导致的。为了提醒用户这种情况的出现,我决定增加额外的代码来检查M15上K线是否足够。
为了实现这一目标,我使用MQL4中的iBarShift()函数,这也是我在“确定分形的价格和时间值”时用到过的函数。
如果没有找到K线,iBarShift()函数会返回-1。因此,我们输出以下警告:
MQL4 |
---|
//--- 检查历史数据加载情况 //--- 如果至少有一个分形对应的K线在M15上没有找到 if(UpperFractal_1_m15==-1 || UpperFractal_2_m15==-1 || LowerFractal_1_m15==-1 || LowerFractal_2_m15==-1) { Alert("The loaded history is insufficient for the correct work!"); } |
在MQl5中我使用Bars()函数,如果时间序列数据没有在生成,它会返回一个空值:
//--- 检查历史数据加载情况 //--- 1. 确定特定时间框架下的K线数量 int High_M15_1=Bars(Symbol(),PERIOD_M15,UpFractalTime_1[0],UpFractalTime_1_15); int High_M15_2=Bars(Symbol(),PERIOD_M15,UpFractalTime_2[0],UpFractalTime_2_15); int Low_M15_1=Bars(Symbol(),PERIOD_M15,LowFractalTime_1[0],LowFractalTime_1_15); int Low_M15_2=Bars(Symbol(),PERIOD_M15,LowFractalTime_2[0],LowFractalTime_2_15); //--- 2. 检查用于正确绘制线段的历史数据是否足够 //--- 如果至少有一个没有找到 if(High_M15_1==0 || High_M15_2==0 || Low_M15_1==0 || Low_M15_2==0) { Alert("The loaded history is insufficient for the correct work!"); } |
6. 突破趋势线的信号,推送通知
为了使图完整,我决定当趋势线被突破时增加一个提示信号。趋势线由日时间框架下的极点绘制,但是为了能够早些确认突破,在H4图上K线必须收盘低于或高于趋势线。
总的来说,我们可以将此过程分为三步:
- 确定K线手哦按家和趋势线价格;
- 确定价格突破趋势线的条件;
- 发送关于突破的通知。
MQL4 |
---|
// 1. 获取趋势线的价格参数 //--- 确定索引为1的K线的收盘价 double Price_Close_H4=iClose(NULL,240,1); //--- 确定索引为1的K线的时间 datetime Time_Close_H4=iTime(NULL,240,1); //---确定H4图上K线的索引 int Bar_Close_H4=iBarShift(NULL,240,Time_Close_H4); //--- 确定H4图上趋势线的价格 double Price_Resistance_H4=ObjectGetValueByShift("TL_Resistance",Bar_Close_H4); //--- 确定H4图上趋势线的价格 double Price_Support_H4=ObjectGetValueByShift("TL_Support",Bar_Close_H4); |
// 2. 突破趋势线的条件 //--- 突破支撑线 bool breakdown=(Price_Close_H4<Price_Support_H4); //--- 突破阻力线 bool breakup=(Price_Close_H4>Price_Resistance_H4); |
// 3. 发送推送消息 if(breakdown==true) { //---每4小时只发送一次通知 int SleepMinutes=240; static int LastTime=0; if(TimeCurrent()>LastTime+SleepMinutes*60) { LastTime=TimeCurrent(); SendNotification(Symbol()+"The price has broken through the support line"); } } if(breakup==true) { //---每4小时只发送一次通知 SleepMinutes=240; LastTime=0; if(TimeCurrent()>LastTime+SleepMinutes*60) { LastTime=TimeCurrent(); SendNotification(Symbol()+"The price has broken through the resistance line"); } } |
MQL5 |
---|
// 1. 获取趋势线的价格参数 double Close[]; CopyClose(Symbol(),PERIOD_H4,TimeCurrent(),10,Close); //--- 设置数组索引顺序 ArraySetAsSeries(Close,true); //--- datetime Close_time[]; CopyTime(Symbol(),PERIOD_H4,TimeCurrent(),10,Close_time); //--- 设置数组索引顺序 ArraySetAsSeries(Close_time,true); //--- double Price_Support_H4=ObjectGetValueByTime(0,"TL_Support",Close_time[1]); double Price_Resistance_H4=ObjectGetValueByTime(0,"TL_Resistance",Close_time[1]); |
// 2. 突破趋势线的条件 bool breakdown=(Close[1]<Price_Support_H4); bool breakup=(Close[1]>Price_Resistance_H4); |
// 3. 发送推送消息 if(breakdown==true) { //---每4小时只发送一次通知 int SleepMinutes=240; static int LastTime=0; if(TimeCurrent()>LastTime+SleepMinutes*60) { LastTime=(int)TimeCurrent(); SendNotification(Symbol()+"The price has broken through the support line"); } } if(breakup==true) { //---每4小时只发送一次通知 int SleepMinutes=240; static int LastTime=0; if(TimeCurrent()>LastTime+SleepMinutes*60) { LastTime=(int)TimeCurrent(); SendNotification(Symbol()+"The price has broken through the resistance line"); } } |
为了确定一个突破,在MQL4中我使用ObjectGetValueByShift()函数,在MQL5中使用ObjectGetValueByTime()函数。
获取我仅仅可以设置1来代替Bar_Close_H4作为ObjectGetValueByShift()的参数,但是我决定先确定H4图上的索引号。我使用这个论坛帖子所介绍的方法来限制消息发送次数,在这里非常感谢这篇帖子的作者。
7. 趋势线在交易中的实际应用
最简单的办法是:确定一个突破,等待回踩后再入场。
理想状态下,会有如下情况:
图 3. 突破趋势线
你可以使用想象力来尝试确定形态,例如,技术分析的形态,三角形。
图4. 三角模式
上图中较小时间框架下的趋势线没有说明。
总结
全文总结,希望那个对你有用。本文面向和我一样的业务初级程序开发者。
在撰写本文时我获益匪浅:首先,我开始更多地对代码进行注释;其次,刚开始时我使用较为笨拙和繁复的方法来查找极点,但是后来我慢慢的使用更为简单的解决方案,正如文中所呈现的。
感谢您,有任何问题都请联系我。
本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/1201
注意: MetaQuotes Ltd.将保留所有关于这些材料的权利。全部或部分复制或者转载这些材料将被禁止。
This article was written by a user of the site and reflects their personal views. MetaQuotes Ltd is not responsible for the accuracy of the information presented, nor for any consequences resulting from the use of the solutions, strategies or recommendations described.



嗨--我不能假装理解所有的编码,但我正在努力完成它,因为它做的正是我一直在尝试自己编码的事情(作为一个新手,我做得很糟糕)。
我重新创建了 EA,并在 MQL4 中成功编译,在首次初始化时,它会绘制支撑线和阻力线,并发送通知,但当出现新的极端点分形时,它不会重新绘制新的支撑线和阻力线--它应该这样做吗?我是否遗漏了什么?
此外,我无法让分形显示在图表上,但在策略测试器中 测试 EA 时,分形会在停止测试后正确显示?您知道我又遗漏了什么吗?
顺便说一句,分形和针对极端点的趋势线不容易解释,更不用说编码了:)
致以最崇高的敬意
安迪
你好,关于第一个问题:如果不重绘新的趋势线,也许你没有使用删除已创建对象的代码。请查看文章的第 4 部分。关于第二个问题:你可以为测试器创建带有分形的新模板,并将其命名为 "tester.tpl"。这样,在使用测试器时,分形就会一直显示在图表上。
你好,关于第一个问题:如果没有重新绘制新的趋势线,也许你没有使用删除已创建对象的代码。请看文章的第 4 部分。关于第二个问题:你可以为测试器创建带有分形的新模板,并将其命名为 "tester.tpl"。这样,在使用 tester 时,分形就会始终显示在图表上。
感谢您的回复,我将 EA 连接到两个图表(1x 4 小时图和 1x 15m=M 图)上过了一夜,它已经重新绘制了它们,所以我的耐心太差了。
感谢您关于 tester.pl 的提示。
非常感谢
为了在测试仪中正确绘制线条,且线条不会停留在第一时间点上,您需要在创建趋势线时从底部开始控制线条。
无论是作为 Expert Advisor 还是作为 MQL4 中的指标,它都没有显示任何迹象!!!!!!!!!!!!!!!!!!!。上传任何东西和很多东西只是为了提高你的评分,这样有意思吗?
让我们在初始化后添加 OnTick 功能,使其在周末和一般情况下,只要您将其贴在图表上,而不是在新价格到达时,它就能工作。