Hareketli Ortalama (ve diğer göstergeler) değerlerinin ve hatanın karşılaştırılması

 

Merhaba!

SMA kesişimine dayalı bir Uzman Danışman yazıyorum (daha doğrusu, zaten yazdığımı düşündüm, çünkü her şey basit görünüyor). Ama ... Bir sorunla karşılaştım. EA aşağıdaki prensibe göre çalışır: yeni bir çubuk göründüğünde, son iki çubuk için SMA değerleri analiz edilir, az önce görüneni saymaz (sondan bir önceki ve sondan bir önceki). Burada açıklandığı gibi değerleri doğru gibi karşılaştırıyorum. Tek istisna, iMA'nın sırasıyla son parametre (çubuklarda ofset) 1 ve 2 ile çağrılmasıdır. Bunun gibi bir şey (kod, alıntılanan koda benzer şekilde yeniden yapılırsa):

 // берем два соседних значения Быстрой МА
double fast0= iMA ( Symbol (), Period (), 10 , 0 , MODE_SMA , PRICE_CLOSE , 1 );
double fast1= iMA ( Symbol (), Period (), 10 , 0 , MODE_SMA , PRICE_CLOSE , 2 );
 
// берем два значения Медленной МА
double slow0= iMA ( Symbol (), Period (), 20 , 0 , MODE_SMA , PRICE_CLOSE , 1 );
double slow1= iMA ( Symbol (), Period (), 20 , 0 , MODE_SMA , PRICE_CLOSE , 2 );
 
// сравниваем значения и определяем направление пересечения
if (fast0>slow0 && fast1<slow1) Print ( "Пересечение ВВЕРХ" );
if (fast0<slow0 && fast1>slow1) Print ( "Пересечение ВНИЗ" );

Uzman Danışman, önceki anlaşmayı kapatma - yeni bir anlaşma açma ilkesine göre kavşak hakkında bir sinyal varlığında ilkel bir biçimde çalışır. Bu durumda elbette tüm kavşaklar belirlenirse işlemler hep sırayla gidecektir (SAT - AL - SAT - AL - ...). Yani, danışmanın herhangi bir zamanda yalnızca bir açık anlaşması vardır (ilk anlaşmaya girmeden önceki an hariç). Demek sorunun özü bu... 17/02/2015 01:24'ten barda strateji test cihazında Close için 1 dakikalık zaman dilimi ve 5 ve 34 SMA periyotları için ilginç bir durum yakaladım. Bu tür özelliklere sahip hareketler, doğrudan barın kapanışında kesişir. İşte resim:

17.02.2015 01:24

Hata ayıklama için bilgileri görüntülüyorum. Günlükte, yukarıdaki kodla karşılaştırıldığında yazışma aşağıdaki gibidir:

SMAFastCurrent = hızlı0

SMASlowCurrent = yavaş0

SMAFastÖnceki = hızlı1

SMASlowPrevious = yavaş1 ve

SMACurDifference = SMFastCurrent - SMASlowCurrent

SMAPrevDifference = SMAFastPrevious - SMASlowPreviousс (yani, hızlı0, yavaş0 ve hızlı1 , yavaş1 arasındaki fark   sırasıyla).

