mql5 언어의 특징, 미묘함 및 작업 방법 - 페이지 185

 
다른 버그를 재현합니다. 우리는 현재 가격 에 지정가 주문을 하고 점차 채워지는 것을 지켜봅니다. 각 단계에서 모든 포지션과 주문의 총 로트를 확인합니다. 변경되지 않아야 합니다. OrderSend에서 보낸 것과 동일해야 합니다.
 // Демонстрация потери данных во время торговли.

template < typename T>
T MyPrint( const T Value, const string Str )
{
   Print (Str + " = " + ( string )Value);

   return (Value);
}

#define _P(A) MyPrint(A, ": " + #A)

sinput double inLots = 100 ;

int OnInit ()
{
   MqlTradeResult Result = { 0 };
   MqlTradeRequest Request = { 0 };
  
  Request.action = TRADE_ACTION_PENDING ;
  Request.symbol = _Symbol ;
  Request.volume = inLots;
  Request.price = SymbolInfoDouble ( _Symbol , SYMBOL_ASK );
  Request.type = ORDER_TYPE_BUY_LIMIT ;
  
   return ( OrdersTotal () || PositionsTotal () || ! OrderSend (Request, Result)); // Работаем, когда ничего не открыто.
}

// Возвращает сумму лотов всех позиций и ордеров.
double GetSumLots()
{
   double Lots = 0 ;
  
   for ( int i = _P( OrdersTotal ()) - 1 ; i >= 0 ; i--)
     if (_P( OrderGetTicket (_P(i))))
      Lots += _P( OrderGetDouble ( ORDER_VOLUME_CURRENT ));
    
   for ( int i = _P( PositionsTotal ()) - 1 ; i >= 0 ; i--)
     if (_P( PositionGetTicket (_P(i))))
      Lots += _P( PositionGetDouble ( POSITION_VOLUME ));

   return (Lots);
}

void OnTradeTransaction ( const MqlTradeTransaction & trans,
                         const MqlTradeRequest & request,
                         const MqlTradeResult & result)
{
   Print ( "---------" );
    
   // Проверяем, что сумма лотов всех позиций и ордеров совпадает с заданной.
   if ( NormalizeDouble (_P(GetSumLots()) - inLots, _Digits ))
     Alert ( "BUG!" );
}


결과.

 2020.08 . 21 01 : 18 : 13.375 : OrdersTotal () = 1
