Projeto do assessor - página 7

 
George Merts:

O que você quer dizer com "ATR não conta como um indicador" ???

E como "não é adequado como um sinal de entrada?? Eu sou um tolo que usa "quebra de volatilidade" usando apenas este indicador...?

Acho que você tem seu próprio entendimento de indicadores. Para mim, um indicador é um objeto que pode produzir algum valor variável, dependendo do tempo. Na verdade, até mesmo uma tabela de preço comum de velas é também um indicador. Mas para você é algo mais... Conseqüentemente, nosso entendimento é diferente.

Essencialmente
indicador = uma ferramenta (ferramenta) que mostra qualquer mudança em alguma coisa.
Neste sentido, o ATR é um indicador.
Ao olhar o gráfico, você notará que o indicador é o mais preciso (ou seja, o indicador não é um indicador independente - é um indicador de posição) e você precisa mantê-lo no mercado.

meu respeito.

 

Я не вижу особой разницы - как я понимаю, WS (WareStore, вероятно ?) - это все тот же мой дата-провайдер.

Esta é uma abreviação para WorkSymbol. A abreviação curta é escolhida de propósito, devido à referência freqüente a este objeto.

Suspeito que deve haver alguns passos preliminares na inicialização do objeto WS.

WS é uma instância de objeto CSymbol cujo construtor por padrão usa o símbolo Symbol() atual. Portanto, a WS não requer inicialização de fora. Ela é simplesmente criada junto com a classe de estratégia.

Pode haver muitos recipientes diferentes de símbolos diferentes e diferentes prazos em uma EA. A ideologia do fornecedor de dados permite não duplicá-los. Uma vez que na realidade - todas as séries de tempo são armazenadas nele, e os recipientes - apenas apontam para as necessárias.

O resultado é um núcleo de uma mega-classe, que é acessado por classes de especialistas. Como ele difere do MQL básico, quando existe o kernel MetaTrader e centenas de suas funções, que o acessam?

Se considerarmos o próprio MT4-5 como o fornecedor de dados, e nossa classe for usada apenas para fornecer acesso - então acontece que, de acordo com sua referência ao preço Open, devemos chamar a função CopyOpen() por um valor - não me parece razoável.

Exatamente. Somente tal apelo garante a unidade da representação de dados e a completa sincronização dos estados. Não há necessidade de fazer qualquer atualização de citações (que podem ser esquecidas), não há necessidade de usar um monte de comutadores adicionais, que inevitavelmente ocorrem ao criar um intermediário de armazenamento de dados. Não há necessidade de pesquisar no banco de dados os dados correspondentes aos dados solicitados. Se a minha EA o fizer:

Trade.SellLimit(WS.High[1]);

Então é garantido saber que a WS.High[1] retornará seu extremo anterior, não importa como o ambiente comercial seja atualizado. Sim, é muito caro ligar para a CopyHigh a cada chamada e copiar um único valor de duplo, mas é 100% confiável. Como as classes de cobertura não armazenam dados, mas apenas passam a chamada para as funções do sistema, então não podemos ter uma situação em que os dados armazenados não correspondam ao ambiente atual.

Também acho muito pouco razoável dar acesso global total a todas as variáveis em qualquer lugar do programa; pelo contrário, tento ter acesso apenas às estruturas e dados necessários para uma determinada ação em cada lugar do programa. Todo o resto deve ser inacessível. A ideologia do fornecedor de dados apenas permite controlar esse acesso.

Georg, na verdade, você já criou este acesso global. Você tem um grande fornecedor de super-classe que todos estão acessando. Este é um grande pool global de objetos (indicadores, séries cronológicas, etc.), que é coletado sob o invólucro do OOP. Em outras palavras, no exemplo com o fornecedor de dados, o OOP se transformou em uma ficção. Ela existe formalmente, mas não existe na realidade.

 
Vasiliy Sokolov:

Georg, na verdade, você já criou este acesso global. Você tem um grande fornecedor de super-classe, que é acessado por todos. Este é um grande pool global de objetos (indicadores, séries cronológicas, etc.) que é montado sob o invólucro do OOP. Em outras palavras, no exemplo com o fornecedor de dados, o OOP se transformou em uma ficção. Está lá formalmente, mas não está lá na realidade.

Não, eu estava comparando as velocidades de execução quando coloco um buffer no provedor de dados ou obtenho dados a cada vez via CopyXXX - eu tenho acesso vezes mais rápido ao meu buffer. É por isso que me instalei em meus buffers, e o Data Provider é apenas um armazenamento centralizado para estes buffers.

De fato, a presença de "camada" - este mesmo fornecedor de dados traz um risco de dessincronização de dados. Mas até agora nunca encontrei tal problema, mas o fornecedor de dados economiza velocidade muito claramente. Na verdade, acho que este teste já foi conduzido por muitas pessoas - todas se mostraram que ao processar um tick é mais lucrativo copiar os dados uma vez e usá-los, ao invés de cada vez que se vai ao terminal para obter dados.

Agora é diferente? E a velocidade de um número de chamadas via CopyXXX para cada valor duplo é a mesma que a velocidade de uma chamada ao mesmo tempo para toda a faixa, e então - chamada para o buffer de valores?

 
George Merts:

Não, eu estava comparando velocidades quando coloco o buffer no Data Provider, ou obtenho dados a cada vez pelo CopyXXX - eu tenho acesso vezes mais rápido ao meu buffer. É por isso que me instalei em meus buffers, e o Data Provider é apenas um armazenamento centralizado para estes buffers.

De fato, a presença de "camada" - este mesmo fornecedor de dados traz um risco de dessincronização de dados. Mas até agora nunca encontrei tal problema, mas o fornecedor de dados economiza velocidade muito claramente. Na verdade, eu acho que muitos já realizaram este teste - todos receberam que ao processar um tick é mais lucrativo copiar os dados uma vez e usá-los, em vez de ir ao terminal toda vez que se busca dados.

Agora é diferente? E a velocidade do número de chamadas via CopyXXX para cada valor duplo é a mesma que a velocidade de uma chamada ao mesmo tempo para toda a faixa, e então - chamada para o buffer de valores?

Sem dúvida, é muito mais rápido copiar todas as citações de uma só vez na memória interna da EA (fornecedor da data) e depois chamar os valores a partir dela, do que chamar constantemente o CopyBuffer. Mas esse é o preço de um sistema baseado no Estado. Basicamente, todo nosso domínio - escrever EAs, scripts, etc. - é a programação de sistemas baseados em estados: temos uma ordem - processar as regras de seu manejo. Se não houver ordem - verificamos as condições de sua abertura.

Quanto ao CopyBuffer, copiar grandes pedaços de citações e medir o ganho de desempenho só é possível em testes sintéticos. Na prática, em 90% dos casos, o Expert Advisor trabalha com o último bar em cada tic ou no momento da abertura de um novo bar. Portanto, os dados da última barra são sempre solicitados, e há uma chamada constante da função CopyBuffer que copia a última barra para o cache.

O único aumento real na produtividade é quando o Expert Advisor requer as últimas barras N, onde o número N é muito maior que 1. Mas qual é o pedido das últimas barras N? É um trabalho na janela deslizante (99% de todo o trabalho do Expert Advisor). E uma janela deslizante, é um amortecedor circular em sua essência. Portanto, ao solicitar as últimas barras N, na realidade, você precisa atualizar ou adicionar apenas uma, última barra. Isto é, tudo isto com cópia de bloco de dados é uma história muito boa, mas não funciona na área temática para a qual foi criado, enquanto que os anéis de segurança funcionam com bastante sucesso.

