mql4 언어의 기능, 미묘함 및 작업 방법 - 페이지 34

 
이러한 불쾌한 문제가 발견되었습니다. 스크립트가 실행 중이고 충돌(플랫폼을 닫음)하면 스크립트가 작동하는 동안 로그 파일에 기록이 저장되지 않아 코드에서 오류를 식별하기가 상당히 어렵습니다. 그 전에는 어떻게 든 그런 문제를 눈치 채지 못했습니다. 이것은 항상 (기록을 저장하지 않음) ?
 

MT4에서는 계정의 거래 레버리지 변경에 대해 (재연결 없이) 알 수 있는 방법이 없는 것 같습니다.

 
fxsaber # :

MT4에서는 계정의 거래 레버리지 변경에 대해 (재연결 없이) 알 수 있는 방법이 없는 것 같습니다.

5년 전에 했습니다. 특정 시간 동안 클라이언트의 레버리지가 감소했으며 AccountInfoInteger(ACCOUNT_LEVERAGE) 변수에서 변경되지 않았습니다. 그리고 그는 그것에 대해 알아야 했습니다.

과학적으로 어느 정도인지는 모르겠지만 계정에 레버리지가 있고 거의 변하지 않는 레버리지가 있지만 하루에 여러 번 변경할 수 있는 레버리지가 있다고 스스로 판단했습니다.
나는 다음과 같이 검사를 했다.

 //+------------------------------------------------------------------------------------------------------------------+
//| Проверяет изменение плеча и сообщает если это было
//+------------------------------------------------------------------------------------------------------------------+
void leverageCheck()
{
   if (MarketInfo( Symbol (), MODE_MARGINREQUIRED) == 0 ) return ;

   // --- получаем текущее плечо из маржинальных требований, стоимости пункта, тек.котировки
   double leverageSymb = MarketInfo( Symbol (),MODE_TICKVALUE) * Bid / MarketInfo( Symbol (),MODE_MARGINREQUIRED) / Point ;
  leverageSymb = int ( MathRound (leverageSymb));
  
   // --- если плечо по символу стало меньше на 10% плеча по счету отметим это
   if (leverageSymb < percVar( AccountInfoInteger ( ACCOUNT_LEVERAGE ), - 10 ))
  {
     string txt = TimeToString ( TimeCurrent ()) + " Leverage is reduced 1:" + ( string )leverageSymb;
     Print (txt, " but account leverage = " + ( string ) AccountInfoInteger ( ACCOUNT_LEVERAGE ));

     // --- вывод информации на график
  }
}

//+-------------------------------------------------------------------------------------------------------------------+
//| Получает переменную, увеличивает или уменьшает его на переданный процент и возвращает новое значение
//| Чтобы уменьшить, нужно передать percent с минусом
//+-------------------------------------------------------------------------------------------------------------------+
double percVar( double var, double percent)
{
   return var*( 1 + percent/ 100 );
}


간혹 현재 계산된 레버리지 심볼의 레버리지가 200이 아닌 199,198이 되는 경우가 있기 때문에(레버리지가 1:200일 때) 표준 레버리지에서 일정 %를 빼서 이 값과 비교해야 했습니다. 위의 솔루션이 도움이 되었을 때 유용할 수 있습니다.

 
Vasiliy Pushkaryov # :

5년 전에 했습니다. 특정 시간 동안 클라이언트의 레버리지가 감소했으며 AccountInfoInteger(ACCOUNT_LEVERAGE) 변수에서 변경되지 않았습니다. 그리고 그는 그것에 대해 알아야 했습니다.

과학적으로 어느 정도인지는 모르겠지만 계정에 레버리지가 있고 거의 변하지 않는 레버리지가 있지만 하루에 여러 번 변경할 수 있는 레버리지가 있다고 스스로 판단했습니다.
나는 다음과 같이 검사를 했다.


간혹 현재 계산된 레버리지 심볼의 레버리지가 200이 아닌 199,198이 되는 경우가 있기 때문에(레버리지가 1:200일 때) 표준 레버리지에서 일정 %를 빼서 이 값과 비교해야 했습니다. 위의 솔루션이 도움이 되었을 때 유용할 수 있습니다.

예, 추적 기호 여백 요구 사항은 문제가 되지 않습니다. ACCOUNT_LEVERAGE - 재연결만 가능.

 

티켓 목록에 필요한 주문을 저장하여 거래 내역을 필터링하는 것은 매우 일반적인 관행입니다. 그런 다음 해당 목록에 대해 SELECT_BY_TICKET.

나는 티켓이 아니라 위치를 기억하는 옵션을 본 적이 없습니다. 아래는 성능 비교입니다.

 #include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006
#include <fxsaber\Benchmark\Benchmark.mqh> // https://www.mql5.com/ru/code/31279

