Beispiel #1
0
def test_parse_views():
    df = get_data()
    S = risk_models.sample_cov(df)

    viewlist = ["AAPL", 0.20, "GOOG", -0.30, "XOM", 0.40]  # incorrect type
    viewdict = {"AAPL": 0.20, "GOOG": -0.30, "XOM": 0.40, "fail": 0.1}

    with pytest.raises(TypeError):
        bl = BlackLittermanModel(S, absolute_views=viewlist)
    with pytest.raises(ValueError):
        bl = BlackLittermanModel(S, absolute_views=viewdict)

    del viewdict["fail"]
    bl = BlackLittermanModel(S, absolute_views=viewdict)

    # Check the picking matrix is correct
    test_P = np.copy(bl.P)
    test_P[0, 1] -= 1
    test_P[1, 0] -= 1
    test_P[2, 13] -= 1
    np.testing.assert_array_equal(test_P, np.zeros((len(bl.Q), bl.n_assets)))

    # Check views vector is correct
    np.testing.assert_array_equal(bl.Q,
                                  np.array([0.20, -0.30, 0.40]).reshape(-1, 1))
Beispiel #2
0
def test_idzorek_confidences_error():
    # if no confidences have been passed
    S = pd.DataFrame(np.diag(np.ones((5, ))), index=range(5), columns=range(5))
    # Constant view of 0.3 return
    views = {k: 0.3 for k in range(5)}
    # Prior
    pi = pd.Series(0.1, index=range(5))

    with pytest.raises(ValueError):
        BlackLittermanModel(S, pi=pi, absolute_views=views, omega="idzorek")

    with pytest.raises(ValueError):
        # Wrong number of views
        BlackLittermanModel(S,
                            pi=pi,
                            absolute_views=views,
                            omega="idzorek",
                            view_confidences=[0.2] * 4)

    with pytest.raises(ValueError):
        #  Conf greater than 1
        BlackLittermanModel(S,
                            pi=pi,
                            absolute_views=views,
                            omega="idzorek",
                            view_confidences=[1.1] * 5)

    with pytest.raises(ValueError):
        #  Conf less than zero
        BlackLittermanModel(S,
                            pi=pi,
                            absolute_views=views,
                            omega="idzorek",
                            view_confidences=[-0.1] * 5)
Beispiel #3
0
def test_bl_cov_default():
    df = get_data()
    cov_matrix = risk_models.CovarianceShrinkage(df).ledoit_wolf()
    viewdict = {"AAPL": 0.20, "BBY": -0.30, "BAC": 0, "SBUX": -0.2, "T": 0.131321}
    bl = BlackLittermanModel(cov_matrix, absolute_views=viewdict)
    S = bl.bl_cov()
    assert S.shape == (20, 20)
    assert S.index.equals(df.columns)
    assert S.index.equals(S.columns)
    assert S.notnull().all().all()
def test_cov_ndarray():
    df = get_data()
    prior_df = df.pct_change().mean()
    S = risk_models.sample_cov(df)
    views = pd.Series(0.1, index=S.columns)
    bl = BlackLittermanModel(S, pi=prior_df, Q=views)
    bl_nd = BlackLittermanModel(S.to_numpy(), pi=prior_df.to_numpy(), Q=views)
    #  Compare without missing ticker index values.
    np.testing.assert_equal(bl_nd.bl_returns().to_numpy(),
                            bl.bl_returns().to_numpy())
    np.testing.assert_equal(bl_nd.bl_cov().to_numpy(), bl.bl_cov().to_numpy())
    assert list(bl_nd.bl_weights().values()) == list(bl.bl_weights().values())
Beispiel #5
0
def test_bl_returns_no_prior():
    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)
    rets = bl.bl_returns()

    # Make sure it gives the same answer as explicit inverse
    test_rets = np.linalg.inv(
        np.linalg.inv(bl.tau * bl.cov_matrix) + bl.P.T @ np.linalg.inv(bl.omega) @ bl.P
    ) @ (bl.P.T @ np.linalg.inv(bl.omega) @ bl.Q)
    np.testing.assert_array_almost_equal(rets.values.reshape(-1, 1), test_rets)
