MT5 e velocidade em ação - página 23

 
Renat Fatkhullin:

No caso de alguém não conseguir, é a biblioteca do fxsaber que está causando a frenagem quando aplicado no código de outra pessoa.

Em vez de apontar isso explicitamente, ele começou a jogar o jogo sobre a frenagem da plataforma e a dar exemplos suicidas. E quando houve uma oportunidade de chegar à verdadeira causa e resolver o problema, ele não a aproveitou.

Em nome da otimização local estava envenenando o cache de histórico para a aplicação principal.

Fórum sobre comércio, sistemas comerciais automatizados e estratégias comerciais de teste

MT5 e velocidade em ação

fxsaber, 2020.09.02 00:02

Havia um código MQL5 limpo e reprodutível por muitos. A cronologia do primeiro estudo, em vez de jogar a teoria da conspiração, de que alguém precisa tanto de você que está disposto a gastar seu tempo com você para o lama.

Você está fazendo um ótimo trabalho como um peru. Não houve aqui nenhuma discussão sobre nenhuma biblioteca especificamente no tópico, pois não é construtiva.

A questão é que se alguém se aventura a usar bibliotecas compartilhadas onde o parâmetro de entrada não coincide, ele terá freios. Não há nenhuma menção a isto em nenhuma parte da Documentação. Pelo menos algo sobre isso foi tirado de você com uma tenaz. E quando isso foi feito, eles começaram a acusá-lo de trapacear.


Esta característica da MQL deve ser escrita no ramo Documentação e Recursos. Execute os scripts MQL5 limpos deste ramo nos builds correspondentes às datas de sua criação. Aparentemente, tantos consertos foram feitos cegamente só por precaução.

 
fxsaber:

Você está fazendo um ótimo trabalho como indie. Nenhuma biblioteca foi especificamente mencionada aqui no tópico, porque não é construtiva.

Porque você fez o melhor que pôde para não tagarelar sobre suas bibliotecas. Na presença dessas bibliotecas. Com a constante oposição do "meu é mais rápido". Assim, você disfarçou inteligentemente o tiro em si mesmo, destacando "veja como ele é lento".


A questão é que se ousarmos usar juntas bibliotecas onde o parâmetro de entrada não é o mesmo, teremos um atraso. Não há nenhuma menção a isto em nenhuma parte da Documentação. Pelo menos algo sobre este tópico foi extraído de você com uma tenaz. E quando isso foi feito, eles começaram a acusá-lo de trapacear.


Esta característica da MQL deve ser escrita no ramo Documentação e Recursos. Execute os scripts MQL5 limpos deste ramo nos builds correspondentes às datas de sua criação. Aparentemente, tantos consertos foram feitos cegamente só por precaução.

A documentação do HistorySelect afirma claramente:

A função HistorySelect() cria uma lista de ordens e uma lista de negócios no programa mql5 para referência posterior aos elementos da lista por meio das funções correspondentes. O tamanho da lista de ofertas pode ser obtido usando a função HistoryDealsTotal(), e o tamanho da lista de ofertas no histórico pode ser obtido usando a função HistoryOrdersTotal(). A enumeração dos elementos da lista de pedidos é melhor realizada usando a função HistoryOrderGetTicket(), para os elementos da lista de negócios, a função HistoryDealGetTicket() é apropriada.

Após o uso da função HistoryOrderSelect(), a lista de pedidos no histórico, disponível para o programa mql5, é reinicializada e preenchida novamente com o pedido, se a busca do pedido por bilhete tiver sido concluída com sucesso. O mesmo se aplica à lista de ofertas, que estão disponíveis para o programa mql5 - ela é reinicializada usando a função HistoryDealSelect() e preenchida novamente se uma oferta for obtida com sucesso pelo número do bilhete.


Quando você está trabalhando com grandes volumes (e você mostrou milhares e dezenas de milhares de negócios na história por uma razão), que requerem acesso atômico/snapshot, você precisa entender o custo deles.

Especialmente desde que expliquei os detalhes técnicos destas caches em grande detalhe neste tópico.


Você já tentou por nada randomizar cada amostra e envenenar o cache o máximo possível? Para o bem de sua posição, qualquer auto-golpe está em ordem?

 
Renat Fatkhullin:

Porque você fez tudo o que pôde para manter suas bibliotecas em silêncio. É por isso que você habilmente mascarou os insetos auto-infligidos, exibindo "veja como é lento".

99% dos insetos são encontrados desta forma. Primeiro, o comportamento estranho é encontrado no grande código. Em seguida, a localização encontra a causa. Eu estava mais preocupado com os freios.

função comercial. Os problemas estão em quase todos os lugares.

KD      0       16:00:33.382    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 34: HistoryOrderSelect(0)] = 25 ms.
PE      0       16:00:44.913    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 17: CopyTicks(Symb,Ticks,COPY_TICKS_ALL,0,1)] = 24 ms.
DP      0       16:00:44.888    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 22: HistorySelect(Tick.time,INT_MAX)] = 46 ms.
FI      0       16:00:49.579    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 28: HistoryDealSelect(0)] = 22 ms.
EE      0       16:01:03.287    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 33: HistoryOrderGetDouble(0,ORDER_PRICE_CURRENT)] = 1 ms.
KE      0       16:01:07.013    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 50: OrderGetDouble(ORDER_PRICE_CURRENT)] = 1 ms.
JM      0       16:01:12.189    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 44: TimeCurrent()] = 39 ms.
MD      0       16:01:13.067    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 81: ResourceFree(NULL)] = 1 ms.
RS      0       16:01:13.572    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 41: SymbolInfoDouble(Symb,SYMBOL_POINT)] = 7 ms.
GL      0       16:01:27.816    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 79: GlobalVariableGet(NULL)] = 22 ms.
PD      0       16:01:33.892    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 58: PositionGetInteger(POSITION_MAGIC)] = 1 ms.
KP      0       16:01:39.864    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 67: OrderCheck(Request,CheckResult)] = 3 ms.
ML      0       16:01:39.970    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 62: AccountInfoInteger(ACCOUNT_MARGIN_MODE)] = 1 ms.
KM      0       16:01:41.045    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 55: PositionSelect(Symb)] = 2 ms.
NS      0       16:01:46.832    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 78: GlobalVariableCheck(NULL)] = 1 ms.
JP      0       16:01:49.211    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 75: SymbolName(0,true)] = 1 ms.
EL      0       16:01:59.101    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 19: CopyTicksRange(Symb,Ticks,COPY_TICKS_ALL,Tick.time_msc)] = 32 ms.
IM      0       16:02:07.462    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 70: AccountInfoInteger(ACCOUNT_TRADE_EXPERT)] = 7 ms.
PJ      0       16:02:11.735    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 37: IsStopped()] = 4 ms.
OG      0       16:03:08.178    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 32: HistoryOrderGetInteger(0,ORDER_MAGIC)] = 14 ms.
JH      0       16:03:16.385    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 40: SymbolInfoDouble(Symb,SYMBOL_TRADE_TICK_VALUE)] = 5 ms.
FM      0       16:03:16.601    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 59: PositionGetString(POSITION_SYMBOL)] = 1 ms.
GH      0       16:03:21.841    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 72: TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)] = 1 ms.
FJ      0       16:03:25.782    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 46: TimeTradeServer()] = 1 ms.
EO      0       16:03:26.772    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 45: TimeLocal()] = 10 ms.
HD      0       16:03:36.595    fxstest (EURUSD,M1)     Alert: Time[fxstest.mq5 13: SymbolInfoTick(Symb,Tick)] = 13 ms.
...
O homem decidiu ajudar e executou um código MQL5 limpo em sua máquina. Uma pequena amostra acima. Leia os nomes das funções acima.


A documentação do HistorySelect declara explicitamente:

A função HistorySelect() cria uma lista de ordens e uma lista de negócios no programa mql5 para referência posterior aos itens da lista através das funções apropriadas. O tamanho da lista de ofertas pode ser obtido usando a função HistoryDealsTotal(), e o tamanho da lista de ofertas no histórico pode ser obtido usando a função HistoryOrdersTotal(). A enumeração dos elementos da lista de pedidos é melhor realizada usando a função HistoryOrderGetTicket(), para os elementos da lista de negócios, a função HistoryDealGetTicket() é apropriada.

