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 test_max_quadratic_utility_market_neutral():
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(-1, 1))
    ef.max_quadratic_utility(market_neutral=True)
    np.testing.assert_almost_equal(ef.weights.sum(), 0)
    np.testing.assert_allclose(
        ef.portfolio_performance(),
        (1.13434841843883, 0.9896404148973286, 1.1260134506071473),
    )
def test_max_quadratic_utility_market_neutral():
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(-1, 1))
    ef.max_quadratic_utility(market_neutral=True)
    np.testing.assert_almost_equal(ef.weights.sum(), 0)
    np.testing.assert_allclose(
        ef.portfolio_performance(),
        (1.248936321062371, 1.0219175004907117, 1.2025787996313317),
    )
def test_max_quadratic_utility_with_shorts():
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(-1, 1))
    ef.max_quadratic_utility()
    np.testing.assert_almost_equal(ef.weights.sum(), 1)

    np.testing.assert_allclose(
        ef.portfolio_performance(),
        (1.3318330413711252, 1.0198436183533854, 1.2863080356272452),
    )
def test_max_quadratic_utility_with_shorts():
    ef = EfficientFrontier(*setup_efficient_frontier(data_only=True),
                           weight_bounds=(-1, 1))
    ef.max_quadratic_utility()
    np.testing.assert_almost_equal(ef.weights.sum(), 1)

    np.testing.assert_allclose(
        ef.portfolio_performance(),
        (1.4170505733098597, 1.0438577623242156, 1.3383533884915872),
    )
Ejemplo 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
Ejemplo n.º 7
0
#                  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()
weights_effrisk
ef_effrisk.portfolio_performance(verbose=True)

# efficient return
ef_effret = EfficientFrontier(exp_ret, S, weight_bounds=(0.03, 0.15))
ef_effret.efficient_return(target_return=0.30, market_neutral=False)
weights_effret = ef_effret.clean_weights()
Ejemplo n.º 8
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