Beispiel #1
0
    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)
Beispiel #2
0
    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)
Beispiel #3
0
    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)
Beispiel #4
0
    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
Beispiel #5
0
    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
Beispiel #6
0
# -*- 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)