Skip to content

Commit e61d8bd

Browse files
authored
Merge pull request #154 from PyFE/ousv
Cumulative Changes in SV models
2 parents c1ab23c + 95fc705 commit e61d8bd

19 files changed

+1010
-433
lines changed

.idea/PyFENG.iml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyfeng/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Norm,
33
) # the order is sensitive because of `price_barrier` method. Put it before .bsm
44
from .bsm import Bsm, BsmDisp
5-
from .cev import Cev
5+
from .cev import Cev, CevMc
66
from .gamma import InvGam, InvGauss
77
from .sv_fft import HestonFft, BsmFft, OusvFft, VarGammaFft, ExpNigFft, Sv32Fft
88
from .sabr import (
@@ -22,6 +22,8 @@
2222
from .sabr_int import SabrUncorrChoiWu2021
2323
from .sabr_mc import SabrMcTimeDisc
2424
from .nsvh import Nsvh1, NsvhMc, NsvhGaussQuad
25+
from .svi import Svi
26+
2527
from .multiasset import (
2628
BsmSpreadKirk,
2729
BsmSpreadBjerksund2014,

pyfeng/bsm.py

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ def moments_vsk(self, texp=1):
406406

407407
class BsmDisp(smile.OptSmileABC, Bsm):
408408
"""
409-
Displaced Black-Scholes-Merton model for option pricing. Displace price,
409+
Displaced Black-Scholes-Merton model for option pricing. Displaced price,
410410
411411
D(F_t) = beta*F_t + (1-beta)*A
412412
@@ -449,7 +449,7 @@ def __init__(self, sigma, beta=1, pivot=0, *args, **kwargs):
449449

450450
@property
451451
def sigma(self):
452-
return self.sigma_disp*self.beta
452+
return self.sigma_disp * self.beta
453453

454454
@sigma.setter
455455
def sigma(self, sigma):
@@ -463,7 +463,7 @@ def disp_spot(self, spot):
463463
spot: spot (or forward) price
464464
465465
Returns:
466-
Displaces spot
466+
Displaced spot
467467
"""
468468
return self.beta*spot + (1 - self.beta)*self.pivot
469469

@@ -476,7 +476,7 @@ def disp_strike(self, strike, texp):
476476
texp: time to expiry
477477
478478
Returns:
479-
Displace strike
479+
Displaced strike
480480
"""
481481
return self.beta*strike + (1 - self.beta)*self.forward(self.pivot, texp)
482482

@@ -540,13 +540,7 @@ def vol_smile(self, strike, spot, texp, cp=1, model="bsm"):
540540
kkd = self.disp_strike(strike, texp)/fwdd
541541
lnkd = np.log(kkd)
542542
# self.sigma actually means self.beta * self._sigma
543-
vol = (
544-
self.sigma_disp
545-
*fwdd
546-
*np.sqrt(kkd)
547-
*(1 + lnkd**2/24)
548-
/(1 + self.sigma**2*texp/24)
549-
)
543+
vol = self.sigma_disp * fwdd * np.sqrt(kkd) * (1 + lnkd**2/24) / (1 + self.sigma**2*texp/24)
550544
elif model.lower() == "bsm-approx":
551545
fwd = self.forward(spot, texp)
552546
kk = strike/fwd
@@ -558,12 +552,7 @@ def vol_smile(self, strike, spot, texp, cp=1, model="bsm"):
558552

559553
# self.sigma actually means self.beta * self.sigma_disp
560554
vol = self.sigma_disp*(fwdd/fwd)*np.sqrt(kkd/kk)
561-
vol *= (
562-
(1 + lnkd**2/24)
563-
/(1 + lnk**2/24)
564-
*(1 + vol**2*texp/24)
565-
/(1 + self.sigma**2*texp/24)
566-
)
555+
vol *= (1 + lnkd**2/24) / (1 + lnk**2/24) * (1 + vol**2*texp/24) / (1 + self.sigma**2*texp/24)
567556
else:
568557
vol = super().vol_smile(strike, spot, texp, model=model, cp=cp)
569558

0 commit comments

Comments
 (0)