איך מחשבים תנודתיות גלומה באופציות
תנודתיות גלומה מחושבת באיטרציה: פותר משוואות מתאים את מודל Black-Scholes למחיר השוק. כך פועל הקוד ב-Python ומה גורם לפערים בין ספקי נתונים.
תנודתיות גלומה מחושבת באמצעות איטרציה, ולא באמצעות נוסחה. אין ביטוי סגור שממיר את מחיר השוק של אופציה בחזרה למספר המייצג תנודתיות. לכן פותר משוואות מנחש ערך לתנודתיות, מתמחר את האופציה באמצעות Black-Scholes, משווה את מחיר המודל לציטוט השוק, וחוזר על התהליך עד ששני המחירים תואמים בדיוק של סנט. להלן השיטה המלאה: פונקציית התמחור, לולאת החיפוש ב-Python באמצעות הספרייה הסטנדרטית, והסיבות לכך ששני ספקי נתונים מפרסמים מספרים שונים עבור אותו חוזה.
מדוע לתנודתיות הגלומה אין נוסחה סגורה
Black-Scholes פועל בכיוון אחד. מזינים לו מחיר ספוט, מחיר מימוש, זמן עד לפקיעה, ריבית ותנודתיות, והוא מחזיר מחיר תאורטי. חמישה מתוך ששת הנתונים האלה ניתנים לצפייה. התנודתיות אינה ניתנת לצפייה. היא הנחה לגבי המרחק שבו המניה תנוע מעכשיו ועד לפקיעה.
סוחרים הופכים את הבעיה. המחיר מופיע על המסך, והתנודתיות היא הנתון הלא ידוע. תנודתיות גלומה היא ערך התנודתיות שגורם למחיר לפי Black-Scholes להיות שווה למחיר השוק של האופציה. Sigma, מונח התנודתיות, מופיעה בתוך פונקציית ההתפלגות הנורמלית פעמיים, גם ב-d1 וגם ב-d2, ואי-אפשר לבודד אותה באמצעות ארגון מחדש של המשוואה. כאן האלגברה נעצרת. מכאן עוברים לחיפוש נומרי. מה מודדת התנודתיות הגלומה מסביר את הפרשנות; העמוד הזה עוסק במנגנון.
שתי תכונות של המודל מקלות על החיפוש. מחיר Call לפי המודל עולה בכל פעם שהתנודתיות עולה, ללא יוצא מן הכלל, והוא משתנה באופן רציף. אפשר לתחום כמות שרק עולה באמצעות צמצום הדרגתי של הטווח סביבה.
הפתרון מתבצע פעם אחת לכל חוזה
הפלט הוא מספר אחד לכל חוזה, ולא מספר אחד לכל מניה. חוזים על אותה מניה ובאותו חלון פקיעה עשויים להציג תוצאות שונות זה מזה. להלן כל אופציות Apple (AAPL) שנותרו להן 20 עד 45 ימים לפקיעה ושנסחרו ב-30 ביוני 2026, מקובצות לפי מחיר המימוש ביחס למחיר המניה:
ה-SQL המדויק מאחורי כל מספר
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)בקריאת סולם מחירי המימוש, אזור 0.80-0.90 הניב את התוצאה 35.5%, ואזור 0.95-1.00 הניב את התוצאה 28.1%, ואילו אזור 1.10-1.20 הניב את התוצאה 27.3%. חברה אחת, יום מסחר אחד, 6 תשובות. לעיקול בעקומה הזו יש שם: הטיית תנודתיות, ותנודתיות יחידה לכל מניה אינה יכולה לשרטט אותו.
מחיר Black-Scholes שעל הפותר להתאים אליו
S הוא מחיר המניה, K הוא מחיר המימוש, T הוא הזמן עד לפקיעה בשנים, r הוא שיעור הריבית חסרת הסיכון, ו-N() היא פונקציית ההתפלגות המצטברת של ההתפלגות הנורמלית הסטנדרטית — כלומר, ההסתברות שמדגם נורמלי סטנדרטי ייפול מתחת לנקודה נתונה. Python כולל את הרכיב האחרון ב-math.erf, ולכן די במפרש עצמו.
apt-get update && apt-get install -y python3
במחשב שבו אינכם משתמשים בהרשאות root, הוסיפו את sudo לפני שתי הפקודות. לאחר מכן שמרו את הקוד הבא בשם 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)
זהו המודל הישיר במלואו. מזינים לו תנודתיות ומקבלים מחיר.
כיצד מחשבים תנודתיות גלומה, שלב אחר שלב
שיטת החצייה היא השיטה הראשונה שכדאי ללמוד. היא אינה יכולה להתבדר ואינה דורשת חשבון דיפרנציאלי.
- תחמו את התשובה בין 0.01 (1% לשנה) לבין 5.0 (500%). כל אופציה נסחרת נמצאת בתוך הטווח הזה.
- תמחור האופציה מתבצע בנקודת האמצע של הטווח.
- אם מחיר האופציה לפי המודל גבוה מהציטוט בשוק, ההערכה גבוהה מדי: הורידו את הגבול העליון של הטווח לנקודת האמצע. אם הוא נמוך יותר, העלו את הגבול התחתון.
- עצרו כאשר מחיר האופציה לפי המודל נמצא בטווח של סנט אחד מהציטוט.
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))
הריצו את python3 iv.py. הקוד מדפיס בערך 0.226, כלומר תנודתיות גלומה של כ-22.6% לשנה עבור הציטוט ההיפותטי הזה. בכל איטרציה הטווח נחצה, וטווח ברוחב 4.99 שנחצה עשרים פעמים נעשה צר יותר מ-0.00001. לכן המגבלה של 100 איטרציות לעולם אינה מופעלת.
מדוע Newton-Raphson מתכנס מהר יותר, והיכן הוא נכשל
שיטת החצייה מתעלמת ממידע שכבר קיים במודל. Vega הוא השינוי במחיר האופציה לכל יחידת תנודתיות, ו-Black-Scholes מספק אותו בצורה סגורה. Newton-Raphson מתייחס אליו כשיפוע: מודדים את שגיאת התמחור, מחלקים ב-vega ומעדכנים את האומדן בהתאם.
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 # לא נותר שיפוע; מחזירים את המשימה לשיטת החצייה
step = (bs_call(S, K, T, r, sigma) - price) / v
sigma -= step
if sigma <= 0.0:
return None # הצעד חרג לתחום חסר משמעות
if abs(step) < 1e-6:
return sigma
return None
באזור הכסף, השיטה מגיעה לתוצאה בתוך שלושה או ארבעה מעברים, לעומת כתריסר בשיטת החצייה. מקור הכשל נמצא במכנה: vega מצטמצם ככל שמחיר המימוש מתרחק ממחיר המניה. עבור אותם חוזי AAPL, כאשר ה-vega הממוצע בכל אזור מוצג כאחוז מקריאת ה-vega במחיר המימוש at the money:
ה-SQL המדויק מאחורי כל מספר
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)באזורי הקצה נותר רק חלק קטן מהרגישות: 33.1% מה-vega במחיר המימוש at the money באזור 0.80-0.90, ו-31.6% באזור 1.10-1.20. חלוקת שגיאת תמחור במספר קטן כל כך יוצרת צעד עצום, שעלול להוריד את האומדן מתחת לאפס — נקודה שבה למודל אין עוד מידע לספק. פותרי בעיות בסביבת ייצור משלבים בין שתי השיטות: תחילה תוחמים את הפתרון, ולאחר מכן משפרים אותו באמצעות Newton. Vega מסביר את ה-greek עצמו.
מדוע שני מקורות מדווחים על סטיית תקן גלומה שונה
המודל ציבורי והחישוב מוסכם, ולכן מקור המחלוקת נמצא בנתוני הקלט.
- מחיר אמצע לעומת עסקה אחרונה. המודל זקוק למחיר אחד. חוזה שמוצג בו ביקוש של $2.00 והיצע של $2.20 מקבל מחיר אמצע של $2.10, בעוד שהעסקה האחרונה עשויה להיות במחיר $2.02 מלפני תשעים דקות. בחוזה כזה, שינוי של עשרה סנט במחיר שווה יותר מנקודת סטיית תקן אחת.
- דיבידנדים ועלות נשיאה. הפונקציה שלעיל מתמחרת אופציית Call אירופית על מניה שאינה משלמת דבר. דיבידנד המשולם לפני הפקיעה מוריד את מחיר הפורוורד, וכל דסק מיישם התאמה משלו וריבית משלו.
- מימוש מוקדם באופציות אמריקאיות. ניתן לממש אופציות על מניות אמריקאיות בכל יום, ולזכות זו יש ערך שלנוסחה האירופית אין דרך להביא בחשבון. מודל שמתעלם ממנה מגלגל את ההפרש אל סטיית התקן. עצי binomial מתמחרים את זכות המימוש ישירות.
- ציטוטים מיושנים. מניית מימוש שנסחרה לאחרונה ביום שלישי עדיין עשויה להציג ציטוט, והמודל מתייחס לכל נתון שנמסר לו כאילו הוא אמת.
התכנסות הפתרון הופכת את שתי הסוגיות האחרונות לגלויות. הטבלה שלהלן כוללת שמונה מניות מוכרות, נכון ל-30 ביוני 2026. היא סופרת חוזים שנסחרו ונותרו להם 20 עד 45 ימים לפקיעה, ומדווחת הן על סטיית התקן במחיר המימוש הקרוב למחיר המניה והן על שיעור החוזים שבהם הפתרון התכנס:
ה-SQL המדויק מאחורי כל מספר
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 הציגה את נתון סטיית התקן הקרוב למחיר המניה הגבוה ביותר מבין 8 המניות, ברמה של 47.7%, לעומת 14.4% עבור SPY, שהייתה בתחתית הדירוג. בשרשרת האופציות של TSLA, עבור 97.8% מהחוזים שנסחרו התקבל פתרון שהתכנס. היתר הם מחירי מימוש שבהם המחיר שנמסר למודל נמצא מחוץ לטווח שניתן לשחזר באמצעות סטיית תקן כלשהי, ציטוט הנמוך מהערך הפנימי או שוק מוצלב. השאלה אם נתון כזה נחשב גבוה היא שאלה נפרדת: האם סטיית תקן גלומה של 30% נחשבת גבוהה עוסקת בכך, ואילו התנועה הצפויה ממירה אותה לטווח דולרי.
אותו חוזה, מחושב מחדש בכל יום מסחר
שום נתון של תנודתיות גלומה אינו נשמר. הנתון מחושב מחדש לפי המחיר המוצג באותו רגע. להלן חוזה ה-AAPL בעל מחזור המסחר הגבוה ביותר, שמועד פקיעתו חל ב-17 ביולי 2026, במעקב מ-1 ביוני ועד הפקיעה. מחיר המימוש ומועד הפקיעה לא השתנו:
ה-SQL המדויק מאחורי כל מספר
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במהלך 29 ימי מסחר, הנתון המחושב נפתח ברמה של 25.1%, כשנותרו 46 ימים לפקיעה, והסתיים ברמה של 26.6%, כשנותרו 4 ימים. כל נקודה בקו הזה היא הרצה אחת של הלולאה לעיל על סמך הציטוטים של אותו יום מסחר. דפי הטיקר שלנו מפרסמים את אותו חישוב: תנודתיות גלומה של AAPL מחושב מדי יום על פני כל שרשרת האופציות, כך שהקורא יכול לשחזר כל נתון המופיע שם באמצעות הקוד שבעמוד זה.
שאלות נפוצות על חישוב התנודתיות הגלומה
האם קיימת נוסחה לתנודתיות גלומה?
לא. מודל Black-Scholes ממפה תנודתיות למחיר, אך למיפוי הזה אין פונקציה הופכית אלמנטרית, משום ש-sigma מופיעה בתוך ההתפלגות הנורמלית פעמיים. כל נתון של תנודתיות גלומה שתפגשו, כאן או בכל מקום אחר, מתקבל באמצעות פותר איטרטיבי.
כמה איטרציות נדרשות לחישוב?
בכל שלב של שיטת החצייה טווח החיפוש מצטמצם בחצי. לכן טווח שבין 0.01 ל-5.0 יורד מתחת ל-0.00001 בתוך twenty passes, והתאמת המחיר המצוטט ל-cent הקרוב נמשכת בדרך כלל כתריסר איטרציות. שיטת Newton-Raphson מגיעה לתוצאה בתוך three or four איטרציות כאשר האופציה קרובה למחיר המימוש, אך היא עלולה להתנהג באופן לא יציב באזורים שבהם vega נמוכה.
מדוע הברוקר שלי וספק נתונים מציגים תנודתיות גלומה שונה?
הם הזינו לפותר נתונים שונים. הפערים הנפוצים נובעים מהשימוש במחיר אמצע לעומת העסקה האחרונה, מהנחת הריבית והדיבידנד, וכן מהשאלה אם המודל מביא בחשבון מימוש מוקדם בסגנון אמריקאי. באופציה עם מחיר מימוש דל-סחירות, ציטוט שאינו מעודכן לבדו יכול לשנות את התוצאה בכמה נקודות.
האם אופציות Call ו-Put עם אותו מחיר מימוש מציגות את אותה תנודתיות גלומה?
תיאורטית כן. שוויון put-call קושר ביניהן כאשר מחיר המימוש ומועד הפקיעה זהים. בפועל, שני הציטוטים נקבעים באופן עצמאי, ולכן התוצאות המחושבות שונות מעט. זו סיבה נוספת לכך שממוצעים על פני כל שרשרת האופציות משתנים בין ספקי נתונים.
האם אפשר לחשב תנודתיות גלומה ללא נתוני שוק?
כן, עבור מחיר היפותטי. הקוד שלמעלה מקבל מחיר, מחיר מימוש, מחיר נכס בסיס, זמן עד הפקיעה ושיעור ריבית, שכולם מוזנים ידנית. התאמת התוצאה לנתון חי של ספק נתונים היא החלק הקשה יותר: לשם כך נדרשים אותם נתונים שבהם השתמש הספק.
כל פאנל כאן שומר את שאילתת ה-SQL שמאחוריו. פתחו פאנל אחד, ולאחר מכן הריצו את אותו חישוב מול שרשרת אופציות חיה במסוף Strasmore.