Processamento de Sinais
Digital Signal Processing no Pine Script
Neste capítulo
Filtros FIR
Filtros FIR (Finite Impulse Response)
Filtros FIR são calculados usando convolução - uma soma ponderada dos valores passados.
Média Móvel Simples como Filtro
A SMA é o filtro FIR mais simples, onde todos os pesos são iguais:
// SMA = Σ(preço × 1/n)
sma = 0.0
for i = 0 to length - 1
sma += close[i] / lengthFiltros Passa-Baixa
Removem ruído (frequências altas), resultando em uma saída suave:
- SMA, EMA, WMA são filtros passa-baixa
- Quanto maior o período, mais suave a saída
Filtros Passa-Alta
Removem tendência, deixando apenas as oscilações:
highpass = close - sma(close, length)Filtros Passa-Banda
Combinam passa-baixa e passa-alta:
bandpass = sma(close - sma(close, length), length)Implementação de filtro gaussiano FIR
1//@version=6
2indicator("Filtro Gaussiano", overlay=true)
3
4length = input.int(20, "Período")
5sigma = input.float(2.0, "Sigma")
6
7// Função gaussiana
8gauss(x, sigma) =>
9 math.exp(-0.5 * math.pow(x / sigma, 2))
10
11// Calcular filtro gaussiano
12sum = 0.0
13sumW = 0.0
14for i = 0 to length - 1
15 // Normalizar x para -1 a 1
16 x = (i - (length - 1) / 2) / (length / 2)
17 w = gauss(x, sigma / length * 2)
18 sum += close[i] * w
19 sumW += w
20
21gaussMA = sum / sumW
22
23// SMA para comparação
24smaLine = ta.sma(close, length)
25
26// Plots
27plot(gaussMA, "Gaussiano", color.blue, 2)
28plot(smaLine, "SMA", color.gray)Filtros IIR
Filtros IIR (Infinite Impulse Response)
Filtros IIR usam feedback - valores de saída passados são usados no cálculo atual.
EMA como Filtro IIR
A EMA é o filtro IIR mais comum:
// EMA recursiva
alpha = 2 / (length + 1)
ema = alpha * close + (1 - alpha) * ema[1]Vantagens dos Filtros IIR
- Mais eficientes computacionalmente
- Resposta mais rápida
- Menos lag para o mesmo nível de suavização
Desvantagens
- Podem ser instáveis se mal projetados
- Resposta ao impulso infinita (nunca volta a zero)
Filtro Butterworth
Um filtro IIR clássico com resposta de frequência plana:
// Butterworth de 2 polos simplificado
a = math.exp(-math.sqrt(2) * math.pi / length)
b = 2 * a * math.cos(math.sqrt(2) * math.pi / length)
c2 = b
c3 = -a * a
c1 = 1 - c2 - c3
butter = c1 * (close + close[1]) / 2 + c2 * nz(butter[1]) + c3 * nz(butter[2])Implementação do filtro Butterworth
1//@version=6
2indicator("Filtro Butterworth", overlay=true)
3
4length = input.int(14, "Período")
5
6// Cálculo do Butterworth de 3 polos
7pi = math.pi
8cf = 2 * math.tan(2 * pi * (1 / length) / 2)
9
10a0 = 8 + 8*cf + 4*math.pow(cf, 2) + math.pow(cf, 3)
11a1 = -24 - 8*cf + 4*math.pow(cf, 2) + 3*math.pow(cf, 3)
12a2 = 24 - 8*cf - 4*math.pow(cf, 2) + 3*math.pow(cf, 3)
13a3 = -8 + 8*cf - 4*math.pow(cf, 2) + math.pow(cf, 3)
14
15c = math.pow(cf, 3) / a0
16d0 = -a1 / a0
17d1 = -a2 / a0
18d2 = -a3 / a0
19
20// Aplicar filtro
21var float butter = na
22butter := nz(c * (close + close[3]) + 3*c * (close[1] + close[2]) + d0*butter[1] + d1*butter[2] + d2*butter[3], close)
23
24// EMA para comparação
25emaLine = ta.ema(close, length)
26
27// Plots
28plot(butter, "Butterworth", color.blue, 2)
29plot(emaLine, "EMA", color.gray)