Erros, bugs, perguntas - página 2099

 
Vladimir Pastushak:
Rapazes, estou farto de introduzir o meu nome de utilizador e palavra-chave de www.mql5.com em andróide no mt5.
Porque é que continuam a perder o seu nome de utilizador e palavra-passe?

Também me perguntam regularmente, mas não introduzo o meu nome de utilizador/senha, apenas carrego no botão Voltar e o registo é feito.

 
Nikolai Semko:

Porque é que uma função muito útil como ChartXYToTimePrice() é tão cara no tempo de execução?

Escrevi uma função análoga a XYToTimePrice() e corre muito mais rápido. Até várias centenas de vezes mais rápido.

Mas há também ChartID_in com SubWindow_out na função original. Fazer um análogo completo.

 
fxsaber:

Portanto, também há ChartID_in com SubWindow_out no original. Fazer um análogo completo.


A adição de ChartID_in e SubWindow_out não é nada difícil. Mas não pretendo criar um analógico completo, apenas criei esta função para mostrar a lentidão do ChartXYToTimePrice().

void XYToTimePrice(long chart_id,int x,int y,int& sub_window,datetime &time,double &price,int id)
  {
   static int left_bar; // номер самого левого бара на экране
   static int WidBar;
   static int Wid;
   static int Hei;
   static double y_min;
   static double y_max;
   static int PerSec=PeriodSeconds();
   static bool ChartChange=true;
   if(id==CHARTEVENT_CHART_CHANGE) { ChartChange=true; return; } 
   if(ChartChange) // если было изменение чатра после последнего вычисления
     {
      left_bar=(int)ChartGetInteger(chart_id,CHART_FIRST_VISIBLE_BAR, sub_window);        // номер самого левого бара на экране
      Wid=(int)ChartGetInteger(chart_id,CHART_WIDTH_IN_PIXELS, sub_window);               // ширина экрана в пикселях
      WidBar=(int)ChartGetInteger(chart_id,CHART_WIDTH_IN_BARS, sub_window);              // ширина экрана в барах
      Hei=(int)ChartGetInteger(chart_id,CHART_HEIGHT_IN_PIXELS, sub_window);              // высота экрана в пикселях
      y_min=ChartGetDouble(chart_id,CHART_PRICE_MIN, sub_window);                         // макс. цена на экране
      y_max=ChartGetDouble(chart_id,CHART_PRICE_MAX, sub_window);                         // мин. цена на экране
     }
   if(x>Wid || x<0 || y<0 || y>Hei) return;  // выходим если точка (x,y) за пределами экрана
   price=y_min+(Hei-y)*(y_max-y_min)/Hei;
   int NrBar=left_bar-(int)((double)x/((double)Wid/(double)WidBar)); 
   datetime T[1];
   if(NrBar>=0) CopyTime(NULL,0,NrBar,1,T);
   else { CopyTime(NULL,0,0,1,T); T[0]+=fabs(NrBar)*PerSec;}
   ChartChange=false;
   time=T[0];
  }

Mas é verdade, a minha função precisa de uma identificação de evento de parâmetro adicional. E até agora, esta função funciona mais ou menos igualmente com a espessura original da vela de um pixel, mas pode melhorá-la, se necessário.

 
Nikolai Semko:

A adição de ChartID_in e SubWindow_out não é nada difícil. Mas não pretendo criar um análogo completo, apenas criei esta função para mostrar a lentidão do ChartXYToTimePrice().

Mas é verdade, a minha função precisa de uma identificação de evento de parâmetro adicional. E embora esta função funcione mais ou menos da mesma forma com a espessura original de uma vela de um pixel, mas pode melhorá-la, se necessário.


E também notei uma característica estranha de ChartXYToTimePrice. O seu tempo de execução é directamente proporcional ao número de barras no gráfico.

Isto indica um algoritmo "estranho" para o seu cálculo. Nomeadamente, é uma soma cíclica que é bastante estranha para a solução óptima de um tal problema.

A velocidade da função XYToTimePrice é a mesma, independentemente do número de barras.

E para ser honesto, a velocidade das funções ChartGetInteger e ChartGetDouble é também claramente sobrestimada e tem características muito estranhas. Por exemplo, a função

ChartGetDouble(0,CHART_PRICE_MAX);

é 20-100 vezes mais rápido do que a função

ChartGetDouble(0,CHART_PRICE_MIN);          

se MAX estiver depois de MIN:

mas se os trocar, a situação é invertida.


Ou seja, parece lógico - a mesma função, que é calculada repetidamente, utiliza dados já calculados e armazenados de uma chamada de função anterior. Mas mostra apenas alguns cálculos loucos e a criação de muitos dados intermédios e talvez até conjuntos para calcular um simples valor duplo de preço máximo (ou mínimo) do gráfico, que provavelmente já se situa em alguma variável e só precisa de ser tomado.

Embora não exclua que este efeito ocorra devido a algumas peculiaridades de traçar perfis e seja de natureza falsa. Mas a morosidade destas funções não é falsa.

 
Nikolai Semko:

pode ser refinado, se necessário.

