QuantBrasil

Como Calcular o Estocástico Lento Utilizando Python

Andressa Quintanilha
Por Andressa Quintanilha
29 março, 2021
Compartilhar:

Criado na década de 50 pelo americano George Lane, o indicador Estocástico faz parte da família dos osciladores de momento, muito utilizados como sinalizadores de reversão de tendência na análise técnica.

Na prática, o Estocástico mede a relação entre o preço atual com as máximas e mínimas de um período pré-determinado. Originalmente, utilizava-se 14 períodos, mas atualmente tornou-se comum sua utilização em intervalos mais curtos, como em uma janela de 8 períodos.

Dito isso, nós definimos o conceito de Estocástico Rápido (%K\%K), usualmente acompanhado de sua média móvel aritmética de n períodos (%D\%D).

Essas curvas são calculadas da seguinte maneira:

%K=(PAMin(n)Max(n)Min(n))100\%K = \left(\dfrac{PA - Min(n)}{Max(n) - Min(n)} \right) *100

%D=MMA(%K,n)\%D = MMA(\%K, n)

PAPA = Preço Atual;
Min(n)Min(n) = Mínima em n períodos;
Max(n)Max(n) = Máxima em n períodos;
MMAMMA = Média Móvel Aritmética.

Estocástico Lento

Para calcular o Estocástico Lento, tudo que precisamos fazer é calcular a média móvel aritmética das curvas acima. Ou seja, %KL=%D\%K_L = \%D. Matematicamente:

%KL=MMA(%K,3)=%D\%K_L = MMA(\%K, 3) = \%D

%DL=MMA(%D)\%D_L = MMA(\%D)

Dessa forma, o Estocástico Lento suaviza as oscilações de preço e, por conta disso, é bastante utilizado entre traders.

Além disso, análogo ao IFR, esse indicador também varia em uma escala de 0 a 100, apresentando regiões que caracterizam estados de sobrecompra e sobrevenda (tipicamente acima de 80 e abaixo de 20).

Agora que nós já vimos o conceito de Estocástico e suas variações, vamos criar uma função, em Python, para calculá-lo em apenas 3 passos:

1. Calcular o Estocástico Rápido;
2. Calcular o Estocástico Lento;
3. Criar a função juntando os passos acima.

Simples assim, vamos trabalhar!

Calculando o Estocástico Rápido

Calcularemos as curvas %K\%K e%D\%D, que caracterizam o estocástico rápido, a partir das fórmulas descritas anteriormente. Mas para isso, precisamos importar as bibliotecas de interesse e baixar os dados necessários.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import yfinance as yf

Faremos o download das colunas com o preço de fechamento ajustado, máximas e mínimas de um ativo qualquer (VVAR3), dentro de um período de 1 ano (01/01/2020 - 31/12/2020).

tickers = "VVAR3.SA"
start = "2020-01-01"
end = "2020-12-31"

df = yf.download(tickers, start= start, end=end).copy()[["High", "Low", "Adj Close"]]
df

[*********************100%***********************] 1 of 1 completed

HighLowAdj Close
Date
2020-01-0211.76000011.2311.730000
2020-01-0312.00000011.4711.480000
2020-01-0611.68000011.2011.480000
2020-01-0711.65000011.4211.650000
2020-01-0811.83000011.4511.600000
............
2020-12-2216.45000115.8615.940000
2020-12-2316.58000015.7116.129999
2020-12-2816.70000116.0016.590000
2020-12-2916.84000016.4816.580000
2020-12-3016.78000116.1616.160000

247 rows × 3 columns

Para o cálculo da curva %K\%K, precisamos primeiro isolar as máximas e mínimas do período escolhido. Isto é, a cada linha isolaremos o valor máximo da coluna High e o mínimo da coluna Low dentre as nnn linhas anteriores.

Utilizaremos a função rolling que faz essa seleção de uma janela móvel, especificada pelo argumento nnn, associada às funções max e min. A janela escolhida foi de 8 períodos.

n = 8 
n_highest_high = df["High"].rolling(n).max()
n_lowest_low = df["Low"].rolling(n).min()

Agora basta inseri-los na fórmula do Estocástico e teremos os valores para curva %K\%K do estocástico rápido.

df["%K"] = (
    (df["Adj Close"] - n_lowest_low) / 
    (n_highest_high - n_lowest_low)
) * 100

df
HighLowAdj Close%K
Date
2020-01-0211.76000011.2311.730000NaN
2020-01-0312.00000011.4711.480000NaN
2020-01-0611.68000011.2011.480000NaN
2020-01-0711.65000011.4211.650000NaN
2020-01-0811.83000011.4511.600000NaN
...............
2020-12-2216.45000115.8615.94000046.590886
2020-12-2316.58000015.7116.12999953.787839
2020-12-2816.70000116.0016.59000071.212116
2020-12-2916.84000016.4816.58000073.622044
2020-12-3016.78000116.1616.16000057.086608

247 rows × 4 columns

Com os valores de %K\%K definidos, podemos calcular a média móvel aritmética para obtermos %D\%D. A função utilizada para isso é a mesma (rolling), dessa vez associada à função mean.

Feito isso, removeremos todas as linhas contendo NaN.

df["%D"] = df['%K'].rolling(3).mean()
df.dropna(inplace=True)
df.head()
HighLowAdj Close%K%D
Date
2020-01-1513.5613.1013.5599.57626299.704444
2020-01-1614.0313.3813.5983.14177694.085036
2020-01-1713.8713.2113.7388.37208590.363374
2020-01-2014.2513.6514.0191.01124587.508369
2020-01-2114.3713.7814.3298.18839992.523910

Calculando o Estocástico Lento

