Hatalar, hatalar, sorular - sayfa 2822

 
Nikolai Semko :

Sadece yuvarlama normal round(), ceil(), floor() ile yapılmaz. onlar da çift döner.

Ve bunlar sayesinde, normal olanlardan daha hızlı çalışırlar:

Belki daha hızlı, ama sadece yanlış.
Tavanınıza 12345.00000000000001 gibi bir şey iletin (örneğinize benzer) ve sonunda 12346 ile sonuçlanabilir.
 
Alexey Navoykov :
Belki daha hızlı, ama sadece yanlış.
Tavanınıza 12345.00000000000001 gibi bir şey iletin (örneğinize benzer) ve sonunda 12346 ile sonuçlanabilir.

Kendin denedin mi?
Denemek:

 Print ( ceil ( 12345.0000000000001 ));
Print (Ceil( 12345.0000000000001 ));
Print ( ceil ( 12345.000000000001 ));
Print (Ceil( 12345.000000000001 ));

Çıktı:

 2020.08 . 10 12 : 03 : 23.856 ErrorNormalizeDouble (EURUSD,M1)         12345.0
2020.08 . 10 12 : 03 : 23.856 ErrorNormalizeDouble (EURUSD,M1)         12345
2020.08 . 10 12 : 03 : 23.856 ErrorNormalizeDouble (EURUSD,M1)         12346.0
2020.08 . 10 12 : 03 : 23.856 ErrorNormalizeDouble (EURUSD,M1)         12346
12346 olmalı, çünkü is ceil (" Üstten en yakın tamsayı değerini döndürür .")
ilk durumda, 12345 elde edilir, çünkü çift tip 17'deki önemli rakamlar ve 18'iniz var
 
Nikolai Semko :

Gerçekten de, çift karşılaştıramazsınız. Sadece zor bir kural.

Tabii ki, çiftleri doğrudan birbirleriyle karşılaştırabilirsiniz ve hatta bazen buna ihtiyaç duyabilirsiniz.

Örneğin, Optimizasyon sırasında OnTick'e bazen trilyon kez denir. Askıda kalma limitinin uygulanıp uygulanmayacağını anlamak için Staff Tester, sembolün mevcut karşılık gelen fiyatı ile limitin fiyatını karşılaştırır. Bunu her OnTick çağrısından önce her erteleme için yapar. Onlar. bu tür kontroller onlarca ve yüz milyarlarca kez yapılır.

Ve bu her seferinde normalleştirme yoluyla yapılır. Yani - bu, hiçbir şey için korkunç bir bilgi işlem kaynakları israfı. Çünkü fiyatlar ve bekleyen emirler ve semboller önceden normalleştirilir. Bu nedenle, doğrudan birbirleriyle karşılaştırılabilir ve karşılaştırılmalıdır.

Maviden değil, MQL-özel Test Cihazı, performans açısından yerel normal Test Cihazından daha iyi performans gösteriyor.

 

fxsaber
:

Tabii ki, çiftleri doğrudan birbirleriyle karşılaştırabilirsiniz ve hatta bazen buna ihtiyaç duyabilirsiniz.

Örneğin, Optimizasyon sırasında OnTick'e bazen trilyon kez denir. Askıda kalma limitinin uygulanıp uygulanmayacağını anlamak için Staff Tester, sembolün mevcut karşılık gelen fiyatı ile limitin fiyatını karşılaştırır. Bunu her OnTick çağrısından önce her erteleme için yapar. Onlar. bu tür kontroller onlarca ve yüz milyarlarca kez yapılır.

Ve bu her seferinde normalleştirme yoluyla yapılır. Yani - bu, hiçbir şey için korkunç bir bilgi işlem kaynakları israfı. Çünkü fiyatlar ve bekleyen emirler ve semboller önceden normalleştirilir. Bu nedenle, doğrudan birbirleriyle karşılaştırılabilir ve karşılaştırılmalıdır.

Maviden değil, MQL-özel Test Cihazı, performans açısından yerel normal Test Cihazından daha iyi performans gösteriyor.

NormalizeDouble() çok pahalı bir fonksiyondur. Bu nedenle, onu unutmak daha iyidir.

NormalizeDouble() ile int ile normalleştirme arasındaki farkı gösteren bir betik:

 #define   SIZE 1000000

