Test Normal model implementation


In [1]:
import numpy as np

In [5]:
# import
#from option_models import bsm
#from option_models import normal

#import option_models as opt
from option_models import normal

In [6]:
### only run this when you changed the class definition
import imp
imp.reload(opt)


Out[6]:
<module 'option_models' from 'C:\\Users\\jaehyuk\\Documents\\GitHub\\SABRmodel_Base\\option_models\\__init__.py'>

In [ ]:

Price


In [11]:
# create model
texp = 0.25
vol = 20
norm1 = normal.Model(texp, vol)

In [13]:
# price
strike = 102
spot = 100

price = norm1.price(strike=strike, spot=spot, cp_sign=1)
print(price)


3.06894635863

Implied vol


In [21]:
# Randomly generate spot/strike/expiry/intr/divr/cp_sign
# Then test implied volatility

for k in range(100):
    spot = np.random.uniform(80,100)
    strike = np.random.uniform(80,100)
    vol = np.random.uniform(10, 20)
    texp = np.random.uniform(0.1, 5)
    intr = np.random.uniform(0, 0.3)
    divr = np.random.uniform(0, 0.3)
    cp_sign = 1 if np.random.rand() > 0.5 else -1

    #print( spot, strike, vol, texp, intr, divr, cp_sign)

    norm1 = normal.Model(texp=texp, vol=vol, intr=intr, divr=divr)
    price = norm1.price(strike, spot, cp_sign=cp_sign)
    
    # get implied vol
    vol_imp = norm1.impvol(price, strike, spot, cp_sign=cp_sign)
    
    # now price option with the obtained implied vol
    price_imp = norm1.price(strike, spot, texp, vol=vol_imp, cp_sign=cp_sign )
    
    # compare the two prices
    assert( abs(price - price_imp) < 1e-8 )


---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-21-3132d7cfd66d> in <module>()
     17 
     18     # get implied vol
---> 19     vol_imp = norm1.impvol(price, strike, spot, cp_sign=cp_sign)
     20 
     21     # now price option with the obtained implied vol

C:\Users\jaehyuk\Documents\GitHub\SABRmodel_Base\option_models\normal.py in impvol(self, price_in, strike, spot, texp, cp_sign)
     72         iv_func = lambda _vol: \
     73             price(strike, forward, _vol, texp, cp_sign=cp_sign) - price_fwd
---> 74         vol = sopt.brentq(iv_func, 0, price_straddle*np.sqrt(np.pi/2/texp))
     75         return vol

C:\sw\Anaconda3\lib\site-packages\scipy\optimize\zeros.py in brentq(f, a, b, args, xtol, rtol, maxiter, full_output, disp)
    440     if rtol < _rtol:
    441         raise ValueError("rtol too small (%g < %g)" % (rtol, _rtol))
--> 442     r = _zeros._brentq(f,a,b,xtol,rtol,maxiter,args,full_output,disp)
    443     return results_c(full_output, r)
    444 

ValueError: f(a) and f(b) must have different signs

In [20]:
k, price, vol, texp, spot, strike


Out[20]:
(0,
 4.7773418584968734,
 18.374885870158657,
 2.5265769662723123,
 87.10695939105364,
 96.05799577665624)

In [ ]: