Bibliotecas: MT4Orders - página 52

 
traveller00:
Por via das dúvidas, gostaria de mencionar que os arquivos ZIP foram corrigidos, pelo que me lembro. Mas agora está tudo bagunçado novamente e há uma versão antiga lá, você tem que atualizar por arquivo.
 
// Lista de modificações:
// 29.08.2020
// Correção: o trabalho com o histórico de negociação foi acelerado.
 

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

Bibliotecas: MT4Orders

fxsaber, 2020.08.29 00:03

2020.08.29 00:57:38.561 HistoryDealsTotal() = 9435
2020.08.29 00:57:38.813 2046.04.30 00:13:20
2020.08.29 00:57:38.813 Time[Bench(LastTimeMQL4)] = 252274
2020.08.29 00:57:38.820 2046.04.30 00:13:20
2020.08.29 00:57:38.820 Time[Bench(LastTimeMQL5)] = 7162

A MQL5 pura foi 40 vezes mais rápida nessa tarefa. Aprenda MQL5!

Após a atualização.

        HistoryDealsTotal() = 9435
        2046.04.30 00:13:20
        Time[Bench(LastTimeMQL4)] = 16984
        2046.04.30 00:13:20
        Time[Bench(LastTimeMQL5)] = 4194

a velocidade dessa tarefa aumentou em 15 vezes. Não foi feita uma manobra óbvia depois de estudar as peculiaridades das funções HistorySelect.

 
Perda vergonhosa do MT4Orders para o MQL5+SB.
// O script calcula a duração total de todas as posições fechadas.

#include <MT4Orders.mqh> // https://www.mql5.com/en/code/16006

// Retorna a duração total de todas as posições fechadas.
int SumPositionsLengthMQL4( void )
{
  int Res = 0;
  
  for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
      Res += (int)(OrderCloseTime() - OrderOpenTime());
      
  return(Res);
}

#include <Generic\HashMap.mqh>

// Retorna a duração total de todas as posições fechadas.
int SumPositionsLengthMQL5( void )
{
  int Res = 0;
  
  if (HistorySelect(0, INT_MAX))
  {
    CHashMap<ulong, ulong> DealsIn;  // Por PositionID, retorna DealIn.
    const int TotalDeals = HistoryDealsTotal();
    
    for (int i = 0; i < TotalDeals; i++)
    {
      const ulong TicketDeal = HistoryDealGetTicket(i);
      
      if (HistoryDealGetInteger(TicketDeal, DEAL_ENTRY) == DEAL_ENTRY_IN)
        DealsIn.Add(HistoryDealGetInteger(TicketDeal, DEAL_POSITION_ID), TicketDeal);
      else if (HistoryDealGetInteger(TicketDeal, DEAL_TYPE) <= DEAL_TYPE_SELL)
      {
        ulong TicketDealIn;
        
        if (DealsIn.TryGetValue(HistoryDealGetInteger(TicketDeal, DEAL_POSITION_ID), TicketDealIn))
          Res += (int)(HistoryDealGetInteger(TicketDeal, DEAL_TIME) - HistoryDealGetInteger(TicketDealIn, DEAL_TIME));        
      }        
    }
  }
      
  return(Res);
}

typedef int (*SumPositionsLength)( void );

void Bench( SumPositionsLength GetSumPositionsLength, const int Amount = 100 )
{
  long Tmp = 0;

  for (int i = 0; !IsStopped() && (i < Amount); i++)
    Tmp += GetSumPositionsLength();
  
  Print(Tmp);
}