int Ceil ( double x) { return (x-( int )x> 0 )?( int )x+ 1 :( int )x;}
int Round( double x) { return (x> 0 )?( int )(x+ 0.5 ):( int )(x- 0.5 );}
int Floor( double x) { return (x> 0 )?( int )x:(( int )x-x> 0 )?( int )x- 1 :( int )x;}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart ()
  {
   double a[SIZE];
   double s1= 0 ,s2= 0 , s3= 0 ;
   for ( int i= 0 ;i<SIZE;i++)  a[i]=( rand ()- 16384 )/ M_PI ;
   
   ulong t1= GetMicrosecondCount ();
   for ( int i= 0 ;i<SIZE;i++) s1+=a[i];
   t1= GetMicrosecondCount ()-t1;  
   
   ulong t2= GetMicrosecondCount ();
   for ( int i= 0 ;i<SIZE;i++) s2+= NormalizeDouble (a[i], 5 );
   t2= GetMicrosecondCount ()-t2; 
   
   ulong t3= GetMicrosecondCount ();
   for ( int i= 0 ;i<SIZE;i++) s3+=Round(a[i]* 100000 );
   s3/= 100000 ;
   t3= GetMicrosecondCount ()-t3; 
   
   Print ( "простая сумма                            - " + string (t1)+ " микросекунд, сумма = " + DoubleToString (s1, 18 ));
   Print ( "сумма с NormalizeDouble                  - " + string (t2)+ " микросекунд, сумма = " + DoubleToString (s2, 18 ));
   Print ( "сумма, нормализированная через int       - " + string (t3)+ " микросекунд, сумма = " + DoubleToString (s3, 18 ));
  }

sonuç:

 2020.08 . 10 12 : 55 : 30.766 TestSpeedNormalizeDouble (USDCAD,H4)    простая сумма                            - 1394 микросекунд, сумма = 626010.5038610587362201
2020.08 . 10 12 : 55 : 30.766 TestSpeedNormalizeDouble (USDCAD,H4)    сумма с NormalizeDouble                   - 5363 микросекунд, сумма = 626010. 50460 99 795727060
2020.08 . 10 12 : 55 : 30.766 TestSpeedNormalizeDouble (USDCAD,H4)    сумма, нормализированная через int        - 1733 микросекунд, сумма = 626010. 50460 99999 453873
Tehdit ve int yoluyla normalleştirme daha da doğrudur (bu, normalleştirmenin son basamağından sonraki dokuz sayısı ile görülebilir - mavi renkle vurgulanır.)
 
Nikolai Semko :

NormalizeDouble() çok pahalı bir fonksiyondur. Bu nedenle, onu unutmak daha iyidir.

NormalizeDouble() ile int ile normalleştirme arasındaki farkı gösteren bir betik:

sonuç:

Tehdit ve int yoluyla normalleştirme daha da doğrudur (bu, normalleştirmenin son basamağından sonraki dokuz sayısı ile görülebilir - mavi renkle vurgulanır.)

ve eğer double ile değil de uzun ile özetlerseniz, sonuç daha da etkileyicidir, çünkü int yoluyla toplama (toplam toplamın daha sonra bölünmesiyle çarpma ve yuvarlama) normal çift toplamdan daha hızlı hesaplanır.

 #define   SIZE 1000000

int Ceil ( double x) { return (x-( int )x> 0 )?( int )x+ 1 :( int )x;}
int Round( double x) { return (x> 0 )?( int )(x+ 0.5 ):( int )(x- 0.5 );}
int Floor( double x) { return (x> 0 )?( int )x:(( int )x-x> 0 )?( int )x- 1 :( int )x;}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart ()
  {
   double a[SIZE];
   double s1= 0 ,s2= 0 , s3= 0 ;
   long s= 0 ;
   for ( int i= 0 ;i<SIZE;i++)  a[i]=( rand ()- 16384 )/ M_PI ;
   
   ulong t1= GetMicrosecondCount ();
   for ( int i= 0 ;i<SIZE;i++) s1+=a[i];
   t1= GetMicrosecondCount ()-t1;  
   
   ulong t2= GetMicrosecondCount ();
   for ( int i= 0 ;i<SIZE;i++) s2+= NormalizeDouble (a[i], 5 );
   t2= GetMicrosecondCount ()-t2; 
   
   ulong t3= GetMicrosecondCount ();
   for ( int i= 0 ;i<SIZE;i++) s+=Round(a[i]* 100000 );
   s3=s/ 100000.0 ;
   t3= GetMicrosecondCount ()-t3; 
   
   Print ( "простая сумма                            - " + string (t1)+ " микросекунд, сумма = " + DoubleToString (s1, 18 ));
   Print ( "сумма с NormalizeDouble                  - " + string (t2)+ " микросекунд, сумма = " + DoubleToString (s2, 18 ));
   Print ( "сумма, нормализированная через int       - " + string (t3)+ " микросекунд, сумма = " + DoubleToString (s3, 18 ));  
  }

