Preveja crises financeiras com o Python

Em 9 de março de 2020, temos um declínio acentuado nos mercados dos EUA, a partir de uma alta histórica em 20 de fevereiro de 2020, que atualmente está em torno de -16%. As notícias estavam cheias de manchetes sobre a recessão iminente devido ao coronavírus, a Rússia retirou-se do acordo da Opep +, que atingiu os preços do petróleo (-20% ao dia) e amanhã (10 de março de 2020), o mercado MICEX também deverá cair 20%, a julgar por cotações de nossas ações nos mercados ocidentais.


Uma recessão global nos espera? Neste artigo, tentaremos descobrir como você pode ver antecipadamente os sinais do início da recessão usando o Python.

Para responder a essa pergunta, tentaremos usar o rendimento em títulos, ações e análises técnicas. Usaremos dados históricos do mercado financeiro dos EUA como o primeiro maior mercado de ações do mundo. De fato, se uma recessão começar nos Estados Unidos, começará em todo o mundo (como aconteceu em 2008). Além disso, é conveniente para nós que existam dados para o mercado dos EUA por décadas, o que nos permitirá analisar durante um período histórico significativo. Obteremos

dados históricos do Yahoo Finance usando a biblioteca yfinance , do site do Fed. Reserva dos EUA usando a biblioteca fredapi e no site da Quandl com várias informações financeiras por meio de pandas_datareader. Observe que, para Fed e Quandl, você precisa se registrar para receber uma chave de API (isso é gratuito).

Todas as crises financeiras nos EUA marcaremos em áreas cinzas diretamente nos gráficos.

Importar bibliotecas
from fredapi import Fred
import pandas as pd
import os
import pandas_datareader.data as web
import pandas_datareader as pdr
%matplotlib inline
from matplotlib import pyplot as plt
from datetime import date
import yfinance
import numpy as np

api = 'YOUR API HERE'
os.environ["QUANDL_API_KEY"] = 'YOUR API HERE'
os.environ["TIINGO_API_KEY"] = 'YOUR API HERE'

fred = Fred(api_key=api)


Obtemos dados históricos do S & P500 com o Yahoo, o rendimento dos títulos se espalha com o FRED e o índice de rendimento acumulado dos títulos com o FRED:

GSPC_h = yfinance.download("^GSPC", start="1962-01-01", end="2020-03-09") #SNP500
T10YFF = fred.get_series('T10YFF', observation_start='1962-01-01', observation_end='2020-03-09') #10YB-FFR
T10Y2Y = fred.get_series('T10Y2Y', observation_start='1976-06-01', observation_end='2020-03-09') #10YB-2YB
# ICE BofA US Corp 10-15yr Total Return Index Value
BAMLCC7A01015YTRIV = fred.get_series('BAMLCC7A01015YTRIV', observation_start='1962-01-01', observation_end='2020-03-09')

Prêmio de risco


O prêmio de risco é um indicador que reflete a lucratividade adicional que um investidor receberá ao assumir um risco aumentado.

É assim que os mercados financeiros funcionam - quanto maior o retorno do investimento, maior o risco.

Para calcular o prêmio de risco, é necessário subtrair do retorno esperado do ativo de risco a taxa de retorno livre de risco.

Para o mercado dos EUA, a taxa de retorno livre de risco é a taxa de reserva do Fed dos EUA (um análogo da nossa principal taxa) - FED.

O prêmio de risco para ações e títulos é considerado de maneira diferente.
Para títulos: rendimento de títulos (rendimento) menos FED.
Para ações: indicador de lucro / preço (E / P) menos FED,
onde lucro é o lucro da empresa para o ano, preço é o preço da ação no momento em que o indicador é calculado.

Para calcular a rentabilidade de uma ação, não consideramos os dividendos pagos como rentabilidade, mas o lucro recebido pela empresa, porque os dividendos são apenas parte do lucro que a empresa paga aos acionistas. Tornar-se proprietário da empresa por meio da compra de suas ações, de fato, a receita final para nós será precisamente o lucro que será distribuído integralmente pelos acionistas no momento da liquidação da empresa.

