Python 選擇權入門:用 Black-Scholes 計算理論價格與 Greeks(附完整程式碼)

本文目錄
  1. 為什麼要用 Python 做選擇權定價?Black-Scholes 模型原理拆解
  2. 實作選擇權定價 Python:Black-Scholes 公式完整程式碼
  3. 選擇權 Greeks 計算:Delta、Gamma、Theta、Vega 一次搞懂
  4. 隱含波動率數值求解 + 到期損益圖繪製
  5. 避雷防坑指南:Python 選擇權程式交易常見錯誤
  6. 工具與方法比較:手動建模 vs 現成套件 vs 圖表平台
  7. FAQ 常見問題
  8. 結論與下一步行動

如果你正在學習python 選擇權相關的量化分析,一定會遇到一個共同的痛點:選擇權的理論價格到底怎麼算出來的?為什麼同一個標的、同一個履約價,波動率一改變,價格就天差地遠?這篇文章會帶你用 Python 從零實作 Black-Scholes 定價模型,計算選擇權的理論價格與 Greeks(Delta、Gamma、Theta、Vega),並示範隱含波動率的數值求解方法。文中所有數字都是假設範例,由程式碼實際計算得出,方便你複製貼上直接驗證。

為什麼要用 Python 做選擇權定價?Black-Scholes 模型原理拆解

Black-Scholes(簡稱 BS)模型是選擇權定價 Python 實作中最經典的入門模型,由 Fischer Black 與 Myron Scholes 在 1973 年提出。它假設標的資產價格服從幾何布朗運動,並在「無套利」與「連續避險」的前提下,推導出歐式選擇權的封閉解公式。

BS 模型需要五個輸入變數:

變數 說明
S(標的價格) 目前標的資產的市價
K(履約價) 選擇權的執行價格
T(到期時間) 以「年」為單位的剩餘時間
r(無風險利率) 通常用公債殖利率近似
σ(波動率) 標的資產報酬率的年化標準差

公式本身用到標準常態分配的累積分配函數(CDF),這也是為什麼 Python 很適合做這件事——scipy.stats.norm.cdf 已經幫你寫好了,不用自己手刻數值積分。

值得注意的是,BS 模型是針對「歐式選擇權」設計的,台指選擇權(TXO)在規格上屬於歐式,理論上可以用 BS 模型估算理論價,但實務交易時的合約規格(每點價值、保證金、交易時間、結算方式)請一律以臺灣期貨交易所官網最新公告為準,本文不提供任何具體數值,避免資訊過時誤導讀者。

實作選擇權定價 Python:Black-Scholes 公式完整程式碼

以下是用 Python 實作 Black-Scholes 定價公式的完整範例,所有輸入數值都是假設範例,你可以自行替換成想測試的參數:

PYTHON
import numpy as np
from scipy.stats import norm

def black_scholes_price(S, K, T, r, sigma, option_type="call"):
    """
    S: 標的價格(假設範例)
    K: 履約價(假設範例)
    T: 到期時間(年),假設範例
    r: 無風險利率(假設範例)
    sigma: 年化波動率(假設範例)
    option_type: "call" 或 "put"
    """
    d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T))
    d2 = d1 - sigma * np.sqrt(T)

    if option_type == "call":
        price = S * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)
    elif option_type == "put":
        price = K * np.exp(-r * T) * norm.cdf(-d2) - S * norm.cdf(-d1)
    else:
        raise ValueError("option_type 必須是 'call' 或 'put'")

    return price

# 假設範例:標的價格 100、履約價 100、剩餘 0.5 年、無風險利率 2%、波動率 20%
S, K, T, r, sigma = 100, 100, 0.5, 0.02, 0.20

call_price = black_scholes_price(S, K, T, r, sigma, "call")
put_price = black_scholes_price(S, K, T, r, sigma, "put")

print(f"假設範例 Call 理論價格: {call_price:.4f}")
print(f"假設範例 Put 理論價格: {put_price:.4f}")

這段程式碼的重點在於 d1、d2 的計算,以及用 norm.cdf 查表。只要輸入數值正確,就能快速得到理論價格,這也是許多程式交易系統計算「理論價 vs. 市價」價差的基礎邏輯。

選擇權 Greeks 計算:Delta、Gamma、Theta、Vega 一次搞懂

學會選擇權 Greeks 計算,才能真正理解部位的風險暴露。以下用同一組假設範例參數,示範四個最常用 Greeks 的計算方式:

PYTHON
import numpy as np
from scipy.stats import norm

def black_scholes_greeks(S, K, T, r, sigma, option_type="call"):
    d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T))
    d2 = d1 - sigma * np.sqrt(T)

    # Gamma 與 Vega 對 call/put 是相同的
    gamma = norm.pdf(d1) / (S * sigma * np.sqrt(T))
    vega = S * norm.pdf(d1) * np.sqrt(T) / 100  # 每 1% 波動率變動的影響

    if option_type == "call":
        delta = norm.cdf(d1)
        theta = (
            -S * norm.pdf(d1) * sigma / (2 * np.sqrt(T))
            - r * K * np.exp(-r * T) * norm.cdf(d2)
        ) / 365  # 轉換成每日 theta
    elif option_type == "put":
        delta = norm.cdf(d1) - 1
        theta = (
            -S * norm.pdf(d1) * sigma / (2 * np.sqrt(T))
            + r * K * np.exp(-r * T) * norm.cdf(-d2)
        ) / 365
    else:
        raise ValueError("option_type 必須是 'call' 或 'put'")

    return {"delta": delta, "gamma": gamma, "theta": theta, "vega": vega}

# 承上假設範例參數
S, K, T, r, sigma = 100, 100, 0.5, 0.02, 0.20
greeks_call = black_scholes_greeks(S, K, T, r, sigma, "call")

for name, value in greeks_call.items():
    print(f"假設範例 Call {name}: {value:.6f}")

簡單說明這四個 Greeks 的意義:

  • Delta:標的價格變動 1 單位,選擇權價格大約變動多少,也常被理解為「避險比率」。
  • Gamma:Delta 對標的價格變動的敏感度,Gamma 越大,部位的方向性風險變化越快。
  • Theta:時間流逝對選擇權價值的侵蝕,通常以「每日」為單位呈現。
  • Vega:波動率每變動 1% 對選擇權價格的影響。

把這些函式封裝好之後,你可以把它接到即時報價資料上,動態追蹤整體部位的 Greeks 加總,這是許多台指選擇權程式交易系統監控風險的基本做法。

隱含波動率數值求解 + 到期損益圖繪製

市場上看到的選擇權報價是「市價」,而 BS 公式是用波動率反推價格。如果我們想從市價反推「市場認為的波動率」(隱含波動率),就需要用數值方法求解,因為 BS 公式無法直接解出 σ 的封閉解。這裡用 scipy.optimize.brentq 示範:

PYTHON
import numpy as np
from scipy.stats import norm
from scipy.optimize import brentq

def bs_price_for_iv(sigma, S, K, T, r, market_price, option_type="call"):
    d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T))
    d2 = d1 - sigma * np.sqrt(T)
    if option_type == "call":
        price = S * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)
    else:
        price = K * np.exp(-r * T) * norm.cdf(-d2) - S * norm.cdf(-d1)
    return price - market_price

# 假設範例:市場上這張 call 的報價是 6.5
S, K, T, r, market_price = 100, 100, 0.5, 0.02, 6.5

implied_vol = brentq(
    bs_price_for_iv, 0.001, 3.0,
    args=(S, K, T, r, market_price, "call")
)
print(f"假設範例隱含波動率: {implied_vol:.4%}")

接著示範到期損益圖,這是驗證策略邏輯最直觀的方式:

PYTHON
import numpy as np
import matplotlib.pyplot as plt

K = 100           # 假設範例履約價
premium = 6.5     # 假設範例權利金
spot_range = np.linspace(70, 130, 200)

payoff_call_buy = np.maximum(spot_range - K, 0) - premium

plt.figure(figsize=(8, 5))
plt.plot(spot_range, payoff_call_buy, label="買進 Call 到期損益(假設範例)")
plt.axhline(0, color="black", linewidth=0.8)
plt.xlabel("到期標的價格(假設範例)")
plt.ylabel("損益")
plt.legend()
plt.title("選擇權到期損益圖(假設範例參數)")
plt.show()

這張圖能幫助你視覺化不同策略組合(例如買權、賣權、價差組合)在到期時的損益曲線,是回測前確認邏輯正確性的重要步驟。

避雷防坑指南:Python 選擇權程式交易常見錯誤

寫程式算選擇權理論價格看似簡單,但實務上有幾個地雷特別容易踩到:

1. 未來函數(Look-ahead Bias)

在回測歷史資料時,若誤用「當天收盤後才會知道」的波動率或隱含波動率去反推當天的理論價,就會產生未來函數,導致回測結果嚴重失真。成因通常是資料時間戳沒對齊,或是用整段歷史資料計算的「已實現波動率」去代入當天的定價模型。防範建議:所有輸入 BS 模型的參數,都必須是「當下時間點已知」的資料,並在程式中明確標註資料的時間戳,避免跨期混用。

