Marcos Júnio Ribeiro

Poupança precaucional

September 30, 2022 | 54 Minute Read

Poupança precaucional com risco

Hoje vamos calcular, utilizando o Python, a poupança precaucional com base no artigo do Barros et. al (2022). Especificamente, vamos resolver a questão 3 da lista 2 de macro.

A poupança precaucional é o acréscimo da poupança em virtude da incerteza sobre a renda futura. Em seu artigo Barros et. al (2022) apresenta a seguinte Equação:

\[\begin{equation} \tag{17} (Y_1 - S^*)^{-\gamma} = \beta R \left[ (1 - p) \left(\dfrac{Y_2}{1 - p} + RS^* \right)^{-\gamma} + p(RS^*)^{-\gamma} \right] \end{equation}\]

Essa equação é derivada de um processo de maximização da utilidade do consumidor. O lado esquerdo da Equação 17 é igual a utilidade marginal do consumo no primeiro período, enquanto o lado direito da Equação 17 é o valor esperado da utilidade marginal do consumo no segundo período multiplicado tanto por \(\beta\) e quanto por \(R\). Note que, queremos encontrar a poupança precaucional \(S^*\) e a igualdade entre estes dois termos é uma condição de necessária para encontrarmos a poupança ótima.

No entanto, resolver a Equação 17 para \(S^*\) analiticamente não é uma tarefa muito simples. Logo vamos usar Python para resolver isso numericamente. Para facilitar, vamos reescrever a Equação 17 como:

\[\begin{equation} \tag{17'} \beta R \left[ (1 - p) \left(\dfrac{Y_2}{1 - p} + RS^* \right)^{-\gamma} + p(RS^*)^{-\gamma} \right] - (Y_1 - S^*)^{-\gamma} = 0 \end{equation}\]

O que devemos fazer então é achar o \(S^*\) que zera essa equação.

O primeiro passo para solucionar o problema é importar a bibliotecas que vamos utilizar.

import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize
import time
import pandas as pd

Feito isso, vamos criar uma função para a Equação 17’. Essa função vai receber como argumento s e gamma. Os demais argumentos dados na questão 3 da lista vou colocá-los dentro da função.

def poup_prec(s, gamma):    
    y1 = 1
    y2 = 0.5
    beta = 0.9
    R = 1.1
    p = 0.1

    val = beta*R*( (1-p) * ( (y2**2)/(1-p) + R*s )**(-gamma) + p*(R*s)**(-gamma) ) - (y1 - s)**(-gamma)
    return val 

Agora vamos criar uma sequência que vai de 1 a 50, essa sequência será nosso gamma. Também vou criar uma lista vazia chamada poup1, essa lista será preenchida com os valores de \(S^*\) calculados pelo solver do scipy.

seq = np.arange(1, 50)
poup1 = []

Agora está tudo pronto e podemos utilizar a função optimize.root para calcular a poupança precaucional. Essa função irá encontrar o valor de \(S\) que zera a Equação 17’ dado os parâmetros que definimos. Uma vez que queremos calcular isso para diferentes valores de gamma vamos utilizar o loop for. Nosso algoritmo armazenará o resultado no objeto sol.x que será guardado na lista de dicionários poup1 que criamos acima. Também vamos guardar nessa lista de dicionários os diferentes valores de gamma e ao final vamos transformá-la em um dataframe. Vou mostrar as 8 primeiras linhas disso.

for gamma in seq:
    sol = optimize.root(poup_prec, [0.4], args = (gamma), method='hybr')

    poup1.append(
        { 
          'poup': sol.x.item(),
          'gamma': gamma
         }
        )

poup1 = pd.DataFrame(poup1)

poup1.head(8)
##        poup  gamma
## 0  0.361870      1
## 1  0.368745      2
## 2  0.375534      3
## 3  0.382732      4
## 4  0.390113      5
## 5  0.397351      6
## 6  0.404177      7
## 7  0.410426      8

Por fim, vamos fazer um gráfico com esses resultados. Sabemos que o parâmetro \(\gamma\) mede o grau de aversão ao risco relativo na função de utilidade. Note no gráfico que a medida que o risco aumenta a poupança precaucional também aumenta.

fig, ax = plt.subplots(1, 1, figsize = (12, 8))

ax.tick_params(axis = 'both', which='major', labelsize = 20)
ax.plot(poup1.gamma, poup1.poup, marker = 'o', color = 'darkred', markersize = 10)
ax.set_xlabel(r"$\gamma$", fontsize = 20)
ax.set_ylabel("Poupança precaucional", fontsize = 20)

Vamos ver o que acontece com a poupança precaucional quando variamos p. O exercício é muito similar ao que fizemos com gamma. Então criamos a função poup_prec2 que tem como entrada s e p.

def poup_prec2(s, p):    
    y1 = 1
    y2 = 0.5
    beta = 0.9 
    R = 1.1
    gamma = 2
    
    val = beta*R*( (1-p) * ( (y2**2)/(1-p) + R*s )**(-gamma) + p*(R*s)**(-gamma) ) - (y1 - s)**(-gamma)
    return val 

Análogo ao problema anterior, vamos criar uma sequência que vai de 0 a 0.5 e uma lista vazia.


seq2 = np.arange(0, 0.5, 0.05)
poup2 = []

Então executamos o processo de otimização.

for p in seq2:
    sol = optimize.root(poup_prec2, [0.25], args = (p), method='hybr')

    poup2.append(
        { 'poup': sol.x.item(),
          'p': p
         }
        )


poup2 = pd.DataFrame(poup2)
poup2.head(8)
##        poup     p
## 0  0.355605  0.00
## 1  0.362342  0.05
## 2  0.368745  0.10
## 3  0.374893  0.15
## 4  0.380847  0.20
## 5  0.386656  0.25
## 6  0.392360  0.30
## 7  0.397993  0.35

Por fim, podemos ver o gráfico da poupança precaucional quando p varia. Como esperado, a poupança precaucional é positiva e quanto maior o risco de desemprego, maior é este acréscimo na poupança em relação ao caso sem risco de desemprego (p = 0).


fig, ax = plt.subplots(1, 1, figsize = (12, 8))
ax.tick_params(axis = 'both', which='major', labelsize = 20)
ax.plot(poup2.p, poup2.poup, marker = 'o', color = 'darkred', markersize=10)
ax.set_xlabel(r"$p$", fontsize = 20)
ax.set_ylabel("Poupança precaucional", fontsize = 20)