Yani, bu farklar işaret değiştirdiğinde, bu Hareketli Ortalamaların kesişimi için bir sinyal anlamına gelir. Ancak gerçek şu ki, bu özel örnekte, aşağı yukarı kontrol çalışmıyor. Bu farklılıkların değerleri logda görüntülenir. Kırmızı dikdörtgen, sorunlu çubuktan sonraki (1:25'te) sonraki farkları, bir sonrakindeki turuncu olanı (1:26'da) vurgular. Ayrıca, önceki çubuktaki SMACurDifference ve mevcut çubuktaki SMACurDifference değerlerinin eşit olması gerektiği açıktır (mevcut çubuk, önceki çubuk gibi görünüyor ve yeni çubuk, mevcut çubuğun yerini alıyor). Bu nedenle, Hareketli Ortalamaların kesişimi doğrudan 1:24'te sorun çubuğunun kapanışında gerçekleştiğinden, bir sonraki çubukta (1:25'te) SMFastCurrent ve SMASlowCurrent değerleri eşittir (yaklaşık olarak). Hata ayıklayıcı bunları genellikle 5 basamak içinde görüntüler (SMAFastCurrent = 1.13371 SMASlowCurrent = 1.13371 bkz. Şekil). Ayrıca, farkları sonsuz derecede küçüktür, ancak 0 değildir (SMACurDifference = 2.220446049250313e-016). Bir sonraki çubukta, farkları tam olarak aynı değerlerle tam olarak sıfır olur (kırmızıdaki SMACurDifference ve turuncu dikdörtgenlerdeki SMACurDifference'ı karşılaştırın). Aslında, genel olarak, görünüşte aynı değerler farklı bir fark verse bile, bu hataların nasıl kesileceği açık değildir. Dolayısıyla iki soru:

1. İki bitişik çubuğun birbirini takip etmesi durumunda basitçe hesaplanan aynı hareketlerin farkı neden farklı bir sonuç veriyor?

2. Bir çeşit epsilon tanıtmayı ve onunla karşılaştırmayı düşündüm, sıfırla değil. Ancak bu genellikle bir sonsuz küçüklüğü 0 ile karşılaştırmak için yapılır. Peki ya bu sonsuz küçüklüğün işaret değişimini belirlemem gerekirse?

Tabii ki, üç bitişik çubuğu da analiz edebilirsiniz, ancak teorik olarak kapanış fiyatlarında hareketli ortalamaların sonsuz küçük bir mesafede birbirine değmesi hala mümkündür. Evet ve böyle bir durumun nadiren meydana geldiğini anlıyorum (özellikle daha büyük bir zaman dilimi alırsanız), ancak yine de olabilir. Ve bir şekilde yakalanmalı ve bu durumda da Hareketli Ortalamaların kesişimi belirlenmelidir.

Herhangi bir yardım için şimdiden teşekkürler!

Навигатор по форуму и ответы на часто задаваемые вопросы. Настоятельно Рекомендуется к Прочтению! - MQL4 форум
  • www.mql5.com
Навигатор по форуму и ответы на часто задаваемые вопросы. Настоятельно Рекомендуется к Прочтению! - MQL4 форум
 

Normalleştirmeyi ve karşılaştırmayı deneyin.

MQL4 Referansı (ve MQL5 aynıdır), " Gerçek türler (çift, kayan nokta)" açık diyor:

"... Eşitlik için iki gerçek sayıyı karşılaştıramazsınız. Çoğu durumda, 15. ondalık basamağın değerindeki fark nedeniyle, görünüşte aynı iki sayı eşit olmayabilir. İki gerçeğin doğru bir karşılaştırması için sayılar, bu sayıların normalleştirilmiş farkını boş değerle karşılaştırmak gerekir .... "

"... eşitlik için iki gerçek sayının karşılaştırılması kategorik olarak önerilmez, çünkü böyle bir karşılaştırma doğru değildir.

................


Hala eşitlik için iki gerçek sayıyı karşılaştırmanız gerekiyorsa, bunu iki farklı şekilde yapabilirsiniz. İlk yol, iki sayı arasındaki farkı, karşılaştırmanın doğruluğunu belirten küçük bir değerle karşılaştırmaktır.

................


İkinci yöntem, iki gerçek sayının normalleştirilmiş farkının sıfır ile karşılaştırılmasını içerir. Normalleştirilmiş sayıların farkını sıfırla karşılaştırmak işe yaramaz, çünkü normalleştirilmiş sayılarla herhangi bir matematiksel işlem sonucunda sonuç normalleştirilmez.

. ... "

 
rosomah :

Normalleştirmeyi ve karşılaştırmayı deneyin.

MQL4 Referansı (ve MQL5 aynıdır), " Gerçek türler (çift, kayan nokta)" açık diyor:

"... Eşitlik için iki gerçek sayıyı karşılaştıramazsınız. Çoğu durumda, 15. ondalık basamağın değerindeki fark nedeniyle, görünüşte aynı iki sayı eşit olmayabilir. İki gerçeğin doğru bir karşılaştırması için sayılar, bu sayıların normalleştirilmiş farkını boş değerle karşılaştırmak gerekir .... "

"... böyle bir karşılaştırma doğru olmadığı için, eşitlik için iki gerçek sayının birbiriyle karşılaştırılması kategorik olarak önerilmez.

................


Hala eşitlik için iki gerçek sayıyı karşılaştırmanız gerekiyorsa, bunu iki farklı şekilde yapabilirsiniz. İlk yol, iki sayı arasındaki farkı, karşılaştırmanın doğruluğunu belirten küçük bir değerle karşılaştırmaktır.

................


İkinci yöntem, iki gerçek sayının normalleştirilmiş farkının sıfır ile karşılaştırılmasını içerir. Normalleştirilmiş sayıların farkını sıfırla karşılaştırmak işe yaramaz, çünkü normalleştirilmiş sayılarla herhangi bir matematiksel işlem sonucunda sonuç normalleştirilmez.

. ... "

Gerçek sayıları eşitlik için karşılaştırmanın imkansız olduğunu çok iyi anlıyorum. Sağladığım kodda eşitlik karşılaştırması yok. Evet ve burada gerekli değildir. Açıkça 0'a düşebilecek bir sonsuz küçük işaretindeki değişikliği yakalamanın gerekli olduğu bir durum. Her şeyi 0'dan büyük veya 0'a eşit olarak karşılaştırmak aptalcadır, bu durumda da tehlikelidir. Ve burada normalleşme daha da tehlikeli olabilir... Başlangıç MA değerlerinin hangi rakama normalize edileceği açık değildir (zaman aralığı ne kadar küçükse MA değerleri o kadar küçüktür). Ondalık nokta ayarlandıktan sonra sabit bir basamağa normalleştirme yapılırsa, tüm MA değerlerinin tam olarak 0 olacağı ortaya çıkabilir. Dürüst olmak gerekirse, iki MA farkının normalleşmesinin ne olduğunu tam olarak anlamıyorum. değerler verecek ...

 

gammaray :

Gerçek sayıları eşitlik için karşılaştırmanın imkansız olduğunu çok iyi anlıyorum. Verdiğim kodda eşitlik karşılaştırması yok. Evet ve gerekli değil. Açıkça 0'a düşebilecek bir sonsuz küçük işaretindeki değişikliği yakalamanın gerekli olduğu bir durum. Her şeyi 0'dan büyük veya 0'a eşit olarak karşılaştırmak aptalcadır, bu durumda da tehlikelidir. Ve burada normalleşme daha da tehlikeli olabilir... Başlangıç MA değerlerinin hangi rakama normalize edileceği açık değildir (zaman aralığı ne kadar küçükse MA değerleri o kadar küçüktür). Ondalık nokta ayarlandıktan sonra sabit bir basamağa normalleştirme yapılırsa, tüm MA değerlerinin tam olarak 0 olacağı ortaya çıkabilir. Dürüst olmak gerekirse, iki MA farkının normalleşmesinin ne olduğunu tam olarak anlamıyorum. değerler verecek ...

Normalleşme neden daha tehlikeli?

Böylece:

...

Hala eşitlik için iki gerçek sayıyı karşılaştırmanız gerekiyorsa , bunu iki farklı şekilde yapabilirsiniz . İlk yol, iki sayı arasındaki farkı, karşılaştırmanın doğruluğunu belirten küçük bir değerle karşılaştırmaktır.

...

İkinci yöntem, iki gerçek sayının normalleştirilmiş farkının sıfır ile karşılaştırılmasını içerir. Normalleştirilmiş sayıların farkını sıfırla karşılaştırmak işe yaramaz, çünkü normalleştirilmiş sayılarla herhangi bir matematiksel işlem sonucunda sonuç normalleştirilmez.

Misal:

 bool CompareDoubles( double number1, double number2)
  {
   if ( NormalizeDouble (number1-number2, 8 )== 0 ) return ( true );
   else return ( false );
  }
void OnStart ()
  {
   double d_val= 0.3 ;
   float   f_val= 0.3 ;
   if (CompareDoubles(d_val,f_val)) Print (d_val, "equals" ,f_val);
   else Print ( "Different: d_val = " , DoubleToString (d_val, 16 ),
               "  f_val = " , DoubleToString (f_val, 16 ));
// Результат: Different: d_val= 0.3000000000000000   f_val= 0.3000000119209290
  }
  • ve kişisel pratik deneyimim (mütevazı söylemek gerekirse, çift sayıların karşılaştırmasını kullandığım ve hala kullandığım programların çalışmalarının titiz mutabakatlarının sayısı açısından, tetikleme koşullarının doğruluğu açısından çok küçük değil. bu tür karşılaştırmalarda),
bu tür karşılaştırmaları sadece zararsız olarak görmeme izin verin:
 if ( NormalizeDouble (number1-number2,dig)== 0 )
if ( NormalizeDouble (number1-number2,dig)> 0 )
if ( NormalizeDouble (number1-number2,dig)< 0 )

// dig=Digits();

aynı zamanda, tersine, Documentation'ın dediği gibi, double türündeki sayıların karşılaştırılması için kullanılabilen iki yoldan birinin çeşitleri .

Çünkü :

Eşitlik için iki gerçek sayıyı birbiriyle karşılaştıramazsınız. Çoğu durumda, görünüşte aynı iki sayı, 15. ondalık basamaktaki değer farkı nedeniyle eşit olmayabilir. İki reel sayının doğru bir şekilde karşılaştırılması için bu sayıların normalleştirilmiş farkını sıfır değeri ile karşılaştırmak gerekir.



P./S.: Öyle oldu ki, Dokümantasyondaki ilk yöntemin, kural olarak kendim için çözdüğüm görevler de dahil olmak üzere benim için daha az uygun olduğu ortaya çıktı. Buna göre, ilk yöntemde çok fazla birikmiş deneyimim yok.

Ancak ikinci yöntemi uygularken (yani, koşullu operatörün ifadesinde iki gerçek sayının normalleştirilmiş farkını sıfır değeriyle karşılaştırırken ), açık bir şekilde herhangi bir sorun ortaya çıkmadı.

Ancak normalleştirilmemiş sayıların karşılaştırmalarını yaptıysam (burada demek istediğim, ilk yöntemi kullanmadan da dahil), o zaman evet, çift sayıların karşılaştırmalarına dayalı koşulların yanlış tetiklendiğini ortaya çıkardı.

 
gammaray :

İşte Belgelerdeki ifadeler:

İkinci yöntem, iki gerçek sayının normalleştirilmiş farkının sıfır ile karşılaştırılmasını içerir. Normalleştirilmiş sayıların farkını sıfırla karşılaştırmak işe yaramaz, çünkü normalleştirilmiş sayılarla herhangi bir matematiksel işlem sonucunda sonuç normalleştirilmez.

benim için, basitleştirilmişse, matematiksel işlemler sırasında (çeşitli dönüşümler dahil) böyle bir şey yapmamanız gerektiği algılanıyor:

 // dig=Digits();

double delta= NormalizeDouble (number1-number2,dig);

if (delta> 0 )


Yani bir önceki gönderide sıfır değerli iki reel sayının normalleştirilmiş farkının karşılaştırmalarına örnekler verdim. Ve bu yazıda, normalleştirilmiş sayıların farkını sıfırla karşılaştırmak (yukarıdaki ifadelerin metnini Belgelerden anladığım kadarıyla).

Kısaca şöyle bir şey.

 

gammaray :

...

Dürüst olmak gerekirse, iki MA değeri arasındaki farkın normalleşmesinin ne vereceğini gerçekten anlamıyorum.

P./S.: Bu soru için, büyük miktarda veriye neyin yazdırılacağını görmek için bir süreliğine Print() kodunu koda koyabilirsiniz. Matematiksel işlemlere dayalı olarak elde edilen normalleştirilmemiş ve normalize edilmiş (deneyler yapacağınız çizelgede dahil ve daha fazlası dahil olmak üzere herhangi bir ondalık basamağa kadar) değerleri yazdırın. Matematiksel işlemler temelinde oluşturuldukları için sadece normalleştirilmemiş ve normalleştirilmiş iMA değerleri dahil.

Her ihtimale karşı, double türündeki normalleştirilmemiş ve normalleştirilmiş değerleri yazdırırken, yine de DoubleToString kullanılarak sayısal bir değerden bir metin değerine ek olarak dönüştürülmeleri gerektiğini açıklığa kavuşturacağım (ve sayıyı deneyin). DoubleToString'de ondalık basamak sayısı).

 
gammaray :

P./S.: Ayrıca, MQL4 programlamaya hakim olmak için yazılmış herhangi bir şema örneğinde, bir yerde matematiksel hesaplamaların değerlerinin normalleştirilmesinin öngörülmeyebileceğini ve/veya doğrudan şart koşulmayacağını da ekleyeceğim:

  • herhangi bir koşulun oluşumu için şemaların algılanması kolaylığı için;
  • her zaman ve / veya her yerde normalleştirme gerekli olmayabilir (görevler için farklı izin verilen hata seviyeleri için kullanıldığı varsayılabileceği ve buna bağlı olarak matematiksel işlemlerin sonuçlarının çeşitli daha fazla normalleştirilmesi (veya yokluğu) dahil olmak üzere) bazı bireysel görevler için ondalık basamak sayısı );
  • ve/veya, büyük olasılıkla, varsayılan olarak, programlama öğrenen kişinin Belgelere zaten aşina olduğu ve/veya sorularını açıklığa kavuşturmak da dahil olmak üzere, üzerinde çalışacağı varsayıldığından.