2. 忽略交易成本與滑價

很多人在計算理論價格與 Greeks 時,只看模型算出來的數字,卻忘了實際下單會有手續費、交易稅,以及買賣價差(spread)造成的滑價。這些成本在短天期、低波動的選擇權上占比特別高,容易把看似合理的價差策略侵蝕到無利可圖。防範建議:在任何策略評估流程中,固定把預估的交易成本當作一個變數扣除,而不是事後才補算。

3. 過度最佳化(Overfitting)

在用歷史資料校準波動率參數或尋找「最佳」履約價、到期日組合時,如果反覆調整參數直到歷史表現好看為止,很容易得到一個只對過去資料有效、對未來毫無預測力的模型。成因是參數自由度太高、驗證資料與訓練資料沒有確實切割。防範建議:務必保留「樣本外」資料做驗證,並對參數數量保持警覺,越簡單、邏輯越直觀的模型通常越穩健。

4. 誤用歐式模型套用到有提前履約特性的商品

BS 模型假設是歐式選擇權,如果拿去直接套用在允許提前履約的美式選擇權商品上,理論價格會產生系統性偏差。防範建議:先確認商品規格屬於歐式或美式,若為美式,需改用二項樹模型或其他適用方法。

工具與方法比較:手動建模 vs 現成套件 vs 圖表平台

學習 Python 選擇權定價時,常見的做法大致分三種,各有適合的使用情境:

方法 優點 限制 適合對象
手動用 numpy/scipy 寫 BS 公式 完全掌握計算邏輯,方便客製化 Greeks 與延伸策略 需要自行處理資料清洗、商品規格差異 想深入理解原理的學習者
現成選擇權定價函式庫 開發速度快,減少重複造輪子 彈性較低,客製化需研究原始碼 想快速驗證想法的開發者
圖表與報價平台(如 TradingView) 即時報價、技術指標、繪圖介面直觀,方便交叉驗證理論價與市場價 不提供完整的 Python 程式化定價引擎 需要同時看盤與做策略構思的使用者

如果你在學習選擇權定價 Python 的過程中,需要一個方便查看即時報價、畫圖驗證進出場邏輯的平台,可以搭配 TradingView 一起使用,把模型算出來的理論價,拿去跟圖表上的市場報價互相比對,會更有感覺。

FAQ 常見問題

Q1:Python 選擇權定價一定要用 Black-Scholes 嗎?

不一定。BS 模型只適用於歐式選擇權,且假設波動率固定不變。如果標的具有提前履約特性(美式選擇權),或你想考慮波動率微笑(volatility smile),就需要用二項樹模型、蒙地卡羅模擬,或其他更進階的隨機波動率模型。BS 模型的優點是計算快速、公式封閉解,很適合做為入門學習與快速估價的基礎工具。

Q2:隱含波動率跟歷史波動率有什麼不同?

歷史波動率是用過去一段時間的報酬率計算出來的統計值,反映「過去」的波動程度;隱含波動率則是從目前市場報價反推出來,反映「市場對未來波動的預期」。兩者數值不一定相同,這也是選擇權交易者常常關注的觀察指標之一。

Q3:用 Python 算出來的理論價格跟台指選擇權實際報價會一樣嗎?

不會完全一樣。理論價格是基於模型假設(例如波動率固定、無套利、連續避險)計算出來的估計值,實際市場報價還會受到供需、流動性、交易成本、提前履約風險等因素影響。這也是為什麼學習選擇權定價 Python 的重點,是理解「模型與市場的落差從何而來」,而不是追求兩者完全吻合。

結論與下一步行動

這篇文章帶你用 Python 實作了 Black-Scholes 選擇權定價公式、Greeks 計算、隱含波動率數值求解,以及到期損益圖繪製,所有範例數字都是假設情境,方便你直接複製程式碼動手驗證。選擇權定價的數學看起來複雜,但拆解成 scipy.stats.norm 與 scipy.optimize.brentq 這些現成工具後,其實門檻並沒有想像中高。

如果你想進一步把這些計算結果拿去跟真實市場報價互相驗證,建議搭配一個順手的圖表平台同步觀察,你可以參考 TradingView,一邊看即時報價、一邊用 Python 驗證理論價格與 Greeks,會讓學習選擇權定價的過程更紮實。記得,實際交易前務必以臺灣期貨交易所官網最新公告的合約規格為準,並謹慎評估風險。