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

 
Interesting :

테스터에는 별도의 도구 목록이 있으며 구성해야 합니다(Expert Advisor를 초기화할 때 이 작업을 수행하는 것이 바람직함).

매우 감사합니다! 일어난. 많이 빠졌다...
 
Renat :

코드는 대략적인 것이었지만(두 부분을 복사하여 붙여넣기) 귀하의 의견은 정확합니다.

수정된 버전은 다음과 같습니다.

실제로 작동하는 방식을 명확히 하기 위해 몇 가지 Print() 호출을 추가했습니다.

 double CalculateMaxVolume( string symbol)
  {
   double price= 0.0 ;
   double margin= 0.0 ;
//--- select lot size
   if (! SymbolInfoDouble (symbol, SYMBOL_ASK ,price))                 return ( 0.0 );
   if (! OrderCalcMargin ( ORDER_TYPE_BUY ,symbol, 1.0 ,price,margin)) return ( 0.0 );
   if (margin<= 0.0 )                                             return ( 0.0 );

   double lot_pure= AccountInfoDouble ( ACCOUNT_FREEMARGIN )/margin;
   double lot= NormalizeDouble (lot_pure, 2 );
   Print ( "lot_pure = " , lot_pure, ", lot = " , lot);
//--- normalize and check limits
   double stepvol= SymbolInfoDouble (symbol, SYMBOL_VOLUME_STEP );
   if (stepvol> 0.0 )
     {
       double newlot=stepvol* NormalizeDouble (lot/stepvol, 0 );
       if (newlot>lot) { Print ( "Чёрт побери: lot = " , lot, ", newlot = " , newlot);
                       lot= NormalizeDouble (newlot-stepvol, 2 );
                     }
       else            lot=newlot;
     }

   double minvol= SymbolInfoDouble (symbol, SYMBOL_VOLUME_MIN );
   if (lot<minvol) lot= 0.0 ;   // 

   double maxvol= SymbolInfoDouble (symbol, SYMBOL_VOLUME_MAX );
   if (lot>maxvol) lot=maxvol;
//--- return trading volume
   return (lot);
  }

void OnStart ()
{
   Print ( "CalculateMaxVolume(Symbol()) = " , CalculateMaxVolume( Symbol ()));
}

/* Вывод в лог (хронология - сверху вниз)
CO      0       1 (EURUSD,M15)  01:40:33        lot_pure = 7.799703611262773, lot = 7.8
JG      0       1 (EURUSD,M15)  01:40:33        Чёрт побери: lot = 7.8, newlot = 7.800000000000001
MQ      0       1 (EURUSD,M15)  01:40:33        CalculateMaxVolume(Symbol()) = 7.7
*/

이제 제대로 작동합니다. 그러나 경고와 함께 - 현재 실제로 발생하는 조건에서. 나중에 확장되면 이 코드도 특정 조건에서 경우에 따라 실수를 시작합니다. 아래에서 설명하겠습니다.

사실, 나는 약간의 조사를 해야 했고, 그 결과 매우 흥미로운 결과를 얻었습니다. 그러나 가장 먼저 해야 할 일.

가장 먼저 시선을 사로잡는 것은 NormalizeDouble()과 함께 춤을 추는 사람이 왜 그렇게 많은가? 결국 NormalizeDoubel()은 무엇을 합니까? 그리드에 자유 값을 스냅합니다. 예를 들어, 이 코드에서:

 double lot= NormalizeDouble (lot_pure, 2 );

NormalizeDouble()은 매개변수로 lot_pure(자유 마진, 즉 반올림 및 기타 바인딩 없이 1랏에 대한 여유 마진과 필요한 마진에서 계산된 값)를 수신하고 시작과 함께 가장 가까운 그리드 값에 연결된 값을 반환합니다. 0 및 0.01 단계에서.
여기에서 주목하는 것이 중요합니다: 더 큰 것을 포함하여 가장 가까운 그리드 노드에 !

코드의 이 시점에서 이 바인딩이 수행되는 이유는 무엇입니까? 그리고 왜 정확히 0.01 그리드가 아닌 0.001 그리드에 맞춰야 합니까?

그런데 로그에 CO 기호(주어진 로그 조각의 첫 번째 줄)로 표시된 출력에 따르면 바인딩이 값의 증가로 이어졌음이 분명합니다.

