Пример #1
0
    def test_vol_values(self):
        """Test values of implied volatility."""
        premium = .024
        price = 1
        strike = 1
        riskfree = .02
        maturity = 30/365
        call = True
        moneyness = lfmoneyness(price, strike, riskfree, maturity)
        vol = imp_vol(moneyness, maturity, premium, call)

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

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

        np.testing.assert_array_almost_equal(vol, [.2, .2], 2)
Пример #2
0
    def test_vol_values(self):
        """Test values of implied volatility."""
        premium = .024
        price = 1
        strike = 1
        riskfree = .02
        maturity = 30 / 365
        call = True
        moneyness = lfmoneyness(price, strike, riskfree, maturity)
        vol = imp_vol(moneyness, maturity, premium, call)

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

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

        np.testing.assert_array_almost_equal(vol, [.2, .2], 2)
Пример #3
0
    def test_moneyness(self):
        """Test conversion to moneyness."""

        price, strike, riskfree, time = 1, 1, 0, .5
        moneyness = lfmoneyness(price, strike, riskfree, time)

        self.assertEqual(moneyness, 0)

        price, riskfree, time = 1, 0, .5
        strike = [1, np.e]
        moneyness = lfmoneyness(price, strike, riskfree, time)

        np.testing.assert_array_equal(moneyness, np.array([0, 1]))

        strike, riskfree, time = 1, 0, .5
        price = [1, np.e]
        moneyness = lfmoneyness(price, strike, riskfree, time)

        np.testing.assert_array_equal(moneyness, np.array([0, -1]))
Пример #4
0
    def test_moneyness(self):
        """Test conversion to moneyness."""

        price, strike, riskfree, time = 1, 1, 0, .5
        moneyness = lfmoneyness(price, strike, riskfree, time)

        self.assertEqual(moneyness, 0)

        price, riskfree, time = 1, 0, .5
        strike = [1, np.e]
        moneyness = lfmoneyness(price, strike, riskfree, time)

        np.testing.assert_array_equal(moneyness, np.array([0, 1]))

        strike, riskfree, time = 1, 0, .5
        price = [1, np.e]
        moneyness = lfmoneyness(price, strike, riskfree, time)

        np.testing.assert_array_equal(moneyness, np.array([0, -1]))
Пример #5
0
def import_vol_surface():
    """Import volatility surface.
    Infer risk-free rate directly from data.

    """
    zf = zipfile.ZipFile(path + "SPX_surface.zip", "r")
    name = zf.namelist()[0]
    df = pd.read_csv(zf.open(name), converters={"date": convert_dates})
    df.loc[:, "weekday"] = df["date"].apply(lambda x: x.weekday())

    # Apply some filters
    df = df[df["weekday"] == 2]
    df = df[df["days"] <= 365]
    df = df.drop("weekday", axis=1)

    surface = df  # .set_index(['cp_flag', 'date', 'days']).sort_index()

    cols = {"impl_volatility": "imp_vol", "impl_strike": "strike", "impl_premium": "premium"}
    surface.rename(columns=cols, inplace=True)

    # TODO : who term structure should be imported and merged!
    riskfree = load_riskfree().reset_index()
    dividends = load_dividends().reset_index()
    spx = load_spx().reset_index()

    surface = pd.merge(surface, riskfree)
    surface = pd.merge(surface, spx)
    surface = pd.merge(surface, dividends)

    # Adjust riskfree by dividend yield
    surface["riskfree"] -= surface["rate"]
    # Remove percentage point
    surface["riskfree"] /= 100
    # Replace 'cp_flag' with True/False 'call' variable
    surface.loc[:, "call"] = True
    surface.loc[surface["cp_flag"] == "P", "call"] = False
    # Normalize maturity to being a share of the year
    surface["maturity"] = surface["days"] / 365
    # Rename columns
    surface.rename(columns={"spx": "price"}, inplace=True)
    # Compute lf-moneyness
    surface["moneyness"] = lfmoneyness(surface["price"], surface["strike"], surface["riskfree"], surface["maturity"])
    # Compute option Delta normalized by current price
    surface["delta"] = delta(surface["moneyness"], surface["maturity"], surface["imp_vol"], surface["call"])
    # Compute option Vega normalized by current price
    surface["vega"] = vega(surface["moneyness"], surface["maturity"], surface["imp_vol"])
    # Sort index
    surface.sort_index(by=["date", "maturity", "moneyness"], inplace=True)

    print(surface.head())

    surface.to_hdf(path + "surface.h5", "surface")
Пример #6
0
def import_vol_surface_simple():
    """Import volatility surface. Simple version.

    """
    zf = zipfile.ZipFile(path + "SPX_surface.zip", "r")
    name = zf.namelist()[0]
    df = pd.read_csv(zf.open(name), converters={"date": convert_dates})
    df.loc[:, "weekday"] = df["date"].apply(lambda x: x.weekday())

    # Apply some filters
    df = df[df["weekday"] == 2]
    df = df[df["days"] <= 365]
    surface = df.drop("weekday", axis=1)

    cols = {"impl_volatility": "imp_vol", "impl_strike": "strike", "impl_premium": "premium"}
    surface.rename(columns=cols, inplace=True)

    spx = load_spx().reset_index()
    standard_options = load_standard_options()[["forward"]].reset_index()

    surface = pd.merge(surface, standard_options)
    surface = pd.merge(surface, spx)

    # Normalize maturity to being a share of the year
    surface["maturity"] = surface["days"] / 365
    surface["riskfree"] = np.log(surface["forward"] / surface["spx"])
    surface["riskfree"] /= surface["maturity"]
    # Remove percentage point

    # Replace 'cp_flag' with True/False 'call' variable
    surface.loc[:, "call"] = True
    surface.loc[surface["cp_flag"] == "P", "call"] = False
    # Rename columns
    surface.rename(columns={"spx": "price"}, inplace=True)
    # Compute lf-moneyness
    surface["moneyness"] = lfmoneyness(surface["price"], surface["strike"], surface["riskfree"], surface["maturity"])
    # Compute option Delta normalized by current price
    surface["delta"] = delta(surface["moneyness"], surface["maturity"], surface["imp_vol"], surface["call"])
    # Compute option Vega normalized by current price
    surface["vega"] = vega(surface["moneyness"], surface["maturity"], surface["imp_vol"])
    # Take out-of-the-money options
    calls = surface["call"] & (surface["moneyness"] >= 0)
    puts = np.logical_not(surface["call"]) & (surface["moneyness"] < 0)
    surface = pd.concat([surface[calls], surface[puts]])
    # Sort index
    surface.sort_index(by=["date", "maturity", "moneyness"], inplace=True)

    print(surface.head())

    surface.to_hdf(path + "surface.h5", "surface")
Пример #7
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)
Пример #8
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)
Пример #9
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))
Пример #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))