Usar o que já se sabe
Ao simular um call você também simula o preço da ação no vencimento S_T, cuja média verdadeira S0 * exp(r * T) você conhece exatamente. Na sua amostra a média de S_T saiu um pouco errada, digamos alta demais. Como o pagamento do call e S_T se movem juntos, a média amostral do call provavelmente também está alta demais. Uma variável de controle aproveita isso: subtrai da estimativa do que você quer um múltiplo do erro observado na quantidade que você conhece.
import numpy as np
rng = np.random.default_rng(1)
z = rng.standard_normal(2000)
s_t = 100.0 * np.exp((0.05 - 0.5 * 0.2 ** 2) + 0.2 * z) # terminal prices
call = np.maximum(s_t - 100.0, 0.0) # the payoff we want
known = 100.0 * np.exp(0.05) # E[S_T], exactly
print(round(float(s_t.mean()), 3), round(known, 3)) # the sample mean of S_T vs its true mean
print(round(float(s_t.mean() - known), 3)) # the observed error of the controlO melhor múltiplo
Que parte do erro do controle se deve subtrair? O múltiplo b que minimiza a variância de payoff - b * control é b = cov(payoff, control) / var(control), exatamente a inclinação da regressão do pagamento sobre o controle (as mesmas somas do beta do tópico CAPM). A estimativa controlada é mean(payoff) - b * (mean(control) - known_mean). Ela é não viesada, pois o termo subtraído tem esperança zero.
import numpy as np
def control_coefficient(payoff, control):
dev = control - control.mean()
return float(np.sum(dev * (payoff - payoff.mean())) / np.sum(dev ** 2))
rng = np.random.default_rng(1)
z = rng.standard_normal(2000)
s_t = 100.0 * np.exp((0.05 - 0.5 * 0.2 ** 2) + 0.2 * z)
call = np.maximum(s_t - 100.0, 0.0)
known = 100.0 * np.exp(0.05)
b = control_coefficient(call, s_t)
controlled = call.mean() - b * (s_t.mean() - known)
print(round(b, 4), round(float(call.mean()), 4), round(float(controlled), 4)) # the plain mean and the corrected one# A payoff that is exactly proportional to the control is estimated without any error
import numpy as np
x = np.random.default_rng(2).standard_normal(50) + 5.0 # the control, known mean 5.0
y = 2.0 * x # the payoff
dev = x - x.mean()
b = np.sum(dev * (y - y.mean())) / np.sum(dev ** 2)
print(round(float(b), 6), round(float(y.mean() - b * (x.mean() - 5.0)), 6)) # 2.0 and exactly 10.0Quanto erro se economiza
As amostras ajustadas payoff - b * control carregam o ruído, então o erro padrão da estimativa controlada é seu desvio-padrão (ddof=1) dividido por sqrt(n). Com correlação rho entre pagamento e controle, a variância cai por um fator 1 - rho^2: uma correlação de 0,9 elimina 81%, e 0,99 elimina 98%. O controle não custa simulação extra, só algumas linhas a mais.
import numpy as np
def control_variate_error(payoff, control):
dev = control - control.mean()
b = np.sum(dev * (payoff - payoff.mean())) / np.sum(dev ** 2)
return float((payoff - b * control).std(ddof=1) / np.sqrt(len(payoff)))
rng = np.random.default_rng(1)
z = rng.standard_normal(20000)
s_t = 100.0 * np.exp((0.05 - 0.5 * 0.2 ** 2) + 0.2 * z)
for strike in (80.0, 100.0, 120.0):
call = np.maximum(s_t - strike, 0.0)
plain = float(call.std(ddof=1) / np.sqrt(len(call)))
print(strike, round(plain, 4), round(control_variate_error(call, s_t), 4), round(plain / control_variate_error(call, s_t), 2))b fica perto de 0 e nada se ganha) e sua média exata deve ser conhecida (senão a correção é um palpite). Bons controles para a média aritmética de uma asiática são a média geométrica, cujo preço tem fórmula, ou o próprio preço terminal. Podem-se usar vários controles ao mesmo tempo, e os coeficientes vêm então de uma regressão múltipla.- Uma variável de controle é uma quantidade simulada de média conhecida; subtrai-se da estimativa um múltiplo de seu erro observado:
mean(Y) - b * (mean(X) - E[X]). - O melhor múltiplo é a inclinação da regressão
b = cov(Y, X) / var(X); o erro é o desvio-padrão deY - b * Xsobresqrt(n). - A variância cai por
1 - rho^2; um bom controle é muito correlacionado com o pagamento e tem média exatamente conhecida, e não custa simulação extra.
A seguir: os pipelines do scikit-learn para retornos, ajustar e avaliar modelos preditivos com dados de retornos.
Lab: o que é avaliado
- Escolher o múltiplo certo com
control_coefficient25 pts - Corrigir a estimativa com
control_variate_estimate25 pts - Encolher a barra de erro com
control_variate_error25 pts - Contar o ganho com
error_reduction25 pts