또한, 로트 수를 매개변수 중 하나로 취하는 모든 거래 기능은 이 값이 그리드에 연결되어야 한다고 알려져 있습니다. minvol + N * stepvol, 여기서 N은 0에서 정수 부분의 값까지의 정수입니다. 식 (maxvol - minvol ) / stepvol. 따라서 이 조각에서 얻은 자유 로트 값은 다음과 같습니다.

 double lot_pure= AccountInfoDouble ( ACCOUNT_FREEMARGIN )/margin;

지정된 그리드의 가장 가까운 노드에 바인딩되어야 합니다: minvol + N * stepvol. 이것은 먼저 로트 값에서 minvol을 빼야 한다는 것을 의미합니다. stepvol로 나누기 전에(동일한 정수 N을 얻기 위해), N을 곱한 후 minvol을 추가합니다. 당신은 즉시 stepvol로 나눕니다. 암시적으로 stepvol이 minvol의 제수라고 가정합니다. 즉, 이 조건이 충족되는 경우에만 이 방법으로 "단순화"할 수 있고 부작용이 발생하지 않기 때문에 정수 횟수만큼 맞습니다.

 double newlot=stepvol* NormalizeDouble (lot/stepvol, 0 );

그리고 다시 NormalizeDouble()을 사용합니다. 이번에는 0에서 시작하고 1의 단계, 즉 정수로 그리드에 스냅합니다. 그리드 스냅 옵션은 정확하지만 스냅 도구는 다소 불행합니다. 더 가까운 노드가 더 가까울 경우 더 큰 노드를 포함하여 가장 가까운 그리드 노드에 스냅됩니다. 그리고 우리의 경우 이것은 수정 코드의 후속 필수 개발로 이어질 것입니다. 캐스트 값을 늘리지 않고 필요한 경우 가장 가까운 작은 정수로 줄이는 정수 유형으로의 캐스트를 사용하여 NormalizeDouble()을 호출하는 대신 여기에서 멋진 "정수 그리드" 바인딩 도구를 사용하지 않는 이유는 무엇입니까? 당신이 필요로하는 무엇?

그러나 이 장소에서 가장 흥미로운 또 다른 인공물이 나타납니다. 그 증거는 JG 기호로 표시된 로그 조각의 두 번째 줄에서 찾을 수 있습니다. "0.1 * NormalizeDouble(7.8 / 0.1)" 표현식은 결과적으로 7.80000000000001을 제공하여 수정 코드를 강제로 처리하는 것으로 나타났습니다! 왜 우리는 그 일을 너무 나쁘게 처리하여 수정 코드로 보완되어야 하는 그러한 코드가 필요합니까?

허용 가능한 로트 값의 그리드에 바인딩하는 코드를 더 나은 코드로 교체해야 하는 것은 분명합니다.

물론, 그러한 코드를 남길 수도 있습니다. 결국 코드의 수정 부분은 작동할 것입니다. 따라서 로그의 세 번째 행이 이를 증명합니다. 결과는 결국 올바르게 반환됩니다. 그러나 이러한 코드는 무엇보다도 작성자의 전문성 수준과 코드 품질을 나타내는 지표입니다. MT5 플랫폼 자체의 코드 품질을 포함합니다. 연구 결과 두 가지 버그를 발견했기 때문에 이에 대한 증거가 저에게 주어질 것입니다.

그건 그렇고, 계산된 lot_pure 값의 초기 바인딩에 대한 코드와 수정 코드를 다시 살펴보겠습니다.

 double lot= NormalizeDouble (lot_pure, 2 );
...
lot= NormalizeDouble (newlot-stepvol, 2 );
두 경우 모두 그리드에 대한 스냅은 0.01 단계로 수행됩니다. 이 특정 네트워크가 필요한 이유는 무엇입니까? 결국 minvol + N * stepvol 그리드에 바인딩이 필요하며, 여기서 단계는 stepvol입니다. 미래에 최소 로트 값과 0.001의 로트 단계를 모두 충족할 수 있게 된다면 어떻게 될까요?

매우 간단합니다. 0.01 단계로 그리드에 스냅하는 과정에서 로트의 자유 값이 0.001 이상 변경되는 경우 코드가 잘못된 결과를 제공하기 시작합니다. 서두에 말씀드린 주의사항입니다.

