Bibliotecas: TesterBenchmark - página 2

 

A ideia é boa, mas a implementação não está correta. Respondido em uma mensagem privada:

fxsaber

Boa tarde!

Você poderia adaptar a lógica de negociação à sua biblioteca de negociação para medir seu desempenho?

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

Bibliotecas: TesterBenchmark

fxsaber, 2017.08.15 19:31

Os lugares foram distribuídos da seguinte forma

  1. Pure MQL5 - 100% de desempenho.
  2. MT4Orders.mqh - ~95% de desempenho.
  3. SB Trade\Trade.mqh - ~84% de desempenho.
O SB começou a se atrasar menos.


ZЫ Gostaria de saber o quanto as outras bibliotecas de negociação mostram...

Obrigado!

Não estou entendendo o desempenho de quê? Da biblioteca? Ela não funciona sem uma estratégia. Você precisa de uma estratégia. Então, precisamos medir o desempenho da estratégia escrita com a ajuda da biblioteca. Digamos que a medimos e obtivemos o resultado. Com o que devemos comparar esse resultado? Precisamos compará-lo com a mesma estratégia escrita em MQL puro. Onde obter duas estratégias? Suponhamos que tenhamos essas duas estratégias. Mas onde está a garantia de que elas são idênticas em termos de entradas/saídas de negociação entre si? Suponhamos que tenhamos duas estratégias que sejam garantidamente idênticas uma à outra e meçamos suas velocidades. As velocidades diferem apenas ligeiramente. Isso significa que o motor é eficiente? Não, não significa, porque a estratégia não usa todos os recursos do mecanismo/MQL. De repente, acontece que se você solicitar um longo histórico de cotações em outra estratégia, o mecanismo começa a trabalhar muito mais devagar. Isso significa que o mecanismo funciona muitas vezes mais lentamente do que o MQL puro? Não, não significa que essa operação específica seja mais lenta, mas digamos que, se você otimizar as classes que fornecem dados, em novas versões, o mecanismo funcionará mais rápido do que o sistema CopyXXX na mesma operação. É por isso que o principal não está claro em toda essa história: o que somos e com o que estamos nos comparando.

 
Vasiliy Sokolov:

A ideia é boa, mas a implementação não está correta. Respondido em uma mensagem privada:


Ele contém a mesma lógica de negociação simples, mas de três formas: MQL5 puro, Trade.mqh e MT4Orders.mqh

Devido a isso, é possível medir o desempenho de cada variante com resultados de negociação absolutamente idênticos.

Até o momento, verifica-se que a Trade.mqh está 15% atrás. Mas a abordagem de medição de desempenho é universal - você pode repetir a lógica de negociação em qualquer API de negociação. Aqui, sugiro que você a escreva em sua Bíblia multiplataforma e meça a velocidade comparando-a com a MQL5 pura.

Graças a essas medições, consegui encontrar gargalos em minha bíblia e eliminá-los. E, ao otimizar, isso às vezes se traduz em horas economizadas. Em geral, acho que isso é útil.


Em seu consultor, você faz apenas
#include <TesterBenchmark.mqh>

e não precisa de mais nada. Em seguida, selecione Otimização e execute-a. Você verá o desempenho nos registros.

 

Em seu código do Expert Advisor de teste, a cada tick, é feita uma pesquisa completa das transações no histórico, levando em conta o lote total e o lucro, e o volume da transação atual é calculado:

if (HistorySelect(0, TimeCurrent()))
    {
      const int Total = HistoryDealsTotal() - 1;
      double SumProfit = 0;
      double SumLots = 0;
      for (int i = Total, Count = 0; (i >= 0) && (Count < AmountLastDeals); i--)
      {
        const ulong Ticket = HistoryDealGetTicket(i);

        if ((ENUM_DEAL_ENTRY)HistoryDealGetInteger(Ticket, DEAL_ENTRY) == DEAL_ENTRY_OUT)
        {
          SumProfit += HistoryDealGetDouble(Ticket, DEAL_PROFIT) * (AmountLastDeals - Count);
          SumLots += HistoryDealGetDouble(Ticket, DEAL_VOLUME) * (AmountLastDeals - Count);

          Count++;
        }
      }
      SumLots /= (AmountLastDeals * (1 + AmountLastDeals)) >> 1;
      ...
   }

Seu Expert Advisor não faz nada além de carregar no HistorySelect. Portanto, ele não pode ser uma referência para medir o desempenho de nada além do próprio HistorySelect. Portanto, suas declarações que eu cito:"O MT5 é 4,4 vezes mais rápido que o MT4!" devem ser corrigidas, no mínimo, para que o HistorySelect no MT5 seja 4,4 vezes mais rápido que um procedimento interno semelhante no MT4.

Quanto ao meu mecanismo CStrategy, ele atualmente não permite trabalhar com negociações, mas apenas com posições, portanto, o exemplo como está escrito agora não pode ser usado no CStrategy.