Beispiel #6
0
def test_bl_equal_prior():
    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, pi="equal")
    np.testing.assert_array_almost_equal(bl.pi, np.ones((20, 1)) * 0.05)

    bl.bl_weights()
    np.testing.assert_allclose(
        bl.portfolio_performance(),
        (0.1877432247395778, 0.3246889329226965, 0.5166274785827545),
    )
Beispiel #7
0
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()
    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
Beispiel #8
0
def test_idzorek_with_priors():
    df = get_data()
    S = risk_models.sample_cov(df)

    mcaps = get_market_caps()

    viewdict = {"GOOG": 0.40, "AAPL": -0.30, "FB": 0.30, "BABA": 0}
    bl = BlackLittermanModel(
        S,
        pi="market",
        market_caps=mcaps,
        absolute_views=viewdict,
        omega="idzorek",
        view_confidences=[1, 1, 0.25, 0.25],
    )
    rets = bl.bl_returns()
    assert bl.omega[0, 0] == 0
    np.testing.assert_almost_equal(rets["AAPL"], -0.3)

    with pytest.raises(ValueError):
        bl.portfolio_performance()

    bl.bl_weights()
    np.testing.assert_allclose(
        bl.portfolio_performance(),
        (0.943431295405105, 0.5361412623208567, 1.722365653051476),
    )
    # 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("tests/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
    assert w == {
        "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,
    }
Beispiel #10
0
def test_market_implied_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()
    pi = black_litterman.market_implied_prior_returns(mcaps, delta, S)
    assert isinstance(pi, pd.Series)
    assert list(pi.index) == list(df.columns)
    assert pi.notnull().all()
    assert pi.dtype == "float64"
    np.testing.assert_array_almost_equal(
        pi.values,
        np.array([
            0.14933293,
            0.2168623,
            0.11219185,
            0.10362374,
            0.28416295,
            0.12196098,
            0.19036819,
            0.08860159,
            0.17724273,
            0.08779627,
            0.0791797,
            0.16460474,
            0.12854665,
            0.08657863,
            0.11230036,
            0.13875465,
            0.15017163,
            0.09066484,
            0.1696369,
            0.13270213,
        ]),
    )

    mcaps = pd.Series(mcaps)
    pi2 = black_litterman.market_implied_prior_returns(mcaps, delta, S)
    pd.testing.assert_series_equal(pi, pi2, check_exact=False)

    # Test alternate syntax
    bl = BlackLittermanModel(
        S,
        pi="market",
        market_caps=mcaps,
        absolute_views={"AAPL": 0.1},
        risk_aversion=delta,
    )
    pi = black_litterman.market_implied_prior_returns(mcaps,
                                                      delta,
                                                      S,
                                                      risk_free_rate=0)
    np.testing.assert_array_almost_equal(bl.pi, pi.values.reshape(-1, 1))
Beispiel #11
0
def test_dataframe_input():
    df = get_data()
    S = risk_models.sample_cov(df)

    view_df = pd.DataFrame(pd.Series(0.1, index=S.columns))
    bl = BlackLittermanModel(S, Q=view_df)
    np.testing.assert_array_equal(bl.P, np.eye(len(view_df)))

    # views on the first 10 assets
    view_df = pd.DataFrame(pd.Series(0.1, index=S.columns)[:10])
    picking = np.eye(len(S))[:10, :]
    assert BlackLittermanModel(S, Q=view_df, P=picking)

    prior_df = df.pct_change().mean()
    assert BlackLittermanModel(S, pi=prior_df, Q=view_df, P=picking)
    omega_df = S.iloc[:10, :10]
    assert BlackLittermanModel(S, pi=prior_df, Q=view_df, P=picking, omega=omega_df)
Beispiel #12
0
def test_bl_relative_views():
    df = get_data()
    S = risk_models.CovarianceShrinkage(df).ledoit_wolf()

    # 1. SBUX will drop by 20%
    # 2. GOOG outperforms FB by 10%
    # 3. BAC and JPM will outperform T and GE by 15%
    views = np.array([-0.20, 0.10, 0.15]).reshape(-1, 1)
    picking = np.array([
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
        [1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, -0.5, 0, 0, 0.5, 0, -0.5, 0, 0, 0, 0, 0, 0, 0, 0.5, 0],
    ])

    bl = BlackLittermanModel(S, Q=views, P=picking)
    rets = bl.bl_returns()
    assert rets["SBUX"] < 0
    assert rets["GOOG"] > rets["FB"]
    assert (rets["BAC"] > rets["T"]) and (rets["JPM"] > rets["GE"])
