Beispiel #1
0
def test_cla_min_volatility_exp_cov_short():
    cla = CLA(*setup_cla(data_only=True), weight_bounds=(-1, 1))
    df = get_data()
    cla.cov_matrix = risk_models.exp_cov(df).values
    w = cla.min_volatility()
    assert isinstance(w, dict)
    assert set(w.keys()) == set(cla.tickers)
    np.testing.assert_almost_equal(cla.weights.sum(), 1)
    np.testing.assert_allclose(
        cla.portfolio_performance(),
        (0.2634735528776959, 0.13259590618253303, 1.8362071642131053),
    )
Beispiel #2
0
def test_cla_min_volatility_exp_cov_short():
    cla = CLA(*setup_cla(data_only=True), weight_bounds=(-1, 1))
    df = get_data()
    cla.cov_matrix = risk_models.exp_cov(df).values
    w = cla.min_volatility()
    assert isinstance(w, dict)
    assert set(w.keys()) == set(cla.tickers)
    np.testing.assert_almost_equal(cla.weights.sum(), 1)
    np.testing.assert_allclose(
        cla.portfolio_performance(),
        (0.23215576461823062, 0.1325959061825329, 1.6000174569958052),
    )
Beispiel #3
0
def test_cla_custom_bounds():
    bounds = [(0.01, 0.13), (0.02, 0.11)] * 10
    cla = CLA(*setup_cla(data_only=True), weight_bounds=bounds)
    df = get_data()
    cla.cov_matrix = risk_models.exp_cov(df).values
    w = cla.min_volatility()
    assert isinstance(w, dict)
    assert set(w.keys()) == set(cla.tickers)
    np.testing.assert_almost_equal(cla.weights.sum(), 1)
    assert (0.01 <= cla.weights[::2]).all() and (cla.weights[::2] <=
                                                 0.13).all()
    assert (0.02 <= cla.weights[1::2]).all() and (cla.weights[1::2] <=
                                                  0.11).all()
def setup_cla(data_only=False):
    df = get_data()
    mean_return = expected_returns.mean_historical_return(df)
    sample_cov_matrix = risk_models.sample_cov(df)
    if data_only:
        return mean_return, sample_cov_matrix
    return CLA(mean_return, sample_cov_matrix)
Beispiel #5
0
def test_cla_max_sharpe_short():
    cla = CLA(*setup_cla(data_only=True), weight_bounds=(-1, 1))
    w = cla.max_sharpe()
    assert isinstance(w, dict)
    assert set(w.keys()) == set(cla.tickers)
    np.testing.assert_almost_equal(cla.weights.sum(), 1)
    np.testing.assert_allclose(
        cla.portfolio_performance(),
        (0.44859872371106785, 0.26762066559448255, 1.601515797589826),
    )
    sharpe = cla.portfolio_performance()[2]

    cla_long_only = setup_cla()
    cla_long_only.max_sharpe()
    long_only_sharpe = cla_long_only.portfolio_performance()[2]

    assert sharpe > long_only_sharpe
Beispiel #6
0
def test_cla_max_sharpe_short():
    cla = CLA(*setup_cla(data_only=True), weight_bounds=(-1, 1))
    w = cla.max_sharpe()
    assert isinstance(w, dict)
    assert set(w.keys()) == set(cla.tickers)
    np.testing.assert_almost_equal(cla.weights.sum(), 1)
    np.testing.assert_allclose(
        cla.portfolio_performance(),
        (0.3799273115521356, 0.23115368271125736, 1.5570909679242886),
    )
    sharpe = cla.portfolio_performance()[2]

    cla_long_only = setup_cla()
    cla_long_only.max_sharpe()
    long_only_sharpe = cla_long_only.portfolio_performance()[2]

    assert sharpe > long_only_sharpe
    def get_efficient_frontier(cls, weights):
        cls.efficient_portfolio = CLA(cls.mean_returns_avg, cls.e_cov)
        (ret, vol, weight) = cls.efficient_portfolio.efficient_frontier()
        plt.show()

        def statistics(weights):
            pret = np.sum(cls.Stock_data_frames.mean() * weights) * 252
            pvol = np.sqrt(np.dot(weights.T, np.dot(cls.e_cov, weights)))
            return np.array([pret, pvol, pret / pvol])

        def min_func_sharpe(weights):
            return -statistics(weights)[2]

        def min_func_variance(weights):
            return statistics(weights)[1]**2

        cons = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
        bnds = tuple((0, 1) for x in range(cls.num_stocks))
        ew = FinancialInfo.num_stocks * [1 / cls.num_stocks]

        cls.opts = sco.minimize(min_func_sharpe,
                                ew,
                                method='SlSQP',
                                bounds=bnds,
                                constraints=cons)
        cls.optv = sco.minimize(min_func_variance,
                                ew,
                                method='SlSQP',
                                bounds=bnds,
                                constraints=cons)
        plt.figure(figsize=(10, 4))
        plt.scatter(cls.pvol,
                    cls.prets,
                    c=cls.prets / cls.pvol,
                    marker='o',
                    cmap='RdYlBu')
        plt.scatter(vol, ret, s=4, c='g', marker='x')
        plt.plot(statistics(cls.opts['x'])[1],
                 statistics(cls.opts['x'])[0],
                 'r*',
                 markersize=15)
        plt.plot(statistics(cls.optv['x'])[1],
                 statistics(cls.optv['x'])[0],
                 'y*',
                 markersize=15)
        plt.grid = True
        plt.xlabel('expected volatility')
        plt.ylabel('expected return')
        plt.colorbar(label='Sharpe ratio')
