오류, 버그, 질문 - 페이지 442

 
voix_kas :

볼륨의 유효 자릿수를 계산하기 위한 기성 코드가 있는 사람이 있습니까?
SymbolInfoInteger(_Symbol, SYMBOL_DIGITS)와 비슷하지만 볼륨 전용입니다.
예를 들어 SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP ) = "1.0"인 경우 - 답은 "0", "0.1" - "1", "0.01" - "2" 등입니다.

뉘앙스를 명확히 하겠습니다. 볼륨 단계 유형의 경우 "0.1", "0.01", "0.001"이 있습니다.

코드는 "0.2", "0.11", 0.023" 등과 같은 경우에 작동해야 합니다.

특정 볼륨이 없습니다 . 무엇이든 있습니다.

 int CountSignedDigits( double x)
{  
  for ( int i= 0 ; i< 1000 ; i++,x*= 10 ) if (x- MathFloor (x)< DBL_MIN * 2 ) return i;
  return - 1 ;
}
트레일러 체크인을 위한 스크립트.
파일:
_UniTest.mq5  2 kb
 
MetaDriver :
트레일러 체크인을 위한 스크립트.
이거 말씀하시는데...주문전에 허용로트를 확인하셔야 할 것 같아요.
 
sergeev :
이거 말씀하시는데...주문전에 허용로트를 확인하셔야 할 것 같아요.

;)

나는 그가 필요로하는 것이 무엇인지 정말로 모릅니다 .. 보자, 나는 그가 구독을 취소 할 것이라고 생각합니다. Et I so - 텔레파시로 훈련합니다. ;)

 
voix_kas :

볼륨의 유효 자릿수를 계산하기 위해 기성품 코드가 있는 사람이 있습니까?
SymbolInfoInteger(_Symbol, SYMBOL_DIGITS)와 비슷하지만 볼륨 전용입니다.
예를 들어 SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP ) = "1.0"인 경우 - 답은 "0", "0.1" - "1", "0.01" - "2" 등입니다.

뉘앙스를 명확히 하겠습니다. 볼륨 단계 유형의 경우 "0.1", "0.01", "0.001"이 있습니다.
코드는 "0.2", "0.11", 0.023" 등과 같은 경우에 작동해야 합니다.

특히 볼륨의 경우 다음을 수행할 수 있습니다.

       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++;
[삭제]  

세르게예프
메타드라이버
발마르

잘 구성된 질문은 답의 절반입니다. :) 죄송합니다. 이미 잠자리에 들었고 문제를 부정확하게 설명했습니다. 다시 한번 시도해 보겠습니다.

우리는 정규화된 거래량거래 주문 으로 이전하는 것에 대해 이야기하고 있습니다.
가격으로 어떻게 합니까?

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

가격 정상화("가격") - 모두가 이해하고 있다고 생각합니다.

한 번에 (여전히 MT4 사용) MT 기사의 어딘가에서 볼륨도 정규화하는 것이 바람직하다고 읽었습니다.
사실 브로커의 조건에서 가능한 가장 작은 볼륨의 자릿수를 찾기 위해 GetVolumeDigits( string Symbol ) 함수를 작성했습니다. 최소한 두 가지 구현이 있습니다(결과는 동일함).
구현 #1 .

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

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

두 옵션 모두 최소 단계 = 1.0, 0.1, 0.01, 0.001 등인 경우에 적합합니다. 저것들. 최소 단계가 1.0이면 함수는 0을 반환합니다. 0.1단계에서 함수는 1을 반환하는 식입니다.
예를 들어 최소 단계가 1.1 또는 0.11 또는 0.011이면 어떻게 됩니까? 이 알고리즘은 최하위 숫자를 잘못 표시합니다.
물론 실제로 그런 사례는 없다고 주장할 수 있다. 나는 단지 EA에서 그러한 가상의 가능성을 고려하고 싶었습니다. 누군가가 이 뉘앙스로 자신의 경험을 공유할 수 있다고 생각했습니다.

 
voix_kas :
예, 이해합니다. 결과가 VolumeStep의 배수가 되어야 합니다. 음, Digits는 그것과 아무 관련이 없습니다. 먼저 Digits를 고려 하여 볼륨을 계산 한 다음 VolumeStep의 가장 가까운 배수로 줄였습니다.
 
voix_kas :

우리는 정규화된 거래량거래 주문 으로 이전하는 것에 대해 이야기하고 있습니다.
나는 단지 EA에서 그러한 가상의 가능성을 고려하고 싶었습니다.

그리고 우리가 말하는 "가상적인" 도구는 무엇입니까?

1. MetaDriver 의 옵션이 적합합니다. CountSignedDigits 는 로트의 기호 수를 표시합니다.

2. dig 문자의 수를 알면 다음과 같이 정규화할 수 있습니다.

 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); // вернули
}
[삭제]  

세르게예프
로트의 유효성을 확인하는 기능을 주셔서 감사합니다. 비슷한 구성/분기 수표를 사용합니다.
내 질문은 정규화를 수행하기 위해 로트에서 최하위 숫자를 결정하는 데 중점을 둡니다.
특히 MetaDriver 는 "모든 것"에 대한 자체 설계를 제공했습니다. :) 그러나 결함이 없는 것은 아닙니다(또는 내 컴파일러에 버그가 있음). 다음은 코드와 결과입니다.

 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 ;
}

결과:

 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

다음 옵션(CountSignedDigits 함수는 동일함):

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

결과:

 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에서 다음 줄을 변경했습니다.

 double value = 210.0 ;

결과:

 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

내가 뭔가 잘못하고 있거나(수정해 주세요), 존경받는 MetaDriver 가 이론상 실수를 저질렀거나(알고리즘을 설계 할 때).

 
voix_kas :

내 질문은 정규화를 수행하기 위해 로트에서 최하위 숫자를 결정하는 데 중점을 둡니다.

로트에 대해 발굴을 정의할 필요가 없으며 원하는 단계로 정규화하면 충분합니다.
   lot = NormalizeDouble ( lot / lot_step, 0 ) * lot_step;
   if ( lot < lot_min ) lot = lot_min;
   if ( lot > lot_max ) lot = lot_max;


거래 요청을 전송하는 동안 쓰레기가 로트 변수(소수점 11자리)에 들어가더라도 터미널 자체에서 필터링해야 합니다.

적어도 몇 년 동안 이 디자인을 사용하는 데 문제가 없었습니다.


그리고 안전하게 플레이하고 싶다면 소수점 이하 8자리(여백 포함)까지 정규화를 고수할 수 있습니다. "올바른" 정규화 쓰레기가 나타난 후에는 훨씬 더 멀어질 것입니다.

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