Beispiel #13
0
def test_black_litterman_market_prior():
    df = get_data()
    S = risk_models.sample_cov(df)

    prices = pd.read_csv(
        "tests/spy_prices.csv", parse_dates=True, index_col=0, squeeze=True
    )
    delta = black_litterman.market_implied_risk_aversion(prices)

    mcaps = {
        "GOOG": 927e9,
        "AAPL": 1.19e12,
        "FB": 574e9,
        "BABA": 533e9,
        "AMZN": 867e9,
        "GE": 96e9,
        "AMD": 43e9,
        "WMT": 339e9,
        "BAC": 301e9,
        "GM": 51e9,
        "T": 61e9,
        "UAA": 78e9,
        "SHLD": 0,
        "XOM": 295e9,
        "RRC": 1e9,
        "BBY": 22e9,
        "MA": 288e9,
        "PFE": 212e9,
        "JPM": 422e9,
        "SBUX": 102e9,
    }
    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
Beispiel #14
0
def test_default_omega():
    df = get_data()
    S = risk_models.sample_cov(df)
    views = pd.Series(0.1, index=S.columns)
    bl = BlackLittermanModel(S, Q=views)

    # Check square and diagonal
    assert bl.omega.shape == (len(S), len(S))
    np.testing.assert_array_equal(bl.omega, np.diag(np.diagonal(bl.omega)))

    # In this case, we should have omega = tau * diag(S)
    np.testing.assert_array_almost_equal(np.diagonal(bl.omega), bl.tau * np.diagonal(S))
Beispiel #15
0
def test_input_errors():
    df = get_data()
    S = risk_models.sample_cov(df)
    views = pd.Series(0.1, index=S.columns)

    # Insufficient args
    with pytest.raises(TypeError):
        BlackLittermanModel(S)

    assert BlackLittermanModel(S, Q=views)

    with pytest.raises(ValueError):
        BlackLittermanModel(S, Q=views, tau=-0.1)

    # P and Q don't match dimensions
    P = np.eye(len(S))[:, :-1]
    with pytest.raises(AssertionError):
        # This doesn't raise the error from the expected place!
        # Because default_omega uses matrix mult on P
        BlackLittermanModel(S, Q=views, P=P)

    with pytest.raises(AssertionError):
        BlackLittermanModel(S, Q=views, P=P, omega=np.eye(len(views)))

    # pi and S don't match dimensions
    with pytest.raises(AssertionError):
        BlackLittermanModel(S, Q=views, pi=df.pct_change().mean()[:-1])
def test_bl_returns_all_views():
    df = get_data()
    prior = expected_returns.ema_historical_return(df)
    S = risk_models.CovarianceShrinkage(df).ledoit_wolf()
    views = pd.Series(0.1, index=S.columns)

    bl = BlackLittermanModel(S, pi=prior, Q=views)
    posterior_rets = bl.bl_returns()
    assert isinstance(posterior_rets, pd.Series)
    assert list(posterior_rets.index) == list(df.columns)
    assert posterior_rets.notnull().all()
    assert posterior_rets.dtype == "float64"

    np.testing.assert_array_almost_equal(
        posterior_rets,
        np.array(
            [
                0.11774473,
                0.1709139,
                0.12180833,
                0.21202423,
                0.28120945,
                -0.2787358,
                0.17274774,
                0.12714698,
                0.25492005,
                0.11229777,
                0.07182723,
                -0.01521839,
                -0.21235465,
                0.06399515,
                -0.11738365,
                0.28865661,
                0.23828607,
                0.12038049,
                0.2331218,
                0.10485376,
            ]
        ),
    )