O Estocástico Lento é ainda mais simples de se calcular, uma vez que ele é oriundo das curvas do estocástico rápido.

Como visto anteriormente, a curva %K lento (%KL\%K_L) nada mais é do que a curva suavizada através da média móvel de %K rápido (%K\%K). Em outras palavras, %KL\%K_L é igual a %D rápido (%D\%D).

A curva %D lento (%DL\%D_L), por sua vez, nada mais é do que a média móvel aritmética de %KL\%K_L.

df["Slow %K"] = df["%D"]
df["Slow %D"] = df["Slow %K"].rolling(3).mean()
df.head()
HighLowAdj Close%K%DSlow %KSlow %D
Date
2020-01-1513.5613.1013.5599.57626299.70444499.704444NaN
2020-01-1614.0313.3813.5983.14177694.08503694.085036NaN
2020-01-1713.8713.2113.7388.37208590.36337490.36337494.717618
2020-01-2014.2513.6514.0191.01124587.50836987.50836990.652260
2020-01-2114.3713.7814.3298.18839992.52391092.52391090.131884

Para ilustrar, vamos plotar ambas as curvas em um gráfico de linha. É muito simples, basta utilizar a função plot.

Para complementar, nós podemos plotar linhas horizontais através da função axhline para delimitar as regiões de sobrecompra e sobrevenda

df[["Slow %K", "Slow %D"]].plot()
plt.axhline(y=20.0, color='black', linestyle='--', linewidth=1)
plt.axhline(y=80.0, color='black', linestyle='--', linewidth=1)
plt.ylim(0, 100.0)
(0, 100.0)

Assim como fizemos no artigo do IFR, nós podemos plotar o estocástico juntamente com o gráfico do preço de fechamento.

Faremos isso através da função plot_stochastic, que recebe como argumento apenas o dataframe que contém as colunas necessárias (Adj CloseSlow %K e Slow %D).

def plot_stochastic(df):
    fig, (ax1, ax2) = plt.subplots(
        nrows=2, 
        sharex=True,
        figsize=(12,8), 
        gridspec_kw={"height_ratios": [3, 1]})

    ax1.plot(df.index, df["Adj Close"], label="Fechamento")
    ax1.legend()

    ax2.plot(df.index, df[["Slow %K"]], label='Estocástico Lento')
    ax2.plot(df.index, df[["Slow %D"]], label='MMA(3)', linewidth=1)
    ax2.axhline(y=80, color='black', linestyle='--', linewidth=1)
    ax2.axhline(y=20, color='black', linestyle='--', linewidth=1)
    ax2.set_ylim(0, 100)
    ax2.legend()
plot_stochastic(df)

Criando uma função para o cálculo do Estocástico

Finalmente, podemos juntar tudo que fizemos até agora em uma função stochastic, que retornará o dataframe selecionado com as colunas %K%DSlow %K e Slow %D.

Essa função receberá 3 argumentos:

  • df: o dataframe que se deseja adicionar as colunas acima (lembrando que ele deve conter as colunas HighLow e Adj Close);
  • k_window: janela móvel que se deseja calcular o estocástico (será de 8 períodos, por padrão);
  • mma_window: janela móvel que se deseja calcular média móvel aritmética (será de 3 períodos, por padrão).
def stochastic(df, k_window=8, mma_window=3):
    
    n_highest_high = df["High"].rolling(k_window).max()
    n_lowest_low = df["Low"].rolling(k_window).min()
    
    df["%K"] = (
        (df["Adj Close"] - n_lowest_low) / 
        (n_highest_high - n_lowest_low)
    ) * 100
    df["%D"] = df['%K'].rolling(mma_window).mean()
    
    df["Slow %K"] = df["%D"]
    df["Slow %D"] = df["Slow %K"].rolling(mma_window).mean()
    
    return df 

Vamos testar em um ativo qualquer:

ticker = "PETR4.SA"
petr4_df = yf.download(ticker, start=start, end=end).copy()[["High", "Low", "Adj Close"]]
stochastic(petr4_df)

[*********************100%***********************] 1 of 1 completed

HighLowAdj Close%K%DSlow %KSlow %D
Date
2020-01-0230.70000130.30999930.697725NaNNaNNaNNaN
2020-01-0331.24000030.45000130.447742NaNNaNNaNNaN
2020-01-0630.94000129.95000130.807716NaNNaNNaNNaN
2020-01-0730.87999930.46999930.687725NaNNaNNaNNaN
2020-01-0830.77000030.24000030.497738NaNNaNNaNNaN
........................
2020-12-2227.46999927.04999927.28000140.64174750.93563850.93563870.116206
2020-12-2328.25000027.35000027.95000176.47064847.95012647.95012655.698310
2020-12-2828.52000028.18000028.18000082.99999266.70412966.70412955.196631
2020-12-2928.43000027.99000028.27000087.50000082.32354782.32354765.659267
2020-12-3028.49000028.20000128.34000090.99998587.16665987.16665978.731445

247 rows × 7 columns

plot_stochastic(petr4_df)

Conclusão

O indicador Estocástico é amplamente utilizado em setups a fim de se beneficiar das oscilações do mercado, embarcando no início de uma perna, seja ela de alta ou de baixa.

A partir de stochastic nós podemos dar início a uma série de backtests utilizando esse indicador. A ideia é testarmos diversas estratégias em vários timeframes.

Dependendo do sistema operacional utilizado, o Estocástico demonstra tanta consistência quanto o IFR2, mas com uma média de sinais ainda maior. Então, se você gostou da série de backtests de IFR2, você não vai querer perder essa! Fique ligado na nossa newsletter ou no Telegram, nós anunciamos tudo por lá.