Desde a versão 1847 do MT5, o bug de travamento na função Bars foi corrigido. Além disso, a função iBarShift padrão foi adicionada.
Portanto, para aumentar o desempenho dessas funções (em algum lugar 10 vezes), agora é melhor usar essa variante de código:
int fBars(string symbol_name,ENUM_TIMEFRAMES timeframe,datetime start_time,datetime stop_time) { static string LastSymb=NULL; static ENUM_TIMEFRAMES LastTimeFrame=0; static datetime LastTime=0; static datetime LastTime0=0; static int PerSec=0; static int PreBars=0; static datetime LastBAR=0; static datetime LastTimeCur=0; static bool flag=true; static int max_bars=TerminalInfoInteger(TERMINAL_MAXBARS); datetime TimeCur; if(timeframe==0) timeframe=_Period; const bool changeTF=LastTimeFrame!=timeframe; const bool changeSymb=LastSymb!=symbol_name; const bool change=changeTF || changeSymb || flag; LastTimeFrame=timeframe; LastSymb=symbol_name; if(changeTF) PerSec=::PeriodSeconds(timeframe); if(PerSec==0) { flag=true; return(0);} if(stop_time<start_time) { TimeCur=stop_time; stop_time=start_time; start_time=TimeCur; } if(changeSymb) { if(!SymbolInfoInteger(symbol_name,SYMBOL_SELECT)) { SymbolSelect(symbol_name,true); ChartRedraw(); } } TimeCur=TimeCurrent(); if(timeframe==PERIOD_W1) TimeCur-=(TimeCur+345600)%PerSec; // 01.01.1970 - Quinta-feira. Menos 4 dias. if(timeframe<PERIOD_W1) TimeCur-=TimeCur%PerSec; if(start_time>TimeCur) { flag=true; return(0);} if(timeframe==PERIOD_MN1) { MqlDateTime dt; TimeToStruct(TimeCur,dt); TimeCur=dt.year*12+dt.mon; } if(changeTF || changeSymb || TimeCur!=LastTimeCur) LastBAR=(datetime)SeriesInfoInteger(symbol_name,timeframe,SERIES_LASTBAR_DATE); LastTimeCur=TimeCur; if(start_time>LastBAR) { flag=true; return(0);} datetime tS,tF=0; if(timeframe==PERIOD_W1) tS=start_time-(start_time+345599)%PerSec-1; else if(timeframe<PERIOD_MN1) tS=start_time-(start_time-1)%PerSec-1; else // PERIOD_MN1 { MqlDateTime dt; TimeToStruct(start_time-1,dt); tS=dt.year*12+dt.mon; } if(stop_time<=LastBAR) { if(timeframe<PERIOD_W1) tF=stop_time-(stop_time)%PerSec; else if(timeframe==PERIOD_W1) tF=stop_time-(stop_time+345600)%PerSec; else // PERIOD_MN1 { MqlDateTime dt0; TimeToStruct(stop_time-1,dt0); tF=dt0.year*12+dt0.mon; } } if(change || tS!=LastTime || tF!=LastTime0) { PreBars=Bars(symbol_name,timeframe,start_time,stop_time); LastTime=tS; LastTime0=tF; } flag=false; return(PreBars); } int fBarShift(string symb,ENUM_TIMEFRAMES TimeFrame,datetime time,bool exact=false) { int Res=fBars(symb,TimeFrame,time+1,UINT_MAX); if(exact) if((TimeFrame!=PERIOD_MN1 || time>TimeCurrent()) && Res==fBars(symb,TimeFrame,time-PeriodSeconds(TimeFrame)+1,UINT_MAX)) return(-1); return(Res); }
A partir da versão 1847 do MT5, o erro de travamento na função Bars foi corrigido. Além disso, a função iBarShift padrão foi adicionada.
Portanto, para aumentar o desempenho dessas funções (em algum lugar 10 vezes) , agora é melhor usar essa variante de código:
Envie o código para o servicedesk e deixe que eles o implementem como padrão na plataforma
Envie o código para a servicedesk e peça que eles o implementem na plataforma como padrão
Quem sou eu para lhes dizer.
Esse código é multiplataforma. E o mais interessante é que não há ganho no MT4, portanto, a função Bars é escrita de forma ideal no MT4.
Quem sou eu para lhes dizer.
Esse código é multiplataforma. E o mais interessante é que não há ganho no MT4, portanto, a função Bars foi escrita de forma otimizada no MT4.
Este tópico está sendo seguido. Insira sua postagem via pocket.
- 2016.09.01
- www.mql5.com
Está bem. Mas, por algum motivo, não está funcionando através do bolso. Não está funcionando. É através do link.
Portanto, para aumentar a velocidade dessas funções (em algum momento 10 vezes), é melhor usar essa variante de código:
Você não está sendo um pouco precipitado em relação à velocidade? Especialmente considerando o grande número de todos os tipos de verificações em seu código. Estou com preguiça de entrar na essência do assunto, mas acho difícil acreditar que essa bagunça funcione rapidamente.
Você não está exagerando em relação à velocidade? Especialmente considerando o grande número de todos os tipos de verificações em seu código. Estou com muita preguiça de analisar a essência dele, mas acho difícil acreditar que essa bagunça funcione rapidamente.
É melhor que você seja preguiçoso demais para escrever esta mensagem. ))
Anexei especificamente um indicador a essas funções para o teste de velocidade.
A função Bars é executada em microssegundos, e as verificações e operações aritméticas(até mesmo o cálculo da raiz quadrada de um número binário) em menos de um nanossegundo:
void OnStart() { ulong t; double sum=0; t=GetMicrosecondCount(); for (double i=1; i<2;i+=0.000001 ) sum+=sqrt(i); t=GetMicrosecondCount()-t; Print("Soma de 1.000.000 de raízes = " + DoubleToString(sum,18)+ " para " + IntegerToString((int)t) + " microssegundos."); } 2018.06.14 19:23:31.188 SpeedSQRT (EURUSD,M4) Сумма 1 000 000 корней = 1218952.6235881459433586 за 1990 микросекунд 2018.06.14 19:26:30.814 SpeedSQRT (EURUSD,M4) Сумма 1 000 000 корней = 1218952.6235881459433586 за 1946 микросекунд 2018.06.14 19:26:34.188 SpeedSQRT (EURUSD,M4) Сумма 1 000 000 корней = 1218952.6235881459433586 за 1946 микросекунд 2018.06.14 19:26:36.344 SpeedSQRT (EURUSD,M4) Сумма 1 000 000 корней = 1218952.6235881459433586 за 1973 микросекунд
A partir desse teste de velocidade, podemos ver que 1 milhão de ciclos para calcular as somas das raízes de números binários é executado em 2.000 microssegundos.
Portanto, um ciclo é executado em 2 nanossegundos. Um ciclo é uma verificação, duas somas de números binários, um cálculo da raiz quadrada de um número binário.
É bom que você seja preguiçoso demais para escrever esta postagem. ))
Anexei especificamente um indicador de teste de velocidade a essas funções.
A função Bars é executada em microssegundos, enquanto as verificações e operações aritméticas(até mesmo o cálculo da raiz quadrada de um número binário) são inferiores a um nanossegundo:
A partir desse teste de velocidade, podemos ver que 1 milhão de ciclos para calcular somas de raízes de números binários é executado em 2.000 microssegundos.
Portanto, um ciclo é executado em 2 nanossegundos. Um ciclo é uma verificação, duas somas de números binários, um cálculo da raiz quadrada de um número binário.
Ainda não coloquei novas compilações, portanto não posso reproduzir o problema. Entendo que sua função é otimizada para um caso especial, que é representado em seu indicador. O símbolo não muda, o período de tempo também não muda, etc. É por isso que, suponho, a função Bars é chamada uma vez lá. E tanto o símbolo quanto o período de tempo são estupidamente definidos como constantes. É por isso que é bem possível que o compilador tenha otimizado toda a sua função, descartando tudo o que é desnecessário.
Em resumo, os testes estão incorretos. Deveria haver uma matriz de símbolos e uma matriz de períodos, e você deveria executar sua função em todos eles. Então, poderemos conversar sobre algo.
Ainda não instalei novas compilações, portanto, não posso reproduzir o problema. Entendo que sua função foi otimizada para um caso especial, representado em seu indicador. O símbolo não muda, o período de tempo também não muda etc. Portanto, suponho que a função Bars seja chamada uma vez. E tanto o símbolo quanto o período de tempo são estupidamente definidos como constantes. Portanto, é bem possível que o compilador tenha otimizado toda a sua função, descartando tudo o que era desnecessário.
Em resumo, os testes são realizados incorretamente. Deveria haver uma matriz de caracteres e uma matriz de períodos. Você deveria executar sua função em todas elas. Então, poderemos conversar sobre algo.
Nada disso é um caso especial: "O símbolo não muda, o período de tempo também não muda"!
Por que você tem muitos desses indicadores ou Expert Advisors, que mudam constantemente o TF e os símbolos?
É claro que você está certo. Se cada chamada de barras for acompanhada por uma mudança de TF ou símbolo, o padrão funcionará mais rápido. Embora, nesse caso, você só precise substituir as variáveis estáticas por uma matriz de variáveis estáticas do mesmo tamanho que o número de TFs. Mas considero isso como um caso especial. Mas essa solução para esse caso especial tem o direito de sobreviver se for necessária. Talvez faça sentido alterar o código para esses casos. А ... Provavelmente é disso que você estava falando.
E sobre as constantes - obrigado por notar. Eu o corrigi porque os parâmetros na função original não são constantes. Nada mudou em termos de velocidade.
Você tem muitos desses indicadores ou Expert Advisors, que mudam constantemente os TFs e os símbolos?
Bem, sim, muitos. Meu foco é a análise de portfólio e a negociação de portfólio. No entanto, quando se trata de cálculos grandes, o iBarShift é inadequado, pois trabalhamos com matrizes. Na verdade, o iBarShift e outras funções semelhantes destinam-se a chamadas raras.É irracional fazer um loop com elas. Basta pegar a matriz em CopyTime e encontrar tudo rapidamente. É por isso que o exemplo de teste é de pouca utilidade na prática real. A menos que o programador seja um idiota, é claro. E não acho que valha a pena se preocupar com os idiotas.)
Acho que seria mais lógico envolver sua função em uma classe. Assim, você não precisará verificar o símbolo/período em cada chamada. Você terá um objeto separado para cada série temporal.
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso
Fast iBarShift and Bars for MT5:
Funções completas e rápidas semelhantes às funções Bars e iBarShift do MQL4.
Autor: Nikolai Semko