Obtemos E / P para S & P500 (SP500_EARNINGS_YIELD_MONTH), a taxa livre de risco (FED Funds Rate) e o rendimento de títulos corporativos do amplo mercado (rendimento de títulos Baa):

# E/P
symbol = 'MULTPL/SP500_EARNINGS_YIELD_MONTH'
SP500_EARNINGS_YIELD_MONTH = web.DataReader(symbol, 'quandl', '1962-01-01', '2020-03-09')
# FED Funds Rate
FEDFUNDS = fred.get_series('FEDFUNDS', observation_start='1962-01-01', observation_end='2020-03-09')
# Baa Bonds Yield
BAA = fred.get_series('BAA', observation_start='1962-01-01', observation_end='2020-03-09')

Calculamos o prêmio de risco como lucro menos a taxa livre de risco:

#     
risk_premium = pd.concat([SP500_EARNINGS_YIELD_MONTH, FEDFUNDS],axis=1).fillna(method='bfill')
risk_premium['premium'] = risk_premium['Value'] - risk_premium[0]

#     
risk_premium_b = pd.concat([BAA, FEDFUNDS],axis=1).fillna(method='bfill')
risk_premium_b.columns = ['BAA', 'FEDFUNDS']
risk_premium_b['premium_b'] = risk_premium_b['BAA'] - risk_premium_b['FEDFUNDS']

Vamos ver o que aconteceu para ações e títulos separadamente.

Para as unidades populacionais:

Código do gráfico
fig, ax = plt.subplots(figsize=(17,6))

line1, = ax.plot(risk_premium['premium'],linewidth=1)
line1.set_label('risk_premium_stocks')

line2, = ax.plot(SP500_EARNINGS_YIELD_MONTH,linewidth=1)
line2.set_label('SP500_EARNINGS_YIELD_MONTH')
ax.legend(loc='upper left')

par1 = ax.twinx()
line3, = par1.plot(np.log(GSPC_h['Close']),linewidth=0.7, color='red')
line3.set_label('S&P500')
par1.legend(loc='upper left', bbox_to_anchor=(0, 0, 1, 0.88))

plt.xlim(left=date(1962, 1, 1), right=date(2020, 3, 9))
ax.axhline(linewidth=2, color='black', alpha=0.7)
ax.axvspan(date(2007, 12, 1), date(2009, 6, 1), alpha=0.3, color='grey')
ax.axvspan(date(2001, 3, 1), date(2001, 11, 1), alpha=0.3, color='grey')
ax.axvspan(date(1990, 8, 1), date(1991, 2, 1), alpha=0.3, color='grey')
ax.axvspan(date(1981, 7, 1), date(1982, 11, 1), alpha=0.3, color='grey')
ax.axvspan(date(1980, 1, 1), date(1980, 7, 1), alpha=0.3, color='grey')
ax.axvspan(date(1973, 12, 1), date(1975, 2, 1), alpha=0.3, color='grey')
ax.axvspan(date(1969, 12, 1), date(1970, 11, 1), alpha=0.3, color='grey')

ax.set_xlabel('')
ax.set_ylabel('  , %')
par1.set_ylabel('Log  S&P500')

plt.show()



Para títulos:

Código do gráfico
fig, ax = plt.subplots(figsize=(17,6))

line1, = ax.plot(risk_premium_b['premium_b'][date(1987, 12, 1):],linewidth=1, color='k')
line1.set_label('risk_premium_bonds')
ax.legend(loc='upper left', bbox_to_anchor=(0, 0, 1, 0.95))

par1 = ax.twinx()
line2, = par1.plot(np.log(BAMLCC7A01015YTRIV),linewidth=0.7, color='green')
line2.set_label('Log ICE BofA US Corp 10-15yr Total Return Index Value')
par1.legend(loc='upper left')
plt.xlim(left=date(1987, 12, 1), right=date(2020, 3, 9))

ax.axhline(y=1.5, linewidth=2, color='red', ls='--', alpha=0.7)

ax.axvspan(date(2007, 12, 1), date(2009, 6, 1), alpha=0.3, color='grey')
ax.axvspan(date(2001, 3, 1), date(2001, 11, 1), alpha=0.3, color='grey')
ax.axvspan(date(1990, 8, 1), date(1991, 2, 1), alpha=0.3, color='grey')
ax.axhline(linewidth=2, color='black', alpha=0.7)

ax.set_xlabel('')
ax.set_ylabel('  , %')
par1.set_ylabel('Log  BofA')

plt.show()




Como podemos ver, os períodos pré-crise são áreas com um prêmio de risco negativo para ações e um prêmio de risco reduzido para títulos.

Ao mesmo tempo, para títulos, nem sempre um prêmio de risco reduzido é um sinal para o início de uma crise no mercado de títulos (o índice Bof diminuiu apenas em 2008), mas um prêmio reduzido no mercado de ações é quase sempre (exceto no período após a crise no início dos anos 80, quando um prêmio negativo foi mantido por muito tempo) leva a uma diminuição no valor das ações.

O que significa um prêmio de risco negativo para as ações?

Ao comprar uma ação, obtemos um retorno abaixo da taxa livre de risco no mercado. Ao mesmo tempo, assumindo total responsabilidade pelos riscos de flutuações no preço das ações e possíveis perdas. Esta não é uma situação padrão, os investidores entendem que o prêmio de risco não pode ser negativo, pelo que os mercados percebem que o valor atual das ações é muito alto e as vendas estão começando. A queda se intensifica depois que investidores de uma ampla variedade (pessoas comuns, não investidores institucionais) começam a entrar em pânico, vendendo suas carteiras e agravando a queda. Assim, a reação dos mercados é rápida e forte.
Vale ressaltar que o declínio do mercado não atinge o nível anterior de prêmio de risco, mas sempre acontece muito mais forte, o que aumenta significativamente o prêmio de risco e, novamente, aumenta a atratividade dos títulos para os investidores.

Além disso, se observarmos os prêmios de risco para ações e títulos em um gráfico, veremos que o prêmio de risco para títulos tradicionalmente tem sido mais alto do que para ações, no entanto, nos últimos 5 anos eles se sincronizaram e ambos estão gradualmente tendendo a zero:

Código do gráfico
fig, ax = plt.subplots(figsize=(17,6))

line1, = ax.plot(risk_premium['premium'],linewidth=1)
line1.set_label('risk_premium_stocks')

par1 = ax.twinx()
line3, = par1.plot(np.log(GSPC_h['Close']),linewidth=0.7, color='red')
line3.set_label('S&P500')
par1.legend(loc='upper left', bbox_to_anchor=(0, 0, 1, 0.88))

line2, = ax.plot(risk_premium_b['premium_b'],linewidth=1, color='k')
line2.set_label('risk_premium_bonds')
ax.legend(loc='upper left')
plt.xlim(left=date(1968, 1, 1), right=date(2020, 3, 9))

ax.axhline(linewidth=2, color='black', alpha=0.7)
ax.axvspan(date(2007, 12, 1), date(2009, 6, 1), alpha=0.3, color='grey')
ax.axvspan(date(2001, 3, 1), date(2001, 11, 1), alpha=0.3, color='grey')
ax.axvspan(date(1990, 8, 1), date(1991, 2, 1), alpha=0.3, color='grey')
ax.axvspan(date(1981, 7, 1), date(1982, 11, 1), alpha=0.3, color='grey')
ax.axvspan(date(1980, 1, 1), date(1980, 7, 1), alpha=0.3, color='grey')
ax.axvspan(date(1973, 12, 1), date(1975, 2, 1), alpha=0.3, color='grey')
ax.axvspan(date(1969, 12, 1), date(1970, 11, 1), alpha=0.3, color='grey')

ax.set_xlabel('')
ax.set_ylabel('  , %')
par1.set_ylabel('Log  S&P500')

plt.show()




Em 9 de março de 2020, apesar de uma queda acentuada e forte no mercado de ações dos EUA, o retorno das ações ainda está longe da zona negativa, o que dá um sinal encorajador.

Spread dos rendimentos do tesouro


Um indicador alternativo da situação do mercado antes da crise é a diferença entre os rendimentos dos títulos do tesouro de longo e curto prazo.

O menos barulhento e mais prático é o spread entre os rendimentos de títulos do tesouro de 10 e 2 anos:

