Como calcular a volatilidade implícita
Veja como um solver calcula a volatilidade implícita por iteração a partir do preço da opçã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 solver estima uma volatilidade, calcula o preço da opção com Black-Scholes, compara esse preço teórico 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 loop 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 se movimentar entre agora 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 input de volatilidade que faz o preço calculado pelo 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 o isola. A álgebra para nesse ponto. Entra em cena a busca numérica. O que a volatilidade implícita mede explica a interpretação; esta página explica o mecanismo.
Duas propriedades do modelo tornam a busca simples. O preço teórico de uma call sobe sempre que a volatilidade aumenta, sem exceções, e essa variação é contínua. Uma grandeza que só aumenta pode ser delimitada estreitando um intervalo em torno dela.
O resolvedor é executado uma vez por contrato
A saída é um número por contrato, não um número por ação. Além disso, os contratos sobre a mesma ação e dentro da mesma janela de vencimento apresentam resultados diferentes entre si. Todas as opções da Apple (AAPL) com 20 a 45 dias até o vencimento que foram negociadas em 30 de junho de 2026, agrupadas pelo strike como fração do preço da ação:
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)Ao percorrer a estrutura de strikes, a zona 0.80-0.90 foi resolvida em 35.5%, a zona 0.95-1.00 em 28.1% e a zona 1.10-1.20 em 27.3%. Uma empresa, um pregão, 6 respostas. A curvatura dessa relação tem um nome: o skew de volatilidade. Uma única volatilidade por ação não consegue representá-la.
O preço de Black-Scholes que o solver precisa igualar
S é o preço da ação, K é o preço de exercício, T é o tempo 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 disponibiliza essa última função em math.erf, portanto o próprio interpretador é suficiente.
apt-get update && apt-get install -y python3
Use sudo como prefixo nos dois comandos em uma máquina na qual você não tenha privilégios de root. Em seguida, salve o código abaixo 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 a termo completo. Informe uma volatilidade e obtenha um preço.
Como calcular a volatilidade implícita, passo a passo
A bisseção é o primeiro método que se deve aprender. Ela 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 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)
# ação a $100, strike de $100, três meses, juros de 4%, $5,00 na tela
print(round(implied_vol(5.00, 100.0, 100.0, 0.25, 0.04), 4))
Execute python3 iv.py. O resultado é aproximadamente 0,226, ou seja, uma volatilidade implícita próxima de 22,6% ao ano para essa cotação hipotética. A cada iteração, o intervalo é reduzido pela metade. Um intervalo de 4,99 reduzido pela metade vinte vezes fica menor que 0,00001, portanto o limite de 100 iterações nunca é atingido.
Por que o método de 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 de 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 esse erro 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 # não há mais inclinação; devolve o cálculo à bisseção
step = (bs_call(S, K, T, r, sigma) - price) / v
sigma -= step
if sigma <= 0.0:
return None # o passo ultrapassou o limite e gerou um valor sem sentido
if abs(step) < 1e-6:
return sigma
return None
Perto do preço de exercício, o método chega ao resultado em três ou quatro iterações, contra cerca de uma dúzia na bisseção. O problema está no denominador: a vega diminui à medida que o strike se afasta do preço da ação. Nos mesmos contratos de AAPL, a vega média de cada zona aparece como percentual da leitura at the money:
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 uma fração da vega at the money: 33.1% 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 abaixo de zero, onde o modelo já não tem informação útil. Solvers de produção combinam os dois métodos: primeiro delimitam o intervalo e depois refinam a solução com Newton. Vega explica o próprio grego.
Por que duas fontes reportam volatilidades implícitas diferentes
O modelo é público e a aritmética está definida. A divergência está nos dados de entrada.
- Mid versus último negócio. O solver precisa de um único preço. Um contrato cotado a US$ 2,00 na compra e US$ 2,20 na venda tem midpoint de US$ 2,10, enquanto o último negócio pode ter sido a US$ 2,02, 90 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 calcula o preço de 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 nos EUA podem ser exercidas em qualquer dia, e esse direito tem valor que a fórmula europeia não consegue incorporar. Um solver que o ignora transfere a diferença para a volatilidade. Árvores binomiais calculam diretamente o valor do 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:
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 são strikes em que o preço fornecido ao solver está fora do intervalo que qualquer volatilidade conseguiria reproduzir, uma cotação abaixo do valor intrínseco ou um mercado crossed. Saber se um número assim é alto é outra questão: 30% de IV é alto aborda esse ponto, e o movimento esperado o converte em uma faixa em dólares.
O mesmo contrato, recalculado em cada sessão
Nada sobre a volatilidade implícita é armazenado. Ela é recalculada a partir do preço que aparece no ecrã. Abaixo está o contrato de AAPL com maior volume de negociação, com vencimento em 17 de julho de 2026, acompanhado desde 1 de junho até ao vencimento. O strike e o vencimento nunca mudaram:
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, a leitura calculada abriu em 25.1%, com 46 dias até ao vencimento, e terminou em 26.6%, com 4 dias restantes. Cada ponto nessa linha corresponde a uma execução do loop acima com a cotação daquela sessão. As nossas páginas por ticker publicam o mesmo cálculo: volatilidade implícita de AAPL é executado diariamente em toda a cadeia, para que o leitor possa reproduzir qualquer valor ali apresentado 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, porque sigma aparece duas vezes dentro da distribuição normal. Todo número de volatilidade implícita que você encontra, aqui ou em qualquer outro lugar, é produzido por um solucionador iterativo.
Quantas iterações o cálculo exige?
Cada etapa da bisseção reduz o intervalo pela metade. Assim, um intervalo de 0,01 a 5,0 cai para menos de 0,00001 em twenty etapas. Para igualar uma cotação ao centavo mais próximo, normalmente são necessárias cerca de uma dúzia de etapas. O método de Newton-Raphson chega ao resultado em três ou quatro etapas quando está próximo do preço de exercício, mas pode apresentar problemas quando o vega é baixo.
Por que meu broker e um fornecedor de dados mostram volatilidades implícitas diferentes?
Eles forneceram entradas diferentes ao solucionador. 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 de o modelo considerar ou não o exercício antecipado de opções americanas. Em um strike com pouca liquidez, uma cotação desatualizada, sozinha, pode alterar o resultado em vários pontos.
Calls e puts com o mesmo strike dão a mesma volatilidade implícita?
Em teoria, sim. A paridade put-call as relaciona no mesmo strike e vencimento. Na prática, as duas cotações são formadas de maneira independente, e os números calculados diferem um pouco. Esse é mais um motivo para as médias de toda a cadeia variarem entre fornecedores.
Posso calcular a volatilidade implícita sem dados de mercado?
Sim, para uma cotação hipotética. O código acima recebe um preço, um strike, o preço do ativo à vista, o prazo até o vencimento e uma taxa, todos inseridos manualmente. Reproduzir o número de um fornecedor em tempo real é a parte mais difícil: isso exige usar as mesmas entradas adotadas pelo fornecedor.
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.