NumPy: Projeto — Simulação de Monte Carlo

Última atualização: 2026-08-26

1. Projeto: Simulação de Monte Carlo

(1) Cenário

Alice precisa avaliar o risco de portfólio — o Valor em Risco (VaR) não tem fórmula fechada. Os métodos tradicionais de variância-covariância assumem distribuições normais, subestimando severamente o risco de cauda. Ela usa simulação de Monte Carlo para modelar 100.000 caminhos de preços.

(1) O Método de Monte Carlo

Ideia central: use muitas amostras aleatórias para aproximar valores reais. Quando os problemas são complexos demais para soluções analíticas, a simulação é o único caminho.

PYTHON
import numpy as np

rng = np.random.default_rng(42)

N = 100_000
x = rng.random(N)
y = rng.random(N)
inside = (x**2 + y**2) <= 1.0
pi_est = 4 * inside.mean()

print(f"Estimativa de Pi: {pi_est:.6f}")
print(f"Pi real:          {np.pi:.6f}")
print(f"Erro:             {abs(pi_est - np.pi):.6f}")

(2) Estimando Pi

PYTHON
print("=== Estimativa de Pi por Monte Carlo ===\n")

for N in [1_000, 10_000, 100_000, 1_000_000]:
    x = rng.random(N)
    y = rng.random(N)
    inside = (x**2 + y**2) <= 1.0
    pi_est = 4 * inside.mean()
    error = abs(pi_est - np.pi)
    print(f"N={N:>9,d}  Pi≈{pi_est:.6f}  Erro={error:.6f}")

(3) Caminhada Aleatória

PYTHON
N = 1000
n_sim = 10_000

steps = rng.choice([-1, 1], size=(n_sim, N))
final_pos = steps.sum(axis=1)

print(f"Estatísticas da posição final ({n_sim} simulações):")
print(f"  Média: {final_pos.mean():.2f}  (teoria: 0)")
print(f"  Desvio: {final_pos.std():.2f}  (teoria: {np.sqrt(N):.2f})")
print(f"  Mín:  {final_pos.min()}")
print(f"  Máx:  {final_pos.max()}")

(4) Precificação de Opções

PYTHON
S0 = 100
K = 105
r = 0.05
sigma = 0.20
T = 1.0

for n_sim in [10_000, 100_000, 1_000_000]:
    z = rng.standard_normal(n_sim)
    ST = S0 * np.exp((r - 0.5 * sigma**2) * T + sigma * np.sqrt(T) * z)

    call_payoff = np.maximum(ST - K, 0)
    put_payoff = np.maximum(K - ST, 0)

    call_price = np.exp(-r * T) * call_payoff.mean()
    put_price = np.exp(-r * T) * put_payoff.mean()
    call_se = np.exp(-r * T) * call_payoff.std() / np.sqrt(n_sim)

    print(f"N={n_sim:>9,d}")
    print(f"  Call: {call_price:.4f} ± {1.96*call_se:.4f}")
    print(f"  Put:  {put_price:.4f}")

(5) Intervalos de Confiança Bootstrap

PYTHON
data = rng.exponential(scale=2.0, size=50)
n = len(data)
B = 10_000

idx = rng.integers(0, n, size=(B, n))
boot_samples = data[idx]
boot_means = boot_samples.mean(axis=1)

ci = np.percentile(boot_means, [2.5, 97.5])
print(f"IC 95% Bootstrap para a média: [{ci[0]:.3f}, {ci[1]:.3f}]")
print(f"Média amostral: {data.mean():.3f}")

▶ Exemplo: Estimando Pi com Monte Carlo (Dificuldade ⭐⭐)

PYTHON
import numpy as np

rng = np.random.default_rng(42)
N = 100_000
x = rng.random(N)
y = rng.random(N)
inside = (x**2 + y**2) <= 1.0
pi_est = 4 * inside.mean()
print(f"Pi estimado: {pi_est:.6f}")
print(f"Pi real:     {np.pi:.6f}")
print(f"Erro:        {abs(pi_est - np.pi):.6f}")

Output:

TEXT 📖 Somente leitura
Pi estimado: 3.141920
Pi real:     3.141593
Erro:        0.000327

▶ Exemplo: Simulando uma caminhada aleatória (Dificuldade ⭐⭐)

PYTHON
import numpy as np

rng = np.random.default_rng(42)
n_steps = 1000
n_simulations = 100

# Todas as caminhadas de uma vez usando vetorização
steps = rng.choice([-1, 1], size=(n_simulations, n_steps))
positions = np.cumsum(steps, axis=1)

final = positions[:, -1]
print(f"Posição final média: {final.mean():.2f}")
print(f"Desvio posição final:  {final.std():.2f}")
print(f"Mín: {final.min()}, Máx: {final.max()}")

Output:

TEXT 📖 Somente leitura
Posição final média: -0.80
Desvio posição final:  31.72
Mín: -78, Máx: 72

▶ Exemplo: Intervalos de confiança Bootstrap (Dificuldade ⭐⭐⭐)

PYTHON
import numpy as np

rng = np.random.default_rng(42)
data = rng.exponential(scale=2.0, size=50)

n = len(data)
B = 10_000
indices = rng.integers(0, n, size=(B, n))
boot_means = data[indices].mean(axis=1)

ci = np.percentile(boot_means, [2.5, 97.5])
print(f"Média amostral: {data.mean():.3f}")
print(f"IC 95%: [{ci[0]:.3f}, {ci[1]:.3f}]")
print(f"Largura do IC: {ci[1] - ci[0]:.3f}")

Output:

TEXT 📖 Somente leitura
Média amostral: 2.165
IC 95%: [1.738, 2.644]
Largura do IC: 0.906


❓ Perguntas Frequentes

P: Quantas simulações de Monte Carlo preciso? R: Erro ∝ 1/√N. 10.000 dá ~1% de erro, 1.000.000 dá ~0.1%. Precificação financeira tipicamente usa 1M, validação rápida 10K. Execute uma amostra pequena primeiro para estimar o erro padrão, depois escale.

P: Qual é a diferença entre VaR e CVaR? R: VaR (Valor em Risco) é o limite de perda no percentil α — "os piores 5% começam aqui." CVaR (VaR Condicional) é a perda média nos piores 5% — "quando as coisas dão errado, quão errado em média?" CVaR é sempre ≥ VaR.

P: Resultados de Monte Carlo são confiáveis? R: Duas ressalvas: (1) números pseudo-aleatórios são determinísticos — sementes diferentes dão resultados diferentes, sempre reporte intervalos de confiança; (2) as suposições do modelo importam — se sua suposição de GBM está errada, um milhão de simulações não vai te salvar.


📖 Resumo

Neste projeto você aplicou:


📝 Exercícios

  1. Básico (Dificuldade ⭐): Modifique a estimativa de Pi para usar 1.000.000 de pontos. Como o erro muda em comparação com 100.000?

  2. Intermediário (Dificuldade ⭐⭐): Implemente uma caminhada aleatória 2D. Cada passo move em uma de 4 direções (cima/baixo/esquerda/direita). Simule 10.000 caminhos de 1000 passos e compute a distância final média da origem.

  3. Desafio (Dificuldade ⭐⭐⭐): Precifique uma opção asiática (payoff depende do preço médio ao longo do caminho) usando Monte Carlo. Compare o preço com uma opção europeia com os mesmos parâmetros. Explique por que a opção asiática é mais barata.

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%