P.S. Observo que, em seu exemplo, a velocidade de trabalho é igual a O(n). E a única diferença entre o MT4 e o MT5, nesse caso, é a velocidade de HistorySelect/HistoryOrderSelect. Naturalmente, a CStrategy em tarefas com complexidade O(n) usará chamadas básicas, nesse caso, HistorySelect e, naturalmente, será um pouco mais lenta do que chamar HistorySelect diretamente. Mas quando você precisar chamar, digamos, HistoryOrderSelect(ticket) - aqui tudo pode ser muito mais interessante e, em algumas tarefas, o CStrategy quebrará o acesso padrão ao ambiente, devido ao acesso por dicionário e ao armazenamento de dados na memória do programa.

 
Vasiliy Sokolov:

Em seu código do Expert Advisor de teste, a cada tick, é feita uma pesquisa completa das transações no histórico, levando em conta o lote total e o lucro, e o volume da transação atual é calculado:

Seu Expert Advisor não faz nada além de carregar no HistorySelect. Portanto, ele não pode ser uma referência para medir o desempenho de nada além do próprio HistorySelect. Portanto, suas declarações que eu cito:"O MT5 é 4,4 vezes mais rápido que o MT4!" devem ser corrigidas para que o HistorySelect no MT5 seja 4,4 vezes mais rápido que um procedimento interno semelhante no MT4.

Você tirou conclusões precipitadas. A parte dada é executada somente na abertura de uma posição uma vez a cada intervalo de segundos. Ou seja, muito raramente.

Quanto ao meu mecanismo CStrategy, atualmente ele não permite trabalhar com negociações, mas apenas com posições, portanto, o exemplo como está escrito agora não pode ser usado no CStrategy.

Aqui está o código MQL4 do EA de teste OnTick, que também funciona somente com posições.

if (!OrderSelect(0, SELECT_BY_POS))
{
  const int Total = OrdersHistoryTotal() - 1;

  double SumProfit = 0;
  double SumLots = 0;

  for (int i = Total, Count = 0; (i >= 0) && (Count < AmountLastDeals); i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
    {
      SumProfit += OrderProfit() * (AmountLastDeals - Count);
      SumLots += OrderLots() * (AmountLastDeals - Count);

      Count++;
    }

  SumLots /= (AmountLastDeals * (1 + AmountLastDeals)) >> 1;

  const int Type = (Total >= 0) && OrderSelect(Total, SELECT_BY_POS, MODE_HISTORY) && (OrderType() == OP_BUY) ? OP_SELL : OP_BUY;

  OrderSend(_Symbol, Type, (SumProfit >= 0) ? Lots : CorrectLot(SumLots),
            SymbolInfoDouble(_Symbol, (Type == OP_BUY) ? SYMBOL_ASK : SYMBOL_BID), 0, 0, 0); // , NULL, 0, 0, 0, 0, INT_MIN);
}
else if (TimeCurrent() - OrderOpenTime() >= Interval)
  OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0);

Não é difícil reescrever essa lógica simples em sua API, é claro. Mas se você tiver uma sugestão de um EA melhor para analisar o desempenho da API de negociação (apenas negociação, não séries temporais etc.), ficarei feliz em ver sua versão da lógica de negociação. Posso reescrevê-la rapidamente para MQL5, MQL4 e Trade.mqh puros.


ZY Ao iniciar um consultor de teste, escolha balance = 1e7. Para sempre ter fundos suficientes para abrir uma posição.

 
fxsaber:

Você tirou conclusões precipitadas. A peça em questão é executada somente na abertura da posição uma vez a cada intervalo de segundos. Ou seja, muito raramente.

Aqui está o código MQL4 do OnTick do Expert Advisor de teste, que também funciona somente com posições.

Não é difícil reescrever essa lógica simples em sua API, é claro. Mas se você tiver uma sugestão de um EA melhor para analisar o desempenho da API de negociação (apenas negociação, não séries temporais etc.), ficarei feliz em ver sua versão da lógica de negociação. Posso reescrevê-la rapidamente para MQL5, MQL4 e Trade.mqh puros.

Dê uma olhada no seu código e me diga o que ele mede

if (!OrderSelect(0, SELECT_BY_POS))
{
  const int Total = OrdersHistoryTotal() - 1;

  double SumProfit = 0;
  double SumLots = 0;

  for (int i = Total, Count = 0; (i >= 0) && (Count < AmountLastDeals); i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
    {
      SumProfit += OrderProfit() * (AmountLastDeals - Count);
      SumLots += OrderLots() * (AmountLastDeals - Count);

      Count++;
    }

  SumLots /= (AmountLastDeals * (1 + AmountLastDeals)) >> 1;

  const int Type = (Total >= 0) && OrderSelect(Total, SELECT_BY_POS, MODE_HISTORY) && (OrderType() == OP_BUY) ? OP_SELL : OP_BUY;

  OrderSend(_Symbol, Type, (SumProfit >= 0) ? Lots : CorrectLot(SumLots),
            SymbolInfoDouble(_Symbol, (Type == OP_BUY) ? SYMBOL_ASK : SYMBOL_BID), 0, 0, 0); // , NULL, 0, 0, 0, 0, INT_MIN);
}
else if (TimeCurrent() - OrderOpenTime() >= Interval)
  OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0);

Há dois gargalos aqui: o loop for e o envio da ordem em si. Você quer comparar onde o loop for funciona mais rápido? Em CTrade ou em MQL puro? Onde é mais rápido enviar uma ordem? No CTrade ou no OrderSend? É claro que no OrderSend puro é mais rápido, porque no CTrade muitas verificações são feitas antes de a ordem ser enviada. Mas que conclusões devem ser tiradas disso?

 
Vasiliy Sokolov:

Dê uma olhada no seu código e me diga o que ele mede

Há dois gargalos aqui: o loop for e o envio real do pedido. Você quer comparar onde o loop for funciona mais rápido?

Por algum motivo, você não está vendo isso

fxsaber:

O trecho fornecido é executado somente na abertura de uma posição uma vez a cada intervalo de segundos. Ou seja, muito raramente.


Vasiliy Sokolov:

Onde é mais rápido enviar uma ordem? No CTrade ou no OrderSend? É claro que no OrderSend puro é mais rápido, porque no CTrade muitas verificações são feitas antes de a ordem ser enviada. Mas quais são as implicações disso?

O CTrade faz muito menos verificações do que o mesmo MT4Orders. As conclusões são simples agora - o SB está 16% atrás do MQL5 puro e pode ser acelerado com absoluta precisão. E quem usa a CTrade perde dinheiro extra na nuvem durante a otimização e tempo para a própria otimização.

 

Você ainda não entende o que seu código está fazendo. Executei o profiler de propósito e, em uma hora, fiz 1800 negociações com intervalos de 1 segundo. 99,66% do tempo de execução do OnTick é ocupado por duas funções OrderSend:

O que você vai otimizar? Os 0,34% restantes não têm sentido. Você não pode otimizar o OrderSend.

Certo. A parte mais interessante. Coloque #include <Trade\Trade.mqh> e veja o que mudou ao usar a biblioteca CTrade:


Agora leva 100% do tempo para chamar Trade.Buy/Sell e Trade.PositionClose. Vamos para Trade.PositionClose e ta-da-mmmm:

Ou seja, em 99,97% das vezes, Trade.PositionClose usa o mesmo OrderSend. Da mesma forma, com Trade.Buy e Trade.Sell.

Então, o que você vai otimizar no SB? Onde está o objeto do teste? O que você está testando em geral?

(Para aqueles que não entendem os números do perfil, explicarei: 99,97% do tempo de execução do programa é consumido pelo envio direto da ordem via OrderSend, os 0,03% restantes são consumidos pela vinculação do CTrade com as verificações necessárias antes do envio da ordem. Ou seja, o uso de um OOP competente introduz atrasos tão insignificantes que podem ser negligenciados e considerados iguais a zero. Não é 0,03%, mas ainda menos, porque a maior parte do tempo desse 0,03% é ocupada por verificações obrigatórias, que devem ser implementadas de forma competente, seja no código de procedimento ou em outro lugar.)

 
Vasiliy Sokolov:

Executei especificamente o criador de perfil e, em uma hora, estava atingindo 1800 negociações em intervalos de 1 segundo.

O que o on-line tem a ver com isso? Tem a ver com o testador.

 
Andrey Khatimlianskii:

O que o on-line tem a ver com isso? Tem a ver com o testador.

Se estivermos falando do MT5 e de seu testador de estratégia, os mesmos 99% do tempo (bem, talvez um pouco menos) são gastos na recriação do ambiente de negociação (daí a lentidão das execuções em comparação com o MT4). E não há razão para pensar que, se o OrderSend na vida real leva 99,9% do tempo, no testador de estratégia ele funcionará duas ordens de magnitude mais rápido.
 
Vasiliy Sokolov:
Se estivermos falando do MT5 e de seu testador de estratégia, os mesmos 99% do tempo (bem, talvez um pouco menos) são gastos na recriação do ambiente de negociação (daí a lentidão das execuções em comparação com o MT4). E não há razão para pensar que, se o OrderSend na vida real leva 99,9% do tempo, de repente ele funcionará duas ordens de magnitude mais rápido no testador de estratégia.

Vasily, você está falando seriamente sobre a comensurabilidade da velocidade de execução do OrderSend no testador e em tempo real?

Online, ele é o mais lento porque envia informações ao servidor e aguarda uma resposta, enquanto no testador (se você não incluir o atraso, mas isso estava fora de questão) ele envia e aguarda instantaneamente.

A tarefa dessa biblioteca é medir a velocidade do testador (em termos de funções de negociação).