Rolling Average Table Below, analisaremos um programa no Excel VBA que cria uma tabela média móvel. Coloque um botão de comando em sua planilha e adicione a seguinte linha de código: Range (quotB3quot).Value WorksheetFunction. RandBetween (0, 100) Esta linha de código insere um número aleatório entre 0 e 100 na célula B3. Queremos que o Excel VBA tire o novo valor de estoque e coloque-o na primeira posição da tabela de média móvel. Todos os outros valores devem mover para baixo um local e o último valor deve ser excluído. Crie um evento de alteração de planilha. O código adicionado ao Evento de Mudança da Planilha será executado pelo Excel VBA quando você alterar uma célula em uma planilha. 2. Clique duas vezes em Sheet1 (Sheet1) no Project Explorer. 3. Escolha a Planilha na lista suspensa à esquerda. Escolha Alterar na lista suspensa direita. Adicione as seguintes linhas de código ao Evento de Mudança da Planilha: 4. Declare uma variável chamada newvalue do tipo Inteiro e dois intervalos (firstfourvalues e lastfourvalues). Dim newvalue As Integer. Firstfourvalues As Range, lastfourvalues As Range 5. O Evento de Mudança de Planilha escuta todas as alterações na Sheet1. Só queremos que o Excel VBA faça algo se algo mudar na célula B3. Para conseguir isso, adicione a seguinte linha de código: Se Target. Address quotB3quot Then 6. Inicializamos o newvalue com o valor da célula B3, firstfourvalues com Range (quotD3: D6quot) e lastfourvalues com Range (quotD4: D7quot). Newvalue Range (quotB3quot).Value Set firstfourvalues Range (quotD3: D6quot) Defina lastfourvalues Range (quotD4: D7quot) 7. Agora vem o truque simples. Queremos atualizar a tabela de média móvel. Você pode conseguir isso substituindo os últimos quatro valores pelos primeiros quatro valores da tabela e colocando o novo valor de estoque na primeira posição. Lastfourvalues. Value firstfourvalues. Value Range (quotD3quot).Value newvalue 8. Não esqueça de fechar a instrução if. 9. Finalmente, digite a fórmula MÉDIA (D3: D7) na célula D8. 10. Teste o programa clicando no botão de comando. Aqui está um código que deve ser útil para aqueles que usam análise técnica na negociação e que desejam testar estratégias no Excel. Ele calcula a média móvel simples, linearmente ponderada e exponencial. Além disso, vou apresentar e explicar as etapas para criar o formulário e o código VBA. Inserir um UserForm 8211 Nome: MAForm Adicionar quatro etiquetas dos controles Toolbox 8211 Legendas conforme a tela de impressão acima Adicionar uma ComboBox para a seleção de tipo de média móvel. Foi chamado comboTypeMA Adicione dois controles RefEdit para o intervalo de entrada e o intervalo de saída. Adicionar uma caixa de texto para selecionar o período médio móvel Adicionar dois botões: Nome: botãoSubmit, Legenda: Enviar e Nome: botãoCancelar, Legenda: Cancelar Para gerar a lista suspensa para a seleção do tipo MA e carregar o formulário do usuário, um novo módulo Será inserido com o código abaixo. Os itens da ComboBox devem ser preenchidos por tipos de médias móveis e o formulário do usuário será carregado. Option Explicit Sub loadMAForm () Com MAFormboTypeMA. RowSource. AddItem Simples. AddItem Ponderado. AddItem Exponential End Com MAForm. Show End Sub Abaixo está o código atribuído ao botão Enviar. Private Sub buttonSubmitClick () Dim inputRange, outputRange As Range O inputRange conterá a série de preços usada para computar as MAs e o outputRange será preenchido com os valores das médias móveis. Dim InputPeriod As Integer O período médio móvel é declarado. Dim inputAddress, outputAddress As String Os intervalos de entrada e saída declarados como string. Se comboTypeMA. Value ltgt Exponential e comboTypeMA. Value ltgt Simples e comboTypeMA. Value ltgt Weighted True Then MsgBox Selecione um tipo de média móvel da lista. RefInputRange. SetFocus Exit Sub Esta parte do procedimento impõe as primeiras restrições relativas aos dados enviados. Se o tipo de média móvel não estiver contido na lista suspensa, o procedimento não procederá ao próximo passo e o usuário será solicitado a selecioná-lo novamente. ElseIf RefInputRange. Value Então MsgBox Selecione o intervalo de entrada. RefInputRange. SetFocus Exit Sub ElseIf RefOutputRange. Value Então MsgBox Selecione o intervalo de saída. RefOutputRange. SetFocus Exit Sub ElseIf RefInputPeriod. Value Then MsgBox Selecione o período médio móvel. RefInputPeriod. SetFocus Exit Sub ElseIf Not IsNumeric (RefInputPeriod. Value) Então MsgBox Moving período médio deve ser um número. RefInputPeriod. SetFocus Exit Sub End Se outras restrições forem criadas. O intervalo de entrada, o intervalo de saída e o período de entrada não devem estar em branco. Além disso, o período médio móvel deve ser um número. InputAddress RefInputRange. Value Set inputRange Range (inputAddress) outputAddress RefOutputRange. Value Definir outputRange Range (outputAddress) inputPeriod RefInputPeriod. Value Os argumentos para inputRange e outputRange intervalos serão inputAddress e outputAddress declarados como strings. Se inputRange. Columns. Count ltgt 1 Então o intervalo de entrada MsgBox pode ter apenas uma coluna. RefInputRange. SetFocus Exit Sub O inputRange deve conter apenas uma coluna. ElseIf inputRange. Rows. Count ltgt outputRange. Rows. Count Então MsgBox O intervalo de saída tem um número diferente de linhas do que o intervalo de entrada. RefInputRange. SetFocus Exit Sub End If O inputRange e outputRange devem ter um número igual de linhas. Dim RowCount As Integer RowCount inputRange. Rows. Count Dim cRow As Integer ReDim inputarray (1 para RowCount) Para cRow 1 Para RowCount inputarray (cRow) inputRange. Cells (cRow, 1).Value Next cRow inputarray é declarado como matriz e it8217s Corresponde aos valores de cada linha do intervalo de entrada. Se inputPeriod gt RowCount Then MsgBox O número de observações selecionadas é amplificador amp RowCount e o período é amplificador amplificador InputPeriod. O intervalo de entrada deve ter uma quantidade maior ou igual de elementos que o período selecionado. RefInputRange. SetFocus Exit Sub End Se Outra restrição for adicionada 8211 O intervalo de entrada deve ter uma quantidade maior ou igual de elementos do que o período. Se inputPeriod lt 0, então MsgBox Moving período médio deve ser superior a 0. RefInputPeriod. SetFocus Exit Sub End If O período médio móvel deve ser superior a zero. ReDim outputarray (inputPeriod To RowCount) Como Variant Também são determinadas as dimensões da matriz do outputarray. O limite inferior da matriz é o valor inputPeriod eo limite superior é o valor de RowCount (o número de elementos na entradaRange). Abaixo da parte do procedimento calculado a média móvel simples, se a seleção para comboTypeMA for simples. SMA ----------------------------------------- Se comboTypeMA. Value Simples Então Dim i J Como Inteiro Dim temp Como Duplo Para i inputPeriod Para Temporidade RowCount 0 Para j (i - (inputPeriod - 1)) Para i temp temp inputarray (j) Próximo j outputarray (i) entrada temporáriaPeriod outputRange. Cells (i, 1).Value outputarray (i) Next i outputRange. Cells (0, 1).Value SMA (amp inputPeriod amp) Basicamente, o procedimento calcula a média móvel dos últimos números x (x é igual ao inputPeriod), começando pelo elemento de O inputarray igual ao InputPeriod. Abaixo está um exemplo simplificado, que mostra cada etapa do procedimento. Neste exemplo, existem quatro números (no01, no02, no03 e no04) da linha 1 à linha 4 e o período médio móvel é 3. Após cada nova média móvel, cada célula do outputRange irá tirar o valor do Outputarray. E depois de todas as médias móveis são computadas, na célula acima do outputRange será inserido um título contendo o tipo e o período da média móvel. Esta próxima parte calculará a média móvel exponencial. EMA ------------------------------------------ ElseIf comboTypeMA. Value Exponential Then Dim Alfa Como duplo alfa 2 (entradaPeriodo 1) Para j 1 Para entrarPeriod temp temp temparrayar (j) Próximo j outputarray (inputPeriod) temp inputPeriod Primeiro o valor de alpha é determinado. Porque na computação, o valor da EMA é baseado no EMA anterior, o primeiro será a média móvel simples. Para i inputPeriod 1 Para RowCount outputarray (i) outputarray (i - 1) alpha (inputarray (i) - outputarray (i - 1)) Próximo i Começando com a segunda média móvel, eles serão computados com base na fórmula acima: Anterior EMA plus alpha multiplicado pela diferença entre o número atual do inputarray e o valor EMA anterior. Para i inputPeriod Para RowCount outputRange. Cells (i, 1). Outputarray de Válido (i) Próximo i outputRange. Cells (0, 1).Value EMA (amp inputPeriod amp) Assim como o código para SMA, o outputarray será preenchido e A célula acima do outputarray representará o tipo eo período da média móvel. Abaixo está o código para calcular a média móvel ponderada. WMA ------------------------------------------ ElseIf comboTypeMA. Value Weighted Then Dim Temp2 As Integer Para i inputPeriod Para RowCount temp 0 temp2 0 Para j (i - (inputPeriod - 1)) Para i temp temp inputarray (j) (j - i inputPeriod) temp2 temp2 (j - i inputPeriod) Próximo j outputarray (i ) Temp temp2 outputRange. Cells (i, 1). Outputarray de Válido (i) Próximo i outputRange. Cells (0, 1).Value WMA (amp inputPeriod amp) End If A tabela abaixo contém as etapas para calcular cada variável usada para o Cálculo de WMA. Assim como no exemplo anterior, neste há os números na entradaRange. E o período de entrada é 3. Abaixo está o código final do procedimento, que descarrega o formulário de usuário. Descarregar o MAForm End Sub O procedimento abaixo é para o botão Cancelar. Será adicionado no mesmo módulo. Botão Sub privadoCancelClick () Descarregar MAForm End SubMoving Cálculo médio Cálculo médio móvel Cálculo médio móvel Estou tentando calcular uma média móvel para uma série de dados. Eu quero gerar a média móvel para cada ponto dentro dos dados, para mostrar em um gráfico. De qualquer forma, abaixo é um exemplo do MS Support. Eu segui para a carta, mas o meu não dá uma média móvel. Ele repete o mesmo ponto de dados repetidamente (o primeiro ponto de dados). Então, eu não acredito que a função é encontrar o início na linha MyRST. Seek, portanto, apenas retornando o primeiro ponto de dados. Finalmente (talvez fará isso realmente fácil) Estou confuso sobre como os índices funcionam. Eu pensei que você só poderia ter uma chave primária, mas, aparentemente, você pode criar várias restrições de campo. Tentei fazer isso com a seguinte consulta de definição de dados: ALTER TABLE Tabela1 ADD CONSTRAINT NoDupes UNIQUE (CurrencyType, TransactionDate) Desculpe o tamanho dessa publicação. Eu aprecio sua ajuda. A seguinte função de exemplo calcula as médias móveis com base em uma tabela com uma chave primária de campo múltiplo. Os valores semanais das moedas estrangeiras são utilizados para este exemplo. Para criar a função de exemplo, siga estas etapas: Crie a seguinte tabela e salve-a como Tabela1: Tabela: Tabela1 --------------------------- -------------- Nome do campo: Tipo de moeda Tipo de dados da chave primária: Tamanho do campo de texto: 25 Nome do campo: Tipo de dados principal do TransactionDate: Formato do DateTime: Data curta Nome do campo: Taxa Tipo de dados: moeda Locais decimais: 4 Veja a tabela na exibição da folha de dados e insira os seguintes valores: Taxa do tipo CurrencyType TransactionDate ------------------------------- ------------- Ien 8693 0.0079 Ien 81393 0.0082 Ien 82093 0.0085 Ien 82793 0.0088 Ien 9393 0.0091 Mark 8693 0.5600 Mark 81393 0.5700 Mark 82093 0.5800 Mark 82793 0.5900 Mark 9393 0.6000 Abra um novo módulo e digite o Seguintes funções: Função MAvgs (Períodos como Inteiro, StartDate, TypeName) Dim MyDB como DATABASE, MyRST Como conjunto de registros, MySum como Double Dim i, x Set MyDB CurrentDb () Definir MyRST MyDB. OpenRecordset (Tabela1) Em Error Resume Next MyRST. Index PrimaryKey x Periods - 1 loja ReDim (x) MySum 0 para i 0 Para x MyRST. MoveFirst MyRST. Seek, TypeName, StartDate Estas duas variáveis devem estar na mesma ordem que os campos da chave primária em sua tabela. Store (i) MyRSTRate Se eu lt x Então StartDate StartDate - 7 O 7 aqui assume dados semanais 1 para dados diários. Se StartDate lt 8693 Então MAvgs Null: Exit Function 8693 é substituído pela data mais antiga dos dados em sua tabela. MySum Store (i) MySum Next I MAvgs Periodos MySum MyRST. Fechar End Function Crie a seguinte consulta com base na tabela Table1: Query: Query1 --------------------- ---------------------------------- Campo: FieldType Campo: TransactionDate Campo: Campo de Taxa: Expr1: MAvgs (3 , TransactionDate, CurrencyType) NOTA: Esta consulta gerará uma média móvel de três semanas dos dados da Taxa. Para calcular uma média móvel mais longa ou mais curta, altere o número 3 na coluna Expr1 de consultas para o valor que deseja calcular. Execute a consulta. Observe que você vê a seguinte média móvel de três semanas para cada moeda. Um valor nulo indica que não havia valores anteriores suficientes para calcular a média da semana. CurrencyType TransactionDate Rate Expr1 Mark 080693 0,5600 Mark 081393 0,5700 Mark 082093 0,5800 0,57 Mark 082793 0,5900 0,58 Mark 090393 0,6000 0,59 Iene 080693 0,0079 Ien 081393 0,0082 Ien 082093 0,0085 0,0082 Ien 082793 0,0088 0,0085 Ien 090393 0,0091 0,0088 RE: Cálculo médio móvel dhookom (Programador) 28 10 de junho 21:15 Quantos anos tem esse código. Não usa explicitamente DAO e não menciona que isso não funcionará com tabelas vinculadas. Dim MyDB como DAO. Database, MyRST como DAO. Recordset. Eu usaria uma subconsulta em vez de um conjunto de registros. Pode parecer algo como: SELECT CurrencyType, TransactionDate, Rate, (SELECT Avg (Rate) FROM Table1 B WHERE A. CurrencyType B. CurrencyType AND A. TransactionDate ENTRE B. TransactionDate - 14 AND B. TransitionDate) FROM Table1 A RE: Moving Cálculo médio que é realmente perfeito. Eu realmente aprecio sua ajuda. No entanto, o código que você deu é calcular a média móvel direta de 14 dias (colocando a média móvel no registro para o dia 1 da média, onde eu queria que ela fosse uma média retroativa, colocada no registro 14). Eu mudei um pouco para o seguinte e parece estar funcionando SELECT A. CurrencyType, A. TransactionDate, A. Rate, (SELECT Avg (Rate) FROM Table1 B WHERE A. CurrencyType B. CurrencyType AND B. TransactionDate ENTRE A. TransactionDate - 14 E A. TransactionDate) AS Expr1 FROM Table1 AS A Você pode ver, tudo o que fiz foi troca A para B na cláusula where. Esta é uma grande ajuda para mim e eu realmente aprecio isso. Eu não vi codificação assim antes, e, honestamente, eu realmente não entendo isso. Não sei como o SQL entende o que B e A são. Eu suponho que eles estão criando algum tipo de referência alternativa ao Table1. Se você pode dar qualquer orientação, eu realmente apreciaria isso. Além disso, talvez alguma referência ao material que eu possa observar Estou sempre muito animado para aprender algo novo sobre o VBASQL, e eu realmente aprecio sua ajuda RE: Cálculo médio móvel PHV (MIS) 29 Jun 10 12:22 entende o que B e A São eles são alias es RE: Cálculo médio móvel Obrigado, PHV. Já faz melhor sentido RE: Cálculo médio em movimento joshery420 (TechnicalUser) 6 Jul 10 15:06 Uau, nunca olhei para o SQL view antes. Supremamente útil. Estou tentando obter esse código para funcionar no meu próprio conjunto de dados e estou preso em uma questão específica. Pd2004, não tenho certeza se o novo código de subconsulta funcionou o mesmo que o seu código VBA antigo ou não, mas com meus dados ainda mostra a média contínua, mesmo que não haja dias suficientes para criar esse tamanho de média. por exemplo. Se eu estiver executando uma média contínua de 7 dias, o dia 1 mostra os mesmos dados na coluna 7DayAvg como faz na coluna diária de dados. O dia 2 mostra a média dos dias 1 e 2, etc. Vocês também sabem como consertar isso por acaso Também, obrigado pela excelente dica de código PHV. RE: Cálculo médio em movimento joshery420 (TechnicalUser) 6 Jul 10 15:08 Woops, obrigado a agradecer a dhookom pela dica de código, não PHV. Mas oi, obrigado a ambos. XD RE: Cálculo médio móvel Eu deixarei as melhores soluções para os profissionais aqui, mas você pode ver na minha publicação original como o exemplo da Ajuda da Microsoft tenta lidar com isso. Aqui está o código: Se StartDate lt 8693 Então MAvgs Null: Exit Function 8693 é substituído pela data mais antiga dos dados em sua tabela. Eles estão apenas saindo da função se a data não corresponder aos critérios. Não sei se você poderia incorporar algo assim no código de alias fornecido pelo dhookem. Eu não gosto da sua maneira de lidar com isso, e eu suspeito que o dhookem fornecerá uma solução muito mais elegante. Para os meus propósitos, o problema que está descrevendo não é uma preocupação, mas estarei interessado em ver quaisquer soluções. RE: cálculo da média móvel dhookom (Programador) 6 Jul 10 17:05 Você pode tentar usar IIf () para testar a contagem do número de registros. Cuidado: o código do bloco de notas não testado segue: SELECT A. CurrencyType, A. TransactionDate, A. Rate, IIF ((SELECT Count (Taxa) FROM Table1 C WHERE A. CurrencyType C. CurrencyType AND C. TransactionDate ENTRE A. TransactionDate - 14 AND A. TransactionDate) 7, (SELECT Média (Taxa) FROM Tabela1 B WHERE A. CurrencyType B. CurrencyType AND B. TransactionDate ENTRE A. TransactionDate - 14 AND A. TransactionDate), Nulo) AS Expr1 FROM Table1 AS A RE: Calculadora média móvel
No comments:
Post a Comment