Ejemplo n.º 1
0
def max_quad_utility_weights(rets_bl, covar_bl, config):
    print('Begin max quadratic utility optimization')
    returns, sigmas, weights, deltas = [], [], [], []
    for delta in np.arange(1, 10, 1):
        ef = EfficientFrontier(rets_bl, covar_bl, weight_bounds= \
                (config['min_position_size'] ,config['max_position_size']))
        ef.max_quadratic_utility(delta)
        ret, sigma, __ = ef.portfolio_performance()
        weights_vec = ef.clean_weights()
        returns.append(ret)
        sigmas.append(sigma)
        deltas.append(delta)
        weights.append(weights_vec)
    fig, ax = plt.subplots()
    ax.plot(sigmas, returns)
    for i, delta in enumerate(deltas):
        ax.annotate(str(delta), (sigmas[i], returns[i]))
    plt.xlabel('Volatility (%) ')
    plt.ylabel('Returns (%)')
    plt.title('Efficient Frontier for Max Quadratic Utility Optimization')
    plt.show()
    opt_delta = float(
        input('Enter the desired point on the efficient frontier: '))
    ef = EfficientFrontier(rets_bl, covar_bl, weight_bounds= \
            (config['min_position_size'] ,config['max_position_size']))
    ef.max_quadratic_utility(opt_delta)
    opt_weights = ef.clean_weights()
    opt_weights = pd.DataFrame.from_dict(opt_weights, orient='index')
    opt_weights.columns = ['Max Quad Util']
    return opt_weights, ef
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
Ejemplo n.º 3
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_custom_tracking_error():
    df = get_data()
    historical_rets = expected_returns.returns_from_prices(df).dropna()
    benchmark_rets = historical_rets["AAPL"]
    historical_rets = historical_rets.drop("AAPL", axis=1)
    S = risk_models.sample_cov(historical_rets, returns_data=True)

    opt = BaseConvexOptimizer(
        n_assets=len(historical_rets.columns),
        tickers=list(historical_rets.columns),
        weight_bounds=(0, 1),
    )

    opt.convex_objective(
        objective_functions.ex_post_tracking_error,
        historic_returns=historical_rets,
        benchmark_returns=benchmark_rets,
    )
    w = opt.clean_weights()

    ef = EfficientFrontier(None, S)
    ef.convex_objective(
        objective_functions.ex_post_tracking_error,
        historic_returns=historical_rets,
        benchmark_returns=benchmark_rets,
    )
    w2 = ef.clean_weights()

    assert w == w2
Ejemplo n.º 5
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)
Ejemplo n.º 6
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))
Ejemplo n.º 7
0
def allocate(df):
    tickers = [df.columns[k] for k in range(df.shape[1])]

    ohlc = yf.download(tickers, start="2010-01-01", end="2020-01-01")
    prices = ohlc["Adj Close"]

    market_prices = yf.download("^BVSP", start="2010-01-01",
                                end="2020-01-01")["Adj Close"]

    mcaps = {}
    for t in tickers:
        stock = yf.Ticker(t)
        mcaps[t] = stock.info["marketCap"]

    S = risk_models.CovarianceShrinkage(prices).ledoit_wolf()
    delta = black_litterman.market_implied_risk_aversion(market_prices)

    market_prior = black_litterman.market_implied_prior_returns(
        mcaps, delta, S)

    bl = BlackLittermanModel(S,
                             pi="market",
                             market_caps=mcaps,
                             risk_aversion=delta,
                             absolute_views=df.to_dict('records')[0])

    ret_bl = bl.bl_returns()
    S_bl = bl.bl_cov()

    ef = EfficientFrontier(ret_bl, S_bl)
    ef.add_objective(objective_functions.L2_reg)
    ef.max_sharpe()
    weights = ef.clean_weights()

    return weights
Ejemplo n.º 8
0
def max_sharpe_weights(rets_bl, covar_bl, config):
    ef = EfficientFrontier(rets_bl, covar_bl, weight_bounds= \
            (config['min_position_size'] ,config['max_position_size']))
    ef.max_sharpe()
    weights = ef.clean_weights()
    weights = pd.DataFrame.from_dict(weights, orient='index')
    weights.columns = ['Max Sharpe']
    return weights, ef
Ejemplo n.º 9
0
def plot_stock_insights(stock_price, Portfolio):
    mu = expected_returns.mean_historical_return(stock_price)
    S = risk_models.sample_cov(stock_price)
    ef = EfficientFrontier(mu, S)
    cleaned_weights = ef.clean_weights()
    cla = CLA(mu, S)
    plotting.plot_efficient_frontier(cla)
    plotting.plot_covariance(S)
    plotting.plot_weights(cleaned_weights)
