Um número cujo valor ainda não se conhece
Uma variável aleatória é uma grandeza cujo valor depende do acaso: o lançamento de um dado, o retorno de amanhã, o preço de uma ação no vencimento. Uma variável aleatória discreta assume uma lista de valores possíveis, cada um com uma probabilidade. Os valores e as probabilidades juntos são sua distribuição. As probabilidades nunca são negativas e somam 1. Em Python são simplesmente duas listas de mesmo comprimento, values e probs. Um dado justo é values = [1, 2, 3, 4, 5, 6] com probs = [1/6] * 6.
import math
values = [1, 2, 3, 4, 5, 6]
probs = [1 / 6] * 6
# A valid distribution: no negatives, and the probabilities add up to 1
print(all(p >= 0 for p in probs)) # True
print(math.isclose(sum(probs), 1.0)) # True (compare floats with isclose)
# A stock tomorrow: down 5%, up 2% or up 8%
returns = [-0.05, 0.02, 0.08]
chances = [0.2, 0.5, 0.3]
print(math.isclose(sum(chances), 1.0)) # TrueA esperança: a média ponderada pelas probabilidades
O valor esperado E[X] é a média que você obteria em muitas repetições: multiplique cada valor pela sua probabilidade e some, sum(v * p). Um dado tem E[X] = 3.5, um número que ele nunca mostra, e tudo bem: é uma média de longo prazo, não a previsão de um resultado. A esperança é linear: E[a*X + b] = a*E[X] + b. A esperança de uma função E[g(X)] aplica antes g a cada valor: sum(g(v) * p). Cuidado: em geral E[g(X)] não é g(E[X]). O payoff de uma opção max(S - K, 0) é o caso clássico.
def expected_value(values, probs):
return sum(v * p for v, p in zip(values, probs))
die = [1, 2, 3, 4, 5, 6]
fair = [1 / 6] * 6
print(round(expected_value(die, fair), 4)) # 3.5
# E[g(X)]: apply g to each value first. Call payoff with strike 100:
prices = [90, 100, 110, 120]
chances = [0.1, 0.4, 0.3, 0.2]
mean_price = expected_value(prices, chances)
print(mean_price) # 106.0
print(expected_value([max(s - 100, 0) for s in prices], chances)) # 7.0 = E[max(S - K, 0)]
print(max(mean_price - 100, 0)) # 6.0 = max(E[S] - K, 0), not the sameA variância: qual a dispersão?
Dois investimentos podem ter o mesmo retorno esperado e riscos muito diferentes. A variância mede a dispersão em torno da média: Var(X) = E[(X - mu)^2], que também se calcula como E[X^2] - E[X]^2. O desvio padrão é sua raiz quadrada, nas mesmas unidades de X; para retornos é a volatilidade. Para o dado, Var = 35/12 = 2.9167. Ambos são construídos a partir de esperanças de funções de X, então uma expected_of(g, values, probs) bem escrita dá a média, o segundo momento e tudo o que vem depois.
def expected_value(values, probs):
return sum(v * p for v, p in zip(values, probs))
def expected_of(g, values, probs):
return expected_value([g(v) for v in values], probs)
def variance(values, probs):
mean = expected_of(lambda v: v, values, probs)
return expected_of(lambda v: v * v, values, probs) - mean ** 2
die, fair = [1, 2, 3, 4, 5, 6], [1 / 6] * 6
print(round(variance(die, fair), 4)) # 2.9167
returns, chances = [-0.05, 0.02, 0.08], [0.2, 0.5, 0.3]
print(round(expected_value(returns, chances), 4)) # 0.024
print(round(variance(returns, chances), 6)) # 0.002044Simulação e lei dos grandes números
Você também pode estimar uma esperança sorteando amostras. rng.choices(values, weights=probs, k=n) devolve n sorteios, e a média dos sorteios se aproxima de E[X] quando n cresce: a lei dos grandes números. É o coração da precificação Monte Carlo. Use seu próprio random.Random(seed) para que a execução seja repetível e não perturbe outro código. Com poucos sorteios a média é ruidosa; o erro só diminui como um sobre a raiz de n, então 100 vezes mais sorteios dão só 10 vezes mais precisão.
import random
die, fair = [1, 2, 3, 4, 5, 6], [1 / 6] * 6
def sample_mean(values, probs, n, seed):
rng = random.Random(seed) # private, repeatable generator
draws = rng.choices(values, weights=probs, k=n)
return sum(draws) / n
for n in (10, 1000, 100000):
print(n, round(sample_mean(die, fair, n, 1), 4))
# 10 3.1
# 1000 3.598
# 100000 3.5017 (closing in on 3.5)
print(sample_mean(die, fair, 1000, 1) == sample_mean(die, fair, 1000, 1)) # True: same seed, same answermath.isclose(sum(probs), 1.0). Gere ValueError em qualquer outro caso. Lembre-se também de que uma esperança é uma média de longo prazo: uma estratégia com esperança positiva pode perder dinheiro em um dia qualquer.- Uma distribuição é
valuesmaisprobs(sem negativos, soma 1);E[X] = sum(v * p). E[g(X)] = sum(g(v) * p), que não ég(E[X]);Var = E[X^2] - E[X]^2.- As médias amostrais convergem para
E[X](lei dos grandes números); use seu própriorandom.Random(seed).
A seguir: arrays NumPy e dtypes, os arrays rápidos e tipados sobre os quais o resto do curso é construído.
Lab: o que é avaliado
- Calcular a média dos resultados por suas probabilidades com
expected_value25 pts - Calcular a esperança de um payoff com
expected_of25 pts - Medir a dispersão com
variance25 pts - Estimar a esperança por simulação com
sample_mean25 pts