Beispiel #8
0
def test_cla_custom_bounds():
    bounds = [(0.01, 0.13), (0.02, 0.11)] * 10
    cla = CLA(*setup_cla(data_only=True), weight_bounds=bounds)
    df = get_data()
    cla.cov_matrix = risk_models.exp_cov(df).values
    w = cla.min_volatility()
    assert isinstance(w, dict)
    assert set(w.keys()) == set(cla.tickers)
    np.testing.assert_almost_equal(cla.weights.sum(), 1)
    assert (0.01 <= cla.weights[::2]).all() and (cla.weights[::2] <=
                                                 0.13).all()
    assert (0.02 <= cla.weights[1::2]).all() and (cla.weights[1::2] <=
                                                  0.11).all()
    # Test polymorphism of the weight_bounds param.
    bounds2 = ([bounds[0][0], bounds[1][0]] * 10,
               [bounds[0][1], bounds[1][1]] * 10)
    cla2 = CLA(*setup_cla(data_only=True), weight_bounds=bounds2)
    cla2.cov_matrix = risk_models.exp_cov(df).values
    w2 = cla2.min_volatility()
    assert dict(w2) == dict(w)
Beispiel #9
0
def calculateInvestment(limit=10,
                        count=10,
                        write_to_file=True,
                        show_cla=False,
                        tpv=20000):
    symbols = getSymbolsFromDatabase()
    prices = createDataFrame(symbols[:limit], count)
    mu = expected_returns.mean_historical_return(prices)
    S = risk_models.CovarianceShrinkage(prices).ledoit_wolf()
    ef = EfficientFrontier(mu, S, weight_bounds=(-1, 1))
    ef.add_objective(objective_functions.L2_reg)
    ef.min_volatility()
    c_weights = ef.clean_weights()
    if write_to_file == True:
        ef.save_weights_to_file("weights.txt")
    if show_cla == True:
        cla = CLA(mu, S)
        ef_plot(cla)
    ef.portfolio_performance(verbose=True)
    latest_prices = disc_alloc.get_latest_prices(prices)
    allocation_minv, leftover = disc_alloc.DiscreteAllocation(
        c_weights, latest_prices, total_portfolio_value=tpv).lp_portfolio()
    return allocation_minv, leftover
Beispiel #10
0
Sigma = risk_models.sample_cov(df_stocks)
#Максимальный коэффициент Шарпа
ef = EfficientFrontier(
    mu, Sigma,
    weight_bounds=(0, 1))  #weight bounds in negative allows shorting of stocks
sharpe_pfolio = ef.max_sharpe(
)  #May use add objective to ensure minimum zero weighting to individual stocks
sharpe_pwt = ef.clean_weights()
print(sharpe_pwt)
ef.portfolio_performance(verbose=True)
ef1 = EfficientFrontier(mu, Sigma, weight_bounds=(0, 1))
minvol = ef1.min_volatility()
minvol_pwt = ef1.clean_weights()
print(minvol_pwt)
ef1.portfolio_performance(verbose=True, risk_free_rate=0.27)
cl_obj = CLA(mu, Sigma)
ax = pplt.plot_efficient_frontier(cl_obj, showfig=False)
ax.xaxis.set_major_formatter(FuncFormatter(lambda x, _: '{:.0%}'.format(x)))
ax.yaxis.set_major_formatter(FuncFormatter(lambda y, _: '{:.0%}'.format(y)))
lalatest_prices = get_latest_prices(df_stocks)
allocation_minv, rem_minv = DiscreteAllocation(
    minvol_pwt, latest_prices, total_portfolio_value=100000).lp_portfolio()
print(allocation_minv)
print(
    "Осталось денежных средств после построения портфеля с минимальной волатильностью - {:.2f} рублей"
    .format(rem_minv))
print()
latest_prices1 = get_latest_prices(df_stocks)
allocation_shp, rem_shp = DiscreteAllocation(
    sharpe_pwt, latest_prices1, total_portfolio_value=100000).lp_portfolio()
print(allocation_shp)
Beispiel #11
0
def test_cla_two_assets():
    mu = np.array([[0.02569294], [0.16203987]])
    cov = np.array([[0.0012765, -0.00212724], [-0.00212724, 0.01616983]])
    assert CLA(mu, cov)
Beispiel #12
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
sample_cov = assets.pct_change().cov() * 252

