def test_vargamma(self): """Test VarGamma model.""" price, strike = 100, 90 riskfree, maturity = 0, 30 / 365 moneyness = np.log(strike / price) - riskfree * maturity nu = .2 theta = -.14 sigma = .25 param = VarGammaParam(theta=theta, nu=nu, sigma=sigma) model = VarGamma(param, riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=True) self.assertEqual(premium.shape, (1, )) moneyness = np.linspace(-.1, .1, 10) premium = cosmethod(model, moneyness=moneyness, call=True) self.assertEqual(premium.shape, moneyness.shape) riskfree = np.zeros_like(moneyness) premium = cosmethod(model, moneyness=moneyness, call=True) self.assertEqual(premium.shape, moneyness.shape)
def test_heston(self): """Test Heston model.""" price, strike = 100, 90 riskfree, maturity = 0, 30 / 365 moneyness = np.log(strike / price) - riskfree * maturity lm = 1.5768 mu = .12**2 eta = .5751 rho = -.0 sigma = .12**2 param = HestonParam(lm=lm, mu=mu, eta=eta, rho=rho, sigma=sigma) model = Heston(param, riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=True) self.assertEqual(premium.shape, (1, )) moneyness = np.linspace(-.1, .1, 10) premium = cosmethod(model, moneyness=moneyness, call=True) self.assertEqual(premium.shape, moneyness.shape) riskfree = np.zeros_like(moneyness) premium = cosmethod(model, moneyness=moneyness, call=True) self.assertEqual(premium.shape, moneyness.shape)
def test_heston(self): """Test Heston model.""" price, strike = 100, 90 riskfree, maturity = 0, 30/365 moneyness = np.log(strike/price) - riskfree * maturity lm = 1.5768 mu = .12**2 eta = .5751 rho = -.0 sigma = .12**2 param = HestonParam(lm=lm, mu=mu, eta=eta, rho=rho, sigma=sigma) model = Heston(param, riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=True) self.assertEqual(premium.shape, (1,)) moneyness = np.linspace(-.1, .1, 10) premium = cosmethod(model, moneyness=moneyness, call=True) self.assertEqual(premium.shape, moneyness.shape) riskfree = np.zeros_like(moneyness) premium = cosmethod(model, moneyness=moneyness, call=True) self.assertEqual(premium.shape, moneyness.shape)
def test_argamma(self): """Test ARG model.""" price, strike = 100, 90 riskfree, maturity = 0, 30/365 moneyness = np.log(strike/price) - riskfree * maturity rho = .55 delta = .75 mu = .2**2/365 sigma = .2**2/365 phi = -.0 theta1 = -16.0 theta2 = 20.95 param = ARGParam(rho=rho, delta=delta, mu=mu, sigma=sigma, phi=phi, theta1=theta1, theta2=theta2) model = ARG(param, riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=True) self.assertEqual(premium.shape, (1,)) moneyness = np.linspace(-.1, .1, 10) premium = cosmethod(model, moneyness=moneyness, call=True) self.assertEqual(premium.shape, moneyness.shape) riskfree = np.zeros_like(moneyness) premium = cosmethod(model, moneyness=moneyness, call=True) self.assertEqual(premium.shape, moneyness.shape)
def test_vargamma(self): """Test VarGamma model.""" price, strike = 100, 90 riskfree, maturity = 0, 30/365 moneyness = np.log(strike/price) - riskfree * maturity nu = .2 theta = -.14 sigma = .25 param = VarGammaParam(theta=theta, nu=nu, sigma=sigma) model = VarGamma(param, riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=True) self.assertEqual(premium.shape, (1,)) moneyness = np.linspace(-.1, .1, 10) premium = cosmethod(model, moneyness=moneyness, call=True) self.assertEqual(premium.shape, moneyness.shape) riskfree = np.zeros_like(moneyness) premium = cosmethod(model, moneyness=moneyness, call=True) self.assertEqual(premium.shape, moneyness.shape)
def single_premium(): """Test COS method for floats. """ price, strike = 100, 90 riskfree, maturity = 0, 30 / 365 sigma = .15 moneyness = np.log(strike / price) - riskfree * maturity model = GBM(GBMParam(sigma=sigma), riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=True) print(premium) nu = .2 theta = -.14 sigma = .25 param = VarGammaParam(theta=theta, nu=nu, sigma=sigma) model = VarGamma(param, riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=True) print(premium) lm = 1.5768 mu = .12**2 eta = .5751 rho = -.0 sigma = .12**2 param = HestonParam(lm=lm, mu=mu, eta=eta, rho=rho, sigma=sigma) model = Heston(param, riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=True) print(premium) rho = .55 delta = .75 mu = .2**2 / 365 sigma = .2**2 / 365 phi = -.0 theta1 = -16.0 theta2 = 20.95 param = ARGParam(rho=rho, delta=delta, mu=mu, sigma=sigma, phi=phi, theta1=theta1, theta2=theta2) model = ARG(param, riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=True) print(premium)
def multiple_premia_argamma(): """Plot model-implied out-of-the-money premium for ARG model. """ nobs = 200 moneyness = np.linspace(-.2, .2, nobs) riskfree, maturity = .1, 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 = .6 param = ARGParam(rho=rho, delta=delta, mu=current_vol, sigma=current_vol, phi=phi, theta1=price_vol, theta2=price_ret) model = ARG(param, riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=call) plt.plot(moneyness, premium) plt.show()
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)
def single_premium(): """Test COS method for floats. """ price, strike = 100, 90 riskfree, maturity = 0, 30/365 sigma = .15 moneyness = np.log(strike/price) - riskfree * maturity model = GBM(GBMParam(sigma=sigma), riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=True) print(premium) nu = .2 theta = -.14 sigma = .25 param = VarGammaParam(theta=theta, nu=nu, sigma=sigma) model = VarGamma(param, riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=True) print(premium) lm = 1.5768 mu = .12**2 eta = .5751 rho = -.0 sigma = .12**2 param = HestonParam(lm=lm, mu=mu, eta=eta, rho=rho, sigma=sigma) model = Heston(param, riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=True) print(premium) rho = .55 delta = .75 mu = .2**2/365 sigma = .2**2/365 phi = -.0 theta1 = -16.0 theta2 = 20.95 param = ARGParam(rho=rho, delta=delta, mu=mu, sigma=sigma, phi=phi, theta1=theta1, theta2=theta2) model = ARG(param, riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=True) print(premium)
def multiple_premia_gbm(nobs=2000): """Test COS method on the grid. """ sigma = .15 price = 1 strike = np.exp(np.linspace(-.1, .1, nobs)) riskfree, maturity = 0, 30/365 moneyness = np.log(strike/price) - riskfree * maturity call = np.ones_like(moneyness).astype(bool) call[moneyness < 0] = False model = GBM(GBMParam(sigma=sigma), riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=call) plt.plot(strike, premium) plt.show()
def multiple_premia_gbm(nobs=2000): """Test COS method on the grid. """ sigma = .15 price = 1 strike = np.exp(np.linspace(-.1, .1, nobs)) riskfree, maturity = 0, 30 / 365 moneyness = np.log(strike / price) - riskfree * maturity call = np.ones_like(moneyness).astype(bool) call[moneyness < 0] = False model = GBM(GBMParam(sigma=sigma), riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=call) plt.plot(strike, premium) plt.show()
def option_premium(self, vol=None, moneyness=None, maturity=None, riskfree=None, call=None, data=None, npoints=2**10): """Model implied option premium via COS method. Parameters ---------- vol : array_like Current variance per day moneyness : array_like Log-forward moneyness, np.log(strike/price) - riskfree * maturity maturity : float, optional Maturity of the option or simply time horizon. Fraction of a year, i.e. 30/365 riskfree : float, optional Risk-free rate of return per day call : bool array_like Call/Put flag data : pandas DataFrame, record array, or dictionary of arrays Structured data. Mandatory labels: vol, moneyness, maturity, riskfree, call npoints : int Number of points on the grid. The more the better, but slower. Returns ------- array_like Model implied option premium via COS method """ if data is not None: try: data = data.to_records() except: pass maturity = data['maturity'] riskfree = data['riskfree'] vol = data['vol'] moneyness = data['moneyness'] call = data['call'] self.maturity = maturity self.riskfree = riskfree self.vol = vol return cosmethod(self, moneyness=moneyness, call=call, npoints=npoints)
def cos_heston_price(S_0, K, r, T, v, v_0, kappa, gamma, rho, call=True): """ Pricer for European option (single asset) under Heston dynamic :param S_0: init stock price :param K: strike :param r: risk-free rate :param T: maturity :param v: long term mean variance :param v_0: initial variance :param kappa: reversion speed :param gamma: vol coefficient of vol :param rho: correlation between stock and volatility dynamic :param call: call if True, put otherwise :return: Option price """ moneyness = np.log(K / S_0) - r * T param = HestonParam(lm=kappa, mu=v, eta=gamma, rho=rho, sigma=v_0) model = Heston(param, r, T) P = cosmethod(model, moneyness=moneyness, call=call) return P[0]
def multiple_premia_heston(nobs=2000): """Test COS method on the grid. """ lm = 1.5768 mu = .12**2 eta = .5751 rho = -.0 sigma = .12**2 price = 1 strike = np.exp(np.linspace(-.1, .1, nobs)) maturity = 30/365 riskfree = .01 * np.ones(nobs) moneyness = np.log(strike/price) - riskfree * maturity call = np.ones_like(moneyness).astype(bool) call[moneyness < 0] = False param = HestonParam(lm=lm, mu=mu, eta=eta, rho=rho, sigma=sigma) model = Heston(param, riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=call) plt.plot(strike, premium) plt.show()
def multiple_premia_heston(nobs=2000): """Test COS method on the grid. """ lm = 1.5768 mu = .12**2 eta = .5751 rho = -.0 sigma = .12**2 price = 1 strike = np.exp(np.linspace(-.1, .1, nobs)) maturity = 30 / 365 riskfree = .01 * np.ones(nobs) moneyness = np.log(strike / price) - riskfree * maturity call = np.ones_like(moneyness).astype(bool) call[moneyness < 0] = False param = HestonParam(lm=lm, mu=mu, eta=eta, rho=rho, sigma=sigma) model = Heston(param, riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=call) plt.plot(strike, premium) plt.show()
def multiple_premia_argamma(): """Plot model-implied out-of-the-money premium for ARG model. """ nobs = 200 moneyness = np.linspace(-.2, .2, nobs) riskfree, maturity = .1, 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 = .6 param = ARGParam(rho=rho, delta=delta, mu=current_vol, sigma=current_vol, phi=phi, theta1=price_vol, theta2=price_ret) model = ARG(param, riskfree, maturity) premium = cosmethod(model, moneyness=moneyness, call=call) plt.plot(moneyness, premium) plt.show()