0.001을 초과하는 값으로 "반올림"하는 경우 위치를 여는 데 충분한 여유 여백이 없는 로트 값이 반환되고 동일한 금액으로 "반올림"하는 경우, 과소 평가된 값 또는 자유 값이 0.001 - 0.004999 이내이면 0...

즉, 코드에 잠재적인 버그가 포함되어 있습니다. 이것은 개발자의 전문성과 코드 품질에 관한 것입니다.

이제 발견된 기능을 고려하여 고유한 버전의 기능을 제공하겠습니다.

 double CalculateMaxVolume_New( string symbol)
{
   double stepvol = SymbolInfoDouble (symbol, SYMBOL_VOLUME_STEP );
   double minvol  = SymbolInfoDouble (symbol, SYMBOL_VOLUME_MIN );
   double maxvol  = SymbolInfoDouble (symbol, SYMBOL_VOLUME_MAX );

   // Не доверяем значениям, которые вернули функции
   if (stepvol > 0 && minvol > 0 && maxvol > minvol)
  {
     double tmp = 0 ;

     // Вычисляем цену Ask, Margin на 1 лот, лотов на FreeMargin
     if ( SymbolInfoDouble (symbol, SYMBOL_ASK , tmp)            && tmp > 0        &&
       OrderCalcMargin ( ORDER_TYPE_BUY , symbol, 1 , tmp, tmp) && tmp > 0        &&
       (tmp = AccountInfoDouble ( ACCOUNT_FREEMARGIN ) / tmp)         >= minvol &&
       tmp < ULONG_MAX * stepvol)
    {
       Print ( "pure_lot = " , tmp); // Эту строку нужно удалить из рабочего кода

       if (tmp > maxvol) // Здесь в tmp содержится недискретизированное число лотов
         return maxvol;

       // Привязываемся к сетке дискретизации
       return minvol + stepvol * ( ulong )((tmp - minvol) / stepvol);
    }
  }

   return 0 ;
}

void OnStart ()
{
   Print ( "CalculateMaxVolume_New(Symbol()) = " , CalculateMaxVolume_New( Symbol ()));
}

/* Вывод в лог (хронология - сверху вниз)
LQ      0       1 (EURUSD,M15)  01:39:07        pure_lot = 7.799095304944626
KD      0       1 (EURUSD,M15)  01:39:07        CalculateMaxVolume_New(Symbol()) = 7.7
*/

많은 경우(내 tmp에 저장됨) 값과 관련하여 계산되었지만 아직 허용 가능한 값 그리드에 연결되지 않은 경우가 있습니다. 그리드에 첨부된 값을 이산화(discretized)라고 합니다.

1. tmp < minvol인 경우. 이 경우 샘플링 프로세스는 계산된 값의 감소만을 의미하기 때문에 tmp 샘플링 후에도 불평등이 유지됩니다(그렇지 않으면 계산된 값이 주어진 여유 양에 대해 가능한 최대값이기 때문에 여유 여유가 충분하지 않습니다. 여유).

따라서 이 경우는 이산화(discretization) 이전의 초기 단계에서 차단될 수 있습니다.

2. tmp > maxvol인 경우. 이 경우 한도는 자유증거금이 아니라 거래기능이 허용하는 랏수의 최대허용값입니다. 이 경우 maxvol 값을 반환하기만 하면 됩니다.

단순히 maxvol 값을 반환하기 위해 tmp 샘플링이 필요하지 않으므로 이 경우도 샘플링 코드로 잘립니다.

3. minvol <= tmp <= maxvol인 경우. 이 경우 이산화를 수행해야 하며, 결과적으로 이산화된 값은 이 경우 부등식 내에 남게 됩니다. 즉, 이산화 후 수정할 필요가 없습니다.

이산화 코드는 간단하고 효율적입니다.

 return minvol + stepvol * ( ulong )((tmp - minvol) / stepvol);

여기서 "(tmp - minvol) / stepvol"이라는 표현은 동일한 숫자 N(앵커 그리드 매개변수)을 계산하지만 소수 부분을 사용합니다. 이 지점(case 3)에서 부등식 minvol <= tmp 가 충족되므로 계산된 값이 음수 가 아님이 보장 됩니다. 다음으로 계산된 값은 ulong 유형의 값으로 명시적으로 캐스트됩니다. 주어진 값이 음수가 아니라는 보장 이 있기 때문에 정확히 ulong입니다.

