def test_es_example_weekly(): df = get_data() df = df.resample("W").first() mu = expected_returns.mean_historical_return(df, frequency=52) historical_rets = expected_returns.returns_from_prices(df).dropna() es = EfficientSemivariance(mu, historical_rets, frequency=52) es.efficient_return(0.2) np.testing.assert_allclose( es.portfolio_performance(), (0.2000000562544616, 0.07667633475531543, 2.3475307841574087), rtol=1e-4, atol=1e-4, )
def test_es_example_monthly(): df = get_data() df = df.resample("M").first() mu = expected_returns.mean_historical_return(df, frequency=12) historical_rets = expected_returns.returns_from_prices(df).dropna() es = EfficientSemivariance(mu, historical_rets, frequency=12) es.efficient_return(0.3) np.testing.assert_allclose( es.portfolio_performance(), (0.3, 0.04746519522734184, 5.899059271933824), rtol=1e-4, atol=1e-4, )
def test_efficient_risk_market_neutral(): es = EfficientSemivariance(*setup_efficient_semivariance(data_only=True), weight_bounds=(-1, 1)) w = es.efficient_risk(0.21, market_neutral=True) assert isinstance(w, dict) assert set(w.keys()) == set(es.tickers) np.testing.assert_almost_equal(es.weights.sum(), 0) assert (es.weights < 1).all() and (es.weights > -1).all() np.testing.assert_allclose( es.portfolio_performance(), (0.9257112257221027, 0.21, 4.312873624163129), rtol=1e-4, atol=1e-4, )
def test_es_errors(): df = get_data() mu = expected_returns.mean_historical_return(df) historical_rets = expected_returns.returns_from_prices(df) with pytest.warns(UserWarning): EfficientSemivariance(mu, historical_rets) historical_rets = historical_rets.dropna(axis=0, how="any") assert EfficientSemivariance(mu, historical_rets) historical_rets = historical_rets.iloc[:, :-1] with pytest.raises(ValueError): EfficientSemivariance(mu, historical_rets)
def test_es_example(): df = get_data() mu = expected_returns.mean_historical_return(df) historical_rets = expected_returns.returns_from_prices(df).dropna() es = EfficientSemivariance(mu, historical_rets) w = es.efficient_return(0.2) assert isinstance(w, dict) assert set(w.keys()) == set(es.tickers) np.testing.assert_almost_equal(es.weights.sum(), 1) assert all([i >= -1e-5 for i in w.values()]) np.testing.assert_allclose( es.portfolio_performance(), (0.20, 0.08558991313395496, 2.1030523036993265), rtol=1e-4, atol=1e-4, )
def test_efficient_return_short(): es = EfficientSemivariance(*setup_efficient_semivariance(data_only=True), weight_bounds=(None, None)) w = es.efficient_return(0.25) assert isinstance(w, dict) assert set(w.keys()) == set(es.tickers) np.testing.assert_almost_equal(es.weights.sum(), 1) np.testing.assert_allclose( es.portfolio_performance(), (0.25, 0.09073654273906914, 2.534811096726317), rtol=1e-4, atol=1e-4, ) sortino = es.portfolio_performance()[2] ef_long_only = setup_efficient_semivariance() ef_long_only.efficient_return(0.25) long_only_sortino = ef_long_only.portfolio_performance()[2] assert sortino > long_only_sortino
def test_es_return_sample(): df = get_data() mu = expected_returns.mean_historical_return(df) S = risk_models.sample_cov(df) # Generate a 1y sample of daily data np.random.seed(0) mu_daily = (1 + mu)**(1 / 252) - 1 S_daily = S / 252 sample_rets = pd.DataFrame(np.random.multivariate_normal( mu_daily, S_daily, 300), columns=mu.index) es = EfficientSemivariance(mu, sample_rets) w = es.efficient_return(0.2) assert isinstance(w, dict) assert set(w.keys()) == set(es.tickers) np.testing.assert_almost_equal(es.weights.sum(), 1) assert all([i >= -1e-5 for i in w.values()]) np.testing.assert_allclose( es.portfolio_performance(), (0.20, 0.10050247458629837, 1.7910016727029479), rtol=1e-4, atol=1e-4, ) # Cover verbose param case np.testing.assert_equal(es.portfolio_performance(verbose=True), es.portfolio_performance())
def test_es_example_short(): df = get_data() mu = expected_returns.mean_historical_return(df) historical_rets = expected_returns.returns_from_prices(df).dropna() es = EfficientSemivariance(mu, historical_rets, weight_bounds=(-1, 1)) w = es.efficient_return(0.2, market_neutral=True) goog_weight = w["GOOG"] historical_rets["GOOG"] -= historical_rets["GOOG"].quantile(0.75) es = EfficientSemivariance(mu, historical_rets, weight_bounds=(-1, 1)) w = es.efficient_return(0.2, market_neutral=True) goog_weight2 = w["GOOG"] assert abs(goog_weight2) >= abs(goog_weight)
def test_es_errors(): df = get_data() mu = expected_returns.mean_historical_return(df) historical_rets = expected_returns.returns_from_prices(df) with pytest.warns(UserWarning): EfficientSemivariance(mu, historical_rets) historical_rets = historical_rets.dropna(axis=0, how="any") es = EfficientSemivariance(mu, historical_rets) with pytest.raises(NotImplementedError): es.min_volatility() with pytest.raises(NotImplementedError): es.max_sharpe() with pytest.raises(ValueError): # Must be > 0 es.max_quadratic_utility(risk_aversion=-0.01) with pytest.raises(ValueError): # Must be > 0 es.efficient_return(target_return=-0.01) with pytest.raises(ValueError): # Must be <= max expected return es.efficient_return(target_return=np.abs(mu).max() + 0.01) with pytest.raises(AttributeError): # list not supported. EfficientSemivariance(mu, historical_rets.to_numpy().tolist()) historical_rets = historical_rets.iloc[:, :-1] with pytest.raises(ValueError): EfficientSemivariance(mu, historical_rets)
def test_es_no_returns(): # Issue 324 df = get_data() historical_rets = expected_returns.returns_from_prices(df).dropna() assert EfficientSemivariance(None, historical_rets)