Ainda é provavelmente válido dizer que é correcto comparar as características de velocidade das duas funções quando os seus resultados coincidem. Por favor, complete-o.

 
Vladimir Pastushak:
Rapazes, estou cansado de introduzir o meu nome de utilizador e palavra-chave de www.mql5.com no androide em mt5.
Porque estão constantemente a perder o seu nome de utilizador e palavra-passe?

Escrever para Servicedesk. Por favor anexar os registos. Obrigado.

 

Fórum sobre comércio, sistemas automatizados de comércio e testes de estratégia comercial

Insectos, insectos, perguntas

fxsaber, 2017.10.04 09:13

Tem sido escrito sobre isto muitas vezes. Não corrigido por qualquer razão.

Parece que já o arranjaram. Já não tenho este problema na construção de 1730.
 
Nikolai Semko:

Também notei uma característica estranha de ChartXYToTimePrice. O seu tempo de execução é directamente proporcional ao número de barras no gráfico.

Isto mostra a "esquisitice" do seu algoritmo de cálculo. Nomeadamente, é uma soma cíclica que é bastante estranha para a solução óptima de um tal problema.

A velocidade da função XYToTimePrice é a mesma, independentemente do número de barras.

E para ser honesto, a velocidade das funções ChartGetInteger e ChartGetDouble é também claramente sobrestimada e tem características muito estranhas. Por exemplo, a função

é 20-100 vezes mais rápido do que a função

se MAX estiver depois de MIN:

mas se os trocar, a situação é invertida.


Ou seja, parece lógico - a mesma função, que é calculada repetidamente, utiliza dados já calculados e armazenados de uma chamada de função anterior. Mas mostra apenas alguns cálculos loucos e a criação de muitos dados intermédios e talvez até conjuntos para calcular um simples valor duplo de preço máximo (ou mínimo) do gráfico, que provavelmente já se situa em alguma variável e só precisa de ser tomado.

Embora não exclua que este efeito ocorra devido a algumas peculiaridades de traçar perfis e seja de natureza falsa. Mas a morosidade destas funções não é falsa.

A lentidão das funções de pedido de dados do gráfico reside na forma como a informação é enviada e recebida, não na implementação em si. A implementação destas funções em si é primitiva e não depende do número de barras no gráfico.

Mas como o gráfico é um objecto cuja informação é distribuída entre muitas fontes, todo o controlo é baseado em filas de mensagens. Até que o pedido anterior seja processado, o seguinte aguarda.

Mas se tiver vários pedidos para o mesmo gráfico numa linha, então estes pedidos subsequentes são executados muito rapidamente. Isto porque ninguém teve tempo de se intrometer entre eles e o primeiro pedido.

 
Slava:

O estrangulamento das funções de pedido de dados do gráfico reside na forma como a informação é enviada e recebida, e não na implementação em si. A implementação destas funções em si é primitiva e não depende do número de barras no gráfico.

Mas como o gráfico é um objecto cuja informação é distribuída entre muitas fontes, todo o controlo é baseado em filas de mensagens. Até que o pedido anterior seja processado, o próximo está à espera.

Mas se tiver vários pedidos para o mesmo gráfico numa fila, então estes pedidos subsequentes são executados muito rapidamente. Isto porque ninguém teve tempo de cortar entre eles e a primeira consulta.


Que assim seja. Mas a realização disto não facilita nada. Slava, não interprete mal um simples programador. O meu exemplo de um indicador de teste de mensagens anteriores mostra claramente que o tempo médio de execução de um pedido deChartXYToTimePrice() é de 5000 - 10000 microssegundos (na espessura de uma vela de 1 pixel e a janela MT padrão no ecrã FullHD). O que pode ser feito em tal tempo?

Bem, por exemplo, durante este tempo pode formar uma imagem no mesmo ecrã de 500 círculos sombreados e exibi-los no ecrã:

Mesmo que haja uma fila, mas porque é que há uma fila tão longa?
De um lado da escala há uma geração pixel por pixel de 500 círculos com a sua saída no ecrã, e do outro lado há uma simples consulta para dois dígitos. E pesa o mesmo.
Um simples programador está ali sentado, coçando a cabeça e não consegue juntar os puzzles.

 
Nikolai Semko:

Que assim seja. Mas perceber que isso não facilita as coisas. Slava, não interprete mal um simples programador. O meu exemplo de um indicador de teste de mensagens anteriores mostra claramente que o tempo médio de execução deChartXYToTimePrice() pedidoé de 5000 - 10000 microssegundos (a uma largura de vela de 1 pixel e janela padrão MT no ecrã FullHD). O que pode ser feito em tal tempo?

Bem, por exemplo, durante este tempo, é possível formar uma imagem no mesmo ecrã de 500 círculos sombreados e exibi-los no ecrã:

Mesmo que haja uma fila, mas porque é que há uma fila tão longa?
De um lado da escala, é uma formação pixel a pixel de 500 círculos e exibindo-os no ecrã, e do outro lado uma simples consulta de dois dígitos. E pesa o mesmo.
Um simples programador senta-se e arranha a cabeça e não consegue juntar os puzzles.

Sentiu a diferença entre comando síncrono e assíncrono.

Razão: