Skip to content

Commit 6835f19

Browse files
authored
Merge pull request #134 from PyFE/heston-mc
Heston mc
2 parents 55fd5d7 + e0cca6d commit 6835f19

File tree

3 files changed

+45
-29
lines changed

3 files changed

+45
-29
lines changed

pyfeng/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
SabrChoiWu2021P,
1414
)
1515
from .garch import GarchMcTimeStep, GarchUncorrBaroneAdesi2004
16+
from .ousv import OusvUncorrBallRoma1994
1617
from .sabr_int import SabrUncorrChoiWu2021
1718
from .sabr_mc import SabrMcCond
1819
from .nsvh import Nsvh1, NsvhMc

pyfeng/data/ousv_benchmark.xlsx

9.02 KB
Binary file not shown.

pyfeng/ousv.py

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,34 @@
22
import numpy as np
33
import scipy.integrate as scint
44
from . import sv_abc as sv
5+
from . import bsm
56

67

7-
class OusvSchobelZhu1998(sv.SvABC):
8+
class OusvABC(sv.SvABC, abc.ABC):
9+
model_type = "OUSV"
10+
11+
def avgvar_mv(self, var_0, texp):
12+
"""
13+
Mean and variance of the variance V(t+dt) given V(0) = var_0
14+
(variance is not implemented yet)
15+
16+
Args:
17+
var_0: initial variance
18+
texp: time step
19+
20+
Returns:
21+
mean, variance(=NULL)
22+
"""
23+
24+
mr_t = self.mr * texp
25+
e_mr = np.exp(-mr_t)
26+
x0 = var_0 - self.theta
27+
vv = self.vov**2/2/self.mr + self.theta**2 + \
28+
((x0**2 - self.vov**2/2/self.mr)*(1 + e_mr) + 4*self.theta * x0)*(1 - e_mr)/(2*self.mr*texp)
29+
return vv, None
30+
31+
32+
class OusvSchobelZhu1998(OusvABC):
833
"""
934
The implementation of Schobel & Zhu (1998)'s inverse FT pricing formula for European
1035
options the Ornstein-Uhlenbeck driven stochastic volatility process.
@@ -13,18 +38,15 @@ class OusvSchobelZhu1998(sv.SvABC):
1338
- Schöbel, R., & Zhu, J. (1999). Stochastic Volatility With an Ornstein–Uhlenbeck Process: an Extension. Review of Finance, 3(1), 23–46. https://doi.org/10.1023/A:1009803506170
1439
1540
Examples:
16-
>>> import pyfeng as pfex
17-
>>> model = pfex.OusvSchobelZhu1998(0.2, mr=4, vov=0.1, rho=-0.7, intr=0.09531)
41+
>>> import pyfeng as pf
42+
>>> model = pf.OusvSchobelZhu1998(0.2, mr=4, vov=0.1, rho=-0.7, intr=0.09531)
1843
>>> model.price(100, 100, texp=np.array([1, 5, 10]))
1944
array([13.21493, 40.79773, 62.76312])
20-
>>> model = pfex.OusvSchobelZhu1998(0.25, mr=8, vov=0.3, rho=-0.6, intr=0.09531)
45+
>>> model = pf.OusvSchobelZhu1998(0.25, mr=8, vov=0.3, rho=-0.6, intr=0.09531)
2146
>>> model.price(np.array([90, 100, 110]), 100, texp=1)
2247
array([21.41873, 15.16798, 10.17448])
2348
"""
2449

25-
model_type = "OUSV"
26-
var_process = False
27-
2850
def D_B_C(self, s1, s2, s3, texp):
2951
# implement the formula for D(t,T), B(t,T), C(t,T) in paper appendix
3052
mr, theta, vov = self.mr, self.theta, self.vov
@@ -106,9 +128,22 @@ def price(self, strike, spot, texp, cp=1):
106128
return df * fwd * price
107129

108130

109-
class OusvMcABC(sv.SvABC, sv.CondMcBsmABC, abc.ABC):
131+
class OusvUncorrBallRoma1994(OusvABC):
132+
133+
def price(self, strike, spot, texp, cp=1):
134+
135+
if not np.isclose(self.rho, 0.0):
136+
print(f"Pricing ignores rho = {self.rho}.")
137+
138+
avgvar, _ = self.avgvar_mv(self.sigma, texp)
139+
m_bs = bsm.Bsm(np.sqrt(avgvar), intr=self.intr, divr=self.divr)
140+
price = m_bs.price(strike, spot, texp, cp)
141+
142+
return price
143+
144+
145+
class OusvMcABC(OusvABC, sv.CondMcBsmABC, abc.ABC):
110146

111-
model_type = "OUSV"
112147
var_process = False
113148

114149
@abc.abstractmethod
@@ -156,26 +191,6 @@ def cond_spot_sigma(self, vol_0, texp):
156191
sigma_cond = np.sqrt((1 - self.rho**2) * var_mean) / vol_0
157192
return spot_cond, sigma_cond
158193

159-
def avgvar_mv(self, var_0, texp):
160-
"""
161-
Mean and variance of the variance V(t+dt) given V(0) = var_0
162-
(variance is not implemented yet)
163-
164-
Args:
165-
var_0: initial variance
166-
texp: time step
167-
168-
Returns:
169-
mean, variance
170-
"""
171-
172-
mr_t = self.mr * texp
173-
e_mr = np.exp(-mr_t)
174-
x0 = var_0 - self.theta
175-
vv = self.vov**2/2/self.mr + self.theta**2 + \
176-
((x0**2 - self.vov**2/2/self.mr)*(1 + e_mr) + 4*self.theta * x0)*(1 - e_mr)/(2*self.mr*texp)
177-
return vv
178-
179194

180195
class OusvMcTimeStep(OusvMcABC):
181196
"""

0 commit comments

Comments
 (0)