Após o uso da função HistoryOrderSelect(), a lista de pedidos no histórico, disponível para o programa mql5, é reinicializada e preenchida novamente com o pedido, se a busca do pedido por bilhete tiver sido concluída com sucesso. O mesmo se aplica à lista de ofertas, que estão disponíveis para o programa mql5 - ela é reinicializada usando a função HistoryDealSelect() e preenchida novamente se uma oferta for obtida com sucesso pelo número do bilhete.

Quem terá visto algo nas entrelinhas deste texto? Pessoalmente, entendi (antes deste ramo), que a HistoryDealSelect e a HistoryOrderSelect devem ser escritas assim.

  static bool HistorySelectOrder( const ulong Ticket )
  {
    return((::HistoryOrderGetInteger(Ticket, ORDER_TICKET) == Ticket) || ::HistoryOrderSelect(Ticket));
  }

  static bool HistorySelectDeal( const ulong &Ticket )
  {
    return((::HistoryDealGetInteger(Ticket, DEAL_TICKET) == Ticket) || ::HistoryDealSelect(Ticket));
  }

Caso contrário, é garantido que você encontrará desfasamentos.

Quando se trabalha com grandes volumes, que requerem acesso atômico/snapshot, é preciso entender o custo deles.

Mais ainda desde que expliquei os detalhes técnicos destas caches em grande detalhe neste tópico.

Tenho coletado as informações necessárias neste tópico.

 
Renat Fatkhullin:

Você já tentou por nada randomizar cada amostra e envenenar o cache o máximo possível? Para o bem de sua posição, qualquer auto-golpe está em ordem?

Você pode ver tudo cronologicamente nesta linha. O problema foi mostrado originalmente sem nenhum randômio.

Este fio é uma grande prova de como você pode distorcer as palavras de seu oponente. Todas as fontes e seus resultados são salvos aqui.

 

Por que o terminal não pode simplesmente aumentar o cache quando o histórico completo é solicitado novamente, recuperar e armazenar em cache a faixa que falta? Isso parece resolver o problema. Afinal de contas, ao solicitar barras/tickets, os pacotes de dados em falta são devolvidos, portanto, existe um mecanismo para isso.

 
Aleksey Vyazmikin:

Por que o terminal não pode simplesmente aumentar o cache quando o histórico completo é solicitado novamente, recuperar e armazenar em cache a faixa que falta?

Isto já foi feito.

Mas se entre HistorySelect( 0, INT_MAX ) chamarHistorySelect( other_time, ... ), o cache será reconstruído a partir de other_time e o próximo pedido deHistorySelect( 0,... ) levará à construção de um novo cache (será mais lento).

 
Andrey Khatimlianskii:

Isto já foi feito.

Mas se entre chamadas de HistorySelect( 0, INT_MAX ) chamarmosHistorySelect( other_time, ... ), o cache será reconstruído a partir de other_time e o próximo pedido deHistorySelect( 0,... ) levará à construção de um novo cache (será mais lento).

Se você fez isso, é bom, a única questão é então sobre a conveniência do trabalho com os dados recebidos, desde que o cache seja construído.

Eu não entendi tão profundamente as operações comerciais, mas se o intervalo de consulta mudar, então não há possibilidade de pesquisar dados rapidamente dentro do histórico sem força bruta total?

 
Aleksey Vyazmikin:

Não estou muito envolvido no comércio, mas se o alcance da consulta mudar, então não há como procurar rapidamente por dados dentro da história sem uma enumeração completa?

Para que serve este conhecimento se você não o utiliza?

Sem problema prático = sem dúvida.

 
Renat Fatkhullin:

OrderExist e PositionExist são funções especiais otimizadas que evitam o estúpido looping por todos os pedidos ou posições em busca de entradas por símbolo, tipo de transação e medzhik.

O resultado é uma variedade de bilhetes.


Os programas podem economizar muito dinheiro usando estas funções. Especialmente ao chamar posições abertas e pedidos a granel, constante e repetidamente em loops em excesso.

Implementaremos funções mais eficazes para acessar dados comerciais massivos no futuro.

A linguagem também será drasticamente reforçada e simplificada com funcionalidades mais poderosas.

"OrderExist e PositionExist" - não encontrado na documentação, onde posso ler sobre eles?
 
HimOrik:
"OrderExist e PositionExist" - não encontrado na documentação, onde ler sobre eles?

Muito provavelmente após a próxima versão de lançamento (agora em beta)