# Compute the returns and efficient covariance for each epoch
e_return = {}
e_cov = {}

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,
Beispiel #14
0
def create_xl_EFPortfolio(df, lb, ub, resample_rule):

    dfReSample = create_epochs(df, resample_rule)
    """
    # Create a dictionary of time periods (or 'epochs')
    epochs = { '0' : {'start': '1-1-2005', 'end': '31-12-2006'},
               '1' : {'start': '1-1-2007', 'end': '31-12-2008'},
               '2' : {'start': '1-1-2009', 'end': '31-12-2010'}
             }
    """
    epochs = dfReSample.to_dict('index')

    # Compute the efficient covariance for each epoch
    e_return = {}
    e_cov = {}
    efficient_portfolio = {}
    liW = []
    liR = []

    for x in epochs.keys():
        period = df.loc[epochs[x]['start']:epochs[x]['end']]

        j = (x + 1) / len(epochs.keys())
        sys.stdout.write('\r')
        sys.stdout.write("[%-20s] %d%%" % ('=' * int(20 * j), 100 * j))
        sys.stdout.flush()

        try:
            # Compute the annualized average (mean) historical return
            # mu = expected_returns.mean_historical_return(period)#, frequency = 252)
            mu = expected_returns.ema_historical_return(period,
                                                        frequency=252,
                                                        span=500)

            # Compute the efficient covariance matrix
            Sigma = risk_models.CovarianceShrinkage(period).ledoit_wolf()

            # Initialize the Crtical Line Algorithm object
            efficient_portfolio[x] = CLA(mu, Sigma, weight_bounds=(lb, ub))
            efficient_portfolio[x].max_sharpe()  # min_volatility()

            cleaned_weights = efficient_portfolio[x].clean_weights()
            e_return[x] = mu
            e_cov[x] = Sigma

            liW.append(pd.DataFrame({'epochs': x, 'weights': cleaned_weights}))
            liR.append(pd.DataFrame({'epochs': x, 'returns': mu}))

        except Exception as e:
            sys.stdout.write('\r')
            sys.stdout.write('%s%s %s%s%s\n' %
                             ('#', x, 'error:', epochs[x], e))

    dfWeightsEF = pd.concat(liW)
    dfWeightsEF.reset_index(inplace=True)
    dfWeightsEF.columns = ['asset', 'epochs', 'weights']
    dfWeightsEF = dfWeightsEF.pivot(index='epochs',
                                    columns='asset',
                                    values='weights')

    dfReturnsEF = pd.concat(liR)
    dfReturnsEF.reset_index(inplace=True)
    dfReturnsEF.columns = ['asset', 'epochs', 'returns']
    dfReturnsEF = dfReturnsEF.pivot(index='epochs',
                                    columns='asset',
                                    values='returns')

    dfWeightsEF.to_excel(r"weightsEF.xlsx")
    dfReturnsEF.to_excel(r"returnsEF.xlsx")

    dfReturns = df.pct_change().dropna()

    dfNAV = pd.merge(dfWeightsEF,
                     dfReSample,
                     left_index=True,
                     right_index=True)
    dfNAV = dfNAV.drop(columns=['start'])
    dfNAV.set_index('end', inplace=True)
    dfNAV.index.names = ['DATE']
    dfNAV = dfNAV.resample('D').ffill()

    dfNAV = dfNAV.loc[dfNAV.index.isin(dfReturns.index.tolist())]
    dfReturns = dfReturns.loc[dfReturns.index.isin(dfNAV.index.tolist())]

    dfNAV['RET'] = (dfNAV.values * dfReturns.values).sum(axis=1).tolist()
    dfNAV['NAV'] = (1 + dfNAV['RET']).cumprod()

    dfNAV = pd.merge(dfNAV,
                     dfReturns,
                     left_index=True,
                     right_index=True,
                     suffixes=('_weight', '_return'))

    dfNAV.to_excel(r"navEF.xlsx")

    return
Beispiel #15
0
 'GM': 0.05557666024185722,
 'GOOG': 0.049560084289929286,
 'JPM': 0.017675709092515708,
 'MA': 0.03812737349732021,
 'PFE': 0.07786528342813454,
 'RRC': 0.03161528695094597,
 'SBUX': 0.039844436656239136,
 'SHLD': 0.027113184241298865,
 'T': 0.11138956508836476,
 'UAA': 0.02711590957075009,
 'WMT': 0.10569551148587905,
 'XOM': 0.11175337115721229}
"""

# Crticial Line Algorithm
cla = CLA(mu, S)
print(cla.max_sharpe())
cla.portfolio_performance(verbose=True)
"""
{'GOOG': 0.020889868669945022,
 'AAPL': 0.08867994115132602,
 'FB': 0.19417572932251745,
 'BABA': 0.10492386821217001,
 'AMZN': 0.0644908140418782,
 'GE': 0.0,
 'AMD': 0.0,
 'WMT': 0.0034898157701416382,
 'BAC': 0.0,
 'GM': 0.0,
 'T': 2.4138966206946562e-19,
 'UAA': 0.0,
Beispiel #16
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