Esempio n. 1
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
def test_max_sharpe_long_weight_bounds():
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(0.03, 0.13))
    ef.max_sharpe()
    np.testing.assert_almost_equal(ef.weights.sum(), 1)
    assert ef.weights.min() >= 0.03
    assert ef.weights.max() <= 0.13

    bounds = [(0.01, 0.13), (0.02, 0.11)] * 10
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=bounds)
    ef.max_sharpe()
    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()
Esempio n. 3
0
    def portfolio_opt(self):
        portfolio = self.portfolio.split(",")
        df = self.db.load_data(TableName.DAY,
                               time_from=self.time_from,
                               symbols=portfolio)
        # df = FinI.add_date_col(df)
        df = df[["close", "sym"]]
        df2 = df.copy()
        df2 = df2.drop(columns=["close", "sym"])
        for sym in portfolio:
            df2[sym] = df[df["sym"] == sym]["close"]

        df2 = df2.drop_duplicates()

        # df = df.transpose()
        # df.index = pd.to_datetime(df['date']).astype(int) / 10**9
        st.write(df2)
        # Calculate expected returns and sample covariance
        mu = expected_returns.mean_historical_return(df2)
        S = risk_models.sample_cov(df2)

        # Optimize for maximal Sharp ratio
        ef = EfficientFrontier(mu, S)
        raw_weights = ef.max_sharpe()
        cleaned_weights = ef.clean_weights()
        # ef.save_weights_to_file("weights.csv")  # saves to file
        st.write(cleaned_weights)
        mu, sigma, sharpe = ef.portfolio_performance(verbose=True)
        st.write("Expected annual return: {:.1f}%".format(100 * mu))
        st.write("Annual volatility: {:.1f}%".format(100 * sigma))
        st.write("Sharpe Ratio: {:.2f}".format(sharpe))
Esempio n. 4
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. 6
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. 7
0
    def plot_stock_insights(self, scatter=False):

        ef = EfficientFrontier(self.mu, self.S)
        weights = ef.max_sharpe()
        cleaned_weights = ef.clean_weights()
        cla = CLA(self.mu, self.S)
        try:
            eff_front = plotting.plot_efficient_frontier(cla)
            eff_front.tick_params(axis='both', which='major', labelsize=5)
            eff_front.tick_params(axis='both', which='minor', labelsize=5)
            eff_front.get_figure().savefig(os.path.join(
                self.output_path, "efficient_frontier.png"),
                                           dpi=300)
        except:
            print("Failed to plot efficient frontier")
        cov = plotting.plot_covariance(self.S)
        weights_bar = plotting.plot_weights(cleaned_weights)
        if self.save_output:
            cov.tick_params(axis='both', which='major', labelsize=5)
            cov.tick_params(axis='both', which='minor', labelsize=5)
            cov.get_figure().savefig(os.path.join(self.output_path,
                                                  "cov_matrix.png"),
                                     dpi=300)
            weights_bar.tick_params(axis='both', which='major', labelsize=5)
            weights_bar.tick_params(axis='both', which='minor', labelsize=5)
            weights_bar.get_figure().savefig(os.path.join(
                self.output_path, "weights_bar.png"),
                                             dpi=300)

        retscomp = self.stock_prices.pct_change()
        corrMatrix = retscomp.corr()
        corr_heat = sns.heatmap(corrMatrix, xticklabels=True, yticklabels=True)
        plt.title("Corr heatmap")
        if self.save_output:
            corr_heat.tick_params(axis='both', which='major', labelsize=5)
            corr_heat.tick_params(axis='both', which='minor', labelsize=5)
            fig = corr_heat.get_figure()
            fig.figsize = (10, 10)
            fig.savefig(os.path.join(self.output_path, "corr_heatmap.png"),
                        dpi=300)
        plt.show()
        if scatter:
            plt.figure()
            plt.title("Corr scatter")
            self.scattermat = pd.plotting.scatter_matrix(retscomp,
                                                         diagonal='kde',
                                                         figsize=(10, 10))

            if self.save_output:
                plt.savefig(os.path.join(self.output_path, "corr_scatter.png"),
                            dpi=300)
            plt.show()
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_max_sharpe_short_semicovariance():
    df = get_data()
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(-1, 1))
    ef.cov_matrix = risk_models.semicovariance(df, benchmark=0)
    w = ef.max_sharpe()
    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.42444834528495234, 0.0898263632679403, 4.50255727350929),
    )
