def test_hrp_portfolio(): df = get_data() returns = df.pct_change().dropna(how="all") hrp = HRPOpt(returns) w = hrp.optimize(linkage_method="single") # uncomment this line if you want generating a new file # pd.Series(w).to_csv(resource("weights_hrp.csv")) x = pd.read_csv(resource("weights_hrp.csv"), squeeze=True, index_col=0) pd.testing.assert_series_equal(x, pd.Series(w), check_names=False, rtol=1e-2) assert isinstance(w, dict) assert set(w.keys()) == set(df.columns) np.testing.assert_almost_equal(sum(w.values()), 1) assert all([i >= 0 for i in w.values()])
def test_bl_tau(): df = get_data() S = risk_models.sample_cov(df) prices = pd.read_csv(resource("spy_prices.csv"), parse_dates=True, index_col=0, squeeze=True) delta = black_litterman.market_implied_risk_aversion(prices) mcaps = get_market_caps() prior = black_litterman.market_implied_prior_returns(mcaps, delta, S) viewdict = {"GOOG": 0.40, "AAPL": -0.30, "FB": 0.30, "BABA": 0} # Need to change omega for this test to work omega = np.diag([0.01, 0.01, 0.01, 0.01]) bl0 = BlackLittermanModel(S, pi=prior, absolute_views=viewdict, tau=1e-10, omega=omega) bl1 = BlackLittermanModel(S, pi=prior, absolute_views=viewdict, tau=0.01, omega=omega) bl2 = BlackLittermanModel(S, pi=prior, absolute_views=viewdict, tau=0.1, omega=omega) # For tiny tau, posterior should roughly equal prior np.testing.assert_allclose(bl0.bl_returns(), bl0.pi.flatten(), rtol=1e-5) # For bigger tau, GOOG should be given more weight assert bl1.bl_returns()["GOOG"] > bl0.bl_returns()["GOOG"] assert bl2.bl_returns()["GOOG"] > bl1.bl_returns()["GOOG"]
def test_bl_market_prior(): df = get_data() S = risk_models.sample_cov(df) prices = pd.read_csv(resource("spy_prices.csv"), parse_dates=True, index_col=0, squeeze=True) delta = black_litterman.market_implied_risk_aversion(prices) mcaps = get_market_caps() with pytest.warns(RuntimeWarning): black_litterman.market_implied_prior_returns(mcaps, delta, S.values) prior = black_litterman.market_implied_prior_returns(mcaps, delta, S) viewdict = {"GOOG": 0.40, "AAPL": -0.30, "FB": 0.30, "BABA": 0} bl = BlackLittermanModel(S, pi=prior, absolute_views=viewdict) rets = bl.bl_returns() # compare posterior with prior for v in viewdict: assert (prior[v] <= rets[v] <= viewdict[v]) or (viewdict[v] <= rets[v] <= prior[v]) with pytest.raises(ValueError): bl.portfolio_performance() bl.bl_weights(delta) np.testing.assert_allclose( bl.portfolio_performance(), (0.2580693114409672, 0.265445955488424, 0.8968654692926723), ) # Check that bl.cov() has been called and used assert bl.posterior_cov is not None
def test_bl_weights(): df = get_data() S = risk_models.sample_cov(df) viewdict = { "AAPL": 0.20, "BBY": -0.30, "BAC": 0, "SBUX": -0.2, "T": 0.131321 } bl = BlackLittermanModel(S, absolute_views=viewdict) prices = pd.read_csv(resource("spy_prices.csv"), parse_dates=True, index_col=0, squeeze=True) delta = black_litterman.market_implied_risk_aversion(prices) bl.bl_weights(delta) w = bl.clean_weights() assert abs(sum(w.values()) - 1) < 1e-5 # check weights are allocated in same direction as views # (in absence of priors) assert all(viewdict[t] * w[t] >= 0 for t in viewdict) # numerical check test_weights = { "GOOG": 0.0, "AAPL": 1.40675, "FB": 0.0, "BABA": 0.0, "AMZN": 0.0, "GE": 0.0, "AMD": 0.0, "WMT": 0.0, "BAC": 0.02651, "GM": 0.0, "T": 2.81117, "UAA": 0.0, "SHLD": 0.0, "XOM": 0.0, "RRC": 0.0, "BBY": -1.44667, "MA": 0.0, "PFE": 0.0, "JPM": 0.0, "SBUX": -1.79776, } assert w == test_weights bl = BlackLittermanModel(S, absolute_views=viewdict) bl.optimize(delta) w2 = bl.clean_weights() assert w2 == w bl = BlackLittermanModel(S, absolute_views=pd.Series(viewdict)) bl.optimize(delta) w2 = bl.clean_weights() assert w2 == w