예제 #1
0
for x in epochs.keys():
    sub_price = assets.loc[epochs[x]['start']:epochs[x]['end']]
    e_return[x] = mean_historical_return(assets, frequency=252)
    e_cov[x] = CovarianceShrinkage(sub_price).ledoit_wolf()

# Display the efficient covariance matrices for all epochs
print("Efficient Covariance Matrices\n", e_cov)

# Initialize the Crtical Line Algorithm object
efficient_portfolio_during = CLA(e_return["during"], e_cov["during"])

# Find the minimum volatility portfolio weights and display them
print(efficient_portfolio_during.min_volatility())

# Compute the efficient frontier
(ret, vol, weights) = efficient_portfolio_during.efficient_frontier()

# Add the frontier to the plot showing the 'before' and 'after' frontiers
plt.scatter(vol, ret, s=4, c='g', marker='.', label='During')
plt.legend()
plt.show()

# plotting using PyPortfolioOpt
pplot.plot_covariance(cs, plot_correlation=False, show_tickers=True)
pplot.plot_efficient_frontier(efficient_portfolio_during,
                              points=100,
                              show_assets=True)
pplot.plot_weights(cw)

# Dealing with many negligible weights
# efficient portfolio allocation
예제 #2
0
 def _get_efficient_weights(self):
     cla = CLA(self.mu, self.S)
     cla.max_sharpe()
     (mu, sigma, weights) = cla.efficient_frontier()
     return mu, sigma, weights
예제 #3
0
def optimal_portfolio(mu, S, objective='max_sharpe', get_entire_frontier=True, **kwargs):
    """Solve for optimal portfolio. Wrapper for pypfopt functions

    Arguments:
        mu (pd.Series) - Expected annual returns
        S (pd.DataFrame/np.ndarray) - Expected annual volatility
        objective (string, optional) - Optimise for either 'max_sharpe', or 'min_volatility', defaults to 'max_sharpe'
        get_entire_frontier (boolean, optional) - Also get the entire efficient frontier, defaults to True

    """

    # if need to efficiently compute the entire efficient frontier for plotting, use CLA
    # else use standard EfficientFrontier optimiser.
    # (Note that optimum weights might be slightly different depending on whether CLA or EfficientFrontier was used)
    Optimiser = CLA if get_entire_frontier else EfficientFrontier
    op = Optimiser(mu, S)
    # risk_aversion = kwargs.get("risk_aversion", 1)  # only for max quadratic utility

    if (objective is None):
        # Get weights for both max_sharpe and min_volatility
        opt_weights = []
        op.max_sharpe()
        opt_weights.append(op.clean_weights())
        op.min_volatility()
        opt_weights.append(op.clean_weights())

        # ef = EfficientFrontier(mu, S)
        # ef.max_quadratic_utility(risk_aversion)
        # opt_weights.append(ef.clean_weights())
    else:
        if (objective == 'max_sharpe'):
            op.max_sharpe()
        elif ('min_vol' in objective):
            op.min_volatility()
        elif (objective == 'efficient_risk'):
            target_volatility = kwargs.get("target_volatility", None)
            if target_volatility is None:
                print("Error: You have to specify the target_volatility!")
                return None, None, None, None
            else:
                try:
                    op.efficient_risk(target_volatility)
                except ValueError:
                    # could not solve based on target_volatility, we try lookup table instead
                    cla = CLA(mu, S)
                    cla.max_sharpe()
                    ef_returns, ef_risks, ef_weights = cla.efficient_frontier(points=300)

                    lookup_v_w = dict(zip(ef_risks, ef_weights))
                    lookup_v_w = OrderedDict(sorted(lookup_v_w.items()))
                    w = lookup_v_w[min(lookup_v_w.keys(), key=lambda key: abs(key-target_volatility))]
                    w = [i[0] for i in w]  # flatten
                    return w, None, None

        elif (objective == 'efficient_return'):
            target_return = kwargs.get("target_return", None)
            if target_return is None:
                print("Error: You have to specify the target_return!")
                return None, None, None, None
            else:
                op.efficient_return(target_return)

        # elif (objective == 'max_quadratic_utility'):
        #     op.max_quadratic_utility(risk_aversion)
        #     # print("Using MAX_QUADRATIC UTILITY")

        opt_weights = op.clean_weights()

    if get_entire_frontier:
        opt_returns, opt_risks, _ = op.efficient_frontier(points=200)
        return opt_weights, opt_returns, opt_risks
    else:
        return opt_weights, None, None