Esempio n. 10
0
def test_max_sharpe_short_semicovariance():
    df = get_data()
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(-1, 1))
    ef.cov_matrix = risk_models.semicovariance(df, benchmark=0)
    w = ef.max_sharpe()
    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.3907992623559733, 0.0809285460933456, 4.581810501430255),
    )
def test_max_sharpe_short_semicovariance():
    df = get_data()
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(-1, 1))
    ef.cov_matrix = risk_models.semicovariance(df, benchmark=0)
    w = ef.max_sharpe()
    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.3564305116656491, 0.07201282488003401, 4.671813836300796),
    )
Esempio n. 12
0
 def calculate_allocation(self, cash):
     # if you have cash to allocate to a set of stocks, this function will return how to allocate that
     # see rebalance_weight to identify most suitable portfolio
     self.cash = cash
     ef = EfficientFrontier(self.mu, self.S)
     weights = ef.max_sharpe()
     cleaned_weights = ef.clean_weights()
     latest_prices = get_latest_prices(self.stock_prices)
     da = DiscreteAllocation(cleaned_weights,
                             latest_prices,
                             total_portfolio_value=cash)
     allocation, leftover = da.lp_portfolio()
     print("Discrete allocation:", allocation)
     print("Funds remaining: ${:.2f}".format(leftover))
Esempio n. 13
0
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.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. 14
0
def build_portfolio_weights(stock_data, weights_filename):

    # Calculate expected returns and sample covariance
    if isinstance(stock_data, pd.Series):
        stock_data = stock_data.to_frame()

    mu = expected_returns.mean_historical_return(stock_data)
    S = risk_models.sample_cov(stock_data)

    # Optimize for maximal Sharpe ratio
    ef = EfficientFrontier(mu, S)
    raw_weights = ef.max_sharpe()
    cleaned_weights = ef.clean_weights()
    ef.save_weights_to_file(weights_filename)  # saves to file
    ef.portfolio_performance(verbose=True)
    return cleaned_weights
Esempio n. 15
0
def optimise_portfolio(stock_price, Portfolio):
    returns = stock_price.pct_change().dropna()
    # Calculate expected returns and sample covariance
    mu = expected_returns.mean_historical_return(stock_price)
    S = risk_models.sample_cov(stock_price)

    # Optimise for maximal Sharpe ratio
    ef = EfficientFrontier(mu, S)
    raw_weights = ef.max_sharpe()
    cleaned_weights = ef.clean_weights()
    ef.save_weights_to_file("weights.csv")  # saves to file
    print(cleaned_weights)
    ef.portfolio_performance(verbose=True)
    Portfolio.ef = ef
    Portfolio.mu = mu
    Portfolio.S = S
    Portfolio.weights = cleaned_weights
def get_result(l):
    data = yf.download(tickers=l,
                       period="max",
                       interval="1d",
                       auto_adjust=True)
    data = data['Close']
    mu = expected_returns.mean_historical_return(data)
    S = CovarianceShrinkage(data).ledoit_wolf()
    ef = EfficientFrontier(mu, S)
    raw_weights = ef.max_sharpe()
    cleaned_weights = ef.clean_weights()
    data = []
    for x in cleaned_weights.keys():
        if cleaned_weights[x] != 0:
            data.append({'name': x, 'y': cleaned_weights[x]})
    answer = {'data': data, 'performance': ef.portfolio_performance()}
    return answer
def test_max_sharpe_L2_reg_with_shorts():
    ef_no_reg = setup_efficient_frontier()
    ef_no_reg.max_sharpe()
    initial_number = sum(ef_no_reg.weights > 0.01)

    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(None, None))
    ef.add_objective(objective_functions.L2_reg)
    w = ef.max_sharpe()
    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.2995338981166366, 0.2234696161770517, 1.2508810052063901),
    )
    new_number = sum(ef.weights > 0.01)
    assert new_number >= initial_number
def test_max_sharpe_short():
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(None, None))
    w = ef.max_sharpe()
    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.4937195216716211, 0.29516576454651955, 1.6049270564945908),
    )
    sharpe = ef.portfolio_performance()[2]

    ef_long_only = setup_efficient_frontier()
    ef_long_only.max_sharpe()
    long_only_sharpe = ef_long_only.portfolio_performance()[2]

    assert sharpe > long_only_sharpe
def test_max_sharpe_short():
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(None, None))
    w = ef.max_sharpe()
    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.4072439477276246, 0.24823487545231313, 1.5599900981762558),
    )
    sharpe = ef.portfolio_performance()[2]

    ef_long_only = setup_efficient_frontier()
    ef_long_only.max_sharpe()
    long_only_sharpe = ef_long_only.portfolio_performance()[2]

    assert sharpe > long_only_sharpe
def test_max_sharpe_L2_reg_with_shorts():
    ef_no_reg = setup_efficient_frontier()
    ef_no_reg.max_sharpe()
    initial_number = sum(ef_no_reg.weights > 0.01)

    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(None, None))
    ef.add_objective(objective_functions.L2_reg)
    w = ef.max_sharpe()
    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.3076093180094401, 0.22415982749409985, 1.2830546901496447),
    )
    new_number = sum(ef.weights > 0.01)
    assert new_number >= initial_number
Esempio n. 21
0
def Optimize(array):
    df = pd.read_csv('latest_stock_prices.csv',
                     parse_dates=True,
                     index_col="date")

    data = df[df.columns.intersection(array)]
    data.dtypes

    mu = expected_returns.mean_historical_return(data)
    S = risk_models.sample_cov(data)

    # Optimise for maximal Sharpe ratio
    ef = EfficientFrontier(mu, S)
    raw_weights = ef.max_sharpe()
    cleaned_weights = ef.clean_weights()

    ef.save_weights_to_file("weights.csv")  # saves to file
    print(cleaned_weights)
    ef.portfolio_performance(verbose=True)
Esempio n. 22
0
def run_portfolio_optimization() -> None:
    df_corr = _load_df_correlation_economist()
    df_corr = df_corr.set_index(df_corr['state'])
    df_mu_sigma = _compute_df_mu_sigma_return()
    df_mu_sigma = df_mu_sigma.sort_values('STATE_INIT')
    df_corr = df_corr.loc[df_mu_sigma['STATE_INIT']][
        df_mu_sigma['STATE_INIT'].values]

    # Covariance = diag(S) * Corr * diag(S)
    # Note: This isn't going to be exactly correct since the Economist correlations are not the
    # market returns, but let's assume they're roughly equal
    df_cov = pandas.DataFrame(np.matmul(
        np.matmul(np.diag(df_mu_sigma['STD_D_YES'].values), df_corr.values),
        np.diag(df_mu_sigma['STD_D_YES'].values)),
                              index=df_mu_sigma['STATE_INIT'].values,
                              columns=df_mu_sigma['STATE_INIT'].values)
    sns.heatmap(df_corr, fmt=',.1f')
    plt.title('Correlation matrix of state performance')
    plt.show()
    df_mu_sigma.to_csv(os.path.join(_data_dir(), 'mu_sigma.csv'))
    df_cov.to_csv(os.path.join(_data_dir(), 'vcov_matrix.csv'))

    ef = EfficientFrontier(
        expected_returns=df_mu_sigma.set_index('STATE_INIT')['MU_D_YES'],
        cov_matrix=df_cov)
    raw_weights = ef.max_sharpe(risk_free_rate=0)
    df_weights = pandas.DataFrame([(state, w)
                                   for state, w in ef.clean_weights().items()],
                                  columns=['STATE_INIT', 'WEIGHT'])

    df_weights[df_weights['WEIGHT'].gt(0)].set_index(
        'STATE_INIT')['WEIGHT'].plot.barh()
    plt.title('Optimal portfolio weights (D win)')
    plt.ylabel('State market')
    plt.xlabel('Weight')
    sns.despine()
    plt.show()
    print(df_weights.sort_values('WEIGHT', ascending=False))
    ef.portfolio_performance(verbose=True)

    df_weights.to_csv('portfolio_weights.csv', index=False)
Esempio n. 23
0
    def optimise_portfolio(self, use_filter=True):
        self.stock_prices.fillna(value=self.stock_prices.mean(), inplace=True)
        self.stock_prices = self.stock_prices.dropna(axis=1, how='any')

        risk_free_rate = 0.02
        risk_aversion = 0.5

        self.filter_stock_prices()
        self.holding = self.holding[self.holding.Symbol.isin(
            self.fil_stock_prices.keys())]
        if use_filter:
            self.mu = expected_returns.mean_historical_return(
                self.fil_stock_prices)
            self.S = risk_models.sample_cov(self.fil_stock_prices)
        else:
            self.mu = expected_returns.mean_historical_return(
                self.stock_prices)
            self.S = risk_models.sample_cov(self.stock_prices)

        self.index_return = self.stock_prices.sum(
            axis=1)[-1] / self.stock_prices.sum(axis=1)[0]
        self.index_price = self.stock_prices.sum(axis=1)
        returns = self.stock_prices.pct_change().dropna()
        # Calculate expected returns and sample covariance
        #calculate old portfolio position
        # Optimise for maximal Sharpe ratio
        ef = EfficientFrontier(self.mu, self.S)

        # raw_weights = ef.max_quadratic_utility(risk_aversion)
        raw_weights = ef.max_sharpe()

        cleaned_weights = ef.clean_weights()
        ef.save_weights_to_file(os.path.join(self.output_path,
                                             "weights.csv"))  # saves to file
        print(cleaned_weights)
        ef.portfolio_performance(verbose=True)
        self.ef = ef
        self.weights = cleaned_weights
        self.rebalance_weight()
Esempio n. 24
0
def cli(risk_free_rate, start, span, verbose, tickers):
    # Read in price data
    thelen = len(tickers)
    price_data = []
    successful_tickers = []
    for ticker in range(thelen):
        click.echo(tickers[ticker])
        try:
            prices = web.DataReader(tickers[ticker],
                                    start=start,
                                    data_source='yahoo')
            if verbose >= 1:
                click.echo(tickers[ticker] + ':')
                click.echo(prices)
            price_data.append(prices.assign(ticker=ticker)[['Adj Close']])
            successful_tickers.append(tickers[ticker])
        except:
            pass

    df = pd.concat(price_data, axis=1)
    df.columns = successful_tickers
    df.head()

    #Checking if any NaN values in the data
    nullin_df = pd.DataFrame(df, columns=tickers)
    print(nullin_df.isnull().sum())

    # Calculate expected returns and sample covariance
    mu = expected_returns.ema_historical_return(df, span=span)
    S = risk_models.sample_cov(df)

    # Optimise for maximal Sharpe ratio
    ef = EfficientFrontier(
        mu, S)  #weight bounds in negative allows shorting of stocks
    raw_weights = ef.max_sharpe(risk_free_rate=risk_free_rate)
    cleaned_weights = ef.clean_weights()
    click.echo(cleaned_weights)
    ef.portfolio_performance(verbose=True)
Esempio n. 25
0
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)
Esempio n. 26
0
def show_ef(stocks: List[str], other_args: List[str]):
    """Display efficient frontier

    Parameters
    ----------
    stocks : List[str]
        List of the stocks to be included in the weights
    other_args : List[str]
        argparse other args
    """

    parser = argparse.ArgumentParser(
        add_help=False,
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        prog="ef",
        description="""This function plots random portfolios based
                    on their risk and returns and shows the efficient frontier.""",
    )
    parser.add_argument(
        "-p",
        "--period",
        default="3mo",
        dest="period",
        help="period to get yfinance data from",
        choices=period_choices,
    )
    parser.add_argument(
        "-n",
        "--number-portfolios",
        default=300,
        type=check_non_negative,
        dest="n_port",
        help="number of portfolios to simulate",
    )

    try:
        if other_args:
            if "-" not in other_args[0]:
                other_args.insert(0, "-n")
        ns_parser = parse_known_args_and_warn(parser, other_args)
        if not ns_parser:
            return
        if len(stocks) < 2:
            print(
                "Please have at least 2 loaded tickers to calculate weights.\n"
            )
            return

        stock_prices = process_stocks(stocks, ns_parser.period)
        mu = expected_returns.mean_historical_return(stock_prices)
        S = risk_models.sample_cov(stock_prices)
        ef = EfficientFrontier(mu, S)
        _, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)

        # Generate random portfolios
        n_samples = ns_parser.n_port
        w = np.random.dirichlet(np.ones(len(mu)), n_samples)
        rets = w.dot(mu)
        stds = np.sqrt(np.diag(w @ S @ w.T))
        sharpes = rets / stds
        ax.scatter(stds, rets, marker=".", c=sharpes, cmap="viridis_r")

        plotting.plot_efficient_frontier(ef, ax=ax, show_assets=True)
        # Find the tangency portfolio
        ef.max_sharpe()
        ret_sharpe, std_sharpe, _ = ef.portfolio_performance()
        ax.scatter(std_sharpe,
                   ret_sharpe,
                   marker="*",
                   s=100,
                   c="r",
                   label="Max Sharpe")

        ax.set_title(
            f"Efficient Frontier simulating {ns_parser.n_port} portfolios")
        ax.legend()
        plt.tight_layout()
        plt.grid(b=True, which="major", color="#666666", linestyle="-")
        plt.minorticks_on()
        plt.grid(b=True,
                 which="minor",
                 color="#999999",
                 linestyle="-",
                 alpha=0.2)

        if gtff.USE_ION:
            plt.ion()

        plt.show()
        print("")

    except Exception as e:
        print(e, "\n")
Esempio n. 27
0
daily_return = np.log(prices / prices.shift(1))
#relabel columns
daily_return['Date'] = dates
cols = ['Date'] + prices.columns.to_list()
daily_return = daily_return.reindex(columns=cols)
#write to csv
daily_return.to_csv(r"C:\Users\Jonathan\Investing\ETF_daily_returns.csv",
                    na_rep=np.nan)

# Read in price data
df = pd.read_csv(r"C:\Users\Jonathan\Investing\ETF_closing_prices.csv",
                 parse_dates=True,
                 index_col="Unnamed: 0")

# Calculate expected returns and sample covariance
mu = expected_returns.mean_historical_return(df)
S = risk_models.sample_cov(df)

# Optimise for maximal Sharpe ratio
ef = EfficientFrontier(mu, S)
raw_weights = ef.max_sharpe()
cleaned_weights = ef.clean_weights()
ef.save_weights_to_file(r"C:\Users\Jonathan\Investing\weights.csv")
print(cleaned_weights)
ef.portfolio_performance(verbose=True)

weights = pd.read_csv(r"C:\Users\Jonathan\Investing\weights.csv", header=None)
weights.columns = ['Ticker', 'Prop']
non_zero_weights = weights[weights.Prop != 0]
print(non_zero_weights)
non_zero_weights.to_csv(r'C:\Users\Jonathan\Desktop\stash_weights.csv')
Esempio n. 28
0
#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()
weights_maxquad
ef_maxquad.portfolio_performance(verbose=True)

# efficient risk
ef_effrisk = EfficientFrontier(exp_ret, S, weight_bounds=(0.0, 0.15))
ef_effrisk.efficient_risk(0.15, market_neutral=False)
weights_effrisk = ef_effrisk.clean_weights()
Esempio n. 29
0
from pypfopt import CLA
from pypfopt import black_litterman
from pypfopt import BlackLittermanModel
from pypfopt import Plotting

# Reading in the data; preparing expected returns and a risk model
df = pd.read_csv("tests/resources/stock_prices.csv",
                 parse_dates=True,
                 index_col="date")
returns = df.pct_change().dropna()
mu = expected_returns.mean_historical_return(df)
S = risk_models.sample_cov(df)

# Long-only Maximum Sharpe portfolio, with discretised weights
ef = EfficientFrontier(mu, S)
weights = ef.max_sharpe()
ef.portfolio_performance(verbose=True)
latest_prices = get_latest_prices(df)

da = DiscreteAllocation(weights, latest_prices)
allocation, leftover = da.lp_portfolio()
print("Discrete allocation:", allocation)
print("Funds remaining: ${:.2f}".format(leftover))
"""
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
Esempio n. 30
0
}
prior = black_litterman.market_implied_prior_returns(mcaps, delta, S)

# 1. SBUX will drop by 20%
# 2. GOOG outperforms FB by 10%
# 3. BAC and JPM will outperform T and GE by 15%
views = np.array([-0.20, 0.10, 0.15]).reshape(-1, 1)
picking = np.array([
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
    [1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, -0.5, 0, 0, 0.5, 0, -0.5, 0, 0, 0, 0, 0, 0, 0, 0.5, 0],
])
bl = BlackLittermanModel(S, Q=views, P=picking, pi=prior, tau=0.01)
rets = bl.bl_returns()
ef = EfficientFrontier(rets, S)
ef.max_sharpe()
print(ef.clean_weights())
ef.portfolio_performance(verbose=True)
"""
{'GOOG': 0.2015,
 'AAPL': 0.2368,
 'FB': 0.0,
 'BABA': 0.06098,
 'AMZN': 0.17148,
 'GE': 0.0,
 'AMD': 0.0,
 'WMT': 0.0,
 'BAC': 0.18545,
 'GM': 0.0,
 'T': 0.0,
 'UAA': 0.0,