Example #1
0
def plot_outofthemoney():
    """Plot model-implied out-of-the-money premium.

    """
    nobs = 200
    moneyness = np.linspace(-.2, .2, nobs)
    riskfree, maturity = .1/365, 30/365
    call = np.ones_like(moneyness).astype(bool)
    call[moneyness < 0] = False
    current_vol = .2**2/365

    rho = .9
    delta = 1.1
    phi = -.5
    price_vol = -1000
    price_ret = .6

    param = ARGparams(mean=current_vol, rho=rho, delta=delta,
                      phi=phi, price_ret=price_ret, price_vol=price_vol)
    argmodel = ARG(param=param)


    premium = argmodel.option_premium(vol=current_vol, moneyness=moneyness,
                                      maturity=maturity,
                                      riskfree=riskfree, call=call)
    vol = impvol_bisection(moneyness, maturity, premium, call)

    fig, axes = plt.subplots(nrows=2, ncols=1)
    axes[0].plot(moneyness, premium, label='premium')
    axes[1].plot(moneyness, vol, label='impvol')
    axes[0].legend()
    axes[1].legend()
    plt.show()
Example #2
0
    def test_gbm(self):
        """Test GBM model."""

        price, strike = 100, 110
        riskfree, maturity = .01, 30 / 365
        call = True
        put = np.logical_not(call)
        moneyness = lfmoneyness(price, strike, riskfree, maturity)

        sigma = .15

        model = GBM(GBMParam(sigma=sigma), riskfree, maturity)
        premium = cosmethod(model, moneyness=moneyness, call=call)
        premium_true = blackscholes_norm(moneyness, maturity, sigma, call)
        impvol_model = impvol_bisection(moneyness, maturity, premium, call)

        self.assertEqual(premium.shape, (1, ))
        np.testing.assert_array_almost_equal(premium, premium_true, 3)
        np.testing.assert_array_almost_equal(impvol_model, sigma, 2)

        moneyness = np.linspace(0, .1, 10)
        premium = cosmethod(model, moneyness=moneyness, call=call)
        premium_true = blackscholes_norm(moneyness, maturity, sigma, call)
        impvol_model = impvol_bisection(moneyness, maturity, premium, call)
        impvol_true = np.ones_like(impvol_model) * sigma

        self.assertEqual(premium.shape, moneyness.shape)
        np.testing.assert_array_almost_equal(premium, premium_true, 2)
        np.testing.assert_array_almost_equal(impvol_model, impvol_true, 2)

        riskfree = np.zeros_like(moneyness)
        premium = cosmethod(model, moneyness=moneyness, call=call)
        premium_true = blackscholes_norm(moneyness, maturity, sigma, call)
        impvol_model = impvol_bisection(moneyness, maturity, premium, call)

        self.assertEqual(premium.shape, moneyness.shape)
        np.testing.assert_array_almost_equal(premium, premium_true, 3)
        np.testing.assert_array_almost_equal(impvol_model, sigma, 2)

        moneyness = np.linspace(-.1, 0, 10)
        premium = cosmethod(model, moneyness=moneyness, call=put)
        premium_true = blackscholes_norm(moneyness, maturity, sigma, put)
        impvol_model = impvol_bisection(moneyness, maturity, premium, put)

        np.testing.assert_array_almost_equal(premium, premium_true, 2)
        np.testing.assert_array_almost_equal(impvol_model, impvol_true, 2)
    def test_gbm(self):
        """Test GBM model."""

        price, strike = 100, 110
        riskfree, maturity = .01, 30/365
        call = True
        put = np.logical_not(call)
        moneyness = lfmoneyness(price, strike, riskfree, maturity)

        sigma = .15

        model = GBM(GBMParam(sigma=sigma), riskfree, maturity)
        premium = cosmethod(model, moneyness=moneyness, call=call)
        premium_true = blackscholes_norm(moneyness, maturity, sigma, call)
        impvol_model = impvol_bisection(moneyness, maturity, premium, call)

        self.assertEqual(premium.shape, (1,))
        np.testing.assert_array_almost_equal(premium, premium_true, 3)
        np.testing.assert_array_almost_equal(impvol_model, sigma, 2)

        moneyness = np.linspace(0, .1, 10)
        premium = cosmethod(model, moneyness=moneyness, call=call)
        premium_true = blackscholes_norm(moneyness, maturity, sigma, call)
        impvol_model = impvol_bisection(moneyness, maturity, premium, call)
        impvol_true = np.ones_like(impvol_model) * sigma

        self.assertEqual(premium.shape, moneyness.shape)
        np.testing.assert_array_almost_equal(premium, premium_true, 2)
        np.testing.assert_array_almost_equal(impvol_model, impvol_true, 2)

        riskfree = np.zeros_like(moneyness)
        premium = cosmethod(model, moneyness=moneyness, call=call)
        premium_true = blackscholes_norm(moneyness, maturity, sigma, call)
        impvol_model = impvol_bisection(moneyness, maturity, premium, call)

        self.assertEqual(premium.shape, moneyness.shape)
        np.testing.assert_array_almost_equal(premium, premium_true, 3)
        np.testing.assert_array_almost_equal(impvol_model, sigma, 2)

        moneyness = np.linspace(-.1, 0, 10)
        premium = cosmethod(model, moneyness=moneyness, call=put)
        premium_true = blackscholes_norm(moneyness, maturity, sigma, put)
        impvol_model = impvol_bisection(moneyness, maturity, premium, put)

        np.testing.assert_array_almost_equal(premium, premium_true, 2)
        np.testing.assert_array_almost_equal(impvol_model, impvol_true, 2)
