Bibliotecas: Fast iBarShift and Bars for MT5 - página 2

 
Alexey Navoykov:

No entanto, quando se trata de cálculos grandes, o iBarShift é inadequado, pois trabalhamos com matrizes. De fato, o iBarShift e outras funções semelhantes destinam-se a chamadas raras.É irracional fazer um loop nelas. 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, é claro, que o programador seja um manequim.)

Acho que é 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 diferente para cada série temporal.

Não estou discutindo. É que essas funções foram criadas quando não havia iBarShift embutido e Bars apresentava falhas.

Pessoalmente, preciso dessas funções para controlar o programa e os gráficos com o mouse. Também crio TFs sintéticos com escala logarítmica e essas funções são muito úteis. Elas são necessárias para resolver o problema de reconhecimento de padrões e acelerar significativamente os cálculos. Esse TF sintético contém todo o histórico de um símbolo e contém apenas 3.000 barras.

 

Estou desapontado com as funções Bars e iBarShift. A MQ não consegue melhorá-las. Elas curam uma coisa e prejudicam outra.

Percebi que essas funções são rudimentares e que é melhor esquecê-las como um sonho terrível.

Que elas permaneçam para estudantes e conservadores.

Acho que é razoável usar a pesquisa do número da barra por hora por meio da pesquisa usual na matriz time[].

Por exemplo, isso pode ser feito com a ajuda dessa função:

int wBarShift(datetime t,datetime &arr[],ENUM_TIMEFRAMES tf)
  {
   int size=ArraySize(arr);
   int PerSec=PeriodSeconds(tf);
   int cur,start=0;
   int fin=size-1;
   if(t<arr[0] || t>=arr[fin]) return(0);
   if(t>=arr[fin] && t<(arr[fin]+PerSec)) return(fin);
   while(true)
     {
      cur=(start+fin)/2;
      if(t<arr[cur]) {if(t>=arr[cur-1]) return(size-cur);    fin=cur;}
      else           {if(t< arr[cur+1]) return(size-cur-1);start=cur;}
      if((arr[fin]-arr[start])==((fin-start)*PerSec) && tf!=PERIOD_MN1)
         return(size-1-start-int(int(t-arr[start])/PerSec));
     }
  }

Sim, você precisa de uma matriz. Mas, pessoalmente, eu sempre a tenho em mãos e ela é atualizada a cada tique. Por isso, nem preciso formá-la.

E essa função é dez vezes mais rápida que a iBarShift original.

Um exemplo de busca do número da barra por hora em uma matriz de 100.000 itens pelo método de meia divisão:

2018.06.22 03:29:35.533 wBarShift (EURUSD,M1)   Время выполнения wBarShift = 26   наносекунд, контрольная сумма = 5407361
2018.06.22 03:29:35.536 wBarShift (EURUSD,M1)   Время выполнения iBarShift = 3368 наносекунд, контрольная сумма = 5407361
2018.06.22 03:29:36.283 wBarShift (EURUSD,M1)   Время выполнения wBarShift = 26   наносекунд, контрольная сумма = 5305162
2018.06.22 03:29:36.286 wBarShift (EURUSD,M1)   Время выполнения iBarShift = 3318 наносекунд, контрольная сумма = 5305162
2018.06.22 03:29:37.033 wBarShift (EURUSD,M1)   Время выполнения wBarShift = 28   наносекунд, контрольная сумма = 5341596
2018.06.22 03:29:37.036 wBarShift (EURUSD,M1)   Время выполнения iBarShift = 3323 наносекунд, контрольная сумма = 5341596
2018.06.22 03:29:37.667 wBarShift (EURUSD,M1)   Время выполнения wBarShift = 30   наносекунд, контрольная сумма = 5367340
2018.06.22 03:29:37.671 wBarShift (EURUSD,M1)   Время выполнения iBarShift = 3819 наносекунд, контрольная сумма = 5367340
Arquivos anexados:
wBarShift.mq5  5 kb
 