Código do gráfico
fig, ax = plt.subplots(figsize=(17,6))
par1 = ax.twinx()
line, = ax.plot(pd.DataFrame(T10Y2Y),linewidth=0.4)
line.set_label('10YB-2YB')
ax.legend(loc='best', bbox_to_anchor=(0.5, 0., 0.5, 0.1))

line1, = par1.plot(np.log(GSPC_h['Close']),linewidth=0.7, color='red')
line1.set_label('S&P500')
par1.legend(loc='best', bbox_to_anchor=(0.5, 0., 0.5, 0.18))
plt.xlim(left=date(1976, 1, 1), right=date(2020, 3, 9))
plt.ylim(bottom=4)
ax.axvspan(date(2007, 12, 1), date(2009, 6, 1), alpha=0.3, color='grey')
ax.axvspan(date(2001, 3, 1), date(2001, 11, 1), alpha=0.3, color='grey')
ax.axvspan(date(1990, 8, 1), date(1991, 2, 1), alpha=0.3, color='grey')
ax.axvspan(date(1981, 7, 1), date(1982, 11, 1), alpha=0.3, color='grey')
ax.axvspan(date(1980, 1, 1), date(1980, 7, 1), alpha=0.3, color='grey')
ax.axvspan(date(1973, 12, 1), date(1975, 2, 1), alpha=0.3, color='grey')
ax.axvspan(date(1969, 10, 1), date(1970, 11, 1), alpha=0.3, color='grey')
ax.axhline(linewidth=2, color='black', alpha=0.7)
plt.scatter(date(2019, 9, 1), 6., color='orange', s=500, marker='o', alpha=0.5)
plt.scatter(date(2007, 1, 1), 6., color='orange', s=500, marker='o', alpha=0.5)
plt.scatter(date(2000, 1, 1), 5.9, color='orange', s=500, marker='o', alpha=0.5)
plt.scatter(date(1998, 8, 1), 5.9, color='orange', s=500, marker='o', alpha=0.5)
plt.scatter(date(1989, 4, 1), 5.8, color='orange', s=500, marker='o', alpha=0.5)
plt.scatter(date(1981, 1, 1), 5.9, color='orange', s=500, marker='o', alpha=0.5)
plt.scatter(date(1978, 11, 1), 5.9, color='orange', s=500, marker='o', alpha=0.5)

ax.set_xlabel('')
ax.set_ylabel('  , %')
par1.set_ylabel('Log  S&P500')

plt.show()




Este indicador é o mais verdadeiro do ponto de vista histórico e previu as últimas 7 crises financeiras.

O spread entre o rendimento dos títulos, neste caso, reflete o humor dos investidores - se eles acreditam que a economia se deteriorará em breve, eles começarão a transferir dinheiro de títulos de curto prazo (com vencimento em 2 anos) para instrumentos de longo prazo (com vencimento em 10 anos) com rendimento fixo O emissor mais confiável é o Tesouro dos EUA.

A compra de títulos de longo prazo afeta seu rendimento, uma vez que a compra de títulos por quantias significativas de caixa leva a um aumento no custo do título. Quando o cupom é um valor fixo, a valorização do corpo do título leva a uma diminuição no seu rendimento.
Para os títulos de curto prazo, vendidos neste caso, a situação é oposta - o corpo começa a ficar mais barato, em um cupom fixo, respectivamente, o rendimento começa a crescer.

No entanto, o FRED não fornece informações além de 1976 sobre esse spread, portanto, para fins ilustrativos, podemos obter o rendimento em títulos do tesouro de 10 anos menos a taxa do FED (em vez de títulos de curto prazo de 2 anos) para ver o que aconteceu desde 1962 e cobriu mais duas crises :

Código do gráfico
fig, ax = plt.subplots(figsize=(17,6))
par1 = ax.twinx()
line, = ax.plot(pd.DataFrame(T10YFF),linewidth=0.4)
line.set_label('10-Year Treasury Constant Maturity Minus Federal Funds Rate')
ax.legend(loc='best', bbox_to_anchor=(0.5, 0., 0.5, 0.1))

