Como é calculada a volatilidade implícita
Entenda como um solucionador extrai a volatilidade implícita do preço de uma opção por iteração, com Python, Black-Scholes e os principais erros.
A volatilidade implícita é calculada por iteração, não por uma fórmula direta. Não existe uma expressão fechada que converta o preço de mercado de uma opção novamente em um número de volatilidade. Por isso, um solucionador estima uma volatilidade, calcula o preço da opção com Black-Scholes, compara o preço do modelo com a cotação e repete o processo até que os dois coincidam ao centavo. A seguir, apresentamos o método completo: a função de precificação, o ciclo de busca em Python usando apenas a biblioteca padrão e as razões pelas quais dois fornecedores publicam números diferentes para o mesmo contrato.
Por que a volatilidade implícita não tem uma fórmula fechada
O Black-Scholes funciona em uma única direção. Informe o preço à vista, o preço de exercício, o prazo até o vencimento, a taxa de juros e a volatilidade, e o modelo retorna um preço teórico. Cinco dessas seis variáveis são observáveis. A volatilidade não é. Ela é uma hipótese sobre quanto a ação vai variar entre o momento atual e o vencimento.
Os traders invertem o problema. O preço está na tela, e a volatilidade é a incógnita. A volatilidade implícita é o valor de volatilidade que faz o preço do Black-Scholes ser igual ao preço de mercado da opção. Sigma, o termo de volatilidade, aparece dentro da função de distribuição normal duas vezes, em d1 e d2, e nenhuma transformação algébrica consegue isolá-lo. A álgebra termina aí. Entra em cena a busca numérica. O que a volatilidade implícita mede explica a interpretação; esta página trata do mecanismo.
Duas propriedades do modelo facilitam a busca. O preço de uma call sobe sempre que a volatilidade aumenta, sem exceções, e varia de forma contínua. Uma variável que só aumenta pode ser delimitada ao estreitar um intervalo em torno dela.
O solucionador é executado uma vez por contrato
O resultado é um número por contrato, não um número por ação. Contratos sobre a mesma ação, na mesma janela de vencimento, podem chegar a resultados diferentes. Esses cálculos por contrato aparecem para o leitor como uma coluna na tela da corretora, com um valor por strike: a leitura de uma cadeia de opções coluna a coluna explica o que aparece ao lado. Todas as opções da Apple (AAPL) com 20 a 45 dias restantes até o vencimento e negociadas em 30 de junho de 2026, agrupadas pelo strike como fração do preço da ação:
| strike vs spot | vol implícita (%) | nº de contratos |
|---|---|---|
| 0.80-0.90 | 35.5 | 24 |
| 0.90-0.95 | 29 | 10 |
| 0.95-1.00 | 28.1 | 18 |
| 1.00-1.05 | 27.4 | 18 |
| 1.05-1.10 | 27.4 | 16 |
| 1.10-1.20 | 27.3 | 20 |
O SQL exato por trás de cada número
WITH toFloat64(strike_price) / toFloat64(underlying_close) AS moneyness
SELECT multiIf(moneyness < 0.90, '0.80-0.90',
moneyness < 0.95, '0.90-0.95',
moneyness < 1.00, '0.95-1.00',
moneyness < 1.05, '1.00-1.05',
moneyness < 1.10, '1.05-1.10',
'1.10-1.20') AS strike_vs_spot,
round(100 * avg(toFloat64(implied_volatility)), 1) AS implied_vol_pct,
count() AS contract_count
FROM global_markets.options_greeks
WHERE underlying_symbol = 'AAPL'
AND date = toDate('2026-06-30')
AND days_to_expiry BETWEEN 20 AND 45
AND iv_converged = 1
AND volume > 0
AND moneyness BETWEEN 0.80 AND 1.20
GROUP BY strike_vs_spot
ORDER BY min(moneyness)Subindo pela escala de strikes, a zona 0.80-0.90 resultou em 35.5%, a zona 0.95-1.00 em 28.1% e a zona 1.10-1.20 em 27.3%. Uma empresa, uma sessão, 6 respostas. A curvatura tem um nome: volatility skew. Uma única volatilidade por ação não consegue representá-la.
O preço Black-Scholes que o solver precisa igualar
S é o preço da ação, K é o preço de exercício, T é o prazo até o vencimento em anos, r é a taxa livre de risco e N() é a distribuição normal acumulada padrão, ou seja, a probabilidade de uma realização normal padrão ficar abaixo de determinado ponto. O Python oferece essa última função em math.erf, portanto o próprio interpretador é suficiente.
apt-get update && apt-get install -y python3
Em uma máquina na qual você não é root, acrescente sudo ao início dos dois comandos. Depois, salve o conteúdo a seguir como iv.py:
import math
def norm_cdf(x):
return 0.5 * (1.0 + math.erf(x / math.sqrt(2.0)))
def bs_call(S, K, T, r, sigma):
if T <= 0.0 or sigma <= 0.0:
return max(S - K, 0.0)
d1 = (math.log(S / K) + (r + 0.5 * sigma * sigma) * T) / (sigma * math.sqrt(T))
d2 = d1 - sigma * math.sqrt(T)
return S * norm_cdf(d1) - K * math.exp(-r * T) * norm_cdf(d2)
Esse é o modelo forward completo. Informe uma volatilidade e obtenha um preço.
Como a volatilidade implícita é calculada, passo a passo
O método da bisseção é o primeiro que se deve aprender. Ele não diverge e não exige cálculo diferencial.
- Delimite a resposta entre 0,01 (1% ao ano) e 5,0 (500%). Toda opção negociada fica dentro desse intervalo.
- Calcule o preço da opção no ponto médio do intervalo.
- Se o preço do modelo ficar acima da cotação de mercado, a estimativa foi alta demais: reduza o limite superior do intervalo até o ponto médio. Se ficar abaixo, eleve o limite inferior.
- Pare quando o preço do modelo ficar a menos de um centavo da cotação.
def implied_vol(price, S, K, T, r, lo=0.01, hi=5.0, tol=0.01):
for _ in range(100):
mid = 0.5 * (lo + hi)
diff = bs_call(S, K, T, r, mid) - price
if abs(diff) < tol:
return mid
if diff > 0.0:
hi = mid
else:
lo = mid
return 0.5 * (lo + hi)
# $100 stock, $100 strike, three months, 4% rates, $5.00 on the screen
print(round(implied_vol(5.00, 100.0, 100.0, 0.25, 0.04), 4))
Execute python3 iv.py. O resultado é aproximadamente 0,226, o que corresponde a uma volatilidade implícita próxima de 22,6% ao ano para essa cotação hipotética. A cada iteração, o intervalo cai pela metade. Um intervalo com amplitude de 4,99, dividido pela metade vinte vezes, fica menor que 0,00001. Por isso, o limite de 100 iterações nunca é atingido.
Por que Newton-Raphson converge mais rápido e onde falha
A bisseção descarta informações que o modelo já contém. Vega é a variação do preço da opção por unidade de volatilidade, e o modelo Black-Scholes fornece esse valor em forma fechada. O método de Newton-Raphson trata a vega como uma inclinação: mede o erro de precificação, divide-o pela vega e ajusta a estimativa nessa proporção.
def bs_vega(S, K, T, r, sigma):
d1 = (math.log(S / K) + (r + 0.5 * sigma * sigma) * T) / (sigma * math.sqrt(T))
return S * math.sqrt(T) * math.exp(-0.5 * d1 * d1) / math.sqrt(2.0 * math.pi)
def implied_vol_newton(price, S, K, T, r, sigma=0.5):
for _ in range(20):
v = bs_vega(S, K, T, r, sigma)
if v < 1e-8:
return None # no slope left, hand the job back to bisection
step = (bs_call(S, K, T, r, sigma) - price) / v
sigma -= step
if sigma <= 0.0:
return None # the step overshot into nonsense
if abs(step) < 1e-6:
return sigma
return None
Nas opções at-the-money, isso leva a três ou quatro iterações, contra cerca de uma dúzia no método da bisseção. A falha está no denominador: a vega diminui à medida que o strike se afasta do preço da ação. Os mesmos contratos de AAPL, com a vega média de cada zona apresentada como percentual da leitura at-the-money:
| strike vs spot | vega como % do ATM | nº de contratos |
|---|---|---|
| 0.80-0.90 | 33.1 | 24 |
| 0.90-0.95 | 62.4 | 10 |
| 0.95-1.00 | 89.8 | 18 |
| 1.00-1.05 | 98.5 | 18 |
| 1.05-1.10 | 73.6 | 16 |
| 1.10-1.20 | 31.6 | 20 |
O SQL exato por trás de cada número
WITH toFloat64(strike_price) / toFloat64(underlying_close) AS moneyness,
(
SELECT avg(toFloat64(vega))
FROM global_markets.options_greeks
WHERE underlying_symbol = 'AAPL'
AND date = toDate('2026-06-30')
AND days_to_expiry BETWEEN 20 AND 45
AND iv_converged = 1
AND volume > 0
AND abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) < 0.025
) AS atm_vega
SELECT multiIf(moneyness < 0.90, '0.80-0.90',
moneyness < 0.95, '0.90-0.95',
moneyness < 1.00, '0.95-1.00',
moneyness < 1.05, '1.00-1.05',
moneyness < 1.10, '1.05-1.10',
'1.10-1.20') AS strike_vs_spot,
round(100 * avg(toFloat64(vega)) / atm_vega, 1) AS vega_pct_of_atm,
count() AS contract_count
FROM global_markets.options_greeks
WHERE underlying_symbol = 'AAPL'
AND date = toDate('2026-06-30')
AND days_to_expiry BETWEEN 20 AND 45
AND iv_converged = 1
AND volume > 0
AND moneyness BETWEEN 0.80 AND 1.20
GROUP BY strike_vs_spot
ORDER BY min(moneyness)Nas pontas da curva, a sensibilidade representa apenas uma fração da vega: 33.1% da vega at-the-money na zona 0.80-0.90 e 31.6% na zona 1.10-1.20. Dividir um erro de precificação por um número tão pequeno produz um passo enorme, que pode levar a estimativa para abaixo de zero, onde o modelo já não tem informação útil. Os solvers usados em produção combinam os dois métodos: primeiro delimitam o intervalo e depois refinam a estimativa com Newton. Vega explica o próprio grego.
Por que duas fontes informam volatilidades implícitas diferentes
O modelo é público e a aritmética está definida. Portanto, a divergência está nos dados de entrada.
- Mid versus último negócio. O solver precisa de um preço. Um contrato cotado a $2,00 de bid e $2,20 de offer tem midpoint de $2,10, enquanto o último negócio pode ter sido a $2,02, noventa minutos antes. Em um contrato assim, dez centavos no preço valem mais do que um ponto de volatilidade.
- Dividendos e carry. A função acima precifica uma call europeia sobre uma ação que não paga dividendos. Um dividendo antes do vencimento reduz o preço a termo, e cada mesa aplica seu próprio ajuste e sua própria taxa.
- Exercício antecipado em opções americanas. As opções de ações individuais dos EUA podem ser exercidas em qualquer dia, e esse direito tem valor, mas a fórmula europeia não tem como incorporá-lo. Um solver que o ignora transfere a diferença para a volatilidade. Árvores binomiais precificam diretamente o direito de exercício.
- Cotações defasadas. Um strike negociado pela última vez na terça-feira ainda pode exibir uma cotação, e o solver trata como verdadeira qualquer informação que receba.
A convergência torna os dois últimos pontos visíveis. O painel abaixo considera oito ações conhecidas em 30 de junho de 2026, conta os contratos negociados com 20 a 45 dias restantes e informa tanto a volatilidade at the money quanto a parcela de contratos em que o cálculo convergiu:
| ticker | IV ATM (%) | resolvido (%) | nº de contratos |
|---|---|---|---|
| TSLA | 47.7 | 97.8 | 364 |
| MSFT | 39.6 | 95.5 | 221 |
| AMZN | 38.7 | 96.3 | 163 |
| NVDA | 38.2 | 93.8 | 209 |
| JNJ | 28.3 | 100 | 53 |
| AAPL | 27.8 | 89.6 | 154 |
| KO | 20.9 | 100 | 79 |
| SPY | 14.4 | 98.5 | 739 |
O SQL exato por trás de cada número
WITH abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) AS distance_from_spot
SELECT underlying_symbol AS symbol,
round(100 * avgIf(toFloat64(implied_volatility), iv_converged = 1 AND distance_from_spot < 0.05), 1) AS atm_iv_pct,
round(100 * countIf(iv_converged = 1) / count(), 1) AS solved_pct,
count() AS contract_count
FROM global_markets.options_greeks
WHERE date = toDate('2026-06-30')
AND underlying_symbol IN ('AAPL', 'MSFT', 'NVDA', 'AMZN', 'TSLA', 'SPY', 'KO', 'JNJ')
AND days_to_expiry BETWEEN 20 AND 45
AND volume > 0
GROUP BY symbol
HAVING countIf(iv_converged = 1 AND distance_from_spot < 0.05) > 0
ORDER BY atm_iv_pct DESCTSLA apresentou a maior leitura at the money entre os 8 nomes, em 47.7%, contra 14.4% para SPY, na última posição. Na cadeia de TSLA, 97.8% dos contratos negociados produziram uma resposta convergente. Os demais correspondem a strikes em que o preço fornecido ao solver está fora do intervalo que qualquer volatilidade consegue reproduzir, a uma cotação abaixo do valor intrínseco ou a um mercado cruzado. Saber se um número assim é alto é uma questão separada: 30% de IV é alto aborda esse tema, e o movimento esperado o converte em uma faixa em dólares.
O mesmo contrato, recalculado a cada sessão
Nada sobre a volatilidade implícita fica armazenado. Ela é recalculada a partir do preço exibido na tela. Abaixo está o contrato de AAPL com maior volume de negociação, com vencimento em 17 de julho de 2026, acompanhado de 1º de junho até o vencimento. O strike não mudou, e o vencimento também não:
| date | vol implícita (%) | dias até o vencimento |
|---|---|---|
| 2026-06-01 | 25.1 | 46 |
| 2026-06-02 | 24.9 | 45 |
| 2026-06-03 | 15.5 | 44 |
| 2026-06-04 | 26.1 | 43 |
| 2026-06-05 | 25.7 | 42 |
| 2026-06-08 | 25.6 | 39 |
| 2026-06-09 | 23.4 | 38 |
| 2026-06-10 | 25.9 | 37 |
| 2026-06-11 | 22.5 | 36 |
| 2026-06-12 | 21.5 | 35 |
| 2026-06-15 | 22.1 | 32 |
| 2026-06-16 | 21.9 | 31 |
| 2026-06-17 | 20.9 | 30 |
| 2026-06-18 | 23 | 29 |
| 2026-06-22 | 25.1 | 25 |
| 2026-06-23 | 22.8 | 24 |
| 2026-06-24 | 26.6 | 23 |
| 2026-06-25 | 26.3 | 22 |
| 2026-06-26 | 25.3 | 21 |
| 2026-06-29 | 25.8 | 18 |
O SQL exato por trás de cada número
WITH (
SELECT ticker
FROM global_markets.options_greeks
WHERE underlying_symbol = 'AAPL'
AND date = toDate('2026-06-30')
AND expiration_date = toDate('2026-07-17')
AND iv_converged = 1
AND volume > 0
ORDER BY volume DESC
LIMIT 1
) AS pinned_contract
SELECT date,
round(100 * avg(toFloat64(implied_volatility)), 1) AS implied_vol_pct,
round(avg(days_to_expiry)) AS days_to_expiry
FROM global_markets.options_greeks
WHERE ticker = pinned_contract
AND date BETWEEN toDate('2026-06-01') AND toDate('2026-07-17')
AND iv_converged = 1
AND volume > 0
GROUP BY date
ORDER BY dateAo longo de 29 sessões, o valor calculado abriu em 25.1%, com 46 dias até o vencimento, e terminou em 26.6%, com 4 dias restantes. Cada ponto dessa linha corresponde a uma execução do loop acima usando a cotação daquela sessão. Nossas páginas por ticker publicam o mesmo cálculo: volatilidade implícita de AAPL o executa diariamente para toda a cadeia de opções, permitindo que o leitor reproduza qualquer valor apresentado ali com o código desta página.
Perguntas frequentes sobre o cálculo da volatilidade implícita
Existe uma fórmula para a volatilidade implícita?
Não. O modelo Black-Scholes relaciona a volatilidade ao preço, mas essa relação não tem uma inversa elementar, pois sigma aparece duas vezes dentro da distribuição normal. Todo valor de volatilidade implícita que você encontra, aqui ou em qualquer outro lugar, é obtido por um algoritmo iterativo.
Quantas iterações o cálculo exige?
Cada passagem pelo método da bisseção reduz o intervalo pela metade. Assim, um intervalo de 0,01 a 5,0 fica abaixo de 0,00001 em vinte passagens. Para ajustar uma cotação ao centavo mais próximo, normalmente são necessárias cerca de doze passagens. O método de Newton-Raphson chega ao resultado em três ou quatro iterações quando a opção está próxima do dinheiro, mas pode apresentar comportamento instável quando o vega é pequeno.
Por que meu broker e um provedor de dados mostram volatilidades implícitas diferentes?
Eles forneceram entradas diferentes ao algoritmo. As diferenças mais comuns são entre a cotação média e o último negócio, a taxa de juros e a premissa de dividendos, além do tratamento, ou não, do exercício antecipado de opções americanas pelo modelo. Em um strike com pouca liquidez, uma cotação desatualizada, sozinha, pode alterar o resultado em vários pontos percentuais.
Calls e puts com o mesmo strike apresentam a mesma volatilidade implícita?
Em teoria, sim. A paridade put/call relaciona as duas opções ao mesmo strike e vencimento. Na prática, as duas cotações são formadas de maneira independente. Por isso, os valores calculados diferem um pouco, o que também explica por que as médias de toda a cadeia variam entre os provedores.
Posso calcular a volatilidade implícita sem dados de mercado?
Sim, para uma cotação hipotética. O código acima usa um preço, um strike, o preço do ativo à vista, o tempo até o vencimento e uma taxa, todos inseridos manualmente. Reproduzir o valor de um provedor em tempo real é a parte mais difícil. Para isso, é preciso usar as mesmas entradas adotadas pelo provedor.
Cada painel aqui armazena o SQL usado por trás dele. Abra um painel e execute o mesmo cálculo em uma cadeia em tempo real no terminal Strasmore.