Hatalar, hatalar, sorular - sayfa 442

 
voix_kas :

Hacim için önemli basamak sayısını hesaplamak için hazır bir kodu olan var mı?
SymbolInfoInteger(_Symbol, SYMBOL_DIGITS) gibi bir şey, ancak yalnızca hacim için.
Örneğin, SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP ) = "1.0" durumunda - cevap "0", "0.1" - "1", "0.01" - "2" vb.

Ben nüansı açıklığa kavuşturacağım. Hacim adımı türü için "0.1", "0.01", "0.001" var.

Kod aşağıdaki durumlar için çalışmalıdır, örneğin "0.2", "0.11", 0.023" vb.

Belirli bir hacim yok . Her şey için var.

 int CountSignedDigits( double x)
{  
  for ( int i= 0 ; i< 1000 ; i++,x*= 10 ) if (x- MathFloor (x)< DBL_MIN * 2 ) return i;
  return - 1 ;
}
Fragmanı kontrol etmek için komut dosyası.
Dosyalar:
_UniTest.mq5  2 kb
 
MetaDriver :
Fragmanı kontrol etmek için komut dosyası.
bundan bahsediyorsun... ve sipariş vermeden önce izin verilen miktarı kontrol etmen gerektiğini düşündüm.
 
sergeev :
bundan bahsediyorsun... ve sipariş vermeden önce izin verilen miktarı kontrol etmen gerektiğini düşündüm.

;)

Neye ihtiyacı olduğunu gerçekten bilmiyorum.. Bakalım, sanırım abonelikten çıkacak. Ve ben - bir telepatide eğitiyorum. ;)

 
voix_kas :

Hacim için önemli basamak sayısını hesaplamak için hazır bir kodu olan var mı?
SymbolInfoInteger(_Symbol, SYMBOL_DIGITS) gibi bir şey, ancak yalnızca hacim için.
Örneğin, SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP ) = "1.0" durumunda - cevap "0", "0.1" - "1", "0.01" - "2" vb.

Ben nüansı açıklığa kavuşturacağım. Hacim adımı türü için "0.1", "0.01", "0.001" var.
Kod aşağıdaki durumlar için çalışmalıdır, örneğin "0.2", "0.11", 0.023" vb.

Özellikle ciltler için şunları yapabilirsiniz:

       int N= 0 ;
       double step= SymbolInfoDouble (symbol, SYMBOL_VOLUME_STEP );
       if (step- 1.0 < 0 )  N++;
       if (step- 0.1 < 0 )  N++;
       if (step- 0.01 < 0 ) N++;
 

sergeev
MetaSürücü
Valmarlar

İyi formüle edilmiş bir soru, cevabın yarısıdır. :) Üzgünüm, zaten yatağa gittim, sorunu yanlış tanımladım. Tekrar deneyeceğim.

Normalleştirilmiş bir hacmi bir ticaret emrine aktarmaktan bahsediyoruz.
Fiyat ile nasıl yaparız:

 MqlTradeRequest TradeRequest;
...
TradeRequest.volume = NormalizeDouble (Volume, GetVolumeDigits( _Symbol ));
TradeRequest.price  = NormalizeDouble (Price, SymbolInfoInteger ( _Symbol , SYMBOL_DIGITS ));
...

Fiyat normalizasyonu ("fiyat") - Sanırım herkes anlıyor.

