def test_custom_tracking_error():
    df = get_data()
    historical_rets = expected_returns.returns_from_prices(df).dropna()
    benchmark_rets = historical_rets["AAPL"]
    historical_rets = historical_rets.drop("AAPL", axis=1)
    S = risk_models.sample_cov(historical_rets, returns_data=True)

    opt = BaseConvexOptimizer(
        n_assets=len(historical_rets.columns),
        tickers=list(historical_rets.columns),
        weight_bounds=(0, 1),
    )

    opt.convex_objective(
        objective_functions.ex_post_tracking_error,
        historic_returns=historical_rets,
        benchmark_returns=benchmark_rets,
    )
    w = opt.clean_weights()

    ef = EfficientFrontier(None, S)
    ef.convex_objective(
        objective_functions.ex_post_tracking_error,
        historic_returns=historical_rets,
        benchmark_returns=benchmark_rets,
    )
    w2 = ef.clean_weights()

    assert w == w2
def test_custom_convex_abs_exposure():
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(None, None))

    ef.add_constraint(lambda x: cp.norm(x, 1) <= 2)
    ef.convex_objective(
        objective_functions.portfolio_variance,
        cov_matrix=ef.cov_matrix,
        weights_sum_to_one=False,
    )
Esempio n. 3
0
def test_custom_convex_objective_market_neutral_efficient_risk():
    target_risk = 0.19
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(-1, 1))
    ef.efficient_risk(target_risk, market_neutral=True)
    built_in = ef.weights

    # Recreate the market-neutral efficient_risk optimiser using this API
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(-1, 1))
    ef.add_constraint(lambda x: cp.sum(x) == 0)
    ef.add_constraint(
        lambda x: cp.quad_form(x, ef.cov_matrix) <= target_risk**2)
    ef.convex_objective(lambda x: -x @ ef.expected_returns,
                        weights_sum_to_one=False)
    custom = ef.weights
    np.testing.assert_allclose(built_in, custom, atol=1e-7)
Esempio n. 4
0
def test_custom_convex_kelly():

    lb = 0.01
    ub = 0.3
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(lb, ub))

    def kelly_objective(w, e_returns, cov_matrix, k=3):
        variance = cp.quad_form(w, cov_matrix)

        objective = variance * 0.5 * k - w @ e_returns
        return objective

    weights = ef.convex_objective(kelly_objective,
                                  e_returns=ef.expected_returns,
                                  cov_matrix=ef.cov_matrix)

    for w in weights.values():
        assert w >= lb - 1e-8 and w <= ub + 1e-8
Esempio n. 5
0
    :type cov_matrix: np.ndarray
    :param negative: whether quantity should be made negative (so we can minimise) 
    :type negative: boolean
    :return: (negative) Sharpe ratio
    :rtype: float
    """
    sk = w @ skew
    sign = -1 if negative else 1
    return sign * sk


ef_skew = EfficientFrontier(exp_ret, S, weight_bounds=(0.0, 0.15))
ef_skew.add_sector_constraints(sector_mapper, sector_lower, sector_upper)
ef_skew.add_objective(objective_functions.L2_reg, gamma=20)
#ef.add_objective(minimize_negative_skew, skew= skw)
ef_skew.convex_objective(minimize_negative_skew, skew=skw)
#ef.max_sharpe()
weights_skew = ef_skew.clean_weights()
weights_skew
ef_skew.portfolio_performance(verbose=True)

# %%

weight_dict = { 
    "Miniumum Variance" : weights_minvol,
    "Maximum Sharpe Ratio" : weights_maxsharpe,
    "Maximum Quadratic Utility" : weights_maxquad, 
    "Efficient Target Risk" : weights_effrisk,
    "Efficient Target Return" : weights_effret, 
    "Maximum Skew" : weights_skew
}
Esempio n. 6
0
"""
Expected annual return: 20.0%
Annual volatility: 16.5%
Sharpe Ratio: 1.09
"""


# Custom convex objective from 60 Years of Portfolio Optimisation, Kolm et al (2014)
def logarithmic_barrier(w, cov_matrix, k=0.1):
    log_sum = cp.sum(cp.log(w))
    var = cp.quad_form(w, cov_matrix)
    return var - k * log_sum


ef = EfficientFrontier(mu, S)
weights = ef.convex_objective(logarithmic_barrier, cov_matrix=ef.cov_matrix)
ef.portfolio_performance(verbose=True)
"""
Expected annual return: 24.0%
Annual volatility: 21.1%
Sharpe Ratio: 1.04
"""


# Now try with a nonconvex objective from  Kolm et al (2014)
def deviation_risk_parity(w, cov_matrix):
    diff = w * np.dot(cov_matrix, w) - (w * np.dot(cov_matrix, w)).reshape(
        -1, 1)
    return (diff**2).sum().sum()