def test_min_volatility_vs_max_sharpe():
    # Test based on issue #75
    expected_returns_daily = pd.Series(
        [0.043622, 0.120588, 0.072331, 0.056586],
        index=["AGG", "SPY", "GLD", "HYG"])
    covariance_matrix = pd.DataFrame(
        [
            [0.000859, -0.000941, 0.001494, -0.000062],
            [-0.000941, 0.022400, -0.002184, 0.005747],
            [0.001494, -0.002184, 0.011518, -0.000129],
            [-0.000062, 0.005747, -0.000129, 0.002287],
        ],
        index=["AGG", "SPY", "GLD", "HYG"],
        columns=["AGG", "SPY", "GLD", "HYG"],
    )

    ef = EfficientFrontier(expected_returns_daily, covariance_matrix)
    ef.min_volatility()
    vol_min_vol = ef.portfolio_performance(risk_free_rate=0.00)[1]

    ef = EfficientFrontier(expected_returns_daily, covariance_matrix)
    ef.max_sharpe(risk_free_rate=0.00)
    vol_max_sharpe = ef.portfolio_performance(risk_free_rate=0.00)[1]

    assert vol_min_vol < vol_max_sharpe
Esempio n. 2
0
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)
Esempio n. 3
0
def min_volatility_weights(rets_bl, covar_bl, config):
    ef = EfficientFrontier(rets_bl, covar_bl, weight_bounds= \
            (config['min_position_size'] ,config['max_position_size']))
    ef.min_volatility()
    weights = ef.clean_weights()
    weights = pd.DataFrame.from_dict(weights, orient='index')
    weights.columns = ['Min Vol']
    return weights, ef
def test_efficient_frontier_expected_returns_list():
    """Cover the edge case that the expected_returns param is a list."""
    ef = setup_efficient_frontier()
    ef.min_volatility()
    ef_r = EfficientFrontier(expected_returns=ef.expected_returns.tolist(),
                             cov_matrix=ef.cov_matrix)
    ef_r.min_volatility()
    np.testing.assert_equal(ef.portfolio_performance(),
                            ef_r.portfolio_performance())
def test_clean_weights_short():
    ef = setup_efficient_frontier()
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(-1, 1))
    ef.min_volatility()
    # In practice we would never use such a high cutoff
    number_tiny_weights = sum(np.abs(ef.weights) < 0.05)
    cleaned = ef.clean_weights(cutoff=0.05)
    cleaned_weights = cleaned.values()
    clean_number_tiny_weights = sum(abs(i) < 0.05 for i in cleaned_weights)
    assert clean_number_tiny_weights == number_tiny_weights
def test_bound_failure():
    # Ensure optimization fails when lower bound is too high or upper bound is too low
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(0.06, 0.13))
    with pytest.raises(exceptions.OptimizationError):
        ef.min_volatility()

    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(0, 0.04))
    with pytest.raises(exceptions.OptimizationError):
        ef.min_volatility()
Esempio n. 7
0
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.min_volatility()
    ef.convex_objective(
        objective_functions.portfolio_variance,
        cov_matrix=ef.cov_matrix,
        weights_sum_to_one=False,
    )
Esempio n. 8
0
def optimise(portfolio_data):
    returns = pd.Series(get_returns(portfolio_data))
    covariance_matrix = pd.DataFrame(get_cov_matrix(portfolio_data))

    ef = EfficientFrontier(returns, covariance_matrix)
    ef.min_volatility()  # max_sharpe or min_volatility
    cleaned_weights = ef.clean_weights()
    fix_keys(cleaned_weights, portfolio_data)
    print(cleaned_weights)
    ef.save_weights_to_file("weights.csv")  # saves to file
    ef.portfolio_performance(verbose=True)
def test_none_bounds():
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(None, 0.3))
    ef.min_volatility()
    w1 = ef.weights

    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(-1, 0.3))
    ef.min_volatility()
    w2 = ef.weights
    np.testing.assert_array_almost_equal(w1, w2)
def test_custom_bounds():
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(0.02, 0.13))
    ef.min_volatility()
    np.testing.assert_allclose(ef._lower_bounds,
                               np.array([0.02] * ef.n_assets))
    np.testing.assert_allclose(ef._upper_bounds,
                               np.array([0.13] * ef.n_assets))

    assert ef.weights.min() >= 0.02
    assert ef.weights.max() <= 0.13
    np.testing.assert_almost_equal(ef.weights.sum(), 1)
