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
Essas curvas são calculadas da seguinte maneira:
PA = Preço Atual;
Min(n) = Mínima em n períodos;
Max(n) = Máxima em n períodos;
MMA = Média Móvel Aritmética.
Para calcular o Estocástico Lento, tudo que precisamos fazer é calcular a média móvel aritmética das curvas acima. Ou seja,
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!
Calcularemos as curvas
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
High | Low | Adj Close | |
---|---|---|---|
Date | |||
2020-01-02 | 11.760000 | 11.23 | 11.730000 |
2020-01-03 | 12.000000 | 11.47 | 11.480000 |
2020-01-06 | 11.680000 | 11.20 | 11.480000 |
2020-01-07 | 11.650000 | 11.42 | 11.650000 |
2020-01-08 | 11.830000 | 11.45 | 11.600000 |
... | ... | ... | ... |
2020-12-22 | 16.450001 | 15.86 | 15.940000 |
2020-12-23 | 16.580000 | 15.71 | 16.129999 |
2020-12-28 | 16.700001 | 16.00 | 16.590000 |
2020-12-29 | 16.840000 | 16.48 | 16.580000 |
2020-12-30 | 16.780001 | 16.16 | 16.160000 |
247 rows × 3 columns
Para o cálculo da curva High
e o mínimo da coluna Low
dentre as
Utilizaremos a função rolling que faz essa seleção de uma janela móvel, especificada pelo argumento
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
df["%K"] = (
(df["Adj Close"] - n_lowest_low) /
(n_highest_high - n_lowest_low)
) * 100
df
High | Low | Adj Close | %K | |
---|---|---|---|---|
Date | ||||
2020-01-02 | 11.760000 | 11.23 | 11.730000 | NaN |
2020-01-03 | 12.000000 | 11.47 | 11.480000 | NaN |
2020-01-06 | 11.680000 | 11.20 | 11.480000 | NaN |
2020-01-07 | 11.650000 | 11.42 | 11.650000 | NaN |
2020-01-08 | 11.830000 | 11.45 | 11.600000 | NaN |
... | ... | ... | ... | ... |
2020-12-22 | 16.450001 | 15.86 | 15.940000 | 46.590886 |
2020-12-23 | 16.580000 | 15.71 | 16.129999 | 53.787839 |
2020-12-28 | 16.700001 | 16.00 | 16.590000 | 71.212116 |
2020-12-29 | 16.840000 | 16.48 | 16.580000 | 73.622044 |
2020-12-30 | 16.780001 | 16.16 | 16.160000 | 57.086608 |
247 rows × 4 columns
Com os valores de 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()
High | Low | Adj Close | %K | %D | |
---|---|---|---|---|---|
Date | |||||
2020-01-15 | 13.56 | 13.10 | 13.55 | 99.576262 | 99.704444 |
2020-01-16 | 14.03 | 13.38 | 13.59 | 83.141776 | 94.085036 |
2020-01-17 | 13.87 | 13.21 | 13.73 | 88.372085 | 90.363374 |
2020-01-20 | 14.25 | 13.65 | 14.01 | 91.011245 | 87.508369 |
2020-01-21 | 14.37 | 13.78 | 14.32 | 98.188399 | 92.523910 |
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 (
A curva %D lento (
df["Slow %K"] = df["%D"]
df["Slow %D"] = df["Slow %K"].rolling(3).mean()
df.head()
High | Low | Adj Close | %K | %D | Slow %K | Slow %D | |
---|---|---|---|---|---|---|---|
Date | |||||||
2020-01-15 | 13.56 | 13.10 | 13.55 | 99.576262 | 99.704444 | 99.704444 | NaN |
2020-01-16 | 14.03 | 13.38 | 13.59 | 83.141776 | 94.085036 | 94.085036 | NaN |
2020-01-17 | 13.87 | 13.21 | 13.73 | 88.372085 | 90.363374 | 90.363374 | 94.717618 |
2020-01-20 | 14.25 | 13.65 | 14.01 | 91.011245 | 87.508369 | 87.508369 | 90.652260 |
2020-01-21 | 14.37 | 13.78 | 14.32 | 98.188399 | 92.523910 | 92.523910 | 90.131884 |
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 Close
, Slow %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)
Finalmente, podemos juntar tudo que fizemos até agora em uma função stochastic
, que retornará o dataframe selecionado com as colunas %K
, %D
, Slow %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 High
, Low
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