def min_var(my_portfolio, perf=True) -> list: ohlc = yf.download( my_portfolio.portfolio, start=my_portfolio.start_date, end=my_portfolio.end_date, progress=False, ) prices = ohlc["Adj Close"].dropna(how="all") prices = prices.filter(my_portfolio.portfolio) mu = expected_returns.capm_return(prices) S = risk_models.CovarianceShrinkage(prices).ledoit_wolf() ef = EfficientFrontier(mu, S) ef.add_objective(objective_functions.L2_reg, gamma=my_portfolio.diversification) if my_portfolio.min_weights is not None: ef.add_constraint(lambda x: x >= my_portfolio.min_weights) if my_portfolio.max_weights is not None: ef.add_constraint(lambda x: x <= my_portfolio.max_weights) ef.min_volatility() weights = ef.clean_weights() wts = weights.items() result = [] for val in wts: a, b = map(list, zip(*[val])) result.append(b) if perf is True: ef.portfolio_performance(verbose=True) return flatten(result)
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, )
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)
def mean_var(my_portfolio, vol_max=0.15, perf=True) -> list: # changed to take in desired timeline, the problem is that it would use all historical data ohlc = yf.download( my_portfolio.portfolio, start=my_portfolio.start_date, end=my_portfolio.end_date, progress=False, ) prices = ohlc["Adj Close"].dropna(how="all") prices = prices.filter(my_portfolio.portfolio) # sometimes we will pick a date range where company isn't public we can't set price to 0 so it has to go to 1 prices = prices.fillna(1) mu = expected_returns.capm_return(prices) S = risk_models.CovarianceShrinkage(prices).ledoit_wolf() ef = EfficientFrontier(mu, S) ef.add_objective(objective_functions.L2_reg, gamma=my_portfolio.diversification) if my_portfolio.min_weights is not None: ef.add_constraint(lambda x: x >= my_portfolio.min_weights) if my_portfolio.max_weights is not None: ef.add_constraint(lambda x: x <= my_portfolio.max_weights) ef.efficient_risk(vol_max) weights = ef.clean_weights() wts = weights.items() result = [] for val in wts: a, b = map(list, zip(*[val])) result.append(b) if perf is True: ef.portfolio_performance(verbose=True) return flatten(result)
def efficient_frontier(my_portfolio, perf=True) -> list: # changed to take in desired timeline, the problem is that it would use all historical data ohlc = yf.download( my_portfolio.portfolio, start=my_portfolio.start_date, end=my_portfolio.end_date, progress=False, ) prices = ohlc["Adj Close"].dropna(how="all") df = prices.filter(my_portfolio.portfolio) # sometimes we will pick a date range where company isn't public we can't set price to 0 so it has to go to 1 df = df.fillna(1) mu = expected_returns.mean_historical_return(df) S = risk_models.sample_cov(df) # optimize for max sharpe ratio ef = EfficientFrontier(mu, S) if my_portfolio.min_weights is not None: ef.add_constraint(lambda x: x >= my_portfolio.min_weights) if my_portfolio.max_weights is not None: ef.add_constraint(lambda x: x <= my_portfolio.max_weights) weights = ef.max_sharpe() cleaned_weights = ef.clean_weights() wts = cleaned_weights.items() result = [] for val in wts: a, b = map(list, zip(*[val])) result.append(b) if perf is True: pred = ef.portfolio_performance(verbose=True) return flatten(result)
def test_constrained_ef_plot_risk(): ef = EfficientFrontier(*setup_efficient_frontier(data_only=True), weight_bounds=(None, None)) ef.add_constraint(lambda w: w[0] >= 0.2) ef.add_constraint(lambda w: w[2] == 0.15) ef.add_constraint(lambda w: w[3] + w[4] <= 0.10) # 100 portfolios with risks between 0.10 and 0.30 risk_range = np.linspace(0.157, 0.40, 100) ax = plotting.plot_efficient_frontier(ef, ef_param="risk", ef_param_range=risk_range, show_assets=True, showfig=False) assert len(ax.findobj()) == 137