Bunun gibi bir şey.
 
daha doğru
 // сравниваем значения и определяем направление пересечения
if (fast0>slow0 && fast1<=slow1) Print ( "Пересечение ВВЕРХ" );
if (fast0<slow0 && fast1>=slow1) Print ( "Пересечение ВНИЗ" );

bir anlamda ma değerlerinin eşit çıkabileceği hesaba katılmamıştır.

сравнивать вещественные числа на равенство нельзя

Başka bir şey hakkında birkaç tane.
 
Aleksey Lebedev :
Başka bir şey hakkında birkaç tane.

Ne demek istediğinize ve hangi görevler/amaçlar için bağlıdır.

Bu yüzden, bu konuya yazı yazarken, şunlardan ilerledim:

  • ekran görüntüsü ve sorular ilk gönderide;
  • konunun yazarının ikinci yazısı (normalleşme tehlikesi hakkında),

ve buna göre, buradan ve kısaca yukarıdaki yazılarımın anlamı:

Karşılaştırmaların (ve / veya değerlerin çıktısının) gerekli doğruluk seviyesini ve / veya bazı görevler ve amaçlar için kabul edilebilir hataları ayarlamak / ayarlamak için normalleştirmeyi kullanma yeteneği hakkında, bu da diğer şeylerin yanı sıra program koşullarına izin verir. tam olarak orada çalışmak ve böylece, kodda belirli koşullar reçete edilirken nerede ve nasıl amaçlandığı. Ve normalleştirilmiş farkı sıfırla karşılaştırmak, yalnızca ilişki işlemini kullanarak karşılaştırırken ayarlamanıza / ayarlamanıza izin vermez: "==".