line1, = par1.plot(np.log(GSPC_h['Close']),linewidth=0.7, color='red')
line1.set_label('S&P500')
par1.legend(loc='best', bbox_to_anchor=(0.5, 0., 0.5, 0.18))
plt.xlim(left=date(1962, 1, 1), right=date(2020, 3, 9))
plt.ylim(bottom=4)
ax.axvspan(date(2007, 12, 1), date(2009, 6, 1), alpha=0.3, color='grey')
ax.axvspan(date(2001, 3, 1), date(2001, 11, 1), alpha=0.3, color='grey')
ax.axvspan(date(1990, 8, 1), date(1991, 2, 1), alpha=0.3, color='grey')
ax.axvspan(date(1981, 7, 1), date(1982, 11, 1), alpha=0.3, color='grey')
ax.axvspan(date(1980, 1, 1), date(1980, 7, 1), alpha=0.3, color='grey')
ax.axvspan(date(1973, 12, 1), date(1975, 2, 1), alpha=0.3, color='grey')
ax.axvspan(date(1969, 12, 1), date(1970, 11, 1), alpha=0.3, color='grey')
ax.axhline(linewidth=2, color='black', alpha=0.7)
plt.scatter(date(2019, 9, 1), 6.7, color='orange', s=500, marker='o', alpha=0.5)
plt.scatter(date(2007, 1, 1), 6.7, color='orange', s=500, marker='o', alpha=0.5)
plt.scatter(date(2000, 11, 1), 6.7, color='orange', s=500, marker='o', alpha=0.5)
plt.scatter(date(1998, 11, 1), 6.6, color='orange', s=500, marker='o', alpha=0.5)
plt.scatter(date(1989, 6, 1), 6.4, color='orange', s=500, marker='o', alpha=0.5)
plt.scatter(date(1973, 6, 1), 6.6, color='orange', s=500, marker='o', alpha=0.5)
plt.scatter(date(1981, 3, 1), 6.3, color='orange', s=500, marker='o', alpha=0.5)
plt.scatter(date(1979, 3, 1), 6.6, color='orange', s=500, marker='o', alpha=0.5)
plt.scatter(date(1969, 3, 1), 6.6, color='orange', s=500, marker='o', alpha=0.5)
plt.scatter(date(1967, 1, 1), 6.6, color='orange', s=500, marker='o', alpha=0.5)

ax.set_xlabel('')
ax.set_ylabel('  , %')
par1.set_ylabel('Log  S&P500')

plt.show()




Apesar do barulho geral desse spread (compare com o spread de 10 anos a 2 anos), as crises de 73 e 69 também foram implementadas reduzindo o spread para a zona negativa.

O que no momento?
As coisas não são muito - o indicador já mostrou uma zona negativa em 2019.
Os investidores institucionais esperam que, no futuro próximo, choques sérios nos aguardem e, por isso, sejam transferidos para instrumentos de renda fixa de longo prazo.

Quanto resta antes da crise?
Como pode ser visto no gráfico de spread, o rendimento invertido antecipa as crises por um ano ou dois.
Dado que a inversão ocorreu no final de 2019 e os mercados dos EUA já começaram a cair devido à expectativa de uma recessão futura devido ao vírus COVID-19, a crise está se aproximando agora.

Em 9 de março de 2020, o rendimento dos títulos do Tesouro dos EUA a 10 anos caiu para 0,318% - o valor mais baixo de todos os tempos!
Parece que algo grande está esperando por nós e já começou.

valor atual T10YFF:
-0.17 valor atual T10Y2Y: 0.25

Preços anteriores não prevêem crise


Para um exemplo do desamparo da análise técnica nesta edição, tomamos o indicador RSI.
RSI - índice de força relativa em teoria mostra o mercado "sobrecomprado" e "sobrevendido".
Mercado sobrecomprado - é o estado em que os preços devem se ajustar, ou seja, uma crise no mercado de ações.

Link para o Wiki com uma descrição do indicador

Podemos calcular esse indicador usando Python, para o cálculo tomamos o período - 244 pregões (1 ano civil):

SP500_returns = GSPC_h['Close'].pct_change()
delta = GSPC_h['Close'].diff()
window_length = 500

# Make the positive gains (up) and negative gains (down) Series
up, down = delta.copy(), delta.copy()
up[up < 0] = 0
down[down > 0] = 0

# Calculate the EWMA
roll_up1 = up.ewm(span=window_length).mean()
roll_down1 = down.abs().ewm(span=window_length).mean()