정수형으로 형변환하는 과정에서 실수형의 소수부는 버린다. 가장 가까운 것으로 반올림하는 것이 아니라 자유 마진이 허용하는 로트의 최대 값이 증가하지 않도록 보장하는 소수 부분을 삭제합니다. 즉, 정확히 우리에게 필요한 것입니다.

정수 값 N이 얻어지기 때문에 표준 방식으로 자유 마진 요구 사항을 충족하는 로트 수의 최대 이산화 값을 얻습니다(즉, 허용 가능한 값의 샘플링 그리드에서 순서대로 다음 값 로트는 더 이상 여유 증거금 요구 사항을 충족하지 않으며 결과 N은 여전히 ): "minvol + stepvol * N"입니다.

나는 오히려 중요한 한 가지 점을 강조하고 싶다. 요점은 double 유형의 수는 최대 약 1.8e308까지, ulong 유형의 수는 약 1.8e19에 불과하다는 것입니다(이것은 편의를 위한 표기일 뿐이며 상수 1.8e19 자체는 ulong 유형이 아닙니다 . ).

"(tmp - minvol) / stepvol" 표현식의 값이 1.8e19를 초과하면 어떻게 됩니까? 그런 다음 ulong 유형으로 캐스팅할 때 "잘림"이 발생합니다. 값은 표현식 값을 ULONG_MAX로 나눈 정수 나누기의 나머지입니다.

숫자가 그렇게 크지 않은 경우 MQL5 측면에서 "X % ULONG_MAX" 값처럼 보일 것입니다. 여기서 X는 "(tmp - minvol) / stepvol"과 같은 정수입니다.

이 경우는 일반적이지 않지만 코드에 버그를 남겨두는 이유는 무엇입니까? 게다가 MQL5 라이브러리의 기능은 신뢰할 수 없으며 말도 안되는 소리가 반환될 수 있습니다(이에 대한 증거를 제공하겠습니다).

"tmp / stepvol" 표현의 값이 1.8e19에 맞지 않는 경우 검사가 특별히 도입되었습니다(if 조건의 마지막 줄).

tmp < ULONG_MAX * stepvol

물론 "tmp / stepvol < (double)ULONG_MAX"로 쓸 수도 있지만, 우선 명시적 필요가 없을 때 나눗셈 연산을 피하려고 하고, 그 다음에는 명시적 형식 변환을 수행해야 할 것입니다. , ULONG_MAX 상수가 ulong 유형이기 때문에 피연산자는 비교 중에 가장 높은 유형으로 암시적으로 캐스트되지 않으며(적어도 C/C ++의 경우) 세 번째로 - 라이브러리 기능이 아닌 언어 자체 - 버그는 DNA가 아니라 문자 그대로 MQL5 분자와 원자에 있습니다.

비교 연산의 왼쪽 피연산자는 tmp이고 double 유형이고 오른쪽 피연산자는 표현식 "ULONG_MAX * stepvol"이고 또한 double 유형입니다.

이 표현식에는 두 개의 피연산자가 있습니다. 하나는 ulong 유형이고 다른 하나는 double 유형입니다. 암시적 형식 캐스팅의 규칙에 따르면 먼저 부 형식의 피연산자가 주 형식의 피연산자 형식으로 캐스팅되고 연산이 수행되고 결과는 주 형식의 피연산자 형식이 됩니다. double형은 ulong형보다 오래된 것이므로 ulong형의 ULONG_MAX 값을 묵시적으로 double형으로 형변환하고 곱셈을 수행하고 결과는 double형이다.

그런데 여기에 버그가 있는데 여기를 포함하여 항상 나타나는 것은 아니고 특정 경우에만 나타나는데, 버그는 "ULONG_MAX * stepvol"이라는 표현의 결과가 단순히 값이라는 사실에 있습니다. 스텝볼.

따라서 내가 제시한 기능은 작동하지 않으며 MetaQuotes 개발자가 이 버그를 수정할 때까지 작동하지 않습니다.

지금 바로 이 함수를 사용하려면 버그의 기능을 활용해야 합니다. 유형에 대한 명시적 캐스트를 수행하면 버그가 사라집니다.

tmp < ( double ) ULONG_MAX * stepvol

설명된 검사로 돌아가서 "tmp / stepvol" 표현식의 값이 ULONG_MAX를 초과하지 않음을 보장 합니다. 그러나 이산화 코드는 "(tmp - minvol) / stepvol"이라는 표현을 사용합니다.

