σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademyRoadmapsSkills
Ctrl K
AO
+1.2k Learners
LoginJoin ↗
RoadmapsSkills
AO
+1.2k Learners
Login
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademyRoadmapsSkills
Ctrl K
AO
+1.2k Learners
LoginJoin ↗
RoadmapsSkills
AO
+1.2k Learners
Login
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
SciPy skill›Module 2 · Curves and integrals›Topic 2.3·~40 minIntermediate

Special functions in option pricing

Skill positionModule 2 of 3 · Topic 3 of 3
2.3 Special functions in option pricing
—Lab score— / 100Total XP—Streak—

The functions behind the formulas

scipy.special collects the named functions that appear again and again in formulas. The most useful for finance is the normal cumulative distribution Φ(x)\Phi(x)Φ(x), available as special.ndtr. It is tied to the error function by Φ(x)=12(1+erf⁡(x/2))\Phi(x)=\tfrac12\big(1+\operatorname{erf}(x/\sqrt2)\big)Φ(x)=21​(1+erf(x/2​)). The Black–Scholes price of a call with spot SSS, strike KKK, rate rrr, volatility σ\sigmaσ and time TTT uses it twice: C=S Φ(d1)−Ke−rTΦ(d2)C=S\,\Phi(d_1)-K e^{-rT}\Phi(d_2)C=SΦ(d1​)−Ke−rTΦ(d2​), where d1=ln⁡(S/K)+(r+σ2/2)TσTd_1=\dfrac{\ln(S/K)+(r+\sigma^2/2)T}{\sigma\sqrt T}d1​=σT​ln(S/K)+(r+σ2/2)T​ and d2=d1−σTd_2=d_1-\sigma\sqrt Td2​=d1​−σT​. The sensitivity of the price to volatility is called vega, and it equals S φ(d1)TS\,\varphi(d_1)\sqrt TSφ(d1​)T​, where φ\varphiφ is the normal density. Vega is what a Newton solver needs to find an implied volatility.

The other group of special functions is about numbers that are too big or too small. A factorial grows so fast that 171!171!171! already overflows a normal decimal number in a computer, but ln⁡n!\ln n!lnn! is easy: special.gammaln(n+1). special.comb(n, k) counts the paths with kkk up-moves in an nnn-step tree. special.logsumexp computes ln⁡∑exi\ln\sum e^{x_i}ln∑exi​ safely by pulling out the largest xxx, so that ln⁡(e1000+e1000)=1000+ln⁡2\ln(e^{1000}+e^{1000})=1000+\ln2ln(e1000+e1000)=1000+ln2 does not overflow. special.expit(x)=1/(1+e^{-x}) turns any score into a probability between 0 and 1, as in a logistic model. The rule is: work in logs when a number can be huge or tiny, and exponentiate only at the end.

Φ(x)=12(1+erf⁡(x2)),C=SΦ(d1)−Ke−rTΦ(d2),vega=S φ(d1)T,ln⁡∑exi=m+ln⁡∑exi−m\Phi(x)=\tfrac12\Big(1+\operatorname{erf}\Big(\frac{x}{\sqrt2}\Big)\Big),\qquad C=S\Phi(d_1)-Ke^{-rT}\Phi(d_2),\qquad \text{vega}=S\,\varphi(d_1)\sqrt T,\qquad \ln\sum e^{x_i}=m+\ln\sum e^{x_i-m}Φ(x)=21​(1+erf(2​x​)),C=SΦ(d1​)−Ke−rTΦ(d2​),vega=Sφ(d1​)T​,ln∑exi​=m+ln∑exi​−m(1)
A call price and an implied-volatility stepTake S=K=100S=K=100S=K=100, r=0r=0r=0, σ=0.2\sigma=0.2σ=0.2 and T=1T=1T=1. Then d1=0.1d_1=0.1d1​=0.1 and d2=−0.1d_2=-0.1d2​=−0.1, and Φ(0.1)=0.5398\Phi(0.1)=0.5398Φ(0.1)=0.5398, Φ(−0.1)=0.4602\Phi(-0.1)=0.4602Φ(−0.1)=0.4602. So C=100⋅(0.5398−0.4602)=7.97C=100\cdot(0.5398-0.4602)=7.97C=100⋅(0.5398−0.4602)=7.97. The normal density at 0.10.10.1 is 0.39700.39700.3970, so vega is 100⋅0.3970⋅1=39.70100\cdot0.3970\cdot1=39.70100⋅0.3970⋅1=39.70. If the market price is 9.009.009.00, the price is too low by 1.031.031.03, and one Newton step raises the volatility to 0.2+1.03/39.70=0.22610.2+1.03/39.70=0.22610.2+1.03/39.70=0.2261. For Φ(1)\Phi(1)Φ(1) you can use erf⁡(0.7071)=0.6827\operatorname{erf}(0.7071)=0.6827erf(0.7071)=0.6827, so Φ(1)=12(1+0.6827)=0.8413\Phi(1)=\tfrac12(1+0.6827)=0.8413Φ(1)=21​(1+0.6827)=0.8413. In the small tools, expit⁡(2)=0.8808\operatorname{expit}(2)=0.8808expit(2)=0.8808, ln⁡4!=3.178\ln 4!=3.178ln4!=3.178, and (103)=120\binom{10}{3}=120(310​)=120. On real data, SPY's daily return has a standard deviation of 1.196%1.196\%1.196%. A fall of 5%5\%5% is z=−4.21z=-4.21z=−4.21 standard deviations, and Φ(−4.21)=1.26⋅10−5\Phi(-4.21)=1.26\cdot10^{-5}Φ(−4.21)=1.26⋅10−5, which a normal model says happens once in about 315315315 years. In the 5,4035{,}4035,403 days of data, it happened on 202020 days.
  • Name the function: ndtr, erf, expit, gammaln, comb and logsumexp replace pages of hand-written maths.
  • Work in logs for extremes: use gammaln and logsumexp instead of a factorial or a sum of huge exponentials.
  • Vega drives the solver: a Newton step for implied volatility is the price gap divided by vega.

