def price0(self, strike, spot, texp=None, cp=1): ''' Your MC routine goes here Generate paths for vol only. Then compute integrated variance and BSM price. Then get prices (vector) for all strikes You may fix the random number seed ''' # method 2 m = pf.BsmNdMc(self.vov, rn_seed=12345) tobs = np.arange(0, 101) / 100 * texp _ = m.simulate(tobs=tobs, n_path=1000) sigma_path = np.squeeze(m.path) * self.sigma sigma0 = sigma_path[0, :] sigma_final = sigma_path[-1, :] int_var = spint.simps(sigma_path**2, dx=1, axis=0) / 100 spot_mc = spot * np.exp(self.rho * (sigma_final - sigma0) / self.vov - 0.5 * self.rho**2 * int_var) vol = np.sqrt((1 - self.rho**2) * int_var / texp) price = [] for s in strike: price.append(bsm.price(s, spot_mc, texp, vol, cp_sign=cp)) return np.mean(price, axis=1)
def test_BsmNormNdMc(self): spot = np.ones(4) * 100 sigma = np.ones(4) * 0.4 texp = 5 # Basket Option with equal weight payoff = lambda x: np.fmax(np.mean(x, axis=1) - strike, 0 ) # Basket option strikes = np.arange(80, 121, 10) # Test BsmNd m = pf.BsmNdMc(sigma, cor=0.5, rn_seed=1234) m.simulate(tobs=[texp], n_path=20000) p = [] for strike in strikes: p.append(m.price_european(spot, texp, payoff)) p = np.array(p) p2 = np.array( [36.31612946, 31.80861014, 27.91269315, 24.55319506, 21.62677625]) np.testing.assert_almost_equal(p, p2) # Test NormNd m = pf.NormNdMc(sigma * spot, cor=0.5, rn_seed=1234) m.simulate(tobs=[texp], n_path=20000) p = [] for strike in strikes: p.append(m.price_european(spot, texp, payoff)) p = np.array(p) p2 = np.array( [39.42304794, 33.60383167, 28.32667559, 23.60383167, 19.42304794]) np.testing.assert_almost_equal(p, p2)
def price0(self, strike, spot, texp=None, cp=1): ''' Your MC routine goes here Generate paths for vol and price first. Then get prices (vector) for all strikes You may fix the random number seed ''' m = pf.BsmNdMc(self.sigma, rn_seed=12345) m.simulate(n_path=20000, tobs=[texp]) p = [] payoff = lambda x: np.fmax(np.mean(x, axis=1) - s, 0) # Basket option for s in strike: p.append(m.price_european(spot, texp, payoff)) return np.array(p)
def price(self, strike, spot, texp=None, cp=1): ''' Your MC routine goes here Generate paths for vol only. Then compute integrated variance and BSM price. Then get prices (vector) for all strikes You may fix the random number seed ''' n_path = 100000 N = 100 # simulate sigma m = pf.BsmNdMc(self.vov) tobs = np.arange(0, N + 1) * texp / N m.simulate(tobs=tobs, n_path=n_path) sigma_path = np.squeeze(m.path) sigma_final = sigma_path[-1, :] int_var = spint.simps(sigma_path**2, dx=1, axis=0) * texp / N # get S(bsm) and sigma(bsm) sigma_0 = self.sigma sigma_T = sigma_final * sigma_0 S_bs = spot * np.exp(self.rho / self.vov * (sigma_T - sigma_0) - 0.5 * (self.rho * sigma_0)**2 * texp * int_var) sigma_bs = sigma_0 * np.sqrt((1 - self.rho**2) * int_var) # bsm formula disc_fac = np.exp(-texp * self.intr) sigma_std = np.maximum( np.array(sigma_bs) * np.sqrt(texp), np.finfo(float).eps) spst = ss # scipy.stats price = np.ones(len(strike)) for i, K in enumerate(strike): d1 = np.log(S_bs / K) / sigma_std d2 = d1 - 0.5 * sigma_std d1 += 0.5 * sigma_std cp = np.array(cp) price_k = S_bs * \ spst.norm.cdf(cp * d1) - K * spst.norm.cdf(cp * d2) price_k *= cp * disc_fac price[i] = np.mean(price_k) return price
def price(self, strike, spot, texp, cp=1): ''' Your MC routine goes here Generate paths for vol only. Then compute integrated variance and normal price. You may fix the random number seed ''' n_path = 100000 N = 100 # simulate sigma m = pf.BsmNdMc(self.vov) tobs = np.arange(0, N + 1) * texp / N m.simulate(tobs=tobs, n_path=n_path) sigma_path = np.squeeze(m.path) sigma_final = sigma_path[-1, :] int_var = spint.simps(sigma_path**2, dx=1, axis=0) * texp / N # get S(norm) and sigma(norm) sigma_0 = self.sigma sigma_T = sigma_final * sigma_0 S_norm = spot + self.rho / self.vov * (sigma_T - sigma_0) sigma_norm = sigma_0 * np.sqrt((1 - self.rho**2) * int_var) # bachelier formula df = np.exp(-texp * self.intr) fwd = S_norm sigma_std = np.maximum( np.array(sigma_norm) * np.sqrt(texp), np.finfo(float).eps) spst = ss price = np.ones(len(strike)) for i, K in enumerate(strike): d = (fwd - K) / sigma_std price_k = df * (cp * (fwd - K) * spst.norm.cdf(cp * d) + sigma_std * spst.norm.pdf(d)) price[i] = np.mean(price_k) return price
# -*- coding: utf-8 -*- """ Created on Sat Apr 10 23:47:26 2021 @author: lenovo """ import pyfeng as pf import numpy as np import imp m = pf.BsmNdMc(np.array([0.1, 0.1, 0.1, 0.1]), cor=0, intr=0.0, divr=0.0, rn_seed=1234) texp = 5 tobs = np.arange(101) * texp / 100 haha = m.simulate(tobs=tobs, n_path=1000)