Strasmore Research
Học tập Matt ConnorBởi Matt Connor · Cập nhật 2026-08-05

Cách tính implied volatility bằng phương pháp lặp

Tìm hiểu cách bộ giải suy ra implied volatility từ giá quyền chọn bằng Black-Scholes, Python và phương pháp lặp, cùng các bẫy thường gặp.

Độ biến động hàm ý được tính bằng phương pháp lặp, không phải bằng công thức trực tiếp. Không có biểu thức dạng đóng nào chuyển giá thị trường của một quyền chọn ngược trở lại thành một con số biến động. Vì vậy, bộ giải sẽ thử một mức biến động, định giá quyền chọn bằng mô hình Black-Scholes, so sánh giá mô hình với giá niêm yết, rồi lặp lại cho đến khi hai mức giá khớp nhau đến từng cent. Phần dưới đây trình bày toàn bộ phương pháp: hàm định giá, vòng lặp tìm kiếm bằng Python chỉ sử dụng thư viện chuẩn, và lý do hai nhà cung cấp dữ liệu công bố các con số khác nhau cho cùng một hợp đồng.

Vì sao implied volatility không có công thức dạng đóng

Black-Scholes chỉ vận hành theo một chiều. Nhập giá spot, giá thực hiện, thời gian đến ngày đáo hạn, lãi suất và volatility, mô hình trả về giá lý thuyết. Năm trong sáu đại lượng này có thể quan sát được. Volatility thì không. Đây là một giả định về mức độ biến động của cổ phiếu từ hiện tại đến ngày đáo hạn.

Traders đảo ngược bài toán. Giá đã hiển thị trên màn hình, còn volatility là ẩn số. Implied volatility là mức volatility đầu vào khiến giá theo Black-Scholes bằng giá thị trường của quyền chọn. Sigma, tức biến số volatility, xuất hiện hai lần trong hàm phân phối chuẩn, trong cả d1 và d2, nên không thể biến đổi đại số để tách riêng nó. Đại số dừng ở đó. Phần còn lại do phương pháp tìm kiếm số xử lý. Implied volatility đo lường điều gì giải thích cách diễn giải; trang này tập trung vào cơ chế tính toán.

Hai đặc tính của mô hình giúp việc tìm kiếm trở nên đơn giản. Giá theo mô hình của call tăng mỗi khi volatility tăng, không có ngoại lệ, và biến động một cách trơn tru. Một đại lượng chỉ tăng có thể được xác định bằng cách thu hẹp dần một khoảng bao quanh nó.

Bộ giải chạy một lần cho mỗi hợp đồng

Kết quả là một con số cho mỗi hợp đồng, không phải một con số cho mỗi cổ phiếu. Các hợp đồng trên cùng một cổ phiếu, cùng trong một khoảng thời gian đến ngày đáo hạn, vẫn cho kết quả khác nhau. Dưới đây là mọi quyền chọn Apple (AAPL) còn từ 20 đến 45 ngày đến hạn và được giao dịch vào ngày 30 tháng 6 năm 2026, được nhóm theo giá thực hiện tính theo tỷ lệ trên giá cổ phiếu:

Truy vấnMột nghiệm cho mỗi hợp đồng: implied volatility của AAPL theo vùng strike, 30/6/2026
Câu lệnh SQL chính xác đằng sau mỗi con số
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)
Run this yourself

Đọc theo dải giá thực hiện, vùng 0.80-0.90 cho kết quả 35.5%, vùng 0.95-1.00 cho kết quả 28.1%, còn vùng 1.10-1.20 cho kết quả 27.3%. Một công ty, một phiên giao dịch, 6 kết quả. Độ cong trong đường này có tên là độ lệch biến động, và một mức biến động duy nhất cho mỗi cổ phiếu không thể mô tả được nó.

Giá Black-Scholes mà bộ giải phải khớp

S là giá cổ phiếu, K là giá thực hiện, T là thời gian đến ngày đáo hạn tính theo năm, r là lãi suất phi rủi ro, còn N() là hàm phân phối tích lũy chuẩn. Hàm này biểu thị xác suất một biến ngẫu nhiên chuẩn có giá trị thấp hơn một điểm nhất định. Python cung cấp hàm này trong math.erf, nên chỉ cần trình thông dịch Python là đủ.

apt-get update && apt-get install -y python3

Nếu không có quyền root trên máy, hãy thêm sudo vào trước cả hai lệnh. Sau đó lưu đoạn mã dưới đây vào tệp 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)

Đó là toàn bộ mô hình xuôi. Nhập một mức volatility vào mô hình để nhận được giá.

Cách tính biến động hàm ý, từng bước

Phương pháp chia đôi là cách đầu tiên bạn nên học. Phương pháp này không thể phân kỳ và không cần phép tính vi phân.

  1. Khoanh vùng đáp án từ 0,01 (1% một năm) đến 5,0 (500%). Mọi quyền chọn được giao dịch đều nằm trong khoảng này.
  2. Định giá quyền chọn tại điểm giữa của khoảng.
  3. Nếu giá theo mô hình cao hơn báo giá thị trường, mức ước tính quá cao: hạ cận trên của khoảng xuống điểm giữa. Nếu giá theo mô hình thấp hơn, nâng cận dưới lên.
  4. Dừng lại khi giá theo mô hình nằm trong phạm vi một cent so với báo giá.
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)