Ejemplo n.º 10
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)
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
def calculate_allocation(stock_price, cash, Portfolio):
    mu = expected_returns.mean_historical_return(stock_price)
    S = risk_models.sample_cov(stock_price)
    ef = EfficientFrontier(mu, S)
    cleaned_weights = ef.clean_weights()
    latest_prices = get_latest_prices(stock_price)
    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))
Ejemplo n.º 13
0
def optimize(data):
    mu = expected_returns.mean_historical_return(data)
    S = risk_models.sample_cov(data)

    # Optimise for maximal Sharpe ratio
    ef = EfficientFrontier(mu, S)
    ef.max_sharpe()
    cleaned_weights = ef.clean_weights()
    weights = np.array(list(cleaned_weights.values()))
    folio = (data.iloc[:, :] * weights).sum(axis=1)
    perf = ef.portfolio_performance(verbose=True)
    return weights, folio, perf
Ejemplo n.º 14
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()
Ejemplo n.º 15
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
Ejemplo n.º 16
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))
Ejemplo n.º 17
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
Ejemplo n.º 18
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
Ejemplo n.º 19
0
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
Ejemplo n.º 20
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)
Ejemplo n.º 21
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)
Ejemplo n.º 22
0
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)
Ejemplo 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()
Ejemplo 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)
Ejemplo 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)
Ejemplo n.º 26
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
Ejemplo 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')
Ejemplo n.º 28
0
class OptPortfolio(BaseEstimator):
    '''
    Portfolio optimization used both for train and validation
    '''
    def __init__(self,
                 target_function: str = "efficient_risk",
                 target_function_params: dict = {},
                 budget: int = 10000):
        self.target_function = target_function
        self.target_function_params = target_function_params
        self.budget = budget
        self.frequency = None
        # self.mu = expected_returns.mean_historical_return(prices)
        # self.S = risk_models.CovarianceShrinkage(prices).ledoit_wolf()
        # self.ef = EfficientFrontier(self.mu, self.S)
        # self.ef.add_objective(objective_functions.L2_reg)
        # getattr(self.ef,target_function)(**target_function_params)
        # self.weights = self.ef.clean_weights()
        #
        # self.da = DiscreteAllocation(self.weights, prices.iloc[-1], total_portfolio_value=money)
        # alloc, leftover = self.da.lp_portfolio()
        # print(f"Leftover: ${leftover:.2f}")
        # print(f"Alloc: ${alloc:.2f}")
        # self.discrete_portfolio = (
        #         prices[[k for k, v in alloc.items()]] * np.asarray([[v for k, v in alloc.items()]])).dropna().sum(
        # axis=1)

    def fit(self, prices: pd.DataFrame):
        # TODO: make prices instance of portfolio
        '''
        Given prices finds wieghts (coefficients), most optimal portfolio given target function.
        :param prices:
        :return:
        '''
        self.frequency = autodetect_frequency(prices)
        self.mu = expected_returns.mean_historical_return(
            prices, frequency=self.frequency)
        self.S = risk_models.CovarianceShrinkage(
            prices, frequency=self.frequency).ledoit_wolf()
        # self.S=risk_models.exp_cov(prices)
        self.ef = EfficientFrontier(self.mu, self.S)
        self.ef.add_objective(objective_functions.L2_reg)
        getattr(self.ef, self.target_function)(**self.target_function_params)
        self.coef_ = self.ef.clean_weights()
        return self

    def predict(self, prices: pd.DataFrame):
        '''
        Predicts portfolio given found optimal portoflio weights.
        :param prices:
        :return: optimal portofolio (in currency of input)
        '''
        self.allocate(prices)
        # da = DiscreteAllocation(self.coef_, prices.iloc[-1], total_portfolio_value=self.budget)
        # alloc, leftover = da.lp_portfolio()
        # print(f"Leftover: ${leftover:.2f}")
        # print(f"Alloc: ${alloc}")
        discrete_portfolio = (
            prices[[k for k, v in self.alloc.items()]] *
            np.asarray([[v for k, v in self.alloc.items()]])).dropna()
        return discrete_portfolio

    def allocate(self, prices: pd.DataFrame) -> Tuple[dict, float]:
        '''
        Given weights for portfolio and last prices, finds best discrete allocation of assets.
        :param prices:
        :return: allocation and leftover of portfolio
        '''
        da = DiscreteAllocation(self.coef_,
                                prices.iloc[-1],
                                total_portfolio_value=self.budget)
        self.alloc, self.leftover = da.lp_portfolio()
        print("Period end:", prices.index[0])
        print(f"Leftover: ${self.leftover:.2f}")
        print(f"Alloc: ${self.alloc}")

        return self.alloc, self.leftover

    @property
    def weights(self):
        return self.coef_

    @property
    def allocations(self):
        return self.alloc

    @property
    def leftover(self):
        return self.leftover
Ejemplo n.º 29
0
    ), 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()
weights_maxquad
Ejemplo 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,
 'SHLD': 0.0,