Beispiel #17
0
def test_bl_returns_all_views():
    df = get_data()
    prior = expected_returns.ema_historical_return(df)
    S = risk_models.CovarianceShrinkage(df).ledoit_wolf()
    views = pd.Series(0.1, index=S.columns)

    bl = BlackLittermanModel(S, pi=prior, Q=views)
    posterior_rets = bl.bl_returns()
    assert isinstance(posterior_rets, pd.Series)
    assert list(posterior_rets.index) == list(df.columns)
    assert posterior_rets.notnull().all()
    assert posterior_rets.dtype == "float64"

    np.testing.assert_array_almost_equal(
        posterior_rets,
        np.array(
            [
                0.11168648,
                0.16782938,
                0.12516799,
                0.24067997,
                0.32848296,
                -0.22789895,
                0.16311297,
                0.11928542,
                0.25414308,
                0.11007738,
                0.06282615,
                -0.03140218,
                -0.16977172,
                0.05254821,
                -0.10463884,
                0.32173375,
                0.26399864,
                0.1118594,
                0.22999558,
                0.08977448,
            ]
        ),
    )
Beispiel #18
0
def assign_strategy(ld: LazyDictionary, algo: str) -> tuple:
    assert ld is not None
    # use of black-litterman is based on https://github.com/robertmartin8/PyPortfolioOpt/blob/master/cookbook/4-Black-Litterman-Allocation.ipynb
    # print(market_prices)
    ld["s"] = CovarianceShrinkage(ld["filtered_stocks"]).ledoit_wolf()
    ld["delta"] = market_implied_risk_aversion(ld["market_prices"])

    # use BlackLitterman model to compute returns - hopefully better estimate of returns than extrapolation of historical prices
    # market_prior = market_implied_prior_returns(ld["market_caps"], delta, ld["s"])
    ld["bl"] = lambda ld: BlackLittermanModel(
        ld["s"],
        pi="market",
        market_caps=ld["market_caps"],
        risk_aversion=abs(ld["delta"]),
        absolute_views={},
    )
    ld["posterior_total_returns"] = lambda ld: ld["bl"].bl_returns()
    ld["posterior_s"] = lambda ld: ld["bl"].bl_cov()
    ld["mu"] = lambda ld: mean_historical_return(ld["filtered_stocks"])
    ld["returns_from_prices"] = lambda ld: returns_from_prices(ld[
        "filtered_stocks"])

    use_bl = ld["returns_by"] != "by_prices"
    kwargs = ({
        "returns": ld["mu"]
    } if use_bl else {
        "returns": ld["posterior_total_returns"]
    })
    if algo != "hrp":
        kwargs["cov_matrix"] = ld["s"] if not use_bl else ld["posterior_s"]
    else:
        # algo is HRP
        kwargs = {"returns": ld["returns_from_prices"]}

    if algo == "hrp":
        ld["title"] = "Hierarchical Risk Parity"
        return (hrp_strategy, kwargs)
    elif algo == "ef-sharpe":
        ld["title"] = "Efficient Frontier - max. sharpe"
        return (ef_sharpe_strategy, kwargs)
    elif algo == "ef-risk":
        ld["title"] = "Efficient Frontier - efficient risk"
        kwargs["target_volatility"] = 5.0
        return (ef_risk_strategy, kwargs)
    elif algo == "ef-minvol":
        ld["title"] = "Efficient Frontier - minimum volatility"
        return (ef_minvol_strategy, kwargs)
    else:
        assert False
Beispiel #19
0
def test_bl_market_automatic():
    df = get_data()
    S = risk_models.sample_cov(df)

    mcaps = get_market_caps()
    viewdict = {"GOOG": 0.40, "AAPL": -0.30, "FB": 0.30, "BABA": 0}
    bl = BlackLittermanModel(S, pi="market", absolute_views=viewdict, market_caps=mcaps)
    rets = bl.bl_returns()

    # Compare with explicit
    prior = black_litterman.market_implied_prior_returns(mcaps, 1, S, 0)
    bl2 = BlackLittermanModel(S, pi=prior, absolute_views=viewdict)
    rets2 = bl2.bl_returns()
    pd.testing.assert_series_equal(rets, rets2)