# Cổ phiếu giá $100, giá thực hiện $100, kỳ hạn ba tháng, lãi suất 4%, giá trên màn hình là $5.00
print(round(implied_vol(5.00, 100.0, 100.0, 0.25, 0.04), 4))

Chạy python3 iv.py. Kết quả là khoảng 0,226, tương đương biến động hàm ý gần 22,6% một năm cho báo giá giả định này. Sau mỗi vòng lặp, khoảng được chia đôi. Khoảng ban đầu rộng 4,99, sau hai mươi lần chia đôi sẽ nhỏ hơn 0,00001. Vì vậy, giới hạn 100 vòng lặp không bao giờ bị chạm tới.

Vì sao Newton-Raphson hội tụ nhanh hơn và khi nào thất bại

Phương pháp chia đôi bỏ qua thông tin mà mô hình đã có. Vega là mức thay đổi giá quyền chọn trên mỗi đơn vị biến động, và Black-Scholes cung cấp đại lượng này dưới dạng công thức đóng. Newton-Raphson xem vega như độ dốc: đo sai số định giá, chia cho vega rồi điều chỉnh giá trị ước tính một lượng tương ứng.

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          # không còn độ dốc, chuyển lại cho phương pháp chia đôi
        step = (bs_call(S, K, T, r, sigma) - price) / v
        sigma -= step
        if sigma <= 0.0:
            return None          # bước nhảy vượt quá giới hạn và cho kết quả vô nghĩa
        if abs(step) < 1e-6:
            return sigma
    return None

Với quyền chọn gần at the money, phương pháp này thường hội tụ sau ba hoặc bốn vòng lặp, so với khoảng một chục vòng của phương pháp chia đôi. Điểm dễ thất bại nằm ở mẫu số: vega giảm khi giá thực hiện cách xa giá cổ phiếu. Với các hợp đồng AAPL tương tự, vega bình quân của từng vùng được thể hiện dưới dạng tỷ lệ phần trăm so với mức vega tại at the money:

Truy vấnKhi bước Newton hoạt động sai: vega của AAPL theo vùng strike, 30/6/2026
Câu lệnh SQL chính xác đằng sau mỗi con số
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)
Run this yourself

Các vùng biên chỉ còn một phần độ nhạy này: 33.1% vega tại at the money trong vùng 0.80-0.90, và 31.6% trong vùng 1.10-1.20. Khi chia sai số định giá cho một con số nhỏ như vậy, kết quả là một bước nhảy rất lớn. Điều này có thể đẩy giá trị ước tính xuống dưới 0, nơi mô hình không còn đưa ra được thông tin hữu ích. Các bộ giải dùng trong môi trường thực tế thường kết hợp hai phương pháp: tạo khoảng bao trước, sau đó dùng Newton để tinh chỉnh. Vega giải thích riêng về greek này.

Vì sao hai nguồn báo cáo implied volatility khác nhau

Mô hình là công khai và phép tính đã được thống nhất, nên khác biệt nằm ở các đầu vào.

  • Giá giữa so với giá khớp gần nhất. Bộ giải cần một mức giá duy nhất. Một hợp đồng có giá bid là 2,00 USD và giá offer là 2,20 USD sẽ có midpoint là 2,10 USD, trong khi print gần nhất có thể là 2,02 USD từ 90 phút trước. Với một hợp đồng như vậy, chênh lệch 10 cent về giá có giá trị lớn hơn một điểm volatility.
  • Cổ tức và chi phí carry. Hàm ở trên định giá một quyền chọn mua kiểu châu Âu trên cổ phiếu không trả cổ tức. Khoản cổ tức trước ngày đáo hạn làm giảm giá kỳ hạn, và mỗi trading desk áp dụng một mức điều chỉnh cùng một mức lãi suất riêng.
  • Thực hiện sớm theo kiểu Mỹ. Quyền chọn cổ phiếu đơn lẻ tại Mỹ có thể được thực hiện vào bất kỳ ngày nào. Quyền này có giá trị nhưng công thức châu Âu không có cách đưa vào. Bộ giải bỏ qua quyền đó sẽ đẩy phần chênh lệch vào volatility. Mô hình cây nhị phân định giá trực tiếp quyền thực hiện này.
  • Báo giá lỗi thời. Một strike đã có giao dịch gần nhất vào thứ Ba vẫn có thể hiển thị báo giá. Bộ giải sẽ coi mọi dữ liệu được cung cấp là đúng.

Tính hội tụ giúp thấy rõ hai vấn đề cuối. Bảng dưới đây lấy tám cổ phiếu quen thuộc vào ngày 30 tháng 6 năm 2026, đếm số hợp đồng đã giao dịch còn từ 20 đến 45 ngày trước đáo hạn, đồng thời báo cáo volatility at the money và tỷ lệ hợp đồng có kết quả hội tụ:

Truy vấnImplied volatility at-the-money và hội tụ của solver, 8 mã, 30/6/2026
Câu lệnh SQL chính xác đằng sau mỗi con số
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 DESC
Run this yourself

TSLA có mức at the money cao nhất trong 8 mã, ở mức 47.7%, so với 14.4% của SPY, mã thấp nhất. Trên chuỗi quyền chọn của TSLA, 97.8% số hợp đồng đã giao dịch cho ra kết quả hội tụ. Phần còn lại là các strike mà mức giá cung cấp cho bộ giải nằm ngoài phạm vi mà bất kỳ mức volatility nào cũng có thể tái tạo, hoặc là báo giá thấp hơn giá trị nội tại hay một thị trường bị crossed. Một con số như vậy có được xem là cao hay không là câu hỏi khác: IV 30% có cao không sẽ phân tích vấn đề này, còn mức biến động kỳ vọng sẽ chuyển nó thành một khoảng giá tính theo USD.

Cùng một hợp đồng, được tính lại trong mỗi phiên

Không có dữ liệu implied volatility nào được lưu trữ. Chỉ số này được tính lại từ mức giá đang hiển thị trên màn hình. Dưới đây là hợp đồng AAPL có khối lượng giao dịch lớn nhất, đáo hạn ngày 17 tháng 7 năm 2026, được theo dõi từ ngày 1 tháng 6 đến khi đáo hạn. Giá thực hiện và ngày đáo hạn không thay đổi:

Truy vấnMột hợp đồng AAPL, giải lại mỗi phiên đến ngày đáo hạn 17/7/2026
Câu lệnh SQL chính xác đằng sau mỗi con số
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 date
Run this yourself

Trong 29 phiên, chỉ số tính được mở đầu ở mức 25.1%, khi còn 46 ngày, và kết thúc ở mức 26.6%, khi còn 4 ngày. Mỗi điểm trên đường biểu diễn là một lần chạy vòng lặp nêu trên với báo giá của phiên tương ứng. Các trang theo từng ticker của chúng tôi cũng công bố kết quả tính toán tương tự: implied volatility của AAPL được tính hằng ngày trên toàn bộ chuỗi quyền chọn, vì vậy bạn có thể dùng đoạn mã trên trang này để tái tạo mọi con số tại đó.

Câu hỏi thường gặp về cách tính implied volatility

Có công thức tính implied volatility không?

Không. Black-Scholes ánh xạ volatility sang giá, nhưng phép ánh xạ này không có hàm nghịch đảo sơ cấp vì sigma xuất hiện hai lần bên trong phân phối chuẩn. Mọi giá trị implied volatility mà bạn thấy, trên trang này hay ở bất kỳ đâu, đều được tính bằng một bộ giải lặp.

Phép tính cần bao nhiêu vòng lặp?

Mỗi vòng bisection thu hẹp khoảng nghiệm xuống một nửa. Vì vậy, khoảng từ 0.01 đến 5.0 sẽ nhỏ hơn 0.00001 sau twenty vòng, còn việc khớp báo giá đến cent gần nhất thường cần khoảng twelve vòng. Newton-Raphson thường đạt kết quả sau three hoặc four vòng khi giá ở gần strike, nhưng các bước tính có thể hoạt động không ổn định ở nơi vega nhỏ.

Vì sao broker của tôi và một nhà cung cấp dữ liệu lại hiển thị implied volatility khác nhau?

Họ đưa các đầu vào khác nhau vào bộ giải. Những khác biệt thường gặp là mid quote so với giao dịch gần nhất, giả định về lãi suất và cổ tức, và việc mô hình có xử lý quyền thực hiện sớm kiểu Mỹ hay không. Với một strike có thanh khoản thấp, chỉ riêng báo giá cũ cũng có thể khiến kết quả lệch vài điểm phần trăm.

Call và put cùng strike có cho ra implied volatility giống nhau không?

Về lý thuyết là có. Put-call parity liên kết hai quyền chọn tại cùng strike và ngày đáo hạn. Trên thực tế, hai báo giá được xác lập độc lập nên các giá trị tính được có thể chênh lệch đôi chút. Đây cũng là một lý do khiến mức trung bình trên toàn bộ option chain khác nhau giữa các nhà cung cấp.

Tôi có thể tính implied volatility mà không cần dữ liệu thị trường không?

Có, nếu đó là một báo giá giả định. Đoạn mã ở trên nhận giá, strike, giá tài sản cơ sở, thời gian đến ngày đáo hạn và lãi suất do bạn tự nhập. Phần khó hơn là khớp với giá trị trực tiếp từ nhà cung cấp dữ liệu. Khi đó, bạn phải sử dụng đúng các đầu vào mà nhà cung cấp đã dùng.


Mỗi panel trên trang này đều lưu câu lệnh SQL phía sau. Hãy mở một panel, sau đó chạy cùng phép tính trên option chain trực tiếp tại terminal Strasmore.

#implied volatility#options#black-scholes#python#how-to