def test_custom_bounds_different_values():
    bounds = [(0.01, 0.13), (0.02, 0.11)] * 10
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=bounds)
    ef.min_volatility()
    assert (0.01 <= ef.weights[::2]).all() and (ef.weights[::2] <= 0.13).all()
    assert (0.02 <= ef.weights[1::2]).all() and (ef.weights[1::2] <=
                                                 0.11).all()
    np.testing.assert_almost_equal(ef.weights.sum(), 1)

    bounds = ((0.01, 0.13), (0.02, 0.11)) * 10
    assert EfficientFrontier(*setup_efficient_frontier(data_only=True),
                             weight_bounds=bounds)
Esempio n. 12
0
def optimMarkowitz(datatrain, datatest, pmin, pmax, optimmodel, returnmodel,
                   riskmodel, Gam, rf):

    try:
        if returnmodel == 'historical':
            mu = expected_returns.mean_historical_return(datatrain)
        elif returnmodel == 'emahistorical':
            mu = expected_returns.ema_historical_return(datatrain)

        if riskmodel == 'historicalcov':
            S = risk_models.sample_cov(datatrain)
        elif riskmodel == 'exphistoricalcov':
            S = risk_models.exp_cov(datatrain)

        ef = EfficientFrontier(mu, S, weight_bounds=(pmin, pmax))

        #gamma>0 permet de forcer l'optimiseur à utiliser plus de titres
        ef.add_objective(objective_functions.L2_reg, gamma=Gam)

        if optimmodel == 'min_volatility':
            ef.min_volatility()
        elif optimmodel == 'max_sharpe':
            ef.max_sharpe(risk_free_rate=rf)

        cleaned_weights = ef.clean_weights()  #round and clean ...
        ef.save_weights_to_file(
            '/Users/Maxime/AMUNDI/PortMgmnt/ModulePyPortfolioOpt/OptimiseurProjet/weights.csv'
        )  # save to file
        perf = ef.portfolio_performance(verbose=True, risk_free_rate=rf)
        weightsfinal = pd.read_csv(
            '/Users/Maxime/AMUNDI/PortMgmnt/ModulePyPortfolioOpt/OptimiseurProjet/weights.csv',
            header=None)

        #For the following chart
        poids = weightsfinal.to_numpy()
        poids = poids[:, 1]
        RankedDataFrame = pd.DataFrame(index=datatest.index)

        for i, rows in weightsfinal.iterrows():
            RankedDataFrame[rows[0]] = datatest[rows[0]]
        weightsfinal.rename(columns={
            0: ' Asset Class',
            1: 'Poids'
        },
                            inplace=True)
        weightsfinal['Poids'] = round(weightsfinal['Poids'] * 100, 4)

    except ValueError:
        print('Le modèle spécifié est incorrect')

    return poids, RankedDataFrame, cleaned_weights, S, mu, perf
Esempio n. 13
0
    def optimizePortfolio(self, option='sharpe'):
        '''
            Optimize for maximal Sharpe ratio / minimum volatility (Default to Sharpe)
            TODO: Allow for more options
            Return EfficientFrontier object
        '''

        mu = self.calculateMu()
        S = self.calculateSampleCovarianceMatrix()
        ef = EfficientFrontier(mu, S)

        if option == 'sharpe':
            weights = ef.max_sharpe(
            )  #Maximize the Sharpe ratio, and get the raw weights

        elif option == 'volatility':
            weights = ef.min_volatility()

        else:
            raise SystemExit("Not found optimize option (Sharpe/Volatility)")

        self.cleaned_weights = ef.clean_weights()
        print(
            self.cleaned_weights
        )  #Note the weights may have some rounding error, meaning they may not add up exactly to 1 but should be close
        ef.portfolio_performance(verbose=True)

        return ef
def test_weight_bounds_minus_one_to_one():
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(-1, 1))
    assert ef.max_sharpe()
    ef2 = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                            weight_bounds=(-1, 1))
    assert ef2.min_volatility()
Esempio n. 15
0
def portfolio_opt(input_return_df: pd.DataFrame, input_freq: str, solution: str, weight_bounds = (0,1), risk_aversion=1, market_neutral=False,
                                risk_free_rate=0.0, target_volatility=0.01, target_return=0.11, 
                                returns_data=True, compounding=False):
    """
    pyportfolioopt Portfolios

    Args
    ----------
    input_return_df: pd.DataFrame
        historical prices only, or historical + forecasts
    solution: str
        'max_sharpe','min_volatility','max_quadratic_utility',
        'efficient_risk','efficient_return','custom'
    input_freq: str
        daily/monthly

    Returns
    ----------
    weights_df: 1 x n pd.DataFrame

    """ 
    if not isinstance(input_return_df, pd.DataFrame):
        raise ValueError("Not a valid input_price_df. Type should be a pd.DataFrame.") 
    if not isinstance(input_freq, str):
        raise ValueError("Not a valid input_freq, please enter daily/monthly.")
    if not isinstance(solution, str):
        raise ValueError("Not a valid solution.")
    # annualized mean returns: returns.mean() * frequency
    mu = calculate_annualized_expected_returns(input_price_df = input_return_df, 
                                                                input_freq = input_freq, 
                                                                returns_data = returns_data, 
                                                                compounding = compounding)
    # annulized return covariance matrix: returns.cov() * frequency
    S = calculate_annualized_return_covariance(input_price_df = input_return_df,
                                                    input_freq = input_freq,
                                                    returns_data = returns_data, 
                                                    compounding = compounding)
    # Optimise for maximal Sharpe ratio
    ef = EfficientFrontier(mu, S, weight_bounds = weight_bounds, gamma = 0)

    if solution == 'max_sharpe':
        raw_weights = ef.max_sharpe(risk_free_rate = risk_free_rate)
    elif solution == 'min_volatility':
        raw_weights = ef.min_volatility()
    elif solution == 'max_quadratic_utility':
        raw_weights = ef.max_quadratic_utility(risk_aversion = risk_aversion, market_neutral = market_neutral)
    elif solution == 'efficient_risk':
        raw_weights = ef.efficient_risk(target_volatility = target_volatility, market_neutral = market_neutral)
    elif solution == 'efficient_return':
        raw_weights = ef.efficient_return(target_return = target_return, market_neutral = market_neutral)
    elif solution == 'custom':
        print('Outside Implement Required.')
        return None

    date = input_return_df.index[-1] # the date on which weights are calculated
    weights_df = pd.DataFrame(raw_weights, columns = raw_weights.keys(), index=[date])
    return weights_df
Esempio n. 16
0
    def lv_backtest(self):
        self.strate = "Low Volatility"

        for i in range(len(self.cov_list)):
            sample_cov = pd.DataFrame(self.cov_list[i])
            df = self.ret_list[i]
            mu = df.mean()
            ef = EfficientFrontier(mu, sample_cov)
            self.weights.append(ef.min_volatility())
def test_min_volatility_no_rets():
    # Should work with no rets, see issue #82
    df = get_data()
    S = risk_models.sample_cov(df)
    ef = EfficientFrontier(None, S)
    w = ef.min_volatility()
    assert isinstance(w, dict)
    assert set(w.keys()) == set(ef.tickers)
    np.testing.assert_almost_equal(ef.weights.sum(), 1)
    assert all([i >= 0 for i in w.values()])
    np.testing.assert_almost_equal(ef.portfolio_performance()[1], 0.15915084514118694)
def optimizePortEfficient(port, weights, start, plot = False, short = False, printBasicStats=True, how = 'Sharpe'):
    #Getting Data
    df = bpf.getData(port, start)
    #Plotting the portfolio
    if plot: 
        bpf.plotPort(df, port)
        
    if printBasicStats:
        bpf.basicStats(df, weights, start)
    #Optimization for Sharpe using Efficient Frontier
    if short: 
        bounds = (-1,1)
    else:
        bounds = (0,1)
    mu = df.pct_change().mean() * 252
    S = risk_models.sample_cov(df)
    #Method and constraints for optimization
    if how == 'Sharpe':
        # Maximized on Sharpe Ratio
        ef = EfficientFrontier(mu, S, weight_bounds=bounds) #Here the weight bounds are being used to allow short positions as well
        weights = ef.max_sharpe()
        cleaned_weights = dict(ef.clean_weights())
        print("Weights of an optimal portfolio maximised on Sharpe Ratio:")
        print(cleaned_weights)
        ef.portfolio_performance(verbose = True)
        bpf.getDiscreteAllocations(df, weights)
        plotting.plot_weights(weights)
        return weights 
    elif how == "Vol":
        # Minimized on Volatility
        efi = EfficientFrontier(mu, S, weight_bounds=bounds)
        w = dict(efi.min_volatility())
        print("Weights of an optimal portfolio minimized on Volatilty (Risk):")
        print(w)
        efi.portfolio_performance(verbose = True)
        bpf.getDiscreteAllocations(df, w)
        plotting.plot_weights(w)
        return w
    elif how == "targetRisk":
        #Optimized for a given target risk
        efi = EfficientFrontier(mu, S, weight_bounds=bounds)
        efi.efficient_risk(0.25)
        w = dict(efi.clean_weights())
        if w ==None:
            print("No portfolio possible at the given risk level")
        else:
            print("Weights of an optimal portfolio for given risk:")
            print(w)
            efi.portfolio_performance(verbose = True)
            bpf.getDiscreteAllocations(df, w)
            plotting.plot_weights(w)
        return w