Example #4
0
    def test_bisection(self):
        """Test values of implied volatility (bisection method)."""
        premium = .024
        price = 1
        strike = 1
        riskfree = .02
        maturity = 30/365
        call = True
        moneyness = lfmoneyness(price, strike, riskfree, maturity)
        vol = impvol_bisection(moneyness, maturity, premium, call)

        self.assertAlmostEqual(float(vol), .2, 2)

        strike = [1, .95]
        premium = [.024, .057]
        moneyness = lfmoneyness(price, strike, riskfree, maturity)
        vol = impvol_bisection(moneyness, maturity, premium, call)

        np.testing.assert_array_almost_equal(vol, [.2, .2], 2)
Example #5
0
    def test_bisection(self):
        """Test values of implied volatility (bisection method)."""
        premium = .024
        price = 1
        strike = 1
        riskfree = .02
        maturity = 30 / 365
        call = True
        moneyness = lfmoneyness(price, strike, riskfree, maturity)
        vol = impvol_bisection(moneyness, maturity, premium, call)

        self.assertAlmostEqual(float(vol), .2, 2)

        strike = [1, .95]
        premium = [.024, .057]
        moneyness = lfmoneyness(price, strike, riskfree, maturity)
        vol = impvol_bisection(moneyness, maturity, premium, call)

        np.testing.assert_array_almost_equal(vol, [.2, .2], 2)
Example #6
0
    def test_bs_prices(self):
        """Test accuracy of back and forth BS conversion."""
        count = int(1e3)
        maturity = 30/365
        call = True
        sigma = np.random.uniform(.05, .8, count)
        moneyness = np.random.uniform(-.1, .1, count)
        premium = blackscholes_norm(moneyness, maturity, sigma, call)
        vol = impvol_bisection(moneyness, maturity, premium, call)

        np.testing.assert_array_almost_equal(vol, sigma, 3)
Example #7
0
    def test_bs_prices(self):
        """Test accuracy of back and forth BS conversion."""
        count = int(1e3)
        maturity = 30 / 365
        call = True
        sigma = np.random.uniform(.05, .8, count)
        moneyness = np.random.uniform(-.1, .1, count)
        premium = blackscholes_norm(moneyness, maturity, sigma, call)
        vol = impvol_bisection(moneyness, maturity, premium, call)

        np.testing.assert_array_almost_equal(vol, sigma, 3)