Beispiel #20
0
def test_bl_no_uncertainty():
    df = get_data()
    S = risk_models.sample_cov(df)
    omega = np.diag([0, 0, 0, 0])

    viewdict = {"GOOG": 0.40, "AAPL": -0.30, "FB": 0.30, "BABA": 0}
    bl = BlackLittermanModel(S, absolute_views=viewdict, omega=omega)
    rets = bl.bl_returns()

    # For 100% confidence, posterior return should equal view return.
    for k, v in viewdict.items():
        assert np.abs(rets[k] - v) < 1e-5

    # If only one view has 100% confidencee, only that asset will have post = prior.
    omega = np.diag([0, 0.2, 0.2, 0.2])
    bl = BlackLittermanModel(S, absolute_views=viewdict, omega=omega)
    rets = bl.bl_returns()
    assert np.abs(bl.bl_returns()["GOOG"] - viewdict["GOOG"]) < 1e-5
    assert np.abs(rets["AAPL"] - viewdict["AAPL"]) > 0.01
def test_input_errors():
    df = get_data()
    S = risk_models.sample_cov(df)
    views = pd.Series(0.1, index=S.columns)

    # Insufficient args
    with pytest.raises(TypeError):
        BlackLittermanModel(S)

    assert BlackLittermanModel(S, Q=views)

    with pytest.raises(ValueError):
        BlackLittermanModel(S, Q=views, tau=-0.1)

    # P and Q don't match dimensions
    P = np.eye(len(S))[:, :-1]
    with pytest.raises(AssertionError):
        # This doesn't raise the error from the expected place!
        # Because default_omega uses matrix mult on P
        BlackLittermanModel(S, Q=views, P=P)

    # P not an DataFrame or ndarray
    with pytest.raises(TypeError):
        BlackLittermanModel(S, Q=views[:-1], P=1.0)

    with pytest.raises(AssertionError):
        BlackLittermanModel(S, Q=views, P=P, omega=np.eye(len(views)))

    # pi and S don't match dimensions
    with pytest.raises(AssertionError):
        BlackLittermanModel(S, Q=views, pi=df.pct_change().mean()[:-1])

    # If pi=="market" then market_caps must be supplied
    with pytest.raises(ValueError):
        BlackLittermanModel(S, Q=views, pi="market")

    # pi's valid numerical types are Series, DataFrame and ndarray
    with pytest.raises(TypeError):
        BlackLittermanModel(S, Q=views, pi=[0.1] * len(S))

    # risk_aversion cannot be negative
    with pytest.raises(ValueError):
        BlackLittermanModel(S, Q=views, risk_aversion=-0.01)

    # omega must be ndarray, DataFrame and string
    with pytest.raises(TypeError):
        BlackLittermanModel(S, Q=views, omega=1.0)
Beispiel #22
0
def test_idzorek_input_formats():
    # Identity covariance
    S = pd.DataFrame(np.diag(np.ones((5, ))), index=range(5), columns=range(5))
    # Constant view of 0.3 return
    views = {k: 0.3 for k in range(5)}
    # Prior
    pi = pd.Series(0.1, index=range(5))

    test_result = pd.Series(0.2, index=range(5))

    bl = BlackLittermanModel(S,
                             pi=pi,
                             absolute_views=views,
                             omega="idzorek",
                             view_confidences=[0.5] * 5)
    pd.testing.assert_series_equal(bl.bl_returns(), test_result)

    bl = BlackLittermanModel(
        S,
        pi=pi,
        absolute_views=views,
        omega="idzorek",
        view_confidences=(0.5, 0.5, 0.5, 0.5, 0.5),
    )
    pd.testing.assert_series_equal(bl.bl_returns(), test_result)

    bl = BlackLittermanModel(
        S,
        pi=pi,
        absolute_views=views,
        omega="idzorek",
        view_confidences=np.array([0.5] * 5),
    )
    pd.testing.assert_series_equal(bl.bl_returns(), test_result)

    bl = BlackLittermanModel(
        S,
        pi=pi,
        absolute_views=views,
        omega="idzorek",
        view_confidences=np.array([0.5] * 5).reshape(-1, 1),
    )
    pd.testing.assert_series_equal(bl.bl_returns(), test_result)