Agora meu CSymbol funciona simplesmente passando o índice correto. Mas posso atualizá-lo de forma a armazenar N últimas barras e N será escolhido pelo próprio CSymbol, dependendo do índice máximo solicitado. E então, sem nenhuma mudança externa, o CSymbol em algumas tarefas, funcionará muitas vezes mais rápido do que a chamada permanente do CopyBuffer. Este é o poder do OOP. Após uma certa sobrecarga associada ao uso de invólucros adicionais, vem um salto qualitativo, quando se pode reduzir drasticamente o uso de memória ou tempo de CPU, devido aos algoritmos adaptativos.

 
Gregory Kovalenko:
Olá.
À medida que a quantidade de código cresce, às vezes fica difícil e confusa.
Já vi código EA com um grande número de linhas de código, eu me pergunto como os EAs complexos são projetados, existem ferramentas ou técnicas para trabalhar com algoritmos tão complexos?

Eu escrevo enormes blocos de código ocupando centenas de linhas. Quase nenhum comentário. Sem OOP. O código está em russo. Tudo funciona muito eficientemente. Não tenho nenhum problema de orientação no programa, embora existam cerca de 100 arquivos conectados a ele. Provavelmente porque já me acostumei e me lembrei de tudo há muito tempo. O principal é conhecer e entender seu programa, todo o resto é secundário. Imho.

 
Реter Konow:

Escrevendo enormes blocos de código ocupando centenas de linhas. Quase nenhum comentário. Sem OOP. Código em russo. Tudo funciona muito eficientemente. Não tenho nenhum problema de orientação no programa, embora existam cerca de 100 arquivos conectados a ele. Provavelmente porque já me acostumei e me lembrei de tudo há muito tempo. O principal é conhecer e entender seu programa, todo o resto é secundário. Meu sentimento é que o principal é conhecer seu programa, e o resto é secundário.

Você passou de 1C para MQL?
 
Vasiliy Sokolov:
Você passou de 1C para MQL?

Eu sou autodidata. A primeira linguagem de programação que eu aprendi foi MQL4. Depois disso, eu pratiquei um pouco em C# e C++.


Nunca ouvi falar de 1C. O que é isso?

 
Vasiliy Sokolov:

Quanto ao CopyBuffer, copiar grandes pedaços de citações e medir o ganho de desempenho só é possível em testes sintéticos. Na prática, em 90% dos casos, o Expert Advisor trabalha com o último bar em cada tic ou no momento da abertura de um novo bar. Portanto, os dados da última barra são sempre solicitados e há uma chamada constante do CopyBuffer, que copia a última barra para o cache.

Portanto, precisamos da velocidade no "teste sintético" - a velocidade se torna crítica ao pesquisar variantes no testador de estratégia. Para mim, o testador de estratégia é um "gargalo de garrafa" onde precisamos de velocidade.

Apenas no trabalho real - a velocidade de acesso direto aos dados via CopyXXX cada vez é suficiente. Mas, para o progresso no testador - a diferença de velocidade é muito importante.

 
Comentários não relevantes a este tópico foram movidos para"OOP vs. programação procedural".
 
George Merts:

Mas é no "teste sintético" que precisamos de velocidade - a velocidade se torna crítica ao tentar opções no testador de estratégia. Para mim, o testador de estratégia é um "gargalo de garrafa" onde a velocidade é necessária.

Apenas no trabalho real - a velocidade de acesso direto aos dados via CopyXXX cada vez é suficiente. Mas, para o programa de testes - a diferença na velocidade é muito importante.

Para explicar em palavras mais simples: na base de seu provedor de dados há a função CopyXXX, que copia o último caractere. Na base do meu CSymbol está também CopyXXX, copiando o mesmo último caractere. Ambas as funções são lentas. Portanto, tanto seu código como meu código são lentos, já que a chamada CopyXXX não pode ser contornada. Mas meu código é mais simples e menor. Então por que toda essa construção de vários andares sobre CopyXXXXX, se ela não resolve o problema do CopyXXX em si?

Razão: