简介
移动平均线的使用在市场时间序列的分析中、在指标和 EA 交易的编程中都是一种常见的实践方法。它是最流行的价格数据平滑方法。在新版本的 MQL 语言中,有成打的移动平均线算法可供使用。
它们之间有何差异?计算速度确实取决于某些移动平均线的算法吗?哪种算法最快?
与 MetaTrader 4 相比,在 MetaTrader 5 中移动平均线的计算速度加快了吗?有很多此类问题出现。因此,让我们探讨一下其中的大多数问题。
当然,新平台的速度令人印象深刻,但是最好通过实验检查一下。
1. 测试条件
计算速度取决于很多因素。因此,本研究作为结果获得的数据在其他测试条件下可能有所不同。换言之,性能的绝对值将有所不同,但是相对值将是类似的(针对某个平台)。
因此 MQL5 中的 iMA 函数本身不返回计算结果(它返回指标的句柄),我们将测试两个函数的速度:iMA 和 CopyBuffer。
测试条件:
- CPU:Core i7 965
- 交易品种:”EURUSD”
- 价格数据大小:10000 个元素
- 客户端:自主交易,图表中的最大柱数设置为 10000
- 移动平均线模型:MODE_SMA、MODE_EMA、MODE_SMMA、MODE_LWMA
- 计算速度的精确度限制为两位有效数字
- 移动平均线函数的可能调用数量:7
2. 如何测试
要测量移动平均线的计算时间,我们使用 GetTickCount() 函数,该函数运行于毫秒级别。此精确度还不足够,因此我们需要组织某些循环以提高测量的质量。
但是,如果我们用相同的计算和相同的输入数据多次重复循环,则结果会失真。该事实的原因如下:iMA 函数在客户端的全局缓存中创建相应技术指标的一个副本。如果在全局缓存中已经存在一个指标的副本(具有相同的参数),则不创建新的副本,指标副本的引用计数器增大。
换言之,整个缓存指标仅在第一次调用时计算一次,所有后续的调用仅采用已经存在的值,它仅重新计算新的数据。
因此,应按这样的方式组织循环:指标的输入参数在循环期间是唯一的。我们已经选择了三个这样的参数:平均周期、时间框架和应用的价格。
参数 | 值范围 |
---|---|
平均周期 | 从 1 至 100 |
时间框架 | М1、М5、М15、М30 |
应用的价格 | PRICE_CLOSE、PRICE_OPEN、PRICE_HIGH、PRICE_LOW、PRICE_MEDIAN、PRICE_TYPICAL、PRICE_WEIGHTED |
表 1. 输入参数的范围
我们将使用七种不同的调用方法计算含有 10000 个元素的数组的移动平均值(详情见第 4 节)。
3. 研究结果
我们已经将所有结果组合在表 1 中,使用以秒为单位的计算时间来评估计算性能(见表 1)。程序计算了 100х4х7=2800 类移动平均线,并且我们确定含有 10000 个元素的价格数组的计算时间。单次循环的计算时间约等于总时间除以 2800。例如,对于案例 1 和 SMA 模式,它约等于 0.0028/2800。
模式 | MODE_SMA | MODE_EMA | MODE_SMMA | MODE_LWMA | 平台 |
---|---|---|---|---|---|
0 (见第 4.1 节) | 0,0041 | 0,0040 | 0,0043 | 0,0041 | MetaTrader 4 |
1 (见第 4.2 节) | 0,0028 | 0,00023 | 0,00027 | 0,0045 | MetaTrader 5 |
2 (见第 4.3 节) | 0,0029 | 0,0029 | 0,0029 | 0,0029 | MetaTrader 5 |
3 (见第 4.4 节) | 0,0998 | 0,0997 | 0,0998 | 0,0998 | MetaTrader 5 |
4 (见第 4.5 节) | 0,0996 | 0,0996 | 0,0996 | 0,0996 | MetaTrader 5 |
5 (见第 4.6 节) | 0,0030 | 0,0029 | 0,0029 | 0,0029 | MetaTrader 5 |
6 (见第 4.7 节) | 0,000140 | 0,000121 | 0,000117 | 0,0035 | MetaTrader 5 |
表 2. 结果
将在下文讨论测试案例的意义(第 4.1-4.7 节)。让我们评估移动平均线计算性能的整个画面。
为方便起见,在图表中表示结果(见图 1-5)。移动平均线的调用类型在 X 轴上表示(见表 2),用对数刻度 -1 表示 Y 轴的值,因此,值越大,性能越快。每个计算模型(SMA、EMA、SMMA、LWMA)对应于图表中的一根柱。
图 1. 不同移动平均线算法的性能测试结果
可以看到在不同的移动平均线计算案例中计算速度出现显著差异。这意味着什么?由 MQL5 开发人员提供的几种移动平均线算法具有不同的计算性能:有很快的算法(案例 6)和较慢的算法(案例 3 和 4)。因此,在用 MQL5 编写使用移动平均线的程序时,必须选择正确的算法。
在以下的图中详细说明了各个移动平均线模型 (0-6) 的计算时间,见表 2。
图 2. MODE_SMA 模式的移动平均线计算性能
图 3. MODE_EMA 模式的移动平均线计算性能
图 4. MODE_SMMA 模式的移动平均线计算性能
图 5. MODE_LWMA 模式的移动平均线计算性能
比较两个平台的计算性能非常有趣:MetaTrader 4 和 MetaTrader 5。表 2 中的案例 0 (MQL4) 和案例 1 (MQL5) 显示了结果。
为方便起见,让我们将 iMA 标准指标的计算结果组合到单独的图和表中(见图 6)。测试的计算时间以 Y 轴表示。
图 6. MetaTrader 4 和 MetaTrader 5 计算性能的比较图
结论:
- 新的 MetaTrader 5 平台比以前的 MetaTrader 4 快 40%。
- SMA、EMA 和 SMMA 模型(案例 6),以及 LWMA(案例 2 和 5)实现了更快的性能。
- 对于测试案例,在使用标准指标 iMA 时,不同模型的计算性能实际上是相同的。对于 MovingAverages.mqh 库函数而言,事实并非如此。对于不同的模型,性能几乎相差一个量级 (0.00023~0.0045)。
- 表示的结果对应于“冷启动”,在客户端的全局缓存中没有任何预先计算的数据。
4. 案例研究
MQL5 开发人员建议使用以下获取标准技术指标的值的方法:
//--- 指标缓冲区 double MA[]; // 用于存放 iMA 指标数值的数组 //---- 指标句柄 int MA_handle; // iMA 指标句柄 //+------------------------------------------------------------------ //| EA 初始化函数 | //+------------------------------------------------------------------ int OnInit() { //--- 创建 iMA 指标句柄 MA_handle=iMA(NULL,0,21,0,MODE_EMA,PRICE_CLOSE); //--- 如果出错,打印消息 if(MA_handle<0) { Print("此 iMA 对象不能创建: MA_handle= ",INVALID_HANDLE); Print("运行时错误 = ",GetLastError()); //--- 强迫中断程序 return(-1); } return(0); } //+------------------------------------------------------------------ //| EA 即时价格处理函数 | //+------------------------------------------------------------------ void OnTick() { //--- 以 iMA 指标当前值填充 MA[] 数组 //--- 我们将复制 100 个元素, 或如果出错则返回 if(CopyBuffer(MA_handle,0,0,100,MA)<=0) return; //--- 设置 MA[] 顺序为时间序列 ArraySetAsSeries(MA,true); //--- 此处我们可以利用数据做任何事 }
在“MQL5 初学者:在‘EA 交易’中使用技术指标的指南”一文中详细说明了此方法。
要测试移动平均线的计算性能,最好使用脚本,因为它能执行所有计算而不必等待事件(例如新的价格变动事件等)。
没有必要针对所有测试案例测试一个单独的通用程序,因此我们将为每个移动平均线计算案例创建单独的脚本。
那么,让我们详细考虑移动平均线计算的每个案例。
4.1. 案例 0
在这个案例中,我们测量 MQL4 的技术指标 iMA 的计算性能。计算在 MetaTrader4 中进行并且计算所有数据。
模型 | 结果 | 最佳结果 |
---|---|---|
MODE_SMA | 0,0041 | 0.000140(案例 6) |
MODE_EMA | 0,0040 | 0.000121(案例 6) |
MODE_SMMA | 0,0043 | 0.000117(案例 6) |
MODE_LWMA | 0,0041 | 0.0029(案例 2、5) |
此案例的代码如下 (MQL4):
int M[4]= { PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30 }; int P[7]= { PRICE_CLOSE, PRICE_OPEN, PRICE_HIGH, PRICE_LOW, PRICE_MEDIAN, PRICE_TYPICAL, PRICE_WEIGHTED }; int periodMA; double buf[]; double time; int count=10000; int startGTC,endGTC; int m,p; //+------------------------------------------------------------------ //| 脚本程序初始函数 | //+------------------------------------------------------------------ int start() { if(ArrayResize(buf,count)<0) return(-1); Print("开始 "); startGTC=GetTickCount(); //---- for(m=0;m<=3;m++) { for(p=0;p<=6;p++) { for(periodMA=1;periodMA<=100;periodMA++) { Test0(); } } } //---- endGTC=GetTickCount(); time=endGTC-startGTC; Print("总计时间 [msec] ",time); time=time/1000/m/p/periodMA; Print("性能 [sec] ",DoubleToStr(time, 10)); return(0); } //+------------------------------------------------------------------ void Test0() { //--- 模式: MODE_SMA; MODE_EMA; MODE_SMMA; MODE_LWMA for(int i=0;i<count;i++) { buf[i]=iMA(NULL,M[m],periodMA,0,MODE_SMA,P[p],i); } }
注:此代码不能在 MetaTrader 5 中运行,因为它是用 MQL4 编写的。应该在 MetaTrader 4 客户端中执行它。
4.2. 案例 1
在这个案例中,我们执行了 4 个模型的计算:案例 1 (SMA)、案例 2 (EMA)、案例 3 (SMMA) 和案例 4 (LWMA) 使用 MovingAverages.mqh 库函数。
用所有数据数组执行计算。
模型 | 结果 | 最佳结果 |
---|---|---|
MODE_SMA | 0,0028 | 0.000140(案例 6) |
MODE_EMA | 0,00023 | 0.000121(案例 6) |
MODE_SMMA | 0,00027 | 0.000117(案例 6) |
MODE_LWMA | 0,0045 | 0.0029(案例 2、5) |
#include <MovingAverages.mqh> ENUM_TIMEFRAMES M[4]= { PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30 }; ENUM_APPLIED_PRICE P[7]= { PRICE_CLOSE, PRICE_OPEN, PRICE_HIGH, PRICE_LOW, PRICE_MEDIAN, PRICE_TYPICAL, PRICE_WEIGHTED }; int periodMA; double buf[],close[]; double time; int count=10000; int startGTC,endGTC; int m,p; //+------------------------------------------------------------------ //| 脚本程序初始函数 | //+------------------------------------------------------------------ int OnStart() { if(ArrayResize(buf,count)<0) return(-1); ArraySetAsSeries(buf,false); ArraySetAsSeries(close,false); startGTC=GetTickCount(); //--- for(m=0;m<=3;m++) { for(p=0;p<=6;p++) { CopyClose(_Symbol,M[m],0,count,close); for(periodMA=1;periodMA<=100;periodMA++) { Test1(); // 测试在此 } } } //--- endGTC=GetTickCount(); time=endGTC-startGTC; time=time/1000/m/p/periodMA; //--- return(0); } //+------------------------------------------------------------------ void Test1() { for(int i=0;i<count;i++) { buf[i]=SimpleMA(i,periodMA,close); } } //+------------------------------------------------------------------ void Test2() { buf[0]=close[0]; for(int i=1;i<count;i++) { buf[i]=ExponentialMA(i,periodMA,buf[i-1],close); } } //+------------------------------------------------------------------ void Test3() { buf[0]=close[0]; for(int i=1;i<count;i++) { buf[i]=SmoothedMA(i,periodMA,buf[i-1],close); } } //+------------------------------------------------------------------ void Test4() { for(int i=0;i<count;i++) { buf[i]=LinearWeightedMA(i,periodMA,close); } }
注:我们已经计划在数组中使用几种类型的数据,但是为了简单起见,我们仅使用一个含有收盘价数据的数组(这不影响计算性能)。
4.3. 案例 2
在这个案例中,我们使用 iMA 标准技术指标和测试 5。
用所有数据数组执行计算。
模型 | 结果 | 最佳结果 |
---|---|---|
MODE_SMA | 0,0029 | 0.000140(案例 6) |
MODE_EMA | 0,0029 | 0.000121(案例 6) |
MODE_SMMA | 0,0029 | 0.000117(案例 6) |
MODE_LWMA | 0,0029 | 0.0029(案例 2、5) |
ENUM_TIMEFRAMES M[4]= { PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30 }; ENUM_APPLIED_PRICE P[7]= { PRICE_CLOSE, PRICE_OPEN, PRICE_HIGH, PRICE_LOW, PRICE_MEDIAN, PRICE_TYPICAL, PRICE_WEIGHTED }; int periodMA; double time; int count=10000; int startGTC,endGTC; int m,p; double MA[]; // 用于存放 iMA 指标数组 int MA_handle; // iMA 指标句柄 //+------------------------------------------------------------------ //| 脚本程序初始函数 | //+------------------------------------------------------------------ int OnStart() { startGTC=GetTickCount(); //--- for(m=0;m<=3;m++) { for(p=0;p<=6;p++) { for(periodMA=1;periodMA<=100;periodMA++) { Test5(); } } } //--- endGTC=GetTickCount(); time=endGTC-startGTC; time=time/1000/m/p/periodMA; //--- return(0); } //+------------------------------------------------------------------ void Test5() { //--- 模式: MODE_SMA; MODE_EMA; MODE_SMMA; MODE_LWMA MA_handle=iMA(NULL,M[m],periodMA,0,MODE_SMA,P[p]); while(BarsCalculated(MA_handle)<count){} CopyBuffer(MA_handle,0,0,count,MA); }
4.4. 案例 3
在案例 3 中,使用标准库类中的指标处理类。
使用元素对元素的数据复制。用所有数据数组执行计算。
模型 | 结果 | 最佳结果 |
---|---|---|
MODE_SMA | 0,0998 | 0.000140(案例 6) |
MODE_EMA | 0,0997 | 0.000121(案例 6) |
MODE_SMMA | 0,0998 | 0.000117(案例 6) |
MODE_LWMA | 0,0998 | 0.0029(案例 2、5) |
#include <Indicators/Trend.mqh> ENUM_TIMEFRAMES M[4]= { PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30 }; ENUM_APPLIED_PRICE P[7]= { PRICE_CLOSE, PRICE_OPEN, PRICE_HIGH, PRICE_LOW, PRICE_MEDIAN, PRICE_TYPICAL, PRICE_WEIGHTED }; int periodMA; double buf[]; double time; int count=10000; int startGTC,endGTC; int m,p; CiMA objMA; //+------------------------------------------------------------------ //| 脚本程序初始函数 | //+------------------------------------------------------------------ int OnStart() { if(ArrayResize(buf,count)<0) return(-1); ArraySetAsSeries(buf,false); startGTC=GetTickCount(); //--- for(m=0;m<=3;m++) { for(p=0;p<=6;p++) { for(periodMA=1;periodMA<=100;periodMA++) { Test6(); } } } //--- endGTC=GetTickCount(); time=endGTC-startGTC; time=time/1000/m/p/periodMA; //--- return(0); } //+------------------------------------------------------------------ void Test6() { //--- 模式: MODE_SMA; MODE_EMA; MODE_SMMA; MODE_LWMA objMA.Create(NULL,M[m],periodMA,0,MODE_SMA,P[p]); objMA.BuffSize(count); objMA.Refresh(1); for(int i=0;i<count;i++) { buf[i]=objMA.Main(i); } }
4.5. 案例 4
在案例 4 中,使用标准库类中的指标处理类。
作为整体复制指标缓存的数组。用所有数据数组执行计算。
模型 | 结果 | 最佳结果 |
---|---|---|
MODE_SMA | 0,0996 | 0.000140(案例 6) |
MODE_EMA | 0,0996 | 0.000121(案例 6) |
MODE_SMMA | 0,0996 | 0.000117(案例 6) |
MODE_LWMA | 0,0996 | 0.0029(案例 2、5) |
#include <Indicators/Trend.mqh> ENUM_TIMEFRAMES M[4]= { PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30 }; ENUM_APPLIED_PRICE P[7]= { PRICE_CLOSE, PRICE_OPEN, PRICE_HIGH, PRICE_LOW, PRICE_MEDIAN, PRICE_TYPICAL, PRICE_WEIGHTED }; int periodMA; double buf[]; double time; int count=10000; int startGTC,endGTC; int m,p; CiMA objMA; //+------------------------------------------------------------------ //| 脚本程序初始函数 | //+------------------------------------------------------------------ int OnStart() { if(ArrayResize(buf,count)<0) return(-1); ArraySetAsSeries(buf,false); startGTC=GetTickCount(); //--- for(m=0;m<=3;m++) { for(p=0;p<=6;p++) { for(periodMA=1;periodMA<=100;periodMA++) { Test7(); } } } //--- endGTC=GetTickCount(); time=endGTC-startGTC; time=time/1000/m/p/periodMA; //--- return(0); } //+------------------------------------------------------------------ void Test7() { //--- 模式: MODE_SMA; MODE_EMA; MODE_SMMA; MODE_LWMA objMA.Create(NULL,M[m],periodMA,0,MODE_SMA,P[p]); objMA.BuffSize(count); objMA.Refresh(1); objMA.GetData(0,count,0,buf); }
4.6. 案例 5
使用测试 8:使用 IndicatorCreate 函数创建指标句柄。
用所有数据数组执行计算。
模型 | 结果 | 最佳结果 |
---|---|---|
MODE_SMA | 0,0030 | 0.000140(案例 6) |
MODE_EMA | 0,0029 | 0.000121(案例 6) |
MODE_SMMA | 0,0029 | 0.000117(案例 6) |
MODE_LWMA | 0,0029 | 0.0029(案例 2、5) |
ENUM_TIMEFRAMES M[4]= { PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30 }; ENUM_APPLIED_PRICE P[7]= { PRICE_CLOSE, PRICE_OPEN, PRICE_HIGH, PRICE_LOW, PRICE_MEDIAN, PRICE_TYPICAL, PRICE_WEIGHTED }; int periodMA; double time; int count=10000; int startGTC,endGTC; int m,p; double MA[]; // 用于存放 iMA 指标数组 int MA_handle; // iMA 指标句柄 MqlParam params[]; //+------------------------------------------------------------------ //| 脚本程序初始函数 | //+------------------------------------------------------------------ int OnStart() { ArrayResize(params,4); startGTC=GetTickCount(); //--- for(m=0;m<=3;m++) { for(p=0;p<=6;p++) { for(periodMA=1;periodMA<=100;periodMA++) { Test8(); } } } //--- endGTC=GetTickCount(); time=endGTC-startGTC; time=time/1000/m/p/periodMA; //--- return(0); } //+------------------------------------------------------------------ void Test8() { //--- 模式: MODE_SMA; MODE_EMA; MODE_SMMA; MODE_LWMA //--- 设置 ma_period params[0].type =TYPE_INT; params[0].integer_value=periodMA; //--- 设置 ma_shift params[1].type =TYPE_INT; params[1].integer_value=0; //--- 设置 ma_method params[2].type =TYPE_INT; params[2].integer_value=MODE_SMA; //--- 设置 applied_price params[3].type =TYPE_INT; params[3].integer_value=P[p]; //--- 创建 MA MA_handle=IndicatorCreate(NULL,M[m],IND_MA,4,params); while(BarsCalculated(MA_handle)<count){} CopyBuffer(MA_handle,0,0,count,MA); }
4.7. 案例 6
在这个案例中,我们执行了 4 个模型的计算:案例 9 (SMA)、案例 10 (EMA)、案例 11 (SMMA) 和案例 12 (LWMA) 使用 MovingAverages.mqh 库函数(与来自 MQL4 的 iMAOnArray 类似的缓存函数)。
用所有数据数组执行计算。
模型 | 结果 | 最佳结果 |
---|---|---|
MODE_SMA | 0,000140 | 0.000140(案例 6) |
MODE_EMA | 0,000121 | 0.000121(案例 6) |
MODE_SMMA | 0,000117 | 0.000117(案例 6) |
MODE_LWMA | 0,00350 | 0.0029(案例 2、5) |
#include <MovingAverages.mqh> ENUM_TIMEFRAMES M[4]= { PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30 }; ENUM_APPLIED_PRICE P[7]= { PRICE_CLOSE, PRICE_OPEN, PRICE_HIGH, PRICE_LOW, PRICE_MEDIAN, PRICE_TYPICAL, PRICE_WEIGHTED }; int periodMA; double buf[],arr[]; double close[]; double time; int count=10000,total; int startGTC,endGTC; int m,p; //+------------------------------------------------------------------ //| 脚本程序初始函数 | //+------------------------------------------------------------------ int OnStart() { CopyClose(_Symbol,_Period,0,count,close); total=ArrayCopy(arr,close); if(ArrayResize(buf,total)<0) return(-1); //--- ArraySetAsSeries(close,false); ArraySetAsSeries(arr,false); ArraySetAsSeries(buf,false); startGTC=GetTickCount(); //--- for(m=0;m<=3;m++) { for(p=0;p<=6;p++) { CopyClose(_Symbol,M[m],0,count,close); total=ArrayCopy(arr,close); for(periodMA=1;periodMA<=100;periodMA++) { Test9(); // 测试在此 } } } //--- endGTC=GetTickCount(); time=endGTC-startGTC; time=time/1000/m/p/periodMA; //--- return(0); } //+------------------------------------------------------------------ void Test9() { SimpleMAOnBuffer(total,0,0,periodMA,arr,buf); } //+------------------------------------------------------------------ void Test10() { ExponentialMAOnBuffer(total,0,0,periodMA,arr,buf); } //+------------------------------------------------------------------ void Test11() { SmoothedMAOnBuffer(total,0,0,periodMA,arr,buf); } //+------------------------------------------------------------------ void Test12() { LinearWeightedMAOnBuffer(total,0,0,periodMA,arr,buf); }
注: 我们已经计划在数组中使用几种类型的数据,但是为了简单起见,我们仅使用一个含有收盘价数据的数组(这不影响计算性能)。
5. 结果的输出
为了输出结果并检查移动平均线,我使用了 PrintTest 函数:
void PrintTest(const int position, const double &price[]) { Print("总计时间 [msec] ",(endGTC-startGTC)); Print("性能 [sec] ",time); Print(position," - 数组元素 = ",price[position]); }
可以按以下方式调用它(柱的位置和数据数组是函数的参数):
//--- ArraySetAsSeries(buf,false); ArraySetAsSeries(close,false); startGTC=GetTickCount(); //--- for(m=0;m<=3;m++) { for(p=0;p<=6;p++) { for(periodMA=1;periodMA<=100;periodMA++) { Test(); } } } //--- endGTC=GetTickCount(); time=endGTC-startGTC; time=time/1000/m/p/periodMA; //--- 输出结果 ArraySetAsSeries(buf,true); ArraySetAsSeries(close,true); PrintTest(0,buf); PrintTest(0,close); //---
注意,数组索引在计算之前和计算之后是不同的。
重要须知:在计算期间,AsSeries 标记被设置为 false,在打印结果时,被设置为 true。
6. 其他调查
为了回答有关初始参数对计算性能的影响的问题,进行了某些其他测量。
如我们所记住的,案例 6 具有最佳性能,因此我们将使用它。
测试参数:
模式 | 时间框架 | 平均周期 |
---|---|---|
1 | М1 | 144 |
2 | М5 | 144 |
3 | М15 | 144 |
4 | М30 | 144 |
5 | М1 | 21 |
6 | М1 | 34 |
7 | М1 | 55 |
8 | М1 | 89 |
9 | М1 | 233 |
10 | М1 | 377 |
11 | М1 | 610 |
12 | М1 | 987 |
表 3. 其他调查
测试的源代码:
//+------------------------------------------------------------------ //| Test_SMA Model: MODE_SMA | //+------------------------------------------------------------------ void Test_SMA(int periodMA,ENUM_TIMEFRAMES periodTF) { CopyClose(_Symbol,periodTF,0,count,close); int total=ArrayCopy(arr,close); SimpleMAOnBuffer(total,0,0,periodMA,arr,buf); } //+------------------------------------------------------------------ //| Test_EMA Model: MODE_EMA | //+------------------------------------------------------------------ void Test_EMA(int periodMA,ENUM_TIMEFRAMES periodTF) { CopyClose(_Symbol,periodTF,0,count,close); int total=ArrayCopy(arr,close); ExponentialMAOnBuffer(total,0,0,periodMA,arr,buf); } //+------------------------------------------------------------------ //| Test_SMMA Model: MODE_SMMA | //+------------------------------------------------------------------ void Test_SMMA(int periodMA,ENUM_TIMEFRAMES periodTF) { CopyClose(_Symbol,periodTF,0,count,close); int total=ArrayCopy(arr,close); SmoothedMAOnBuffer(total,0,0,periodMA,arr,buf); } //+------------------------------------------------------------------ //| Test_LWMA Model: MODE_LWMA | //+------------------------------------------------------------------ void Test_LWMA(int periodMA,ENUM_TIMEFRAMES periodTF) { CopyClose(_Symbol,periodTF,0,count,close); int total=ArrayCopy(arr,close); LinearWeightedMAOnBuffer(total,0,0,periodMA,arr,buf); }
对于其他测试,我们将使用自动测试程序,其图形用户界面如图 7 所示。
图 7. 用于自动测试的自动测试程序
结果:(X 轴具有对数时间序列)
图 8. 时间框架参数 (Y) 和移动平均线计算性能 (X)
图 9. 周期参数 (Y) 和移动平均线计算性能 (X)
从其他调查的结果得出的结论:
- 时间框架参数并不重要,它不影响计算性能(见图 8)。
- 对于模型 SMA、EMA 和 SMMA 的移动平均线计算的性能,周期并不是重要的参数。但是相反,它显著减慢 LWMA 模型的计算(从 0.00373 秒到 0.145 秒)。
总结
不正确地选择移动平均线算法会降低程序的计算性能。
本文译自 MetaQuotes Software Corp. 撰写的俄文原文
原文地址: https://www.mql5.com/ru/articles/106
(13.82 KB)
MyFxtop迈投-靠谱的外汇跟单社区,免费跟随高手做交易!
免责声明:本文系转载自网络,如有侵犯,请联系我们立即删除,另:本文仅代表作者个人观点,与迈投财经无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。