Uau, aparentemente, a mudança para as funções incorporadas realmente reduz o tempo de trabalho do EA no testador...
 

Correção. Se você for além do histórico existente, ele retornará a posição errada:

void OnStart()
  {
   datetime tm=StringToTime("2000.01.01");
   int pos=fBarShift(Symbol(),Period(),tm);
   double open[];
   Print(CopyOpen(Symbol(),Period(),pos,1,open));
   ArrayPrint(open);
  }

Resultado:

2020.03.13 13:35:50.729 test2 (EURUSD,M1)       -1
A função fBarShift(), nesse caso, retorna o número total de barras, o que não é uma posição correta.
 
A julgar pelo código, não há pesquisa para a barra necessária, ela é calculada. E se o histórico estiver quebrado?
 
Aliaksandr Hryshyn:

Correção. Se você for além do histórico existente, ele retornará a posição errada:

Resultado:

2020.03.13 13:35:50.729 test2 (EURUSD,M1)       -1
A função fBarShift(), nesse caso, retorna o número total de barras, o que não é uma posição correta.


Não entendo, ela retorna -1, como deveria ser.

 
Aliaksandr Hryshyn:
A julgar pelo código, não há pesquisa para a barra necessária, ela é calculada. E se o histórico estiver quebrado?

O que você quer dizer com as palavras "a julgar pelo código"?

É apenas sua imaginação ou você estudou a fundo?

Foi há muito tempo, mas, pelo que me lembro, havia um cálculo somente quando era apropriado, ou seja, quando o histórico não estava 100% quebrado e não havia buracos. Isso é facilmente verificado ao verificar a diferença de tempo entre as barras. Em detrimento disso, há um ganho de velocidade. Verifique se você não acredita em mim.

Agora esse código é mais rápido do que o iBarShift padrão, mas não significativamente (20-50%, antes era 10 vezes mais rápido). A MQ já corrigiu o código. Portanto, podemos dizer que esse código não é mais tão relevante.

 
Nikolai Semko:


Não entendo, ele retorna -1 como deveria.

Este é o código de retorno da função CopyOpen()

Print(CopyOpen(Symbol(),Period(),pos,1,open));

E o quarto parâmetro está faltando aqui:

int pos=fBarShift(Symbol(),Period(),tm);
 
Nikolai Semko:

O que você quer dizer com "a julgar pelo código"?

É apenas sua imaginação ou você o estudou minuciosamente?

Foi há muito tempo, mas, pelo que me lembro, havia um cálculo somente quando era apropriado, ou seja, quando o histórico era 100% ininterrupto e não havia buracos. Isso é facilmente verificado ao verificar a diferença de tempo entre as barras. Em detrimento disso, há um ganho de velocidade. Verifique se você não acredita em mim.

Agora esse código é mais rápido do que o iBarShift padrão, mas não significativamente (20-50%, antes era 10 vezes mais rápido). A MQ já corrigiu o código. Portanto, podemos dizer que esse código não é mais tão relevante.

Usei o código da primeira página. Não há ciclos, portanto, apenas cálculo (excluindo variantes estúpidas). Não estou dizendo que está errado, tudo está correto, exceto por uma exceção.

 
Aliaksandr Hryshyn:

Usei o código da primeira página. Não há loops, portanto, apenas cálculo (excluindo variantes estúpidas). Não estou dizendo que está errado, tudo está correto, exceto por uma exceção.

Você não precisa de loops, porque a função Bars() padrão é usada, e a essência do algoritmo é minimizar seu uso por meio de cálculos com dados armazenados de chamadas anteriores à função em variáveis estáticas.

Corrigi um erro (troquei - por + na função fBarShift). Ele acabou sendo corrigido em meu código, mas devo ter esquecido de publicá-lo. Atualizado. Versão 1.04.

O objetivo desse código era combater o bug que estava na função Bars(). O aumento da velocidade foi um efeito "colateral". Agora esse bug desapareceu e a velocidade foi significativamente melhorada. Portanto, não faz sentido usar essa biblioteca agora.