#define  BENCH(A)                                                              \
{                                                                             \
  const ulong StartTime = GetMicrosecondCount();                              \
  A;                                                                          \
  Print("Time[" + #A + "] = " + (string)(GetMicrosecondCount() - StartTime)); \
}

#define  PRINT(A) Print(#A + " = " + (string)(A))

void OnStart()
{  
  if (HistorySelect(0, INT_MAX))
    PRINT(HistoryDealsTotal());

  BENCH(Bench(SumPositionsLengthMQL4))
  BENCH(Bench(SumPositionsLengthMQL5))
}


Resultado.

        HistoryDealsTotal() = 9435
        3132754100
        Time[Bench(SumPositionsLengthMQL4)] = 871406
        3132754100
        Time[Bench(SumPositionsLengthMQL5)] = 109411


Diferença de 9 vezes no desempenho. Aprenda MQL5.

 
fxsaber:

Resultado.

Se não for muito difícil, mostre a diferença entre o tempo de execução desse teste no 4k e no MT5 (terminais).

fxsaber:
Perda vergonhosa do MT4Orders antes do MQL5+SB.

tudo é relativo.... 5 linhas de código e uma dúzia de linhas para o MT5 - se você testar a ideia, então é preferível o 5-stock, se você otimizar, então definitivamente a segunda opção

 
Igor Makanu:

Se não for difícil, a diferença entre o 4 e o MT5 (terminais) mostra o tempo de execução desse teste

MT4:

OrdersHistoryTotal() = 10291
Time[Bench(SumPositionsLengthMQL4)] = 56548

OrdersHistoryTotal() = 32020
Time[Bench(SumPositionsLengthMQL4)] = 186761

OrdersHistoryTotal() = 41815
Time[Bench(SumPositionsLengthMQL4)] = 249371


O MT4x32 é mais de quatro vezes mais rápido do que o MT5x64, com o mesmo número de posições fechadas.


ZЫ Provavelmente, se você esquecer a economia de memória no MT4Orders, salvando o histórico em uma matriz interna, também poderá vencer o MT4. Talvez isso deva ser feito dessa forma.

 
fxsaber:

O MT4x32 é mais de quatro vezes mais rápido que o MT5x64, com o mesmo número de posições fechadas.

Obrigado, na minha opinião, esse é um defeito da MK, mas eles têm sua própria visão das finalidades para as quais um MT5 produtivo deve ser usado.

fxsaber:

ZЫ Provavelmente, se esquecermos a economia de memória no MT4Orders, salvando o histórico em uma matriz interna, poderemos vencer o MT4. Talvez isso deva ser feito dessa forma.

Bem, você pode definitivamente fazer isso com uma opção de desativação, pelo menos seus códigos sempre tiveram esses recursos.

SZY: Testei os tamanhos das cadeias de caracteres para eliminar o terminal, o MT5 não é eliminável - ele sempre consegue alocar memória, acho que somente em um testador com vários núcleos é possível obter falhas ao alocar grandes quantidades de memória..... em geral, você precisa testar


SZYZY: nunca verificou quanta memória uma matriz de estruturas com dados do histórico de transações pode ocupar? Bem, digamos que a estrutura pesa 200 bytes e o histórico de transações 100K registros - o resultado é 20 Mb... Na minha opinião, isso não é um problema se você não sobrecarregar o terminal com tarefas sofisticadas... em geral, teste tudo da mesma forma - então ficará claro

 
Igor Makanu:

ZYZY: nunca verifiquei, quanta memória uma matriz de estruturas com dados do histórico de negociação pode ocupar?

        sizeof(MT4_ORDER) = 280
 

Parece que não consigo voltar a ficar em forma depois dos dias de verão...

fxsaber:

MT4:

O MT4x32 é mais de quatro vezes mais rápido que o MT5x64, com o mesmo número de posições fechadas.

@fxsaber, você poderia verificar esse teste em um ambiente virtual? (Biblioteca virtual.mqh)

 
Igor Makanu:

@fxsaber, você poderia verificar esse teste em um ambiente virtual? (Biblioteca virtual.mqh)

#include <MT4Orders.mqh> // https://www.mql5.com/en/code/16006
#include <fxsaber\Virtual\Virtual.mqh>

// Retorna a duração total de todas as posições fechadas.
int SumPositionsLengthMQL4( void )
{
  int Res = 0;
  
  for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
      Res += (int)(OrderCloseTime() - OrderOpenTime());
      
  return(Res);
}

typedef int (*SumPositionsLength)( void );

void Bench( SumPositionsLength GetSumPositionsLength, const int Amount = 100 )
{
  long Tmp = 0;

  for (int i = 0; !IsStopped() && (i < Amount); i++)
    Tmp += GetSumPositionsLength();
  
  Print(Tmp);
}

#define  BENCH(A)                                                              \
{                                                                             \
  const ulong StartTime = GetMicrosecondCount();                              \
  A;                                                                          \
  Print("Time[" + #A + "] = " + (string)(GetMicrosecondCount() - StartTime)); \
}

#define  PRINT(A) Print(#A + " = " + (string)(A))

bool CreateHistory( const int Amount = 10000 )
{
  const bool Res = VIRTUAL::GetHandle();
  
  if (Res)
  {
    MqlTick Tick;
    
    _V(0, SymbolInfoTick(_Symbol, Tick));
    VIRTUAL::NewTick(Tick);
        
    for (int i = 0; i < Amount; i++)
    {      
      const TICKET_TYPE Ticket = OrderSend(_Symbol, OP_BUY, 1, Tick.ask, 0, 0, 0);
      
      Tick.time_msc += 1000;
      VIRTUAL::NewTick(Tick);
      
      OrderClose(Ticket, 1, Tick.bid, 0);            
    }
  }
  
  return(Res);
}

void OnStart()
{    
  PRINT(OrdersHistoryTotal());
  BENCH(Bench(SumPositionsLengthMQL4))
  
  VIRTUAL::SelectByHandle(VIRTUAL::Create());

  if (CreateHistory())  
  {
    PRINT(OrdersHistoryTotal());
    BENCH(Bench(SumPositionsLengthMQL4))
  }    
}


Resultado

// MT4
// Real:
VIRTUAL::VirtualOrdersHistoryTotal() = 10291
Time[Bench(SumPositionsLengthMQL4)] = 63774

// Virtual
VIRTUAL::VirtualOrdersHistoryTotal() = 10001
Time[Bench(SumPositionsLengthMQL4)] = 158218

// MT5
// Virtual
VIRTUAL::VirtualOrdersHistoryTotal() = 10001
Time[Bench(SumPositionsLengthMQL4)] = 43343

Você pode ver claramente que o histórico do MT4 é três vezes mais rápido do que o ambiente virtual no MT4. Ao mesmo tempo, no MT5, o mesmo ambiente virtual é quatro vezes mais rápido do que no MT4.

Ou seja, o ambiente virtual no MT5 é mais rápido do que o ambiente real no MT4.