Beispiel #23
0
def test_idzorek_basic():
    # Identity covariance
    S = pd.DataFrame(np.diag(np.ones((5, ))), index=range(5), columns=range(5))
    # Constant view of 0.3 return
    views = {k: 0.3 for k in range(5)}
    # Prior
    pi = pd.Series(0.1, index=range(5))

    # Perfect confidence - should equal views
    bl = BlackLittermanModel(
        S,
        pi=pi,
        absolute_views=views,
        omega=np.diag(np.zeros(5))  # perfect confidence
    )
    pd.testing.assert_series_equal(bl.bl_returns(), pd.Series([0.3] * 5))

    # No confidence - should equal priors
    bl = BlackLittermanModel(S, pi=pi, absolute_views=views, omega=S * 1e6)
    pd.testing.assert_series_equal(bl.bl_returns(), pi)

    # Idzorek 100% confidence
    bl = BlackLittermanModel(S,
                             pi=pi,
                             absolute_views=views,
                             omega="idzorek",
                             view_confidences=[1] * 5)
    np.testing.assert_array_almost_equal(bl.omega, np.zeros((5, 5)))
    pd.testing.assert_series_equal(bl.bl_returns(),
                                   pd.Series(0.3, index=range(5)))

    # Idzorek 0% confidence
    bl = BlackLittermanModel(S,
                             pi=pi,
                             absolute_views=views,
                             omega="idzorek",
                             view_confidences=[0] * 5)
    np.testing.assert_array_almost_equal(bl.omega, np.diag([1e6] * 5))
    pd.testing.assert_series_equal(bl.bl_returns(), pi)

    # Idzorek confidence range
    for i, conf in enumerate(np.arange(0, 1.2, 0.2)):
        bl = BlackLittermanModel(S,
                                 pi=pi,
                                 absolute_views=views,
                                 omega="idzorek",
                                 view_confidences=[conf] * 5)
        # Linear spacing
        np.testing.assert_almost_equal(bl.bl_returns()[0], 0.1 + i * 0.2 / 5)
Beispiel #24
0
    "PFE": 212e9,
    "JPM": 422e9,
    "SBUX": 102e9,
}
prior = black_litterman.market_implied_prior_returns(mcaps, delta, S)

# 1. SBUX will drop by 20%
# 2. GOOG outperforms FB by 10%
# 3. BAC and JPM will outperform T and GE by 15%
views = np.array([-0.20, 0.10, 0.15]).reshape(-1, 1)
picking = np.array([
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
    [1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, -0.5, 0, 0, 0.5, 0, -0.5, 0, 0, 0, 0, 0, 0, 0, 0.5, 0],
])
bl = BlackLittermanModel(S, Q=views, P=picking, pi=prior, tau=0.01)
rets = bl.bl_returns()
ef = EfficientFrontier(rets, S)
ef.max_sharpe()
print(ef.clean_weights())
ef.portfolio_performance(verbose=True)
"""
{'GOOG': 0.2015,
 'AAPL': 0.2368,
 'FB': 0.0,
 'BABA': 0.06098,
 'AMZN': 0.17148,
 'GE': 0.0,
 'AMD': 0.0,
 'WMT': 0.0,
 'BAC': 0.18545,
Beispiel #25
0
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_tau():
    df = get_data()
    S = risk_models.sample_cov(df)

    prices = pd.read_csv("tests/spy_prices.csv",
                         parse_dates=True,
                         index_col=0,
                         squeeze=True)
    delta = black_litterman.market_implied_risk_aversion(prices)

    mcaps = {
        "GOOG": 927e9,
        "AAPL": 1.19e12,
        "FB": 574e9,
        "BABA": 533e9,
        "AMZN": 867e9,
        "GE": 96e9,
        "AMD": 43e9,
        "WMT": 339e9,
        "BAC": 301e9,
        "GM": 51e9,
        "T": 61e9,
        "UAA": 78e9,
        "SHLD": 0,
        "XOM": 295e9,
        "RRC": 1e9,
        "BBY": 22e9,
        "MA": 288e9,
        "PFE": 212e9,
        "JPM": 422e9,
        "SBUX": 102e9,
    }
    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"]