P./S.: Aynı zamanda, her ihtimale karşı, burada listelenen ikisinden ilk şekilde gerçek sayıları karşılaştırmayı, sayılardaki farkı küçük bir değerle karşılaştırarak, yapabileceğimi bir kez daha açıklayacağım. Karşılaştırma seviyesini ayarlamanız gerektiğinde normalleştirmeyi kullanmaktan daha kötü deyin (ikinci yöntemin benim için daha uygun olduğu ortaya çıktığından, birincisi pratik uygulama için kendim için daha ayrıntılı olarak düşünmedi).

 

Burada mql'nin prensipte bununla hiçbir ilgisi yoktur. Soyut bir programlama dili alın. Verdiğim bu özel örnekte asıl sorun, aynı çubuktaki hareketlerin farkı değerlerinin eşit olmamasıdır (ilk hesaplamada 2e-16 ve ikinci hesaplamada tam olarak 0). Bu durumda genel olarak bu kavşak hiçbir şekilde belirlenemez. Mql'ye dönersek, normalleştirme sayıyı yuvarlamak anlamına gelir (daha doğrusu, C kat işlevine benzer şekilde belirli bir işaretten sonra tüm sayıları atmak, yalnızca ondalık noktadan sonra belirli bir işarete kadar). Peki hangi sayıya normalleştirileceğini nasıl belirlersiniz? Yanlış sayıyı seçerseniz, tüm değerler DAİMA tam olarak 0'a yuvarlanabilir. Bu nedenle, normalleştirme burada tehlikelidir ve genellikle sorunu çözmez.