Lab · what's graded

  • The normal function from erf10 pts
  • A Black–Scholes call20 pts
  • Vega10 pts
  • An implied-volatility step15 pts
  • What each function is for15 pts
  • The safe way to add10 pts
  • Why compute factorials through logs20 pts
0/ 7 answered
Tasks
1Numeric answer10 ptsNot answered

Given erf⁡(0.7071)=0.6827\operatorname{erf}(0.7071)=0.6827erf(0.7071)=0.6827, compute Φ(1)=12(1+erf⁡(1/2))\Phi(1)=\tfrac12\big(1+\operatorname{erf}(1/\sqrt2)\big)Φ(1)=21​(1+erf(1/2​)). Give four decimals.

p=p =p=accepted: ± 0.0005
2Numeric answer20 ptsNot answered

With S=K=100S=K=100S=K=100, r=0r=0r=0, σ=0.2\sigma=0.2σ=0.2, T=1T=1T=1 we get d1=0.1d_1=0.1d1​=0.1, d2=−0.1d_2=-0.1d2​=−0.1, Φ(0.1)=0.5398\Phi(0.1)=0.5398Φ(0.1)=0.5398 and Φ(−0.1)=0.4602\Phi(-0.1)=0.4602Φ(−0.1)=0.4602. What is C=SΦ(d1)−KΦ(d2)C=S\Phi(d_1)-K\Phi(d_2)C=SΦ(d1​)−KΦ(d2​)? Give two decimals.

c=c =c=accepted: ± 0.03
3Numeric answer10 ptsNot answered

The normal density at d1=0.1d_1=0.1d1​=0.1 is φ(0.1)=0.3970\varphi(0.1)=0.3970φ(0.1)=0.3970. With S=100S=100S=100 and T=1T=1T=1, what is vega =S φ(d1)T=S\,\varphi(d_1)\sqrt T=Sφ(d1​)T​? Give two decimals.

v=v =v=accepted: ± 0.1
4Numeric answer15 ptsNot answered

The market price is 9.009.009.00 and the model price at σ=0.2\sigma=0.2σ=0.2 is 7.96567.96567.9656, with vega 39.7039.7039.70. What is the new volatility σ+(market−model)/vega\sigma+(\text{market}-\text{model})/\text{vega}σ+(market−model)/vega? Give four decimals.

s=s =s=accepted: ± 0.0005
5Match15 ptsNot answered

Match each scipy.special function with its job.

Pick the partner of each item on the left.

ndtr
expit
gammaln
logsumexp
comb
6Choice10 ptsNot answered

You need ln⁡(e1000+e1002)\ln(e^{1000}+e^{1002})ln(e1000+e1002) on a computer. Which way is safe?

7Explain in words20 ptsNot answered

A binomial probability for a 200-step tree contains 200!200!200!. In one or two sentences, explain why you should compute it with gammaln and logs.

Math modeKeyboard or LaTeX inputTask 1 of 7 · Ctrl ⏎ to check

Log in to run your code.

Every lecture is free to read. Create an account or log in to run code, run tests and submit this lab.

  • In-browser IDE with a bash terminal — nothing to install
  • Instant grading, XP and your place on the skill
Create an accountLog in
OR
Continue with GitHub