2020.08 . 21 01 : 18 : 13.375 : i = 0
2020.08 . 21 01 : 18 : 13.375 : OrderGetTicket (MyPrint(i,: +i)) = 1197440
2020.08 . 21 01 : 18 : 13.375 : OrderGetDouble ( ORDER_VOLUME_CURRENT ) = 68.59999999999999
2020.08 . 21 01 : 18 : 13.375 : PositionsTotal () = 1
2020.08 . 21 01 : 18 : 13.375 : i = 0
2020.08 . 21 01 : 18 : 13.375 : PositionGetTicket (MyPrint(i,: +i)) = 1197440
2020.08 . 21 01 : 18 : 13.375 : PositionGetDouble ( POSITION_VOLUME ) = 31.4
2020.08 . 21 01 : 18 : 13.375 : GetSumLots() = 100.0
2020.08 . 21 01 : 18 : 13.377 ---------
2020.08 . 21 01 : 18 : 13.377 : OrdersTotal () = 1
2020.08 . 21 01 : 18 : 13.377 : i = 0
2020.08 . 21 01 : 18 : 13.377 : OrderGetTicket (MyPrint(i,: +i)) = 1197440
2020.08 . 21 01 : 18 : 13.377 : OrderGetDouble ( ORDER_VOLUME_CURRENT ) = 68.59999999999999
2020.08 . 21 01 : 18 : 13.377 : PositionsTotal () = 1
2020.08 . 21 01 : 18 : 13.377 : i = 0
2020.08 . 21 01 : 18 : 13.377 : PositionGetTicket (MyPrint(i,: +i)) = 1197440
2020.08 . 21 01 : 18 : 13.377 : PositionGetDouble ( POSITION_VOLUME ) = 31.4
2020.08 . 21 01 : 18 : 13.377 : GetSumLots() = 100.0
2020.08 . 21 01 : 18 : 13.389 ---------
2020.08 . 21 01 : 18 : 13.389 : OrdersTotal () = 1
2020.08 . 21 01 : 18 : 13.389 : i = 0
2020.08 . 21 01 : 18 : 13.389 : OrderGetTicket (MyPrint(i,: +i)) = 1197440
2020.08 . 21 01 : 18 : 13.389 : OrderGetDouble ( ORDER_VOLUME_CURRENT ) = 41.4
2020.08 . 21 01 : 18 : 13.389 : PositionsTotal () = 1
2020.08 . 21 01 : 18 : 13.389 : i = 0
2020.08 . 21 01 : 18 : 13.389 : PositionGetTicket (MyPrint(i,: +i)) = 1197440
2020.08 . 21 01 : 18 : 13.389 : PositionGetDouble ( POSITION_VOLUME ) = 31.4
2020.08 . 21 01 : 18 : 13.389 : GetSumLots() = 72.8
2020.08 . 21 01 : 18 : 13.389 Alert : BUG!
2020.08 . 21 01 : 18 : 13.389 ---------
2020.08 . 21 01 : 18 : 13.389 : OrdersTotal () = 1
2020.08 . 21 01 : 18 : 13.389 : i = 0
2020.08 . 21 01 : 18 : 13.389 : OrderGetTicket (MyPrint(i,: +i)) = 1197440
2020.08 . 21 01 : 18 : 13.389 : OrderGetDouble ( ORDER_VOLUME_CURRENT ) = 41.4
2020.08 . 21 01 : 18 : 13.389 : PositionsTotal () = 1
2020.08 . 21 01 : 18 : 13.389 : i = 0
2020.08 . 21 01 : 18 : 13.389 : PositionGetTicket (MyPrint(i,: +i)) = 1197440
2020.08 . 21 01 : 18 : 13.389 : PositionGetDouble ( POSITION_VOLUME ) = 31.4
2020.08 . 21 01 : 18 : 13.389 : GetSumLots() = 72.8
2020.08 . 21 01 : 18 : 13.389 Alert : BUG!
2020.08 . 21 01 : 18 : 13.389 ---------
2020.08 . 21 01 : 18 : 13.389 : OrdersTotal () = 1
2020.08 . 21 01 : 18 : 13.389 : i = 0
2020.08 . 21 01 : 18 : 13.389 : OrderGetTicket (MyPrint(i,: +i)) = 1197440
2020.08 . 21 01 : 18 : 13.389 : OrderGetDouble ( ORDER_VOLUME_CURRENT ) = 41.4
2020.08 . 21 01 : 18 : 13.389 : PositionsTotal () = 1
2020.08 . 21 01 : 18 : 13.389 : i = 0
2020.08 . 21 01 : 18 : 13.389 : PositionGetTicket (MyPrint(i,: +i)) = 1197440
2020.08 . 21 01 : 18 : 13.389 : PositionGetDouble ( POSITION_VOLUME ) = 31.4
2020.08 . 21 01 : 18 : 13.389 : GetSumLots() = 72.8
2020.08 . 21 01 : 18 : 13.389 Alert : BUG!
2020.08 . 21 01 : 18 : 13.389 ---------
2020.08 . 21 01 : 18 : 13.389 : OrdersTotal () = 1
2020.08 . 21 01 : 18 : 13.389 : i = 0
2020.08 . 21 01 : 18 : 13.389 : OrderGetTicket (MyPrint(i,: +i)) = 1197440
2020.08 . 21 01 : 18 : 13.389 : OrderGetDouble ( ORDER_VOLUME_CURRENT ) = 41.4
2020.08 . 21 01 : 18 : 13.389 : PositionsTotal () = 1
2020.08 . 21 01 : 18 : 13.389 : i = 0
2020.08 . 21 01 : 18 : 13.389 : PositionGetTicket (MyPrint(i,: +i)) = 1197440
2020.08 . 21 01 : 18 : 13.390 : PositionGetDouble ( POSITION_VOLUME ) = 58.6
2020.08 . 21 01 : 18 : 13.390 : GetSumLots() = 100.0

