Não consigo entender se é possível resolver esse problema com velocidade de teste sem usar as funções de linguagem do MT5. O problema surgiu há muito tempo, mas só agora consegui resolvê-lo.
Build 3802, __MT4ORDERS__ "2022.07.20"
Função condicional chamada no Expert Advisor em cada tick. Teste no testador de estratégia mt5.
datetime get_last_order_close_time () {
datetime last_close_time=0;
for ( int i = OrdersHistoryTotal() - 1; i >= 0; i-- ) {
if ( !OrderSelect ( i, SELECT_BY_POS, MODE_HISTORY )) {
continue;
}
last_close_time=OrderCloseTime();
return last_close_time;
}
return last_close_time;
}
Onúmero de negócios é de cerca de 26 mil. O tempo de teste é de cerca de 1 hora e 10 minutos.
Se removermos a função do código, o tempo de teste será de cerca de 17 minutos.
Reescrevi a mesma função usando a funcionalidade do MT5:
datetime get_last_order_close_timeMT5 () {
datetime last_close_time=0;
HistorySelect(0,TimeCurrent());
for ( int i = HistoryDealsTotal() - 1; i >= 0; i-- ) {
ulong ticket=HistoryDealGetTicket(i);
if((ENUM_DEAL_ENTRY)HistoryDealGetInteger(ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT)
{
last_close_time=(datetime)HistoryDealGetInteger(ticket,DEAL_TIME);
return last_close_time;
}
}
return last_close_time;
}
O tempo de teste é de cerca de 18 minutos.
Reverto a biblioteca para a versão __MT4ORDERS__ "2020.01.12" e compilo o Expert Advisor no build 2980.
O tempo do Expert Advisor com a função get_last_order_close_time é de cerca de 20 minutos.
fxsaber #: Em todos os três casos, o resultado final é o mesmo?
Sim, com certeza.
Isso começou a acontecer depois de outra atualização do terminal. Eu não alterei sua biblioteca e compilei o bot no terminal antigo para que ele funcionasse como antes.
Isso começou a acontecer depois de outra atualização do terminal. Não alterei sua biblioteca e compilei o bot no terminal antigo para que ele funcionasse como antes.
Em cada tick do inMod, uma posição é aberta e fechada. E, em cada tick, o OrderCloseTime é calculado.
OnTester serve como um critério para verificar a identidade dos resultados em diferentes configurações.
Funções correspondentes de trabalho com histórico.
datetime LastCloseTimeMQL4()
{
datetime Res = 0;
for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
{
Res = OrderCloseTime();
break;
}
return(Res);
}
datetime LastCloseTimeMQL5()
{
datetime Res = 0;
if (HistorySelect(0, INT_MAX))
for (int i = HistoryDealsTotal() - 1; i >= 0; i--)
{
constulong Ticket = HistoryDealGetTicket(i);
if (HistoryDealGetInteger(Ticket, DEAL_ENTRY) != DEAL_ENTRY_IN)
{
Res = (datetime)HistoryDealGetInteger(Ticket, DEAL_TIME);
break;
}
}
return(Res);
}
#define MACROS(A, B) \
datetime A##_2() \
{ \
staticdatetime Res = 0; \
staticint PrevTotal = 0; \
\
constint Total = B; \
\
if (PrevTotal != Total) \
{ \
Res = A(); \
\
PrevTotal = Total; \
} \
\
return(Res); \
}
// LastCloseTimeMQL4_2
MACROS(LastCloseTimeMQL4, OrdersHistoryTotal())
// LastCloseTimeMQL5_2
MACROS(LastCloseTimeMQL5, HistorySelect(0, INT_MAX) ? HistoryDealsTotal() : 0)
Metodologia.
Uma única execução nas configurações como na fonte (inMod = 5).
2023.07.0623:59:5928179final balance 99996992.20 pips
OnTester result 2761115
EURUSD,M1: 274413 ticks, 70443 bars generated. Environment synchronized in 0:00:00.021. Test passed in 0:00:03.712 (including ticks preprocessing 0:00:00.031).
28 mil transações, quase quatro segundos. Como precisamos medir o desempenho no modo de otimização, todas as leituras de desempenho a seguir foram feitas dessa forma.
shortest pass 0:00:02.875, longest pass 0:00:03.094, average pass 0:00:02.919
Com recompilação obrigatória antes da execução e apenas um agente habilitado para execução sequencial de passes.
Desempenho.
Tabela de desempenho (tempo de execução em milissegundos) para b3815 e b2958.
Construção MT5
LastCloseTimeMQL4
LastCloseTimeMQL5
LastCloseTimeMQL4_2
LastCloseTimeMQL4+VIRTUAL::Snapshot
LastCloseTimeMQL4+VirtualTester
b3815
2875
113
708
732
45
b2958
2718
107
675
715
50
O MT4Orders de 20.07.2022 foi usado em todos os lugares.
Conclusões.
O OrderSelect é lento. Isso se deve ao fato de que o OrderSelect calcula absolutamente todos os dados da ordem selecionada a partir do histórico (o OrderPrint é gratuito). Essa é uma ótima combinação das funções HistoryOrderGet* e HistoryDealGet*, que lida com qualquer complexidade de situações de mercado e com um grande número de armadilhas. Dê uma olhada em MT4ORDERS::GetHistoryPositionData(). Essa é uma função única para o Terminal e para o Testador, mas é especialmente acelerada para o Testador, porque muitas armadilhas do Terminal não estão presentes no Testador. Exemplos de configurações: uma, duas, três.
Dessa forma, é necessário reduzir as chamadas de OrderSelect para ordens históricas. Isso pode ser feito das maneiras indicadas nas três colunas da direita da tabela.
O trabalho mais rápido (antes da MQL5 pura) é a negociação em um ambiente virtual. Eu recomendaria a otimização no ambiente virtual, e passes únicos - fora dele.
O desempenho do Tester b2958 e do b3815 é quase idêntico.
Não recomendo vincular a lógica do TS para o testador ao histórico de negociação com referência a ele. Por exemplo, você pode saber o OrderCloseTime do seu TS sem fazer referência ao histórico.
É possível que haja um vazamento de memória ou um uso de memória maior do que o necessário? Talvez em this.tickets ou em this.amount (::ArrayResize) ou em outro lugar?
O tamanho das matrizes só aumenta com o tempo. Isso é obrigatório? É possível esvaziá-las ou talvez não carregar todas as negociações anteriores?
É possível que haja um vazamento de memória ou um uso de memória maior do que o necessário? Talvez em this.tickets ou em this.amount (::ArrayResize) ou em outro lugar?
O tamanho das matrizes só aumenta com o tempo. Isso é obrigatório? É possível esvaziá-las ou talvez não carregar todas as negociações anteriores?
A biblioteca não armazena totalmente em cache os dados do histórico. A falta de memória é possível apenas na teoria, mas não na prática.
Escreva um script que classifique todo o histórico de negociação usando a biblioteca e veja quanta memória é consumida.
Para login e uso do site MQL5.com, você deve ativar o uso de cookies.
Ative esta opção no seu navegador, caso contrário você não poderá fazer login.
Você entrou na conta. A autenticação de dois fatores foi desativada. Configure-a novamente e escaneie um novo código QR ou continue com a autenticação de dois fatores desativada.
Não consigo entender se é possível resolver esse problema com velocidade de teste sem usar as funções de linguagem do MT5. O problema surgiu há muito tempo, mas só agora consegui resolvê-lo.
Build 3802, __MT4ORDERS__ "2022.07.20"
Função condicional chamada no Expert Advisor em cada tick. Teste no testador de estratégia mt5.
Onúmero de negócios é de cerca de 26 mil. O tempo de teste é de cerca de 1 hora e 10 minutos.
Se removermos a função do código, o tempo de teste será de cerca de 17 minutos.
Reescrevi a mesma função usando a funcionalidade do MT5:
O tempo de teste é de cerca de 18 minutos.
Reverto a biblioteca para a versão __MT4ORDERS__ "2020.01.12" e compilo o Expert Advisor no build 2980.
O tempo do Expert Advisor com a função get_last_order_close_time é de cerca de 20 minutos.
Não consigo ver se esse problema de velocidade de teste pode ser resolvido sem o uso dos recursos de idioma do MT5.
Em todos os três casos, o resultado final é o mesmo?
Sim, com certeza.
Isso começou a acontecer depois de outra atualização do terminal. Eu não alterei sua biblioteca e compilei o bot no terminal antigo para que ele funcionasse como antes.
Isso começou a acontecer depois de outra atualização do terminal. Não alterei sua biblioteca e compilei o bot no terminal antigo para que ele funcionasse como antes.
Fiz algumas pesquisas.
Expert Advisor.
Em cada tick do inMod, uma posição é aberta e fechada. E, em cada tick, o OrderCloseTime é calculado.
OnTester serve como um critério para verificar a identidade dos resultados em diferentes configurações.
Funções correspondentes de trabalho com histórico.
Metodologia.
Uma única execução nas configurações como na fonte (inMod = 5).
28 mil transações, quase quatro segundos. Como precisamos medir o desempenho no modo de otimização, todas as leituras de desempenho a seguir foram feitas dessa forma.
Com recompilação obrigatória antes da execução e apenas um agente habilitado para execução sequencial de passes.
Desempenho.
Tabela de desempenho (tempo de execução em milissegundos) para b3815 e b2958.
O MT4Orders de 20.07.2022 foi usado em todos os lugares.
Conclusões.
O tempo de teste é de aproximadamente 1 hora e 10 minutos.
Reverto a biblioteca para a versão __MT4ORDERS__ "2020.01.12" e compilo o Expert Advisor no build 2980.
O tempo de funcionamento do Expert Advisor com a função get_last_order_close_time é de cerca de 20 minutos.
Experimente o código acima em uma versão antiga da biblioteca (eu não a tenho).
Se houver alguma diferença no desempenho, envie-o para a PM.
É possível que haja um vazamento de memória ou um uso de memória maior do que o necessário? Talvez em this.tickets ou em this.amount (::ArrayResize) ou em outro lugar?
O tamanho das matrizes só aumenta com o tempo. Isso é obrigatório? É possível esvaziá-las ou talvez não carregar todas as negociações anteriores?
É possível que haja um vazamento de memória ou um uso de memória maior do que o necessário? Talvez em this.tickets ou em this.amount (::ArrayResize) ou em outro lugar?
O tamanho das matrizes só aumenta com o tempo. Isso é obrigatório? É possível esvaziá-las ou talvez não carregar todas as negociações anteriores?
A biblioteca não armazena totalmente em cache os dados do histórico. A falta de memória é possível apenas na teoria, mas não na prática.
Escreva um script que classifique todo o histórico de negociação usando a biblioteca e veja quanta memória é consumida.
A biblioteca não armazena totalmente em cache os dados do histórico. A falta de memória é possível apenas na teoria, mas não na prática.
Escreva um script que classifique todo o histórico de negociação usando a biblioteca e veja quanta memória é consumida.
No teste de estratégia, o EA está usando 25 GB por núcleo.
editar: é um teste de período de 1 ano, portanto, não é muito.no teste de estratégia, o ea está usando 25 GB por núcleo.
editar: é um teste de período de 1 ano, portanto, não muito.A biblioteca (MT4Orders.mqh) não consome essa quantidade de memória. Você pode executar, por exemplo, este EA para ver por si mesmo.
Provavelmente, você está trabalhando com indicadores de forma incorreta: você cria novos identificadores de indicadores, mas não exclui os antigos.