이 표현식의 값도 ULONG_MAX 값을 초과하지 않습니다. 이전 검사 에서 minvol > 0 및 tmp >= minvol, 즉 tmp - minvol < tmp를 확인했기 때문입니다.

따라서 ULOMG_MAX가 초과되지 않는다는 보장 은 "(tmp - minvol) / stepvol" 표현식에도 적용됩니다.

일반적으로 전문가와 비전문가의 주요 차이점 중 하나는 전문가가 최소한 무언가를 보장 할 수는 있지만 비전문가는 ...

발견된 두 버그는 MetaQuotes가 할 수 있는 것과 할 수 없는 것을 지정하는 동시에 다른 메시지 에서 분석되었습니다.

 

Для чего в этом месте кода выполняется эта привязка? И почему именно к сетке 0.01, а не к, скажем, 0.001?

시스템에서 최소 로트 = 0.01


노트:

  1. 초기 조건 minvol + N * stepvol은 참이 아닐 수 있습니다. 설정에서 다중이 아닌 minlot 값을 설정할 수 있으며 모든 계산 논리가 위반됩니다.
  2. 당신은 헛되이 ulong으로 전환했습니다 - 당신은 스스로 어려움을 일으켰고 그것에 대한 생각의 전체 페이지를 썼습니다.
  3. 당신의 코드에서 영리한 대체와 tmp의 사용은 많은 사람들의 마음을 날려버릴 것입니다. 제 버전에서는 작업의 의미 측면에서 모든 것이 훨씬 더 명확합니다.
 

나는 나 자신을 위해서만 말합니다 (그러나 누군가가 그의 반사를 본다면 당신이 유일한 사람이 아니라는 것을 명심하십시오).

최근 몇 달 동안 버그 경쟁은 먼저 작동하지 않는 프로그램을 MetaTrader 버그로 간주하는 습관을 개발했습니다.

예, 예, 템플릿을 잘 만든 것뿐입니다. 작동하지 않는 경우 버그이므로 전화를 겁니다.

예: 버그를 발견하고 , 서비스 데스크에 요청을 보내고, 버그가 수정되었다고 답장하고, 인증 코드를 작성했지만 아무 것도 없었습니다.

나는 다시 항소하고 이미 내 곡률을 찾는 답변을 기대합니다.

결과적으로 사람들을 갑자기 혼란스럽게 만든 것은 수치스러운 일입니다.

그러나 메시지의 흐름을 분석해 보면 많은 사람들, 심지어 똑똑한 사람들도 여전히 군중 심리에 종속되어 있다는 것을 이해합니다.

버그가 있으므로 이것이 버그라고 쓰고 버그인지 아닌지에 상관없이 Renat이 내 코드를 긁어 모아 오류가 있는 부분을 지적하게 하십시오.

나는 관용이 당신이 말할 수 없다는 것을 이해합니다. 예, 당신은 양입니다. 당신은 곡선 코드를 가지고 있습니다.

그러나 결국, 당신은 그렇게 멀리 가지 않을 것이고, 이 방법을 계속하면, 전체 MQ 스태프는 곧 다른 사람들의 코드 위에 앉아 "도대체 우리에게 이 모든 것이 필요한 것이 무엇입니까"라는 슬픈 생각으로 바쁠 것이고 한편 챔피언십은 코에, 거기에 실제 계정을 입력할 수 없습니다.

정리하겠습니다. 오늘 제가 본 모토는 "버그를 게시하려고 했습니다. 문제가 비뚤어진 손에 있는지 확인하십시오."입니다.

Общайтесь с разработчиками через Сервисдеск!
Общайтесь с разработчиками через Сервисдеск!
  • www.mql5.com
Ваше сообщение сразу станет доступно нашим отделам тестирования, технической поддержки и разработчикам торговой платформы.
 

새로운 빌드 - 새로운 문제. 314에서 컴파일(오류 없는 컴파일) 후 306에서 정상적으로 작동했던 Expert Advisor는 테스터에서 다음과 같이 출력합니다.

2010.08.21 17:03:36 코어 1 분리
2010.08.21 17:03:36 OnInit 실패로 인해 Core 1 테스터가 중지됨
2010.08.21 17:03:36 Core 1 2010.01.04 00:00:00 0x0000000000000014 에 대한 접근 위반 읽기
2010.08.21 17:03:36 코어 1 2010.01.04 00:00:00 잔액=10000.00 자산=10000.00 이익=0.00
2010.08.21 17:03:36 코어 1 2010.01.04 00:00:00 PriceChannel_multi_Ch_Timer EA 가 EURUSD 차트 에서 01.2010 00:00에 작업 시작, 기간 H1

