I have written before about what implied volatility is and how it comes out of the Black-Scholes formula. This post is the worked version: a real Bitcoin option, real numbers, and the short piece of Python I use to back the volatility out of the price. I had said earlier that I would do this for the VIX. A Bitcoin option is a better example, partly because the numbers are bigger and the point is easier to see, and partly because it is where most of the questions I get come from.

What we are solving for
Black-Scholes gives the price of a European call as
\[C = S\,N(d_1) – K e^{-rT} N(d_2)\] \[d_1 = \frac{\ln(S/K) + \left(r + \tfrac{1}{2}\sigma^2\right)T}{\sigma\sqrt{T}}, \qquad d_2 = d_1 – \sigma\sqrt{T}\]where S is the current Bitcoin price, K the strike, T the time to expiry in years, r the risk-free rate, N the standard normal cumulative distribution, and σ the volatility. In the normal use of the formula you know σ and want C. Implied volatility is the same formula used backwards: the market has already told you C, and you want the σ that produces it.
The awkward part is that you cannot rearrange the formula to get σ on its own. It is buried inside the normal distribution. So you guess a value, see what price it gives, and adjust. Newton’s method does that efficiently because the derivative of the price with respect to σ, which options people call vega, has a closed form, so each step knows how far to move and in which direction. From a sensible starting guess it usually lands within a handful of iterations.
The example
A 30-day Bitcoin call, with these inputs:
- Bitcoin price, S: $93,491
- Strike, K: $100,000
- Time to expiry, T: 30 days, so 30/365 = 0.0822 years
- Risk-free rate, r: 4%, so 0.04
- Market price of the call, C: $2,500
The option is out of the money by about 7 per cent and has a month to run, and the market is charging $2,500 for it. The question is what level of volatility justifies that price.
The code
import math
from scipy.stats import norm
def black_scholes_call(S, K, T, r, sigma):
d1 = (math.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * math.sqrt(T))
d2 = d1 - sigma * math.sqrt(T)
return S * norm.cdf(d1) - K * math.exp(-r * T) * norm.cdf(d2)
def implied_volatility(S, K, T, r, market_price, tol=1e-6, max_iter=100):
sigma = 0.5 # starting guess, 50%
for _ in range(max_iter):
price = black_scholes_call(S, K, T, r, sigma)
d1 = (math.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * math.sqrt(T))
vega = S * norm.pdf(d1) * math.sqrt(T)
diff = market_price - price
if abs(diff) < tol:
return sigma
sigma += diff / vega # Newton step
raise ValueError("did not converge")
S = 93491 # Bitcoin price, USD
K = 100000 # strike, USD
T = 30 / 365 # 30 days, in years
r = 0.04 # risk-free rate
market_price = 2500
iv = implied_volatility(S, K, T, r, market_price)
print(f"Implied volatility: {iv:.2%}")
Run that and you get an implied volatility of about 45.3 per cent, and it gets there in three iterations from the 50 per cent starting guess. If you start from 20 per cent instead it takes a few more steps but arrives at the same place, which is a useful check that the solver is working rather than just stopping.
A note on the starting guess, because people ask. For Bitcoin, 50 per cent is a reasonable place to begin; for an equity index you would start lower. It does not change the answer, only how many steps it takes to get there, and if the guess is wildly wrong the vega can be tiny and the first step overshoots. A tolerance of a millionth of a dollar is more precision than any market needs, but it costs nothing.
What 45 per cent means
This is the part that gets misread most often, so I want to be careful with it. Implied volatility is quoted annualised. It does not mean the market expects Bitcoin to move 45 per cent in the next 30 days. To get the expected one-standard-deviation move over the life of the option you scale by the square root of time: 45.3 per cent times the square root of 0.0822 is about 13 per cent. So the option price is consistent with a market that thinks a move of roughly 13 per cent in either direction over the month is a one-standard-deviation event, and a move of 26 per cent is a two-standard-deviation one.
Whether 13 per cent in a month is high depends on what Bitcoin has actually been doing. Compare it with the historical volatility over the previous 30 or 60 days, which I show how to calculate in the historical volatility post. If implied is well above historical, the market is paying up for protection or expecting an event. If it is below, options are cheap relative to how the asset has been moving. That comparison, implied against realised, is the whole reason to do this calculation. The number on its own tells you very little.