Alexey Lebedev'in yazdıklarına gelince. Evet, bu doğrultuda düşünüyordum. Ancak her iki farkı 0'dan büyük veya 0'a eşit olarak karşılaştırırsak, yanlış bir sinyal alma olasılığı vardır (örneğin, komşu çubuklar arasında hareket ederken teorik olarak olası bir durum tamamen aynı değerlerle gelir). O zaman farklılıkları, olduğu gibi, işareti değiştirmez (kavşak yoktur), ancak kavşağa giden sinyal programlı olarak belirlenir. Önerdiğiniz gibi, büyüktür veya eşittir üzerine yalnızca bir karşılaştırma yapmak mümkündür. Ancak o zaman bütün sorun şu ki, bu durumda hesaplarken, ilk başta 0'a (2e-16) eşit olmayacak ve bir sonraki çubukta zaten tam olarak 0 olacak, ancak zaten katı bir karşılaştırma olacak.

Burada, farklı çubuklar üzerinde hesaplandığında aynı farkın neden aynı sonucu VERMİYOR olduğunu anlamak önemlidir??? Sonuç aynı olsaydı, sorunun her zaman katı olmayan bir karşılaştırma yaparak çözüleceği anlaşılıyordu.

 

gammaray :

Ancak o zaman bütün sorun şu ki, bu durumda hesaplarken, ilk başta 0'a (2e-16) eşit olmayacak ve bir sonraki çubukta zaten tam olarak 0 olacak, ancak zaten katı bir karşılaştırma olacak.

Burada, farklı çubuklar üzerinde hesaplandığında aynı farkın neden aynı sonucu VERMİYOR olduğunu anlamak önemlidir??? Sonuç aynı olsaydı, sorunun her zaman katı olmayan bir karşılaştırma yaparak çözüleceği anlaşılıyordu.

Büyük olasılıkla, iMA işlevinin hesaplanması optimize edilmiştir. İlk değer = toplam(kapat)/N, ikinci = MA+(yeni yakın eski kapanış)/N'nin önceki değeri.