sonuç:

 2020.08 . 10 13 : 15 : 58.982 TestSpeedNormalizeDouble (USDCAD,H4)    простая сумма                            - 1408 микросекунд, сумма = 460384.3207830497995019
2020.08 . 10 13 : 15 : 58.982 TestSpeedNormalizeDouble (USDCAD,H4)    сумма с NormalizeDouble                   - 6277 микросекунд, сумма = 460384.3162300114054233
2020.08 . 10 13 : 15 : 58.982 TestSpeedNormalizeDouble (USDCAD,H4)    сумма, нормализированная через int        - 964 микросекунд,  сумма = 460384.3162299999967218
 
Nikolai Semko :

ve eğer double ile değil de uzun ile özetlerseniz, sonuç daha da etkileyicidir, çünkü int yoluyla toplama (toplam toplamın daha sonra bölünmesiyle çarpma ve yuvarlama) normal çift toplamdan daha hızlı hesaplanır.

sonuç:

Karşılaştırma için Decimal ekleyin.

Yanlış bağlantı, tam bir uygulama yok.

 
fxsaber :

Ve bu her seferinde normalleştirme yoluyla yapılır. Yani - bu, hiçbir şey için korkunç bir bilgi işlem kaynakları israfı.

Bunu nasıl biliyorsun? Sonuçta, fiyatlar normalleştirilmese bile, kontrol herhangi bir normalleştirme olmadan yapılır:

 if ( fabs (price-limitprice) < ticksize/ 2 )

fiyatların ticksize'ın katları olduğu göz önüne alındığında

 
Nikolai Semko :
Tehdit ve int yoluyla normalleştirme daha da doğrudur (bu, normalleştirmenin son basamağından sonraki dokuz sayısı ile görülebilir - mavi renkle vurgulanır.)

Test yanlış. Neden sonunda 100000.0'a yalnızca bir kez bölüyorsunuz? Her yinelemede yürütülmeli ve ardından özetlenmelidir. O zaman adil bir karşılaştırma olacak. Yani herhangi bir normalleştirmeniz yok, sadece test algoritmanızı optimize ettiniz. Doğal olarak hem daha hızlı hem de daha doğru olacaktır (çünkü biriken hata azalır)

 
Alexey Navoykov :

Bunu nasıl biliyorsun?

Çünkü Tester'a normalleştirilmemiş fiyatları girdi olarak gönderebilirsiniz ve onlarla aynı şekilde çalışacaktır.

Sonuçta, fiyatlar normalleştirilmese bile, kontrol basitçe ve herhangi bir normalleştirme yapılmadan yapılır.

Bu durumda, normalleştirme ile, uyguladıktan sonra bu standardın çiftlerini doğrudan karşılaştırmanın mümkün olduğu tek bir standart algoritmayı kastettim.

Ve böylece Test Cihazı doğrudan karşılaştırma yapmaz. Ve bunu ya NormalizeDouble aracılığıyla ya da ticksize aracılığıyla ya da başka bir şekilde yapar. Ama kesinlikle çiftlerin doğrudan bir karşılaştırması değil. Ve bu tamamen mantıksız.

 
fxsaber :

Tabii ki, çiftleri doğrudan birbirleriyle karşılaştırabilirsiniz ve hatta bazen buna ihtiyaç duyabilirsiniz.

Örneğin, Optimizasyon sırasında OnTick'e bazen trilyon kez denir. Askıda kalma limitinin uygulanıp uygulanmayacağını anlamak için Staff Tester, sembolün mevcut karşılık gelen fiyatı ile limitin fiyatını karşılaştırır. Bunu her OnTick çağrısından önce her erteleme için yapar. Onlar. bu tür kontroller onlarca ve yüz milyarlarca kez yapılır.

Ve bu her seferinde normalleştirme yoluyla yapılır. Yani - bu, hiçbir şey için korkunç bir bilgi işlem kaynakları israfı. Çünkü fiyatlar ve bekleyen emirler ve semboller önceden normalleştirilmiştir. Bu nedenle, doğrudan birbirleriyle karşılaştırılabilir ve karşılaştırılmalıdır.

Maviden değil, MQL-özel Test Cihazı, performans açısından yerel normal Test Cihazından daha iyi performans gösteriyor.

Çılgın versiyonu hız için kontrol etmeye karar verdim.
Ve sonuç şaşırttı.
Önceden normalleştirilmiş çiftlerin bile karşılaştırılması, çiftin epsilon veya int'ye dönüştürülmesi yoluyla karşılaştırılmasından ortalama olarak daha yavaştır.

#define  SIZE 1000000