Bir zamanlar (MT4'ten beri), MT makalelerinde bir yerde, hacmin de normalleştirilmesinin istendiğini okudu.
Aslında, aracının koşulları altında mümkün olan hacmin en küçük basamağını bulmak için GetVolumeDigits( string Symbol ) işlevini yazdım. En az iki uygulaması vardır (sonuç aynıdır):
Uygulama #1 .

 int GetVolumeDigits( string Symbol ) {
   int VolumeDigits = 0 ;
   double VolumeStep = SymbolInfoDouble ( Symbol , SYMBOL_VOLUME_STEP );
   while (VolumeStep < 1 ) {
    VolumeStep *= 10 ;
    VolumeDigits++;
  }
  return VolumeDigits;
}
Uygulama #2 .

 int GetVolumeDigits( string Symbol ) {
   return ( int ) MathLog10 ( 1.0 / SymbolInfoDouble ( Symbol , SYMBOL_VOLUME_STEP ));
}

Her iki seçenek de minimum adımın = 1.0, 0.1, 0.01, 0.001 vb. olduğu durumlarda harika çalışır. Onlar. min adım 1.0 ise, fonksiyon 0 döndürür; 0.1 adımında, işlev 1 değerini döndürür ve bu böyle devam eder.
Minimum adım, örneğin 1.1 veya 0.11 veya 0.011 ise ne olur? Bu algoritma yanlış olarak en az anlamlı basamağı gösterecektir.
Elbette pratikte böyle bir durumun olmadığı söylenebilir. EA'da böyle bir varsayımsal olasılığı hesaba katmak istedim. Belki birileri bu nüanstaki deneyimlerini paylaşabilir diye düşündüm...

 
voix_kas :
Evet, anlıyorum, sonucun VolumeStep'in katı olması gerekiyor. Pekala, Digits'in bununla hiçbir ilgisi yok, önce hacmi Digits'i hesaba katarak hesapladık ve sonra onu VolumeStep'in en yakın katına indirdik.
 
voix_kas :

Normalleştirilmiş bir hacmi bir ticaret emrine aktarmaktan bahsediyoruz.
EA'da böyle bir varsayımsal olasılığı hesaba katmak istedim.

ve hangi "varsayımsal" araçtan bahsediyoruz?

1. MetaDriver seçeneği size uygun. CountSignedDigits , herhangi bir lottaki işaretlerin sayısını gösterecektir.

2. Dig karakter sayısını bilerek, aşağıdaki gibi normalize edebilirsiniz:

 double MinLot; // минимальный лот по символу
double MaxLot; // максимальный лот по символу
double LotStep; // шаг лота по символу
int dig; // знаковость лота узнали из функции CountSignedDigits

double NL( double lot)
{
   if (lot<=MinLot) return (MinLot); // проверка на минимальный
   double d= MathFloor ((lot-MinLot)/StepLot); // сколько ЦЕЛЫХ шагов умещается в проверяемом лоте
  lot=MinLot+StepLot*d; // рассчитали по этому целому числу
  lot= MathMin (lot, MaxLot); lot= NormalizeDouble (lot, dig); // не забыли проверить на максимальный // нормализовали
   return (lot); // вернули
}
 

sergeev
Partinin geçerliliğini kontrol etme işlevi için teşekkür ederiz. Benzer bir yapı/dallanma çek kullanıyorum.
Sorum, üzerinde normalleştirme yapmak için partideki en az anlamlı basamağı belirlemeye odaklanıyor.
Özellikle, MetaDriver "her şey" için kendi tasarımını sağladı. :) Ancak, hatasız değil (veya derleyicim hatalı). Kod ve sonuç aşağıdadır:

 void OnStart () {
   Print (CountSignedDigits( 110.0 ));
   Print (CountSignedDigits( 11.0 ));
   Print (CountSignedDigits( 1.1 ));
   Print (CountSignedDigits( 0.11 ));
   Print (CountSignedDigits( 0.011 ));
   Print (CountSignedDigits( 0.0011 ));
   Print (CountSignedDigits( 0.00011 ));
}

int CountSignedDigits( double x) {  
   for ( int i = 0 ; i < 1000 ; i++, x *= 10 )
     if (x - MathFloor (x) < DBL_MIN * 2 )
       return i;
   return - 1 ;
}

Sonuç:

 2011.07 . 03 13 : 15 : 21      test (EURUSD,M5)         5
2011.07 . 03 13 : 15 : 21      test (EURUSD,M5)         4
2011.07 . 03 13 : 15 : 21      test (EURUSD,M5)         18       -    Здесь только у меня бяка вылазиет?
2011.07 . 03 13 : 15 : 21      test (EURUSD,M5)         2
2011.07 . 03 13 : 15 : 21      test (EURUSD,M5)         1
2011.07 . 03 13 : 15 : 21      test (EURUSD,M5)         0
2011.07 . 03 13 : 15 : 21      test (EURUSD,M5)         0