# Calculate the RSI based on EWMA
RS1 = roll_up1 / roll_down1
RSI1 = 100.0 - (100.0 / (1.0 + RS1))

Código do gráfico
# Compare graphically
fig, ax = plt.subplots(figsize=(20,4))
plt.xlim(left=date(1968, 1, 1), right=date(2020, 3, 9))
line, = ax.plot(np.log(GSPC_h['Close']),linewidth=0.7, color='red')

line.set_label('SNP500')
ax.legend(loc='upper left')

fig1, ax1 = plt.subplots(figsize=(20,4))
plt.xlim(left=date(1968, 1, 1), right=date(2020, 3, 9))
line1, = ax1.plot(RSI1[80:],linewidth=1)

line1.set_label('RSI (1Y)')
ax1.legend(loc='upper left')

ax.axvspan(date(2007, 12, 1), date(2009, 6, 1), alpha=0.3, color='grey')
ax.axvspan(date(2001, 3, 1), date(2001, 11, 1), alpha=0.3, color='grey')
ax1.axhline(y=57, linewidth=2, color='black', alpha=0.7)
ax1.axhline(y=45, linewidth=2, color='black', alpha=0.7)

ax.axvspan(date(1990, 8, 1), date(1991, 2, 1), alpha=0.3, color='grey')
ax.axvspan(date(1981, 7, 1), date(1982, 11, 1), alpha=0.3, color='grey')
ax.axvspan(date(1980, 1, 1), date(1980, 7, 1), alpha=0.3, color='grey')
ax.axvspan(date(1973, 12, 1), date(1975, 2, 1), alpha=0.3, color='grey')
ax.axvspan(date(1969, 12, 1), date(1970, 11, 1), alpha=0.3, color='grey')

ax1.axvspan(date(1990, 8, 1), date(1991, 2, 1), alpha=0.3, color='grey')
ax1.axvspan(date(1981, 7, 1), date(1982, 11, 1), alpha=0.3, color='grey')
ax1.axvspan(date(1980, 1, 1), date(1980, 7, 1), alpha=0.3, color='grey')
ax1.axvspan(date(1973, 12, 1), date(1975, 2, 1), alpha=0.3, color='grey')
ax1.axvspan(date(1969, 12, 1), date(1970, 11, 1), alpha=0.3, color='grey')
ax1.axvspan(date(2007, 12, 1), date(2009, 6, 1), alpha=0.3, color='grey')
ax1.axvspan(date(2001, 3, 1), date(2001, 11, 1), alpha=0.3, color='grey')

ax1.set_xlabel('')
ax.set_xlabel('')
ax1.set_ylabel(' RSI')
ax.set_ylabel('Log  S&P500')

plt.show()




O que vemos no gráfico RSI?

Muitas zonas de "sobrecompra", que podem sinalizar muito mercado, que é hora de ajustar. Mas continuou a subir (por exemplo, um longo período desde 1995, o indicador mostra "sobrecomprado", mas antes da crise de 2001 ele volta à sua zona habitual e não sinaliza sobre "sobrecomprado", que, no entanto, termina com a crise).

Em outras palavras, o uso de osciladores para prever uma crise é um exercício altamente controverso.

Antes das crises, o mercado cresce suavemente, sem mostrar alta volatilidade para cima, diferentemente das quedas - elas são sempre nítidas e rápidas. Vemos isso perto da borda inferior do oscilador - sua interseção quase sempre mostrava exatamente quando a crise chegava e a parte inferior do outono estava próxima. Compre sinal?

achados


No momento, a situação parece alarmante: há indicadores diretos que mostram uma possível recessão. Além dos revisados, há também um índice de produção industrial (é líder em crises econômicas (não financeiras!)). Poder-se-ia também aprofundar nas estatísticas macroeconômicas e adicionar a balança de pagamentos, o PIB e similares à análise, no entanto, os investidores institucionais já fizeram isso por nós - sua reação se reflete no spread de rendimento dos títulos de longo e curto prazo. Resta relaxar e assistir ao show, se você não tiver investimentos financeiros. E se houver - pense em um possível hedge de suas posições ou vá para o cache até tempos melhores.

All Articles