Média Móvel Sem Buffer


Estou tentando completar um projeto de atribuição matlab com a seguinte pergunta: Escreva uma função chamada motionaverage que leva um escalar chamado x como um argumento de entrada e retorna um escalar. A função usa um buffer para armazenar as entradas anteriores e o buffer pode conter no máximo 25 entradas. Especificamente, a função deve salvar as 25 entradas mais recentes em um vetor (o buffer). Cada vez que a função é chamada, ele copia o argumento de entrada em um elemento do buffer. Se já houver 25 entradas armazenadas no buffer, ele descarta o elemento mais antigo e salva o atual no buffer. Depois de armazenar a entrada no buffer, ele retorna a média de todos os elementos no buffer. A solução que eu forneço é a seguinte: de acordo com a graduação automática, minha função funciona corretamente quando os valores 1-50 estão passando consecutivamente, mas falham quando os valores de uma onda sinusoidal barulhenta estão passando consecutivamente (o que foi informado que pode ser devido a alguns Tipo de erro de redondeamento). Eu ficaria grato se algum de vocês pudesse me fornecer algumas dicas sobre as possíveis etapas de erro no meu código (anexado acima). Obrigado antecipadamente, é possível implementar uma média móvel em C sem a necessidade de uma janela de amostras. Achei que posso otimizar um pouco, escolhendo um tamanho de janela que seja um poder de dois para permitir a mudança de bits em vez de dividir, Mas não precisar de um buffer seria bom. Existe uma maneira de expressar um novo resultado de média móvel apenas como função do resultado antigo e da nova amostra. Definir um exemplo de média móvel, em uma janela de 4 amostras para ser: Adicionar nova amostra e: Uma média móvel pode ser implementada de forma recursiva , Mas para uma computação exata da média móvel você deve lembrar a amostra de entrada mais antiga na soma (ou seja, a no seu exemplo). Para um comprimento N média móvel você calcula: onde yn é o sinal de saída e xn é o sinal de entrada. Eq. (1) pode ser escrito de forma recursiva, então você sempre precisa se lembrar da amostra xn-N para calcular (2). Conforme demonstrado por Conrad Turner, você pode usar uma janela exponencial (infinitamente longa) em vez disso, o que permite calcular a saída apenas da saída passada e da entrada atual: mas esta não é uma média móvel padrão (não ponderada), mas exponencialmente Média móvel ponderada, onde as amostras no passado obtêm um peso menor, mas (pelo menos em teoria) você nunca esquece nada (os pesos ficam cada vez menores e menores para amostras no passado). Eu implementei uma média móvel sem memória de item individual para um programa de rastreamento GPS que eu escrevi. Eu começo com 1 amostra e divide por 1 para obter o valor médio atual. Em seguida, adicione uma amostra e divida em 2 para a média atual. Isso continua até chegar ao comprimento da média. Cada vez, adiciono na nova amostra, obtenho a média e retire essa média do total. Eu não sou matemático, mas isso pareceu uma boa maneira de fazê-lo. Eu pensei que isso tornaria o estômago de um verdadeiro matemático, mas, parece que é uma das maneiras aceitas de fazê-lo. E funciona bem. Basta lembrar que, quanto mais alto for seu comprimento, mais lento seguirá o que você deseja seguir. Isso pode não importar a maior parte do tempo, mas ao seguir os satélites, se você estiver lento, a trilha pode estar longe da posição real e parecerá ruim. Você poderia ter uma lacuna entre o Sáb e os pontos de fuga. Eu escolhi um período de 15 atualizado 6 vezes por minuto para obter um alisamento adequado e não chegar muito longe da posição real de SAT com os pontos de trilhos alisados. Respondido 16 de novembro 16 às 23:03 inicializar total 0, count0 (cada vez que vê um novo valor Então uma entrada (scanf), uma adicionar totalnewValue, um incremento (contagem), uma média de divisão (total total) Esta seria uma média móvel em relação a Todas as entradas Para calcular a média sobre apenas as últimas 4 entradas, seria necessário 4 variáveis ​​de entrada, talvez copiando cada entrada para uma variável de entrada mais antiga, calculando a nova média móvel. Como soma das 4 variáveis ​​de entrada, divididas por 4 (o turno direito 2 seria Bom, se todas as entradas fossem positivas para que o cálculo médio fosse respondido 3 de fevereiro 15 às 4:06 Isso realmente calculará a média total e NÃO a média móvel. À medida que a contagem aumenta, o impacto de qualquer nova amostra de entrada se torna ndash extremamente lento Hilmar Feb 3 15 às 13:53 Sua resposta 2017 Stack Exchange, IncMetaTrader 5 - Indicadores Série de preços de média para cálculos intermediários sem usar tampões adicionais Introdução No meu artigo Os Princípios do Cálculo Econômico de Indicadores Eu fiz testes razoavelmente convincentes que comprovam o fato de que nem todos os chamados de um indicador personalizado ou técnico em um código são a maneira mais ideal de realizar cálculos intermediários em um indicador desenvolvido. A velocidade final de execução pode parecer muito menor, comparando o que teríamos se colocarmos o código para cálculos intermediários diretamente em nosso indicador. Esse tipo de abordagem para escrever um código seria muito atraente, se fosse bastante simples. Na verdade, parece ser uma complicação séria de um código com a descrição de buffers adicionais usados ​​para armazenar resultados intermediários de cálculo. Apesar da variedade de cálculos intermediários, a maioria deles é necessária em algoritmos diferentes de média. Na maioria dos casos, para eles podemos usar funções personalizadas simples e universais que simplificam significativamente a tarefa de escrever esse código. O processo de criação dessas funções e o trabalho com elas serão descritos neste artigo. 1. A idéia geral de funções da média que funcionam com uma barra A abordagem clássica para a média de uma barra atual consiste em um buffer de indicador intermediário, que preenchemos com informações necessárias e, em seguida, selecione um intervalo de valores anteriores, o que é igual a O período de média e calcular o valor médio. O procedimento de processamento desta seleção é o seguinte: Função SmoothVar (bar) (Var (barra - (n-1)), Var (barra - (n-2)). Var (barra)) Barra de parâmetros média SmoothVar (barra) Número de uma barra, para o qual o cálculo é executado Var (barra - (n-1)) parâmetros médios com uma mudança nas barras (n-1) n número de barras para a média. Essa abordagem para a média, no nosso caso, leva a aparência de dois ciclos de cálculo. No primeiro ciclo, os dados são calculados e colocados em um buffer intermediário. No segundo ciclo, a média usando outro ciclo de busca adicional de células do buffer de indicadores é realizada com base na fórmula sugerida acima. Este cálculo ficará muito mais fácil, se acumularmos a seleção de dados intermediários dentro da própria função. Neste caso, a função da média será a seguinte: Função SmoothVar (bar) (Var (barra), barra) Um novo valor Var (bar) é escrito para a seleção de valores dentro da função em uma barra atual e Os valores de Var (barra - n) que se tornam desnecessários são excluídos da seleção. Com esta abordagem, um código de média parece muito trivial e não requer tampões de indicadores adicionais. Dentro da função, a matriz armazena exatamente a quantidade necessária de dados necessários para o cálculo de uma barra, e não os dados de histórico inteiros. Neste caso, há apenas um ciclo de cálculo de dados. Deve-se notar que, para chamar essa função de média em uma barra atual, você deve chamá-la em todas as barras anteriores primeiro 2. A média clássica como um exemplo de implementar uma função que funciona com uma barra. Essas funções de média devem conter Variáveis ​​que não devem perder seus valores entre as chamadas dessas funções. Além disso, a média única com diferentes parâmetros pode ser usada em um código por muitas vezes, portanto, para evitar um conflito usando recursos de memória compartilhada, devemos implementar essas funções como classes e é isso que eu fiz. Os algoritmos da média clássica são descritos na classe CMovingAverage: Esta classe é derivada da classe base CMovSeriesTools que contém funções-métodos protegidos adicionais e uma verificação da correção do período de médias móveis. A classe base contém um código universal adicional que é usado em todas as classes que eu sugiro, e não há nenhum motivo para copiá-lo várias vezes para as classes derivadas. Nas tarefas aplicadas de usar a média, os membros da classe protegidos não são usados ​​de forma explícita, portanto, suspendamos sua visão geral por enquanto. A classe CMovingAverage consiste em cinco funções de tipo único de média, cujos nomes falam por si mesmos, e eles não precisam ser descritos em detalhes. A primeira função MASeries () é uma coleção integral de quatro outras funções que permitem selecionar um algoritmo de média utilizando o parâmetro MAMethod. O código dos algoritmos de média é otimizado para o desempenho máximo, e é por isso que os principais parâmetros de funções (Comprimento, série, barra) são complementados com parâmetros adicionais iniciados, pré-calculados, pontuais e configurados, cujo propósito é absolutamente idêntico ao As variáveis ​​indicadores com os mesmos nomes. O conjunto de parâmetros define a bandeira de indexação de elementos de uma série de séries de preços nas funções de média para ser o mesmo que as matrizes de variáveis. Devemos considerar que todas as funções de média desta classe possuem o parâmetro Comprimento fixo e não pode ser alterado quando o código do programa está sendo executado A função EMASeries () da classe CMovingAverage possui este parâmetro do tipo duplo. Agora, como nos conhecemos Com a classe CMovingAverage. Podemos começar a usá-lo em indicadores. Para fazê-lo, usando a diretiva de inclusão adicione o conteúdo do arquivo MASeriesCls. mqh no escopo global ao código do indicador que você desenvolve: então você deve determinar o número necessário de procedimentos de média no código do indicador e, em seguida, no OnCalculate () (Antes dos operadores de loop e braçadeiras) declaram as variáveis ​​estáticas da classe CMovingAverage de acordo com o número necessário de procedimentos de média. Deve haver uma variável separada da classe e uma célula separada na matriz da classe para cada procedimento de média. As variáveis ​​da classe na função OnCalculate () são declaradas como estáticas, pois seus valores devem ser mantidos entre as chamadas desta função. Agora, podemos começar a trabalhar com a média. Como exemplo, vou mostrar quatro procedimentos consecutivos de média das séries de preços - SMAEMASMMALWMA (o indicador MAx4.mq5): o resultado de cada média anterior (excluindo o último) é usado no próximo algoritmo de média e o final O resultado é passado para o buffer do indicador. Acho que a parte mais crucial deste código é uma inicialização preliminar muito cuidadosa de variáveis ​​de índices que mostram o início de barras confiáveis. Nessa situação, será como segue: Note que, nessa situação, o algoritmo LWMA de média é o último e não afeta nada, senão se fosse o último, então o deslocamento do início de informações confiáveis ​​seria igual A Comprimento41, não Comprimento4 Quero adicionar, se não for claro a partir do código anterior, em qual número as informações confiáveis ​​começam, pegue um número maior e, em seguida, diminua-o experimentalmente, se necessário. 3. Comparando o Indicador Criado usando Classes com seus Analógicos que Usam Indicadores Técnicos e Personalizados Seria muito interessante comparar o desempenho do indicador criado MAx4.mq5 com seu análogo idêntico (iMAx4.mq5) que usa o indicador técnico iMA () . Bem, assim que decidimos realizar o teste, será razoável testar outro indicador (MAx3x1.mq5) semelhante ao MAx4.mq5, mas tendo a primeira média feita usando a chamada do indicador técnico iMA () e o Outros três usando a classe CMovingAverage. E assim que o conjunto padrão de indicadores do terminal do cliente inclui o indicador Custom Moving Average. mq5, fiz outro indicador análogo nas bases para fins de teste (cMAx4.mq5). Para a próxima análise, preparei para o teste Expert Advisors: MAx4Test. mq5, iMAx4Test. mq5, MAx3x1Test. mq5 e cMAx4Test. mq5, respectivamente. As condições de realização de tais testes foram descritas em detalhes no artigo "Princípios de cálculo econômico dos indicadores". Neste artigo, não vou descrever os detalhes do teste, mas vou mostrar os resultados finais do funcionamento dos quatro Expert Advisor no testador de estratégia nos últimos 12 meses no EURUSD 4 com modelagem de cada marca e o valor Dos parâmetros de entrada de período de todas as EAs iguais a 500. Os piores resultados em nossos testes são mostrados pelo indicador que chama indicadores personalizados, portanto, esta variante de escrever um código pode ser recomendada apenas para os preguiçosos. Claro, outro líder que venha no último Mas um que é baseado em chamadas de indicadores técnicos tem resultados muito melhores, no entanto, eles estão muito longe de um ideal. O verdadeiro líder dos testes é o indicador que é desenvolvido usando classes O híbrido que usa classes e indicadores técnicos ocupou o segundo lugar, mas isso não acontece sempre se o tempo de teste de um indicador for crucial, então é melhor verificar essas variantes Pessoalmente para cada situação. Visão geral das classes implementadas da média A classe CMovingAverage descrita anteriormente inclui cinco algoritmos de média. A classe CCMO contém algoritmos de média e oscilador. As outras classes incluem algoritmos únicos de média. A ideologia de usar qualquer uma das classes sugeridas é absolutamente o mesmo para o procedimento de utilização da classe CMovingAverage descrita acima. O código de todos os algoritmos de média (exceto o parabólico) é otimizado para a velocidade máxima de execução. O código de média parabólica não foi otimizado, devido à complexidade desse processo. Os três últimos algoritmos não representam uma média. Eu os adicionei por causa de sua alta popularidade e compatibilidade com os trabalhos dos analistas técnicos populares. Para facilitar a compreensão da informação, é melhor representar os algoritmos de média em arquivos. mqh separados e para uso prático, a melhor variante é tê-los em um único arquivo. Para usar em indicadores, todas as classes sugeridas são embaladas para o arquivo único SmoothAlgorithms. mqh. Além disso, o arquivo é complementado com as funções do arquivo iPriceSeries. mqh. Somente a função PriceSeries () é usada em exemplos deste artigo: Esta função destina-se a trabalhar com bases de indicadores no uso do segundo tipo de chamada da função OnCalculate (). A idéia principal de criar esta função é estender o conjunto de timeseries de preços da enumeração ENUMAPPLIEDPRICE com variantes personalizadas. A função retorna o valor de um preço por meio de seu número que varia de 1 a 11. 4. Exemplos práticos de implementação de um código de programa usando as classes de média Se for suficiente para mostrar outro exemplo de usar as outras classes, para ter certeza de que Tudo é feito da mesma forma que com a média quádrupla. Vou mostrar uma variante de implementação da função OnCalculate () em um análogo do indicador CCI usando as classes CJJMA e CJurX (JCCX. mq5). Mas desta vez adicionei as classes apropriadas de outro arquivo no escopo global no código Do indicador: agora, quero manter sua atenção em outra coisa. A questão é um grande número de indicadores que podem ser representados como funções de um bar, que são realmente confortáveis ​​para trabalhar usando classes. Por exemplo, seria interessante desenhar o canal Bollinger com base na média móvel de Vidya de Tushar Chande. Neste caso, são utilizadas duas classes CCMO e CStdDeviation. Usando a primeira classe, obtemos o valor da VIDYA média móvel e usando o segundo, calculamos o valor do desvio padrão da série de preços para a média móvel. Depois disso, usamos esse desvio para o cálculo do limite superior e inferior do canal. Então, obtivemos uma classe simples e pequena. Os três últimos parâmetros de entrada da função VidyaBandsSeries () passam os valores necessários do canal através de um link . Gostaria de notar que neste caso, você não pode declarar as variáveis ​​das classes dentro da função VidyaBandsSeries () e torná-las estáticas, porque as variáveis ​​estáticas nas classes têm um significado muito diferente. É por isso que essa declaração deve ser feita no escopo global da classe: em um canal Bollinger normal, o período de média da média móvel e o período de média do canal em si são sempre iguais. Nesta classe, eu fiz esses parâmetros separados para dar-lhe mais liberdade (EMAperiod e BBLength). O indicador em si (VidyaBBands. mq5) feito com base nesta classe é tão simples no uso da classe CVidyaBands que não precisamos analisar seu código no artigo. Essas classes de funções de indicadores devem ser colocadas em um arquivo mqh separado. Coloquei tais funções no arquivo IndicatorsAlgorithms. mqh. 5. Comparando o Desempenho de um Indicador que Utiliza Classes com um que não Primeiro De tudo, eu quero descobrir, como o uso de classes ao escrever um código de um indicador diminui seu desempenho. Para este propósito, o código do indicador JJMA. mq5 foi escrito sem usar as classes (JMA. mq5). Então foi testado nas mesmas condições que durante o teste anterior. Os resultados finais dos testes não têm uma grande diferença: claro, existem algumas taxas adicionais para o uso das aulas, mas não são comparáveis ​​às vantagens que eles oferecem. 6. Vantagens de usar as classes de média A vantagem de usar esses algoritmos, o que é realmente convincente, é que a substituição de chamadas de indicadores técnicos e personalizados leva a um grande aumento de desempenho do código desenvolvido descrito acima. Outra vantagem prática de tais classes é uma grande conveniência de usá-los. Por exemplo, tudo o que é descrito no livro popular de William Blau Momentum, Direction e Divergence parece ser um verdadeiro campo de testes para esse tipo de abordagem para escrever indicadores. O código de indicadores surge como maximamente comprimido, compreensível e muitas vezes consistindo em um único ciclo de recálculo de barras. Você pode facilmente desenvolver qualquer indicador - um clássico ou técnico, usando os métodos alternativos de média. Uma grande variedade de algoritmos de média proporciona amplas possibilidades para a criação de sistemas de comércio não tradicionais, muitas vezes com uma detecção precoce de tendências e menor número de falhas desencadeantes. 7. Algumas Recomendações sobre como usar os Algoritmos de média num Código de Indicador Específico Um único olhar simples em qualquer indicador desenvolvido com diferentes algoritmos de média descritos aqui é suficiente para entender como são diferentes esses algoritmos. Portanto, seria razoável supor que nem todos os algoritmos sugeridos são igualmente bons em todas as situações. Embora seja difícil determinar um limite estrito de uso de um ou outro algoritmo, é possível fornecer algumas recomendações gerais sobre como usá-los. Por exemplo, os algoritmos de Tushar Chande e Kaufman destinam-se a determinar situações de tendência e não são adequados para suavização adicional com o propósito de filtragem de ruído. Portanto, é melhor inserir séries de preços não processados ​​ou valores de indicadores sem calcular a média desses algoritmos. Aqui está o resultado do processamento de valores do indicador Momentum usando o algoritmo Kaufmans (o indicador 4cMomentumAMA. mq5). Penso que os algoritmos da média clássica não precisam de recomendações especiais. Sua área de aplicação é bastante ampla. Em todos os lugares, onde esses algoritmos são usados, você pode usar com sucesso os quatro algoritmos esquerdos (JMA, T3, ultralineira e parabólica). Aqui está um exemplo do indicador MACD onde EMA e SMA são substituídos pela média JMA (o indicador JMACD. mq5): E aqui é o resultado do alisamento do indicador calculado em vez de alterar seu algoritmo de média para uma melhor qualidade de determinação A tendência atual (o indicador JMomentum. mq5): não é uma surpresa que o comportamento dos mercados mude constantemente, portanto, seria ingênuo pensar que você pode encontrar o único algoritmo ideal para uma certa parte do mercado financeiro agora e Para sempre Alas Nada neste mundo dura para sempre. No entanto, como para mim, por exemplo, neste mercado que se altera eternamente, uso frequentemente os indicadores das tendências de curto e médio prazo como JFATL. mq5 e J2JMA. mq5. Estou bastante satisfeito com as previsões por sua base. Outra coisa que eu quero adicionar. Os algoritmos de média são reutilizáveis. Podem ser obtidos bons resultados ao aplicar uma média repetida para valores já médios. Na verdade, neste artigo comecei a analisar o processo de desenho do indicador a partir dele (o indicador MAx4.mq5). 8. A idéia geral de compor o Código dos Algoritmos da média e agora, no final do artigo, gostaria de prestar atenção ao mecanismo das funções de se promediar. Em primeiro lugar, a maioria dos algoritmos de média inclui matrizes dinâmicas de variáveis ​​do tipo mSeriesArray para armazenar os valores da série de parâmetros de entrada. Assim que a informação significativa para o cálculo aparecer, você deve alocar a memória para essa matriz por uma vez. É feito usando a função SeriesArrayResize () da classe CMovSeriesTools. Em seguida, em cada barra, você deve escrever o valor atual da série de séries de preços para o valor mais antigo da matriz e memorizar o número de sua posição na contabilidade variável. É feito usando a função RecountArrayZeroPos () da classe CMovSeriesTools. E agora, se precisarmos encontrar um elemento com uma mudança relativa para o elemento atual, devemos usar a função RecountArrayNumber () da classe CMovSeriesTools: Geralmente, em tais situações, o elemento mais novo é escrito para uma posição zero e os outros ( Exceto o mais antigo) são preliminares para as próximas posições por turno no entanto, não é salvar os recursos do computador, e a abordagem mais complexa descrita acima parece ser mais racional Além dos algoritmos de média, os corpos dessas funções contêm As chamadas de funções usadas para a determinação de posições de barras relativamente ao início do cálculo de barras: o momento em que há informações suficientes para a inicialização de variáveis: e situações em que a última barra é fechada: a primeira verificação determina uma situação quando existe Não são suficientes barras para que a função de média funcione, e retorna um resultado vazio. Uma vez que a segunda verificação é aprovada com sucesso e há dados suficientes para o primeiro cálculo, a inicialização de variáveis ​​é realizada por uma vez. Duas últimas verificações são necessárias para o processamento múltiplo correto de valores na barra não fechada atual. Eu já descrevi isso em meu artigo dedicado à otimização de um código de programa. E agora algumas palavras sobre a otimização do código do programa de tais funções para o máximo desempenho. Por exemplo, o algoritmo SMA implica em média os valores selecionados de um período de uma série de preços em cada barra. Esses valores são literalmente somados e divididos pelo período em cada barra. Mas a diferença entre a soma na barra anterior e a soma na barra atual é a primeira é somada com o valor da série de preços com uma mudança em um período relativamente ao período atual e o segundo - com o valor atual . Por conseguinte, seria muito racional calcular essa soma apenas uma vez durante a inicialização das funções e, em seguida, em cada barra adicionar apenas novos valores da série de preços a esta soma e subtrair os valores mais antigos da mesma. Isso exatamente é feito em tal função. Conclusão Sugeridas nas implementações de artigos dos algoritmos de média usando as classes são simples, simples e universais, então você não terá problemas para estudá-las. Os arquivos anexados ao artigo contêm muitos exemplos para facilitar a compreensão dessa abordagem para escrever código de indicadores. No arquivo Includingeen. zip todas as classes são distribuídas em arquivos. O arquivo Includeen. zip contém apenas dois arquivos que são suficientes para compilar todos os indicadores no arquivo Indicators. zip. Os Expert Advisors para testes estão no arquivo Experts. zip.

Comments