def test_min_volatility_sector_constraints():
    sector_mapper = {
        "T": "auto",
        "UAA": "airline",
        "SHLD": "retail",
        "XOM": "energy",
        "RRC": "energy",
        "BBY": "retail",
        "MA": "fig",
        "PFE": "pharma",
        "JPM": "fig",
        "SBUX": "retail",
        "GOOG": "tech",
        "AAPL": "tech",
        "FB": "tech",
        "AMZN": "tech",
        "BABA": "tech",
        "GE": "utility",
        "AMD": "tech",
        "WMT": "retail",
        "BAC": "fig",
        "GM": "auto",
    }

    sector_upper = {
        "tech": 0.2,
        "utility": 0.1,
        "retail": 0.2,
        "fig": 0.4,
        "airline": 0.05,
        "energy": 0.2,
    }
    sector_lower = {"utility": 0.01, "fig": 0.02, "airline": 0.01}

    # ef = setup_efficient_frontier()
    ef = EfficientFrontier(
        *setup_efficient_frontier(data_only=True), weight_bounds=(None, None)
    )
    ef.add_sector_constraints(sector_mapper, sector_lower, sector_upper)

    weights = ef.min_volatility()

    for sector in list(set().union(sector_upper, sector_lower)):
        sector_sum = 0
        for t, v in weights.items():
            if sector_mapper[t] == sector:
                sector_sum += v
        assert sector_sum <= sector_upper.get(sector, 1) + 1e-5
        assert sector_sum >= sector_lower.get(sector, 0) - 1e-5
def test_min_volatility_short():
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(None, None))
    w = ef.min_volatility()
    assert isinstance(w, dict)
    assert set(w.keys()) == set(ef.tickers)
    np.testing.assert_almost_equal(ef.weights.sum(), 1)
    np.testing.assert_allclose(
        ef.portfolio_performance(),
        (0.1721356467349655, 0.1555915367269669, 0.9777887019776287),
    )

    # Shorting should reduce volatility
    volatility = ef.portfolio_performance()[1]
    ef_long_only = setup_efficient_frontier()
    ef_long_only.min_volatility()
    long_only_volatility = ef_long_only.portfolio_performance()[1]
    assert volatility < long_only_volatility
Esempio n. 21
0
def get_portfolio_distribution(watchlist_id):
    
    assets = get_assets(watchlist_id)


    if (len(assets) == 0):
        aggregate_data = {}
        aggregate_data['composition'] = "No stocks in the watchlist"
        aggregate_data['Expected annual return:'] = "0"
        aggregate_data['Annual volatility:'] = "0"
        aggregate_data['Sharpe Ratio:'] = "0"
        return aggregate_data

    tickers = []
    for stock_x in assets:
        # Create empty dict for stock data
        tickers.append(f"{stock_x[1]}.AX")

    yf.pdr_override()
    x = datetime.datetime.now()
    Previous_Date = datetime.datetime.today() - datetime.timedelta(days=365)

    data = pdr.get_data_yahoo(tickers, start=Previous_Date.strftime('%Y-%m-%d'), end=x.strftime('%Y-%m-%d'))
    data = data['Close']
    mu = expected_returns.mean_historical_return(data)
    S = risk_models.sample_cov(data)
    ef = EfficientFrontier(mu, S)
    raw_weights = ef.min_volatility()
    cleaned_weights = ef.clean_weights()  
    perf = ef.portfolio_performance()
    
    aggregate_data = {}
    aggregate_data['dictionary_composition'] = cleaned_weights.items()
    aggregate_data['Expected_annual_return:'] = f"Expected annual return: {perf[0]*100:.2f}%"
    aggregate_data['Annual_volatility:'] = f"Annual volatility: {perf[1]*100:.2f}%"
    aggregate_data['Sharpe_Ratio:'] = f"Sharpe Ratio: {perf[2]:.2f}""
    return aggregate_data