실생활에서도 언로드됩니다. 오류의 원인이 다음 줄임이 밝혀졌습니다.

m_symbol[j].Name(TradeSymbols[i]);

몇 줄로 대체

 string curSymbol=TradeSymbols[i];
m_symbol[j].Name(curSymbol);

현상 유지를 전문가에게 반환했습니다.

무슨일이야???

그건 그렇고, 이전 빌드에서 컴파일된 코드는 이 빌드에서도 잘 작동합니다.

 
Valmars :

무슨일이야???

그건 그렇고, 이전 빌드에서 컴파일된 코드는 이 빌드에서도 잘 작동합니다.

우리의 실수 - 우리는 확실히 고칠 것입니다.
 
Renat :

시스템에서 최소 로트 = 0.01


노트:

  1. 초기 조건 minvol + N * stepvol은 참이 아닐 수 있습니다. 설정에서 다중이 아닌 minlot 값을 설정할 수 있으며 모든 계산 논리가 위반됩니다.
  2. 당신은 헛되이 ulong으로 전환했습니다 - 당신은 스스로 어려움을 일으켰고 그것에 대한 생각의 전체 페이지를 썼습니다.
  3. 당신의 코드에서 교활한 대체와 tmp의 사용은 많은 사람들의 마음을 날려버릴 것입니다. 제 버전에서는 작업의 의미 측면에서 모든 것이 훨씬 더 명확합니다.

이것은 이제 시스템의 최소 로트 = 0.01입니다. 그리고 1년 안에? 두개의?

1. 그리고 어떤 조건이 참입니까? 그렇다면 올바른 공식은 무엇입니까? minvol = 0.15 및 stepvol = 0.1인 경우 허용되는 처음 몇 개의 로트 값은 무엇입니까? a) 0.15, 0.25, 0.35...? b) 0.15, 0.2, 0.3...? 에) ... ? 나는 옵션을 생각했다.

2. 나는 헛되이 ulong으로 전환했습니다. 나는 가장 넓은 범위의 유형을 선택할 권리가 있습니다. 그러한 기능은 매우 기본적인 빌딩 블록이기 때문에 가능한 가장 넓은 범위의 경우에 충분합니다. 그리고 내가 버그를 발견했다는 사실이 나 자신을 위해 어려움을 만든 것이 나임을 의미하지는 않습니다. :) Reasoning은 다른 사람들을 위해 더 많이 썼으므로 가능한 한 가장 넓은 범위에서 명확하게 알 수 있습니다. 여기에는 개인적인 서신이 없습니다.

3. 대체는 까다롭지 않습니다. 일회용 변수가 없도록 저장하는 것입니다. 또한, 이로 인해 발생할 수 있는 오류를 배제하기 위해 최대 1회 함수 호출 시 변수가 참조로 전달되었는지 모니터링 및 확인하였다. 이것이 누군가를 위해 "두뇌를 제거"한다면, 당신이 한 것처럼 수신된 각 값(심지어 매도 가격과 같은 중간 값도 포함)에 대한 변수를 만들 수 있습니다. 이 순간은 중요하지 않습니다.

훨씬 더 중요한 것은 유효한 값의 그리드에 바인딩하는 메커니즘입니다. 여기에는 아무 것도 조정할 필요가 없으며 최대한의 단순성을 유지하면서 일반적이지 않은 다양한 경우에 글리치가 발생하지 않도록 보장합니다.

나는 기본 벽돌이 가능한 한 안정적이고 다재다능해야 한다는 사실에서 출발했습니다. 그러면 집 전체가 지진에서도 살아남을 가능성이 큽니다.

 
Urain :

나는 나 자신을 위해서만 말합니다 (그러나 누군가가 그의 반사를 본다면 당신이 유일한 사람이 아니라는 것을 명심하십시오).

최근 몇 달 동안 버그 경쟁은 먼저 작동하지 않는 프로그램을 MetaTrader 버그로 간주하는 습관을 개발했습니다.

예, 예, 템플릿을 잘 만든 것뿐입니다. 작동하지 않는 경우 버그이므로 전화를 겁니다.

