O ambiente de execução percorre a sequência de candles. Mas você também pode precisar repetir operações dentro de um único candle: somar os últimos cinco fechamentos, por exemplo. Para isso, pode usar um laço.

for e range

for offset in range(5):
    total += close[offset]

Com range(5), o laço atribui à variável offset, em sequência, os valores 0, 1, 2, 3 e 4. O 5 não está incluído. A linha indentada é executada uma vez para cada valor.

Assim, close[offset] representa primeiro o fechamento atual, depois o de um, dois, três e quatro candles atrás. Somamos exatamente cinco valores.

É preciso zerar total antes do laço. Ele é um resultado intermediário do cálculo de um candle, não um contador preservado entre candles.

range(1, 5) fornece outra sequência: 1, 2, 3, 4. O início está incluído; o limite final, não. Se omitirmos o início, começamos em zero.

Uma média móvel escrita à mão

Crie o arquivo manual_average.py:

"""
@pyne edge
"""
from pynecore.lib import close, color, input, plot, script, ta


@script.indicator("Manual Average Check", overlay=False)
def main(
    length: int = input.int(5, title="Length", minval=1, maxval=100),
):
    total = 0.0
    for offset in range(length):
        total += close[offset]
    manual_average = total / length
    builtin_average = ta.sma(close, length)
    difference = manual_average - builtin_average
    plot(difference, "Difference", color=color.blue)

Execute com os dados de demonstração. A linha mostra a diferença entre a nossa média e a SMA pronta. Depois do aquecimento, ela deve permanecer em zero ou muito perto de zero, devido à representação numérica.

Ao lado de manual_average.py, um painel separado do PyneIDE mostra a linha da diferença entre as médias.
A diferença entre o laço próprio e a SMA pronta permanece perto de zero depois do aquecimento.

Não desenhamos duas linhas sobrepostas, pois assim seria difícil perceber pequenas diferenças. A subtração mostra diretamente se os dois cálculos coincidem.

O que acontece em uma execução?

Com comprimento cinco, a sequência de operações é:

  1. total recebe zero.
  2. O laço soma o fechamento atual e os quatro anteriores.
  3. Dividimos a soma por cinco.
  4. Calculamos também a SMA pronta e subtraímos nosso resultado dela.
  5. Desenhamos um único ponto na linha da diferença.

Depois, o ambiente de execução avança para o próximo candle. Nele, total começa novamente em zero, e o laço soma os cinco valores correspondentes ao novo candle.

Se você tornasse total uma variável Persistent, o próximo candle continuaria com a soma anterior. A cada candle, acrescentaria mais cinco valores ao resultado antigo e já não calcularia a média da janela atual.

Quando falta histórico

Nos quatro primeiros candles dos dados, falta pelo menos um fechamento para completar a janela de cinco elementos. O na que entra na soma também torna a nossa média ausente. A SMA pronta de cinco também só fica válida no quinto candle.

Todos os fechamentos dos dados de demonstração do livro são válidos. Em uma fonte com lacunas no meio da série, o tratamento de valores ausentes de ta.sma pode ser diferente de uma soma simples que percorre deslocamentos de candles. Por isso, conferimos o exemplo com os dados especificados aqui.

Quantas repetições você está pedindo?

Uma janela de cem candles realiza cem somas em cada candle. Com dois mil candles, já são duzentas mil iterações.

A função pronta ta.sma serve justamente para executar essa tarefa comum com o cálculo do ambiente de execução projetado para isso. O laço próprio serve aqui para entender o funcionamento e comparar os resultados. Use a função pronta quando ela resolver a tarefa desejada.

O fim do laço deve ser conhecido e limitado. O valor máximo do input também limita a quantidade de trabalho que o usuário pode solicitar dentro de um candle.

break e continue

break interrompe o laço. continue ignora o restante da iteração atual e passa à próxima.

Use-os com cuidado em uma janela de média. Se você somou três valores e parou, já não pode dividir a soma por cinco como se tivesse usado cinco valores. As omissões mudam o significado do cálculo.

Tente por conta própria

Defina o comprimento como três. Em um candle, anote os deslocamentos usados no laço e os três preços correspondentes. Depois, modifique o programa para desenhar também a média própria e a pronta no gráfico de preços, em modo overlay, além de examinar a diferença.

Solução do exercício

Os três deslocamentos são 0, 1 e 2. O decorador deve usar overlay=True; depois do cálculo:

plot(manual_average, "Manual average", color=color.blue, linewidth=2)
plot(builtin_average, "Built-in average", color=color.orange)

Retire o desenho da diferença dessa visualização. Uma linha próxima de zero e médias no nível dos preços ficam difíceis de ler na mesma escala. Você pode manter o painel original da diferença em uma versão separada do programa para a conferência.

Identifique uma janela deslocada

Pense no que mudaria se escrevesse o laço como range(1, length + 1). A quantidade de elementos continuaria em cinco, mas o candle atual sairia e entraria o de cinco candles atrás. Essa seria a janela de média do candle anterior, não do atual.