Esempio n. 22
0
T = risk_models.CovarianceShrinkage(prices).ledoit_wolf()

plotting.plot_covariance(S)
plotting.plot_covariance(T)

#equal weights
initial_weights = np.array([1 / len(tickers)] * len(tickers))
print(initial_weights)

#transaction cost objective
ef = EfficientFrontier(mum, T)
# 1% broker commission
ef.add_objective(objective_functions.transaction_cost,
                 w_prev=initial_weights,
                 k=0.01)
ef.min_volatility()
weights = ef.clean_weights()
weights

# smaller broker comms
ef = EfficientFrontier(mu, S)
ef.add_objective(objective_functions.transaction_cost,
                 w_prev=initial_weights,
                 k=0.001)
ef.min_volatility()
weights = ef.clean_weights()
weights

#limit number of zero weights
ef = EfficientFrontier(mu, S)
ef.add_objective(objective_functions.transaction_cost,
Esempio n. 23
0
def BLmain():

    #Excell Call
    sht = xw.Book.caller().sheets['Optim']
    shtdata = xw.Book.caller().sheets['Data']
    sht.range('J17').value = 'Optimizing...'

    #Clear Values
    sht.range('L23').expand().clear_contents()
    shtdata.range('A1').expand().clear_contents()
    shtdata.range('J1').expand().clear_contents()

    #Set variables from excel
    rf = sht.range('J10').value
    MinWeight = sht.range('J11').value
    MaxWeight = sht.range('J12').value
    Delta = sht.range('J13').value
    Tau = sht.range('J14').value
    Output = sht.range('J15').value
    ModelOptim = sht.range('J8').value
    RiskModel = sht.range('J9').value
    listticker = xw.Range('B3').expand().value
    indexname = sht.range('J7').value
    startdate = sht.range('J3').value
    enddate = sht.range('J6').value
    EFBool = sht.range('J16').value
    traintestdate = sht.range(
        'J4'
    ).value  #Dataset is divided in two sub: train (optimization) and test for backtest

    #Initializing
    train, test = initialize(startdate, enddate, traintestdate, listticker)
    trainindex, testindex = initializeIndex(startdate, enddate, traintestdate,
                                            indexname)  #for risk aversion

    #Black Litterman
    if RiskModel == 'historicalcov':
        S = risk_models.sample_cov(train)
    elif RiskModel == 'exphistoricalcov':
        S = risk_models.exp_cov(train)

    if Delta != None:
        delta = Delta
    else:
        delta = black_litterman.market_implied_risk_aversion(trainindex,
                                                             risk_free_rate=rf)

    s = data.get_quote_yahoo(listticker)['marketCap']
    mcaps = {tick: mcap
             for tick, mcap in zip(listticker, s)
             }  #Dictionnary of Market Cap for each stock

    #Expected returns implied from the market
    prior = black_litterman.market_implied_prior_returns(mcaps,
                                                         delta,
                                                         S,
                                                         risk_free_rate=rf)
    views, picking = createviews(listticker)
    bl = BlackLittermanModel(S, Q=views, P=picking, pi=prior, tau=Tau)
    rets = bl.bl_returns()
    cov = bl.bl_cov()

    #Two ways of displaying outputs: either using Optimizer, either returning implied weights
    if Output == 'Optimization':
        ef = EfficientFrontier(rets, S, weight_bounds=(MinWeight, MaxWeight))
        #RiskModel
        if ModelOptim == 'min_volatility':
            raw_weights = ef.min_volatility()
        elif ModelOptim == 'max_sharpe':
            raw_weights = ef.max_sharpe()
        cleaned_weights = ef.clean_weights()
        finalw = [cleaned_weights.get(i, 1) for i in listticker]
        perf = ef.portfolio_performance(verbose=True, risk_free_rate=rf)
        sht.range('H21').value = perf

    elif Output == 'Return-Implied-Weight':
        bl.bl_weights(delta)
        weights = bl.clean_weights()
        finalw = [weights.get(i, 1) for i in listticker]
    finalr = [rets.get(i, 1) for i in listticker]  #E(R) from BL

    #Display results
    sht.range('L23').options(transpose=True).value = listticker
    sht.range('M23').options(transpose=True).value = finalw
    sht.range('N23').options(transpose=True).value = finalr

    #Copy Data in Data Range
    shtdata.range((1, 1)).value = train
    shtdata.range((1, len(listticker) + 3)).value = test
    #numshares, left = getoptimprices(test, cleanW, InitialAmountInPortfolio)

    #Visualisation
    sht.charts['BLweights'].set_source_data(
        sht.range((23, 12), (22 + len(listticker), 13)))
    CorrMap(sht, 'CorrMatPrior', S, 'coolwarm')
    CorrMap(sht, 'CorrMatBL', cov, 'YlGn')
    if EFBool == "YES":
        effrontier(rets, S, sht, 'EFBL')

    #Done
    sht.range('J17').value = 'Optimization Done'
Esempio n. 24
0
def update_graph1(n_clicks, stock_ticker, lookforward_period, risk):
    exp_ret = pd.Series()
    content1 = list(stock_ticker)
    data3 = pd.DataFrame()
    for contents in content1:
        data3 = pd.concat([
            data3,
            yf.download(f"{contents}", start="2015-01-01",
                        end="2020-01-01").iloc[:, 4]
        ],
                          axis=1,
                          sort=False)
    data3.columns = content1

    data4 = data3.dropna(how="all")
    data4 = data4.dropna(axis='columns', how="any")

    cumulative_ret_data = pd.DataFrame()
    for contents in content1:
        cumulative_ret_data[f"{contents}"] = (
            1 + (data4[f"{contents}"]).pct_change()).cumprod()
    cumulative_ret_data = cumulative_ret_data.fillna(1)
    S = risk_models.sample_cov(data4)

    if lookforward_period == 2:
        exp_ret = pypfopt.expected_returns.mean_historical_return(
            data4, frequency=500)
        if (risk == 2):
            ef = EfficientFrontier(exp_ret, S, weight_bounds=(-1, 1), gamma=1)
            weights_ef = ef.max_sharpe(risk_free_rate=0.02)
        elif (risk == 3):
            ef = EfficientFrontier(exp_ret, S, weight_bounds=(-1, 1), gamma=1)
            weights_ef = ef.max_quadratic_utility(risk_aversion=0.00001,
                                                  market_neutral=False)
        else:
            ef = EfficientFrontier(exp_ret, S, weight_bounds=(-1, 1), gamma=1)
            weights_ef = ef.min_volatility()
    elif (lookforward_period == 3):
        exp_ret = pypfopt.expected_returns.mean_historical_return(
            data4, frequency=750)
        if (risk == 2):
            ef = EfficientFrontier(exp_ret, S, weight_bounds=(-1, 1), gamma=1)
            weights_ef = ef.max_sharpe(risk_free_rate=0.02)
        elif (risk == 3):
            ef = EfficientFrontier(exp_ret, S, weight_bounds=(-1, 1), gamma=1)
            weights_ef = ef.max_quadratic_utility(risk_aversion=0.00001,
                                                  market_neutral=False)
        else:
            ef = EfficientFrontier(exp_ret, S, weight_bounds=(-1, 1), gamma=1)
            weights_ef = ef.min_volatility()
    else:
        exp_ret = pypfopt.expected_returns.mean_historical_return(
            data4, frequency=250)
        if (risk == 2):
            ef = EfficientFrontier(exp_ret, S, weight_bounds=(-1, 1), gamma=1)
            weights_ef = ef.max_sharpe(risk_free_rate=0.02)
        elif (risk == 3):
            ef = EfficientFrontier(exp_ret, S, weight_bounds=(-1, 1), gamma=1)
            weights_ef = ef.max_quadratic_utility(risk_aversion=0.00001,
                                                  market_neutral=False)
        else:
            ef = EfficientFrontier(exp_ret, S, weight_bounds=(-1, 1), gamma=1)
            weights_ef = ef.min_volatility()
        #exp_ret=pypfopt.expected_returns.mean_historical_return(data4, frequency=250)

    #exp_ret=pypfopt.expected_returns.mean_historical_return(data4, frequency=252)

    if (risk == 2):
        ef = EfficientFrontier(exp_ret, S, weight_bounds=(-1, 1), gamma=1)
        weights_ef = ef.max_sharpe(risk_free_rate=0.02)
    elif (risk == 3):
        ef = EfficientFrontier(exp_ret, S, weight_bounds=(-1, 1), gamma=1)
        weights_ef = ef.max_quadratic_utility(risk_aversion=0.00001,
                                              market_neutral=False)
    else:
        ef = EfficientFrontier(exp_ret, S, weight_bounds=(-1, 1), gamma=1)
        weights_ef = ef.min_volatility()

    dictlist = []
    for key, value in weights_ef.items():
        temp = [key, value]
        dictlist.append(temp)

    weights = pd.DataFrame(dictlist, columns=['ticker',
                                              'weight']).set_index('ticker')
    weights = weights.iloc[:, 0]
    weights = weights.sort_index()
    weight_list = weights.tolist()

    HRP_df = weights.multiply(weights, weight_list)
    HRP_cumu = cumulative_ret_data.reindex(
        sorted(cumulative_ret_data.columns),
        axis=1)  #sort column by company names
    HRP_df = HRP_cumu.mul(weight_list, axis=1)
    HRP_df['final_returns'] = HRP_df.sum(axis=1)

    fig2 = {
        # set data equal to traces
        'data': [{
            'x': HRP_df.index,
            'y': HRP_df["final_returns"],
            'name': tic
        }],
        # use string formatting to include all symbols in the chart title
        'layout': {
            'title': ', '.join(stock_ticker) + ' portfolio'
        }
    }
    return fig2
Esempio n. 25
0
"""
Expected annual return: 33.0%
Annual volatility: 21.7%
Sharpe Ratio: 1.43

Discrete allocation: {'AAPL': 5.0, 'FB': 11.0, 'BABA': 5.0, 'AMZN': 1.0, 
                      'BBY': 7.0, 'MA': 14.0, 'PFE': 50.0, 'SBUX': 5.0}
Funds remaining: $8.42
"""

# Long-only minimum volatility portfolio, with a weight cap and regularisation
# e.g if we want at least 15/20 tickers to have non-neglible weights, and no
# asset should have a weight greater than 10%
ef = EfficientFrontier(mu, S, weight_bounds=(0, 0.10))
ef.add_objective(objective_functions.L2_reg, gamma=0.1)
weights = ef.min_volatility()
print(weights)
ef.portfolio_performance(verbose=True)
"""
{'GOOG': 0.0584267903998156,
 'AAPL': 0.0369081348579286,
 'FB': 0.0997609043032782,
 'BABA': 0.1,
 'AMZN': 0.0,
 'GE': 0.0646457157900559,
 'AMD': 0.0,
 'WMT': 0.1,
 'BAC': 0.0,
 'GM': 0.1,
 'T': 0.1,
 'UAA': 0.0,
Esempio n. 26
0
    y=df.columns,
    ), layout = layout)

fig.show()
fig.write_image(fr"{output_dir}\CorrelationHeatmap.png")
#py.iplot(fig, filename='Beta/Untreated_Heatmap')


#fig.write_image(fr"{output_dir3}\{name}_range_graph.png")


# min volatility portfolio
ef_minvol = EfficientFrontier(exp_ret, S)
# ef.add_objective(objective_functions.transaction_cost,
#                  w_prev=initial_weights, k=0.01)
ef_minvol.min_volatility()
weights_minvol = ef_minvol.clean_weights()
weights_minvol
ef_minvol.portfolio_performance(verbose=True)

# max sharpe portfolio
ef_maxsharpe = EfficientFrontier(exp_ret, S)
ef_maxsharpe.max_sharpe(risk_free_rate=0.005)
weights_maxsharpe = ef_maxsharpe.clean_weights()
weights_maxsharpe
ef_maxsharpe.portfolio_performance(verbose=True)

# max quadratic utility
ef_maxquad = EfficientFrontier(exp_ret, S, weight_bounds=(0.025, 0.15))
ef_maxquad.max_quadratic_utility(risk_aversion=1, market_neutral=False)
weights_maxquad = ef_maxquad.clean_weights()