Example #8
0
def plot_smiles(fname=None):
    """Plot model-implied volatility smiles.

    """
    price = 1
    nobs = 100
    moneyness = np.linspace(-.1, .1, nobs)
    riskfree, maturity = .0, 30/365
    call = np.ones_like(moneyness).astype(bool)
    call[moneyness < 0] = False
    current_vol = .2**2/365

    rho = .9
    delta = 1.1
    phi = -.5
    price_vol = -1
    price_ret = .5

    points = 5

    sns.set_palette(sns.color_palette("binary_r", desat=.5))
    fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(7, 3))
    loc = 'upper center'

    phis = np.linspace(0, -.5, points)

    for phi in phis:
        param = ARGparams(mean=current_vol, rho=rho, delta=delta,
                          phi=phi, price_ret=price_ret, price_vol=price_vol)
        argmodel = ARG(param=param)

        premium = argmodel.option_premium(vol=current_vol, moneyness=moneyness,
                                          maturity=maturity,
                                          riskfree=riskfree, call=call)

        vol = impvol_bisection(moneyness, maturity, premium/price, call)
        axes[0].plot(moneyness*100, vol*100, label=str(phi))

    axes[0].legend(title='Leverage, $\phi$', loc=loc)
    axes[0].set_xlabel('Log-forward moneyness, $\log(F/S)$, %')
    axes[0].set_ylabel('Implied volatility, annualized %')

    maturities = np.linspace(30, 90, points) / 365
    phi = 0.

    for matur in maturities:
        param = ARGparams(mean=current_vol, rho=rho, delta=delta,
                          phi=phi, price_ret=price_ret, price_vol=price_vol)
        argmodel = ARG(param=param)

        premium = argmodel.option_premium(vol=current_vol, moneyness=moneyness,
                                          maturity=matur,
                                          riskfree=riskfree, call=call)

        vol = impvol_bisection(moneyness, matur, premium/price, call)
        axes[1].plot(moneyness*100, vol*100, label=str(int(matur*365)))

    axes[1].legend(title='Maturity, $T$', loc=loc)
    axes[1].set_xlabel('Log-forward moneyness, $\log(F/S)$, %')
    axes[1].set_ylabel('Implied volatility, annualized %')
    plt.tight_layout()
    if fname is not None:
        plt.savefig(fname)
    plt.show()
import pandas as pd

from impvol import (imp_vol, impvol_bisection, lfmoneyness, blackscholes_norm,
                    impvol_table)


if __name__ == '__main__':

    price = 1
    strike = 1
    riskfree = .02
    maturity = 30/365
    premium = .057
    call = True
    moneyness = lfmoneyness(price, strike, riskfree, maturity)
    vol = impvol_bisection(moneyness, maturity, premium, call)

    count = int(1e2)
    sigma = np.random.uniform(.05, .8, count)
    moneyness = np.random.uniform(-.1, .1, count)
    premium = blackscholes_norm(moneyness, maturity, sigma, call)

    text = 'Time elapsed: %.2f seconds'

    time_start = time.time()
    # Based on SciPy root method
    vol = imp_vol(moneyness, maturity, premium, call)
    print(np.allclose(sigma, vol))
    print(text % (time.time() - time_start))

    time_start = time.time()
Example #10
0
import numpy as np
import pandas as pd

from impvol import (imp_vol, impvol_bisection, lfmoneyness, blackscholes_norm,
                    impvol_table)

if __name__ == '__main__':

    price = 1
    strike = 1
    riskfree = .02
    maturity = 30 / 365
    premium = .057
    call = True
    moneyness = lfmoneyness(price, strike, riskfree, maturity)
    vol = impvol_bisection(moneyness, maturity, premium, call)

    count = int(1e2)
    sigma = np.random.uniform(.05, .8, count)
    moneyness = np.random.uniform(-.1, .1, count)
    premium = blackscholes_norm(moneyness, maturity, sigma, call)

    text = 'Time elapsed: %.2f seconds'

    time_start = time.time()
    # Based on SciPy root method
    vol = imp_vol(moneyness, maturity, premium, call)
    print(np.allclose(sigma, vol))
    print(text % (time.time() - time_start))

    time_start = time.time()
Example #11
0
    def impvol(self):
        """Implied Volatility.

        """
        return impvol_bisection(self.data['moneyness'], self.data['maturity'],
                                self.premium(), self.data['call'])
Example #12
0
    def impvol(self):
        """Implied Volatility.

        """
        return impvol_bisection(self.data['moneyness'], self.data['maturity'],
                                self.premium(), self.data['call'])