Sonraki seçenek (CountSignedDigits işlevi aynıdır):

 void OnStart() {
   double value = 110.0 ;
   int count = 9 ;
   while (count) {
    Print(DoubleToString( value ), " - " , CountSignedDigits( value ));
     value /= 10 ;
    count--;
  }
}

Sonuç:

 2011.07 . 03 13 : 23 : 32      test (EURUSD,M5)         0.00000110 - 22        -   Почему-то здесь бяка...
2011.07 . 03 13 : 23 : 32      test (EURUSD,M5)         0.00001100 - 21        -
2011.07 . 03 13 : 23 : 32      test (EURUSD,M5)         0.00011000 - 5
2011.07 . 03 13 : 23 : 32      test (EURUSD,M5)         0.00110000 - 4
2011.07 . 03 13 : 23 : 32      test (EURUSD,M5)         0.01100000 - 3         - Здесь уже все нормально. Почему результаты разные?!
2011.07 . 03 13 : 23 : 32      test (EURUSD,M5)         0.11000000 - 2
2011.07 . 03 13 : 23 : 32      test (EURUSD,M5)         1.10000000 - 1
2011.07 . 03 13 : 23 : 32      test (EURUSD,M5)         11.00000000 - 0
2011.07 . 03 13 : 23 : 32      test (EURUSD,M5)         110.00000000 - 0
 

OnStart'ta aşağıdaki satırı değiştirdi:

 double value = 210.0 ;

Sonuç:

 2011.07 . 03 13 : 28 : 01      test (EURUSD,M5)         0.00000021 - 23
2011.07 . 03 13 : 28 : 01      test (EURUSD,M5)         0.00000210 - 22
2011.07 . 03 13 : 28 : 01      test (EURUSD,M5)         0.00002100 - 21
2011.07 . 03 13 : 28 : 01      test (EURUSD,M5)         0.00021000 - 20
2011.07 . 03 13 : 28 : 01      test (EURUSD,M5)         0.00210000 - 19
2011.07 . 03 13 : 28 : 01      test (EURUSD,M5)         0.02100000 - 3
2011.07 . 03 13 : 28 : 01      test (EURUSD,M5)         0.21000000 - 2
2011.07 . 03 13 : 28 : 01      test (EURUSD,M5)         2.10000000 - 1
2011.07 . 03 13 : 28 : 01      test (EURUSD,M5)         21.00000000 - 0
2011.07 . 03 13 : 28 : 01      test (EURUSD,M5)         210.00000000 - 0

Ya yanlış bir şey yapıyorum (lütfen beni düzeltin) ya da saygıdeğer MetaDriver teoride bir hata yaptı (algoritmayı tasarlarken ).

 
voix_kas :

Sorum, üzerinde normalleştirme yapmak için partideki en az anlamlı basamağı belirlemeye odaklanıyor.

Parti için dig tanımlamaya gerek yoktur, istenilen adıma normalize edilmesi yeterlidir:
   lot = NormalizeDouble ( lot / lot_step, 0 ) * lot_step;
   if ( lot < lot_min ) lot = lot_min;
   if ( lot > lot_max ) lot = lot_max;


Bir ticaret talebinin aktarımı sırasında lot değişkenine (onbirinci ondalık basamakta) çöp girse bile, terminalin kendisi tarafından filtrelenmesi gerekecektir.

En azından, bu tasarımı kullanarak birkaç yıldır herhangi bir sorun yaşamadım.


Ve güvenli oynamak istiyorsanız, normalleştirmeyi sekizinci (bir kenar boşluğu ile) ondalık basamağa kadar yapıştırabilirsiniz - "doğru" normalleştirme çöpünden sonra ortaya çıkarsa, o zaman çok daha fazla olacaktır.

Документация по MQL5: Стандартные константы, перечисления и структуры / Структуры данных / Структура торгового запроса
Документация по MQL5: Стандартные константы, перечисления и структуры / Структуры данных / Структура торгового запроса
  • www.mql5.com
Стандартные константы, перечисления и структуры / Структуры данных / Структура торгового запроса - Документация по MQL5