int Filter( TICKET_TYPE &Tickets[], int &Pos[] )
{
   const int Total = OrdersHistoryTotal();            

   ArrayResize (Tickets, Total);
   ArrayResize (Pos, Total);
  
   int Amount = 0 ;

   for ( int i = 0 ; i < Total; i++)
     if ( OrderSelect (i, SELECT_BY_POS, MODE_HISTORY) && (OrderProfit() > 0 ))
    {
      Tickets[Amount] = OrderTicket();
      Pos[Amount] = i;
      
      Amount++;
    }
    
   ArrayResize (Tickets, Amount);
   ArrayResize (Pos, Amount);
  
   return (Amount);
}

template < typename T>
double Func1( int TypeSelect, const T &Array[] )
{
   double Res = 0 ;
   const int Total = ArraySize (Array);
  
   for ( int i = 0 ; i < Total; i++)
     if ( OrderSelect (Array[i], TypeSelect, MODE_HISTORY))
      Res += OrderProfit();
      
   return (Res);
}

void OnStart ()
{   
  TICKET_TYPE Tickets[];
   int Pos[];

   Print (Filter(Tickets, Pos));
  
   const double Res1 = _B(Func1(SELECT_BY_TICKET, Tickets), 1 ); // Так делают почти все.
   const double Res2 = _B(Func1(SELECT_BY_POS, Pos), 1 );         // Не встречал.
  
   Print (Res1);
   Print (Res2);
}


 2021.10 . 11 01 : 37 : 08.254 Test19 EURUSD.rann,M1: 561002.61
2021.10 . 11 01 : 37 : 08.254 Test19 EURUSD.rann,M1: 561002.61
2021.10 . 11 01 : 37 : 08.254 Test19 EURUSD.rann,M1: Alert : Bench_Stack = 0 , 1 <= Time[Test19.mq4 49 in OnStart : Func1(SELECT_BY_POS,Pos)] = 2827 mcs.
2021.10 . 11 01 : 37 : 08.251 Test19 EURUSD.rann,M1: Alert : Bench_Stack = 0 , 1 <= Time[Test19.mq4 48 in OnStart : Func1(SELECT_BY_TICKET,Tickets)] = 7460 mcs.
2021.10 . 11 01 : 37 : 08.244 Test19 EURUSD.rann,M1: 35936

티켓이 있는 옵션은 성능이 거의 3배 정도 떨어지는 것을 알 수 있습니다.

 
fxsaber # :

티켓이 있는 옵션은 성능이 거의 3배 정도 떨어지는 것을 알 수 있습니다.

위치가 닫히거나 열리면 티켓이 있는 논리가 깨지지 않고 위치가 있는 논리가 깨질 수 있습니다.

 
TheXpert # :

위치가 닫히거나 열리면 티켓이 있는 논리가 깨지지 않고 위치가 있는 논리가 깨질 수 있습니다.

MODE_HISTORY 모드에 관한 것입니다.

 

이 코드가 함수 호출 이전과 이후에 있었던 어떤 순서를 건너뛸 것이라는 이론적인 가능성이 있습니까? 또는 두 번 계산합니다.

 double GetLots()
{
   double Lots = 0 ;
  
   for ( int i = OrdersTotal () - 1 ; i >= 0 ; i--)
     if ( OrderSelect (i, SELECT_BY_POS))
      Lots += OrderLots();
      
   return (Lots);
}

저것들. 주문이 삭제되거나 열거 중에 나타날 때 인덱싱은 어떻게 됩니까?

 
fxsaber # :

또는 두 번 계산합니다.

일반적으로 정렬에 따라 다릅니다. 기본적으로 시간 또는 티켓순으로 정렬하면 목록의 끝에 새 주문이 표시됩니다. 가장 오래된 주문이 삭제되면 모든 것이 이동하는 것이 논리적입니다.

목록의 시작 부분에서 주문이 제거되면 목록 중 하나를 두 번 고려할 수 있습니다. 하기 쉬운 것 같습니다 - 이전 패스의 티켓을 기억하고 비교하기만 하면 됩니다(여전히 보장되지는 않음).

돌아오는 길에 패스를 얻는 방법 - 생각해내지 못했습니다.

 
Andrei Trukhanovich # :

일반적으로 정렬에 따라 다릅니다. 기본적으로 시간 또는 티켓으로 정렬하는 것을 수락하면 새 주문이 목록 끝에 표시되며 가장 오래된 주문이 삭제되면 모든 것이 이동하는 것이 논리적입니다.

목록의 시작 부분에서 주문이 제거되면 목록 중 하나를 두 번 고려할 수 있습니다. 하기 쉬운 것 같습니다 - 이전 패스의 티켓을 기억하고 비교하기만 하면 됩니다(여전히 보장되지는 않음).

돌아오는 길에 패스를 얻는 방법 - 생각해내지 못했습니다.

자세한 답변 감사합니다! 그래서 지금은 모든 주문을 한 번에 정렬하는 방법을 생각하고 있습니다.