우리는 100로트를 내놓았지만 어느 시점에는 72.8랏이 있었습니다. 분명히 그러한 상황에서 거래 알고리즘은 방향을 잃을 수 있습니다.

검색 문자열 : Osibka 011.
 

fxsaber :
Он должен быть неизменным - равным тому, что был отправлен в OrderSend.

실제로 아니오, 동기화되지 않을 가능성이 있습니다. 발생하는 일입니다. 우회할 수 있습니다. 아주 간단한 해결책은 없습니다.

 
Andrei Trukhanovich :

실제로 아니오, 동기화되지 않을 가능성이 있습니다. 발생하는 일입니다. 우회할 수 있습니다. 아주 간단한 해결책은 없습니다.

나는 어려운 해결책조차 가지고 있지 않다. 실행 중인 일부 스크립트에 비동기화가 있는지 확인하는 방법은 전혀 명확하지 않습니다.

 
fxsaber :

나는 어려운 해결책조차 가지고 있지 않다. 실행 중인 일부 스크립트에 비동기화가 있는지 확인하는 방법은 전혀 명확하지 않습니다.

총 로트가 변경된 경우 주문 및 위치에 대한 로트가 두 번 동일할 때까지 계산을 실행합니다. 있을 때 - 이것은 동기화된 상태입니다.

성능에 거의 영향을 미치지 않도록 분수 또는 백분율 단위의 비동기화 확률.

__________

지문을 보면 버그일 수 있습니다. 동기화되지 않은 경우 여러 계산에서 잘못된 금액이 같은 방식으로 반복되어서는 안 됩니다.

 
Andrei Trukhanovich :

총 로트가 변경된 경우 주문 및 위치에 대한 로트가 두 번 동일할 때까지 계산을 실행합니다. 있을 때 - 이것은 동기화된 상태입니다.

성능에 거의 영향을 미치지 않도록 분수 또는 백분율 단위의 비동기화 확률.

위의 로그에서 세 번의 연속 계산은 잘못된 결과를 보여줍니다. 잠이 필요하지만 거래 주문 에 반응할 시간이 없을 때 지연이 발생합니다.

불쾌한 상황입니다.

 
fxsaber :

위의 로그에서 세 번의 연속 계산은 잘못된 결과를 보여줍니다.

예, 위에서 추가했습니다.

 
이 주제와 관련이 없는 댓글은 " MQL4 및 MQL5에 대한 모든 초보자 질문, 알고리즘 및 코드에 대한 도움말 및 토론 "으로 이동되었습니다.
 
Alexey Viktorov :

헛되이 당신은 기분이 상합니다. 가장 큰 가능성은 코드의 버그입니다. 2위는 높은 스프레드입니다. 그러나 당신 외에는 첫 번째 옵션을 버리고 코드를 보지 않고 두 번째 옵션을 고려할 수 있습니다. 예, 잘못된 주제를 선택했습니다. 중재자가 주제를 전달해 주기를 바랍니다.

정확한 답변 감사합니다. 나는 화를 내지 않고 화를 낸다)))). 나는 이것을 경험한 사람이 이미 가지고 있을 수 있는 빠른 해결책을 찾기 위해 썼습니다. 코드는 절대적으로 표준이며, 특히 코드가 두 개의 다른 계정에서 실패 없이 작동했기 때문에 총 수익 주기를 요약하고 주어진 값과 비교합니다. 좋은 하루 되세요.

 
Evgeny Vlasov :

정확한 답변 감사합니다. 나는 화를 내지 않고 화를 낸다)))). 나는 이것을 경험한 사람이 이미 가지고 있을 수 있는 빠른 해결책을 찾기 위해 썼습니다. 코드는 절대적으로 표준이며, 특히 코드가 두 개의 다른 계정에서 실패 없이 작동했기 때문에 총 수익 주기를 요약하고 주어진 값과 비교합니다. 좋은 하루 되세요.

기능에 대한 주제에서 벗어났습니다.
 
Artyom Trishkin :
기능에 대한 주제에서 벗어났습니다.

동의한다.