int Ceil ( double x) { return (x-( int )x> 0 )?( int )x+ 1 :( int )x;}
int Round( double x) { return (x> 0 )?( int )(x+ 0.5 ):( int )(x- 0.5 );}
int Floor( double x) { return (x> 0 )?( int )x:(( int )x-x> 0 )?( int )x- 1 :( int )x;}

bool is_equal( double d1, double d2, double e= 0.000000001 ) { return fabs (d1-d2)<e;}

void OnStart ()
  {
   double a[SIZE], a_norm[SIZE];
   int s1= 0 ,s2= 0 , s3= 0 ;
   for ( int i= 0 ;i<SIZE;i++)  {
     a[i]=( rand ()- 16384 )/ 1641.1452 ;
     a_norm[i]= NormalizeDouble (a[i], 2 );
   }
   double test = 1.11 ;
   
   ulong t1= GetMicrosecondCount ();
   for ( int i= 0 ;i<SIZE;i++) if (a_norm[i]==test) s1++;
   t1= GetMicrosecondCount ()-t1;  
   
   ulong t2= GetMicrosecondCount ();
   for ( int i= 0 ;i<SIZE;i++) if (is_equal(a[i],test, 0.005 )) s2++;
   t2= GetMicrosecondCount ()-t2; 
   
   ulong t3= GetMicrosecondCount ();
   int test_int = test* 100 ;
   for ( int i= 0 ;i<SIZE;i++) if (Round(a[i]* 100 )==test_int) s3++;
   t3= GetMicrosecondCount ()-t3; 
   
   
   Print ("простое сравнение предварительно нормализированых double - " + string (t1)+ " микросекунд, всего совпадений = "+ string (s1));
   Print ("сравнение double через эпсилон                           - " + string (t2)+ " микросекунд, всего совпадений = "+ string (s2));
   Print ("сравнение double через преобразование в int               - " + string (t3)+ " микросекунд, всего совпадений = "+ string (s3));  
  }

Sonuç:

 2020.08 . 10 14 : 31 : 39.620 TestCompareDouble (USDCAD,H4)   простое сравнение предварительно нормализированых double - 900  микросекунд, всего совпадений = 486
2020.08 . 10 14 : 31 : 39.620 TestCompareDouble (USDCAD,H4)   сравнение double через эпсилон                           - 723  микросекунд, всего совпадений = 486
2020.08 . 10 14 : 31 : 39.620 TestCompareDouble (USDCAD,H4)   сравнение double через преобразование в int               - 805  микросекунд, всего совпадений = 486
2020.08 . 10 14 : 31 : 42.607 TestCompareDouble (USDCAD,H4)   простое сравнение предварительно нормализированых double - 1533 микросекунд, всего совпадений = 488
2020.08 . 10 14 : 31 : 42.607 TestCompareDouble (USDCAD,H4)   сравнение double через эпсилон                           - 758  микросекунд, всего совпадений = 488
2020.08 . 10 14 : 31 : 42.607 TestCompareDouble (USDCAD,H4)   сравнение double через преобразование в int               - 790  микросекунд, всего совпадений = 488
2020.08 . 10 14 : 31 : 44.638 TestCompareDouble (USDCAD,H4)   простое сравнение предварительно нормализированых double - 986  микросекунд, всего совпадений = 472
2020.08 . 10 14 : 31 : 44.638 TestCompareDouble (USDCAD,H4)   сравнение double через эпсилон                           - 722  микросекунд, всего совпадений = 472
2020.08 . 10 14 : 31 : 44.638 TestCompareDouble (USDCAD,H4)   сравнение double через преобразование в int               - 834  микросекунд, всего совпадений = 472

Pek çok şeyin işlemcinin yeniliğine ve mimarisine bağlı olduğunu ve birisi için sonucun farklı olabileceğini göz ardı etmiyorum.

Dürüst olmak gerekirse tehdit - Bunun neden olduğunu bile anlamıyorum.
Derleyicinin rastgele sayıların toplamı ile optimize edecek hiçbir şeyi yok gibi görünüyor. Köşeli parantezlerden yuvarlama alamazsınız.
İşlemcide çift karşılaştırmanın bir komut olduğu görülüyor
Epsilon karşılaştırma seçeneği (en hızlı seçenek) ile iki çifti karşılaştırma işlemi yine de gerçekleşir, ancak bu durumda fonksiyon ayrıca üç parametrenin aktarılması ve bir çıkarma işlemi ile çağrılır.
İki ikili karşılaştırma işleminin performansı gerçekten değişkenlerin kendi değerlerine mi bağlı? Ben şüpheliyim.
Lanet olsun, anlamıyorum. Yardım edin lütfen - neyi hesaba katmadım veya nerede hata yaptım?