여기서 MQL5 버그가 자신의 버그와 매우 유사하다는 사실이 매우 중요한 역할을 합니다. 그리고 MQL5 버그가 많이 있습니다.

MQL5 버그가 훨씬 적고 그렇게 간단하지도 않습니다. 혼동하기가 훨씬 더 어려울 것입니다.

우크라이나 :

그러나 결국, 당신은 그렇게 멀리 가지 않을 것이고, 이 방법을 계속하면, 전체 MQ 스태프는 곧 다른 사람들의 코드 위에 앉아 "도대체 우리에게 이 모든 것이 필요한 것이 무엇입니까"라는 슬픈 생각으로 바쁠 것이고 한편 챔피언십은 코에, 거기에 실제 계정 을 입력할 수 없습니다.

정리하겠습니다. 오늘 제가 본 모토는 "버그를 게시하려고 했습니다. 문제가 비뚤어진 손에 있는지 확인하십시오."입니다.

MQL5로만 작성된 Expert Advisors의 챔피언십이 도박이라는 사실은 이번 결정 발표 당시에도 분명했습니다. 그러나 경영에는 나름의 비전이 있습니다. 그들 스스로 그렇게 결정했습니다. 아무도 그들이 결정하는 것을 방해하지 않았습니다. 그래서 - 그래서 챔피언십이 코에 있다는 것을 - 그들은 스스로 그러한 삶을 마련했습니다.

여기에서는 간단합니다. 버그를 현지화하는 작업을 직접 수행해야 합니다. 버그에 영향을 주지 않는 코드에서 모든 것을 버리기 시작합니다. 결국, 테스트 케이스와 같은 것을 얻게 됩니다. 아주 작고 동시에 대부분 버그와 시연입니다. 더 이상 "다른 사람의 코드"가 아니라 "MQL5 버그를 보여주는 코드"가 됩니다.

 
OrderCalcMargin() 함수 를 테스트하는 스크립트를 작성했습니다.
 void OnStart ()
  {
//---
   int total= SymbolsTotal (false);
   double marginbay;
   double marginsell;
   MqlTick last_tick;
   for ( int i= 0 ;i<total;i++)
     {

       string symbol= SymbolName (i,false);
       Print ( "************************************************" );
       Print ( "Инструмент - " ,symbol);
       Print ( "Валюта депозита = " , AccountInfoString ( ACCOUNT_CURRENCY ));
       Print ( "Базовая валюта = " , SymbolInfoString (symbol, SYMBOL_CURRENCY_BASE ));
       Print ( "Валюта маржи = " , SymbolInfoString (symbol, SYMBOL_CURRENCY_MARGIN ));
       if ( SymbolInfoTick (symbol,last_tick))
        {
         OrderCalcMargin ( ORDER_TYPE_BUY ,symbol, 1.0 ,last_tick.ask,marginbay);
         OrderCalcMargin ( ORDER_TYPE_SELL ,symbol, 1.0 ,last_tick.bid,marginsell);
         Print ( "Маржа для покупки = " ,marginbay);
         Print ( "Маржа для продажи = " ,marginsell);
        }
       else Print ( "SymbolInfoTick() failed, error = " , GetLastError ());
     }
  }
//+------------------------------------------------------------------+
일부 도구의 경우 함수가 0을 반환합니다. 이것은 버그입니까 아니면 의도된 것입니까?
 
sergey1294 :
OrderCalcMargin() 함수를 확인하는 스크립트를 작성했습니다. 일부 도구의 경우 함수가 0을 반환합니다. 이것은 버그입니까 아니면 의도된 것입니까?

SymbolName 이 다음과 같이 말하므로 MarketWatch에 없는 기호에 대한 것일 수 있습니다.

기호 이름

지정된 기호의 이름을 반환합니다.

문자열 기호 이름 (
    정수     pos , // 목록의 숫자
    부울    선택된        // true - MarketWatch의 기호만
);

옵션

포스

【인】 순서대로 기호 번호입니다.

선택된

【인】 요청 모드입니다. true 이면 MarketWatch에서 선택한 목록에서 기호를 가져옵니다. 값이 false 이면 문자는 일반 목록에서 가져옵니다.

반환 값

기호 이름이 있는 유형 문자열의 값입니다.

예상치 못한 결과를 얻은 기호의 이름을 인쇄하고 MarketWatch의 목록과 비교하십시오.