
MQL5'te Hareketli Ortalamalar Hesaplamasının Test Performansı
Giriş
Hareketli Ortalamaların kullanımı, piyasa zaman serilerinin analizinde, göstergelerde ve Expert Advisor programlamasında yaygın bir uygulamadır. En popüler fiyat verisi yumuşatma yöntemidir. MQL dilinin yeni sürümünde bir düzine Hareketli Ortalama algoritması mevcuttur.
Peki bunların aralarındaki fark bu mu? Gerçekten, hesaplama hızı Hareketli Ortalamaların belirli bir algoritmasına mı bağlı? Hangi algoritma daha hızlı?
MetaTrader 5'te Hareketli Ortalamaların hesaplama hızı MetaTrader 4'e kıyasla arttı mı? Bunlara benzer bir çok soru ortaya çıkıyor. O halde, bunların büyük bir kısmını ele alalım.
Kuşkusuz ki, yeni bir platformun hızı etkileyicidir fakat bunu deneysel olarak kontrol etmek daha iyidir.
1. Test koşulları
Hesaplama hızı birçok faktöre bağlıdır. Bu nedenle, bu araştırma sonucunda elde edilen veriler, diğer test koşullarında farklı olacaktır. Başka bir deyişle, performansın mutlak değerleri farklı olacaktır fakat bağıl değerlerin benzer olması gerekir (belirli bir platform için).
MQL5'teki iMA işlevinin hesaplama sonuçlarını kendisinin döndürmemesi nedeniyle (bir göstergenin tanıtıcısını döndürür), iki işlevin hızını test edeceğiz: iMA ve CopyBuffer.
- CPU: Core i7 965
- Sembol: "EURUSD"
- Fiyat veri boyutu: 10000 öğe
- İstemci terminali: Bağımsız, grafikteki maksimum çubuk sayısı 10000 olarak ayarlanmıştır
- Hareketli ortalama modelleri: MODE_SMA, MODE_EMA, MODE_SMMA, MODE_LWMA
- Hesaplama hızının doğruluğu iki önemli basamakla sınırlıdır
- Hareketli Ortalama işlevlerinin olası çağrı sayısı: 7
2. Nasıl test ettik?
Hareketli ortalama hesaplama süresini ölçmek için milisaniye cinsinden çalışan GetTickCount() işlevine sahibiz. Bu doğruluk yeterli değildir; bu nedenle ölçümlerin kalitesini iyileştirmek için bazı döngüleri düzenlememiz gerekir.
Ancak, aynı hesaplama ve aynı giriş verileri ile döngüyü birçok kez tekrarlamamız halinde sonuçlar bozulacaktır. Bu gerçeğin nedeni şudur: iMA işlevi, istemci terminalinin genel önbelleğinde karşılık gelen teknik göstergenin bir kopyasını oluşturur. Bir göstergenin kopyası (aynı parametrelere sahip) genel önbellekte zaten mevcutsa yeni kopya oluşturulmaz, gösterge kopyasının referans sayacı artırılır.
Diğer bir deyişle, tüm arabellek göstergesi ilk çağrıda yalnızca bir kez hesaplanır ve sonraki tüm çağrılarda yalnızca hazır değerleri alır ve yalnızca yeni verileri tekrar hesaplar.
Bu nedenle, döngü, göstergenin giriş parametreleri döngü sırasında benzersiz olduğunda düzenlenmelidir. Bu tür üç parametre seçtik: Ortalama alma süresi, zaman dilimi ve uygulanan fiyat.
Parametre | Değer aralığı |
---|---|
Ortalama alma süresi | 1'den 100'e kadar |
Zaman dilimi | М1, М5, М15, М30 |
Uygulanan fiyat | PRICE_CLOSE, PRICE_OPEN, PRICE_HIGH, PRICE_LOW, PRICE_MEDIAN, PRICE_TYPICAL, PRICE_WEIGHTED |
Tablo 1. Giriş parametrelerinin aralıkları
Yedi farklı çağrı yöntemini kullanarak 10000 öğeli dizi için hareketli ortalama değerlerini hesaplayacağız (bölüm 4'teki ayrıntılara bakınız).
3. Çalışmanın sonuçları
Tüm sonuçları Tablo 1'de birleştirdik, hesaplama performansı saniye cinsinden hesaplama süresi (bkz. Tablo 1) kullanılarak tahmin edilmiştir. Program 100х4х7=2800 tür hareketli ortalamayı hesaplar ve 10.000 öğeli fiyat dizisi için hesaplama süresini belirleriz. Tek geçişin (döngü) hesaplama süresi yaklaşık olarak toplam sürenin 2800'e bölünmesine eşittir. Örneğin, durum 1 ve SMA modu için ~ 0,0028/2800'e eşittir.
Mod | MODE_SMA | MODE_EMA | MODE_SMMA | MODE_LWMA | Platform |
---|---|---|---|---|---|
0 (bkz. bölüm 4.1) | 0,0041 | 0,0040 | 0,0043 | 0,0041 | MetaTrader 4 |
1 (bkz. bölüm 4.2) | 0,0028 | 0,00023 | 0,00027 | 0,0045 | MetaTrader 5 |
2 (bkz. bölüm 4.3) | 0,0029 | 0,0029 | 0,0029 | 0,0029 | MetaTrader 5 |
3 (bkz. bölüm 4.4) | 0,0998 | 0,0997 | 0,0998 | 0,0998 | MetaTrader 5 |
4 (bkz. bölüm 4.5) | 0,0996 | 0,0996 | 0,0996 | 0,0996 | MetaTrader 5 |
5 (bkz. bölüm 4.6) | 0,0030 | 0,0029 | 0,0029 | 0,0029 | MetaTrader 5 |
6 (bkz. bölüm 4.7) | 0,000140 | 0,000121 | 0,000117 | 0,0035 | MetaTrader 5 |
Tablo 2. Sonuçlar
Test durumlarının anlamı daha ayrıntılı olarak ele alınacaktır (bölüm 4.1-4.7). Hareketli Ortalamanın hesaplama performansı ile ilgili resmin tamamını tahmin edelim.
Kolaylık sağlamak için sonuçlar grafiklerde sunulmuştur (bkz. şekil 1-5). Hareketli Ortalamanın çağrı türü X eksenlerinde sunulurken (bkz. tablo 2), Y eksenlerindeki değerler -1 ile çarpılan logaritmik ölçekte sunulmuştur; bu nedenle daha büyük değerler daha hızlı performans anlamına gelir. Hesaplama modellerinin her biri (SMA, EMA, SMMA, LWMA) grafikte bir sütuna karşılık gelir.
Şekil 1. Farklı Hareketli Ortalama algoritmaları için performans testi sonuçları
Hareketli Ortalama hesaplamasının farklı durumları için hesaplama hızında önemli bir fark görülebilir. Bu ne anlama gelir? MQL5 geliştiricileri tarafından sağlanan birkaç Hareketli Ortalama hesaplama algoritması farklı hesaplama performanslarına sahiptir: Hızlı bir algoritma (durum 6) ve daha yavaş yöntemler (durum 3 ve 4) vardır. Dolayısıyla, Hareketli Ortalamaları kullanan MQL5'te program yazarken doğru algoritmaları seçmek gerekir.
Her Hareketli Ortalama modelinin (0-6) hesaplama süresi aşağıdaki şekillerde ayrıntılı olarak sunulmuştur (bkz. tablo 2).
Şekil 2. MODE_SMA modunun MA hesaplama performansı
Şekil 3. MODE_EMA modunun MA hesaplama performansı
Şekil 4. MODE_SMMA modunun MA hesaplama performansı
Şekil 5. MODE_LWMA modunun MA hesaplama performansı
İki platformun hesaplama performansını karşılaştırmak ilginçtir: MetaTrader 4 ve MetaTrader 5. Sonuçlar Tablo 2'de, durum №0 (MQL4) ve durum №2'de (MQL5) sunulmuştur.
Kolaylık sağlamak için, iMA standart göstergesinin hesaplama sonuçlarını ayrı bir grafik ve tabloda birleştirelim (bkz. şekil 6). Testin hesaplama süresi Y eksenlerinde sunulmuştur.
Şekil 6. MetaTrader 4 и MetaTrader 5 hesaplama performansının karşılaştırmalı grafiği
Sonuçlar:
- Yeni MetaTrader 5 platformu, önceki MetaTrader 4'ten %40 oranında daha hızlıdır.
- En hızlı performans SMA, EMA ve SMMA modelleri için (durum №6), LWMA için (durum №2 ve №5) elde edilmiştir.
- Test durumları için, standart gösterge iMA kullanıldığında, farklı modellerin hesaplama performansı pratik olarak aynıdır. Bu, MovingAverages.mqh kitaplığı işlevleri için doğru değildir. Farklı modeller için performans neredeyse bir sıra (0,00023~0,0045) farklılık gösterir.
- Sunulan sonuçlar "soğuk başlatma"ya karşılık gelir, istemci terminalinin genel önbelleğinde önceden hesaplanmış herhangi bir veri yoktur.
4. Durum Çalışmaları
MQL5 geliştiricileri, standart teknik göstergelerin değerlerini almak için aşağıdaki yöntemi önerirler:
//---- indicator buffers double MA[]; // array for iMA indicator values //---- handles for indicators int MA_handle; // handle of the iMA indicator //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- creating handle of the iMA indicator MA_handle=iMA(NULL,0,21,0,MODE_EMA,PRICE_CLOSE); //--- print message if there was an error if(MA_handle<0) { Print("The iMA object is not created: MA_handle= ",INVALID_HANDLE); Print("Runtime error = ",GetLastError()); //--- forced termination of program return(-1); } return(0); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- filling the MA[] array with current values of the iMA indicator //--- we will copy 100 elements, or return if there was an error if(CopyBuffer(MA_handle,0,0,100,MA)<=0) return; //--- set ordering of MA[] as timeseries ArraySetAsSeries(MA,true); //--- here you can do anything with these data }
Hareketli ortalamaların hesaplama performansını test etmek için script dosyası kullanmak daha iyidir; zira bu, tüm hesaplamaları olayları beklemeden (örneğin, yeni tick olayı vb.) yapabilir.
Tüm test durumları için ayrı bir evrensel program oluşturmak gerekli değildir; bu nedenle her MA hesaplama durumu için ayrı bir script dosyası oluşturacağız.
Öyleyse, Hareketli Ortalama hesaplamalarının durumlarının her birini ayrıntılı olarak ele alalım.
4.1. Durum №0
Bu durumda MQL4'ün teknik göstergesi iMA'nın hesaplama performansını ölçtük. Hesaplamalar MetaTrader4'te gerçekleştirildi ve tüm veriler üzerinde uygulandı.
Model | Sonuç | En iyi sonuç |
---|---|---|
MODE_SMA | 0,0041 | 0,000140 (durum 6) |
MODE_EMA | 0,0040 | 0,000121 (durum 6) |
MODE_SMMA | 0,0043 | 0,000117 (durum 6) |
MODE_LWMA | 0,0041 | 0,0029 (durum 2, 5) |
Bu durumun kodu şu şekildedir (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; //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ int start() { if(ArrayResize(buf,count)<0) return(-1); Print("START "); 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("Total time [msec] ",time); time=time/1000/m/p/periodMA; Print("Performance [sec] ",DoubleToStr(time, 10)); return(0); } //+------------------------------------------------------------------+ void Test0() { //--- Model: 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); } }
Not: Bu kod, MQL4'te yazıldığı için MetaTrader 5'te çalışmayacaktır. MetaTrader 4 istemci terminalinde yürütülmelidir.
4.2. Durum №1
Bu durumda MovingAverages.mqh kitaplık işlevlerini kullanarak 4 modelin hesaplanmasını gerçekleştirdik: №1(SMA), №2(EMA), №3(SMMA) и №4(LWMA).
Hesaplama tüm veri dizisinde gerçekleştirildi.
Model | Sonuç | En iyi sonuç |
---|---|---|
MODE_SMA | 0,0028 | 0,000140 (durum 6) |
MODE_EMA | 0,00023 | 0,000121 (durum 6) |
MODE_SMMA | 0,00027 | 0,000117 (durum 6) |
MODE_LWMA | 0,0045 | 0,0029 (durum 2 ve 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; //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ 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(); // the test is here } } } //--- 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); } }
Not. Dizideki çeşitli veri türlerini kullanmayı planladık ancak kolaylık sağlamak için, yalnızca kapanış fiyatı verilerini içeren bir diziyi kullandık (bu, hesaplamaların performansını etkilemez).
4.3. Durum №2
Bu durumda iMA standart teknik göstergesini ve test №5'i kullandık.
Hesaplama tüm veri dizisinde gerçekleştirildi.
Model | Sonuç | En iyi sonuç |
---|---|---|
MODE_SMA | 0,0029 | 0,000140 (durum 6) |
MODE_EMA | 0,0029 | 0,000121 (durum 6) |
MODE_SMMA | 0,0029 | 0,000117 (durum 6) |
MODE_LWMA | 0,0029 | 0,0029 (durum 2 ve 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[]; // array for the iMA indicator int MA_handle; // handle of the iMA indicator //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ 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() { //--- Model: 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. Durum №3
№3 durumunda, Standart kitaplık sınıflarının göstergeleriyle çalışan sınıflar kullanıldı.
Elementwise veri kopyalama özelliği kullanıldı. Hesaplama tüm veri dizisinde gerçekleştirildi.
Model | Sonuç | En iyi sonuç |
---|---|---|
MODE_SMA | 0,0998 | 0,000140 (durum 6) |
MODE_EMA | 0,0997 | 0,000121 (durum 6) |
MODE_SMMA | 0,0998 | 0,000117 (durum 6) |
MODE_LWMA | 0,0998 | 0,0029 (durum 2 ve 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; //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ 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() { //--- Model: 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. Durum №4
№4 durumunda, Standart kitaplık sınıflarının göstergeleriyle çalışan sınıflar kullanıldı.
Gösterge arabelleğinin dizisi bir bütün olarak kopyalandı. Hesaplama tüm veri dizisinde gerçekleştirildi.
Model | Sonuç | En iyi sonuç |
---|---|---|
MODE_SMA | 0,0996 | 0,000140 (durum 6) |
MODE_EMA | 0,0996 | 0,000121 (durum 6) |
MODE_SMMA | 0,0996 | 0,000117 (durum 6) |
MODE_LWMA | 0,0996 | 0,0029 (durum 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; //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ 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() { //--- Models: 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. Durum №5
№8 testi kullanıldı: Gösterge tanıtıcısı IndicatorCreate işlevi kullanılarak oluşturuldu.
Hesaplama tüm veri dizisinde gerçekleştirildi.Model | Sonuç | En iyi sonuç |
---|---|---|
MODE_SMA | 0,0030 | 0,000140 (durum 6) |
MODE_EMA | 0,0029 | 0,000121 (durum 6) |
MODE_SMMA | 0,0029 | 0,000117 (durum 6) |
MODE_LWMA | 0,0029 | 0,0029 (durum 2 ve 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[]; // array for the iMA indicator int MA_handle; // handle of the iMA indicator MqlParam params[]; //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ 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() { //--- Model: MODE_SMA; MODE_EMA; MODE_SMMA; MODE_LWMA //--- set ma_period params[0].type =TYPE_INT; params[0].integer_value=periodMA; //--- set ma_shift params[1].type =TYPE_INT; params[1].integer_value=0; //--- set ma_method params[2].type =TYPE_INT; params[2].integer_value=MODE_SMA; //--- set applied_price params[3].type =TYPE_INT; params[3].integer_value=P[p]; //--- create 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. Durum №6
Bu durumda MovingAverages.mqh kitaplık işlevlerini (MQL4'ten iMAOnArray gibi arabellek işlevleri) kullanarak 4 modelin hesaplanmasını gerçekleştirdik: №9(SMA), №10(EMA), №11(SMMA) и №12(LWMA).
Hesaplama tüm veri dizisinde gerçekleştirildi.
Model | Sonuç | En iyi sonuç |
---|---|---|
MODE_SMA | 0,000140 | 0,000140 (durum 6) |
MODE_EMA | 0,000121 | 0,000121 (durum 6) |
MODE_SMMA | 0,000117 | 0,000117 (durum 6) |
MODE_LWMA | 0,00350 | 0,0029 (durum 2 ve 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; //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ 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(); // the test is here } } } //--- 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); }
Not. Dizideki çeşitli veri türlerini kullanmayı planladık fakat kolaylık sağlamak için kapanış fiyatı verileriyle yalnızca bir dizi kullandık (bu, hesaplamaların performansını etkilemez).
5. Sonuçların Çıktısı
Sonuçların çıktısı ve hareketli ortalamaların kontrolü için PrintTest işlevini kullandım:
void PrintTest(const int position, const double &price[]) { Print("Total time [msec] ",(endGTC-startGTC)); Print("Performance [sec] ",time); Print(position," - array element = ",price[position]); }
Bu, şu şekilde çağrılabilir (çubuk pozisyonu ve veri dizisi, işlevin parametreleridir):
//--- 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; //--- Output of results ArraySetAsSeries(buf,true); ArraySetAsSeries(close,true); PrintTest(0,buf); PrintTest(0,close); //---
Dizi indekslemenin hesaplamalardan önce ve sonra farklı olduğunu unutmayın.
ÖNEMLİ. AsSeries bayrağı, hesaplamalar sırasında false olarak ayarlanır ve sonuçlar yazdırılırken true olarak ayarlanır.
6. Ek Araştırmalar
Başlangıç parametrelerinin hesaplama performansı üzerindeki etkisi ile ilgili soruyu yanıtlamak için bazı ek ölçümler yapılmıştır.
Hatırladığımız üzere, №6 durumu en iyi performansa sahiptir; bu nedenle onu kullanacağız.
Test parametreleri:
Mod | Zaman dilimi | Ortalama alma süresi |
---|---|---|
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 |
Tablo 3. Ek araştırmalar
Testlerin kaynak kodu:
//+------------------------------------------------------------------+ //| 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); }
Ek testler için otomatik test programını kullanacağız; buna ait grafik kullanıcı arayüzü Şekil 7'de sunulmuştur.
Şekil 7. Otomatik test için otomatik test programı
Sonuçlar: (X ekseninin logaritmik bir zaman ölçeği vardır)
Şekil 8. Zaman dilimi parametresi (Y) ve Hareketli Ortalamalar hesaplama performansı (X)
Şekil 9. Dönem parametresi (Y) ve Hareketli Ortalamalar hesaplama performansı (X)
Ek araştırmaların sonuçlarının sonuçları:
- Zaman dilimi parametresi önemli değildir; hesaplama performansını etkilemez (bkz. şek. 8).
- SMA, EMA ve SMMA modelleri için hareketli ortalamalar hesaplama performansı için dönem önemli bir parametre değildir. Ancak bunun aksine, LWMA modeli için hesaplamaları önemli ölçüde (0,00373 saniyeden 0,145 saniyeye) yavaşlatır (bkz. şek. 9).
Sonuç
Hareketli ortalamalar algoritmasının yanlış şekilde seçilmesi, programlarınızın hesaplama performansını düşürebilir.
MetaQuotes Ltd tarafından Rusçadan çevrilmiştir.
Orijinal makale: https://www.mql5.com/ru/articles/106





- Ücretsiz alım-satım uygulamaları
- İşlem kopyalama için 8.000'den fazla sinyal
- Finansal piyasaları keşfetmek için ekonomik haberler
Gizlilik ve Veri Koruma Politikasını ve MQL5.com Kullanım Şartlarını kabul edersiniz