def test_mean_historical_returns_type_warning():
    df = get_data()
    mean = expected_returns.mean_historical_return(df)

    with warnings.catch_warnings(record=True) as w:
        mean_from_array = expected_returns.mean_historical_return(np.array(df))
        assert len(w) == 1
        assert issubclass(w[0].category, RuntimeWarning)
        assert str(w[0].message) == "prices are not in a dataframe"

    np.testing.assert_array_almost_equal(mean.values, mean_from_array.values, decimal=6)
def setup_cla(data_only=False):
    df = get_data()
    mean_return = expected_returns.mean_historical_return(df)
    sample_cov_matrix = risk_models.sample_cov(df)
    if data_only:
        return mean_return, sample_cov_matrix
    return CLA(mean_return, sample_cov_matrix)
def setup_efficient_frontier(data_only=False):
    df = get_data()
    mean_return = expected_returns.mean_historical_return(df)
    sample_cov_matrix = risk_models.sample_cov(df)
    if data_only:
        return mean_return, sample_cov_matrix
    return EfficientFrontier(mean_return, sample_cov_matrix)
def test_mean_historical_returns():
    df = get_data()
    mean = expected_returns.mean_historical_return(df)
    assert isinstance(mean, pd.Series)
    assert list(mean.index) == list(df.columns)
    assert mean.notnull().all()
    assert mean.dtype == "float64"
    correct_mean = np.array(
        [
            0.26770284,
            0.3637864,
            0.31709032,
            0.22616723,
            0.49982007,
            0.16888704,
            0.22754479,
            0.14783539,
            0.19001915,
            0.08150653,
            0.12826351,
            0.25797816,
            0.07580128,
            0.16087243,
            0.20510267,
            0.3511536,
            0.38808003,
            0.24635612,
            0.21798433,
            0.28474973,
        ]
    )
    np.testing.assert_array_almost_equal(mean.values, correct_mean)
def test_negative_mean_return_real():
    df = get_data()
    e_rets = mean_historical_return(df)
    w = np.array([1 / len(e_rets)] * len(e_rets))
    negative_mu = objective_functions.negative_mean_return(w, e_rets)
    assert isinstance(negative_mu, float)
    assert negative_mu < 0
    assert negative_mu == -w.dot(e_rets)
    assert negative_mu == -(w * e_rets).sum()
    np.testing.assert_almost_equal(-e_rets.sum() / len(e_rets), negative_mu)
def test_mean_historical_returns_dummy():
    data = pd.DataFrame(
        [
            [4.0, 2.0, 0.6, -12],
            [4.2, 2.1, 0.59, -13.2],
            [3.9, 2.0, 0.58, -11.3],
            [4.3, 2.1, 0.62, -11.7],
            [4.1, 2.2, 0.63, -10.1],
        ]
    )
    mean = expected_returns.mean_historical_return(data, frequency=1)
    test_answer = pd.Series([0.00865598, 0.025, 0.01286968, -0.03632333])
    pd.testing.assert_series_equal(mean, test_answer)
def test_negative_sharpe():
    df = get_data()
    e_rets = mean_historical_return(df)
    S = sample_cov(df)
    w = np.array([1 / len(e_rets)] * len(e_rets))

    sharpe = objective_functions.negative_sharpe(w, e_rets, S)
    assert isinstance(sharpe, float)
    assert sharpe < 0

    sigma = np.sqrt(np.dot(w, np.dot(S, w.T)))
    negative_mu = objective_functions.negative_mean_return(w, e_rets)
    np.testing.assert_almost_equal(sharpe * sigma - 0.02, negative_mu)

    # Risk free rate increasing should lead to negative Sharpe increasing.
    assert sharpe < objective_functions.negative_sharpe(
        w, e_rets, S, risk_free_rate=0.1
    )
Ejemplo n.º 8
0
def test_greedy_portfolio_allocation_short_different_params_reinvest():
    df = get_data()
    mu = mean_historical_return(df)
    S = sample_cov(df)
    ef = EfficientFrontier(mu, S, weight_bounds=(-1, 1))
    w = ef.max_sharpe()

    latest_prices = get_latest_prices(df)
    da = DiscreteAllocation(w,
                            latest_prices,
                            total_portfolio_value=50000,
                            short_ratio=0.5)
    allocation, leftover = da.greedy_portfolio(reinvest=True)
    print(allocation)
    assert allocation == {
        "MA": 145,
        "PFE": 317,
        "FB": 53,
        "GOOG": 6,
        "BABA": 34,
        "AAPL": 27,
        "SBUX": 58,
        "AMZN": 2,
        "BBY": 41,
        "XOM": 30,
        "WMT": 17,
        "JPM": 1,
        "BAC": -269,
        "AMD": -399,
        "SHLD": -1099,
        "GM": -78,
        "RRC": -154,
        "GE": -119,
        "T": -41,
        "UAA": -64,
    }
    long_total = 0
    short_total = 0
    for ticker, num in allocation.items():
        if num > 0:
            long_total += num * latest_prices[ticker]
        else:
            short_total -= num * latest_prices[ticker]
    np.testing.assert_almost_equal(long_total + short_total + leftover, 100000)
def test_greedy_portfolio_allocation_short_different_params():
    df = get_data()
    mu = mean_historical_return(df)
    S = sample_cov(df)
    ef = EfficientFrontier(mu, S, weight_bounds=(-1, 1))
    w = ef.max_sharpe()

    latest_prices = get_latest_prices(df)
    da = DiscreteAllocation(w,
                            latest_prices,
                            total_portfolio_value=50000,
                            short_ratio=0.5)
    allocation, leftover = da.greedy_portfolio()

    assert da.allocation == {
        "MA": 77,
        "PFE": 225,
        "FB": 41,
        "BABA": 25,
        "AAPL": 23,
        "BBY": 44,
        "AMZN": 2,
        "SBUX": 45,
        "GOOG": 3,
        "WMT": 11,
        "XOM": 11,
        "BAC": -271,
        "GM": -133,
        "GE": -356,
        "SHLD": -922,
        "AMD": -285,
        "JPM": -5,
        "T": -14,
        "UAA": -8,
        "RRC": -3,
    }
    long_total = 0
    short_total = 0
    for ticker, num in allocation.items():
        if num > 0:
            long_total += num * latest_prices[ticker]
        else:
            short_total -= num * latest_prices[ticker]
    np.testing.assert_almost_equal(long_total + short_total + leftover, 75000)
Ejemplo n.º 10
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.º 11
0
    def test_estimate(self, estimator, expected_value, prices_df):
        mu = mean_historical_return(prices_df).values
        cov = sample_cov(prices_df).values

        allocation = np.array([
            0.01269, 0.09202, 0.19856, 0.09642, 0.07158, 0.0, 0.0, 0.0, 0.0,
            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.06129, 0.24562, 0.18413, 0.0,
            0.03769
        ])

        optimal_allocation = np.array([
            0.0, 0.15, 0.27, 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.02, 0.35, 0.1, 0.0, 0.01
        ])

        estimation = estimator.estimate(mu, cov, allocation,
                                        optimal_allocation)

        assert_almost_equal(estimation, expected_value)
def test_portfolio_allocation_errors():
    df = get_data()
    e_ret = mean_historical_return(df)
    cov = sample_cov(df)
    ef = EfficientFrontier(e_ret, cov)
    w = ef.max_sharpe()
    latest_prices = discrete_allocation.get_latest_prices(df)

    with pytest.raises(TypeError):
        discrete_allocation.portfolio(ef.weights, latest_prices)

    with pytest.raises(TypeError):
        discrete_allocation.portfolio(w, latest_prices.values.tolist())

    with pytest.raises(ValueError):
        discrete_allocation.portfolio(w, latest_prices, min_allocation=0.5)

    with pytest.raises(ValueError):
        discrete_allocation.portfolio(w, latest_prices, total_portfolio_value=0)
Ejemplo n.º 13
0
def test_es_example():
    df = get_data()
    mu = expected_returns.mean_historical_return(df)
    historical_rets = expected_returns.returns_from_prices(df).dropna()

    es = EfficientSemivariance(mu, historical_rets)
    w = es.efficient_return(0.2)

    assert isinstance(w, dict)
    assert set(w.keys()) == set(es.tickers)
    np.testing.assert_almost_equal(es.weights.sum(), 1)
    assert all([i >= -1e-5 for i in w.values()])

    np.testing.assert_allclose(
        es.portfolio_performance(),
        (0.20, 0.08558991313395496, 2.1030523036993265),
        rtol=1e-4,
        atol=1e-4,
    )
def test_lp_portfolio_allocation():
    df = get_data()
    mu = mean_historical_return(df)
    S = sample_cov(df)
    ef = EfficientFrontier(mu, S)
    w = ef.max_sharpe()

    latest_prices = get_latest_prices(df)
    da = DiscreteAllocation(w, latest_prices, short_ratio=0.3)
    allocation, leftover = da.lp_portfolio()

    #  Weirdly, this gives different answers for py3.8+ vs py3.6-3.7.
    assert allocation == {
        "AMD": 1,
        "GOOG": 1,
        "AAPL": 4,
        "FB": 12,
        "BABA": 4,
        "BBY": 2,
        "MA": 20,
        "PFE": 54,
        "SBUX": 1,
    } or allocation == {
        "GOOG": 1,
        "AAPL": 4,
        "FB": 12,
        "BABA": 4,
        "BBY": 2,
        "MA": 20,
        "PFE": 54,
        "SBUX": 1,
    }

    total = 0
    for ticker, num in allocation.items():
        total += num * latest_prices[ticker]
    np.testing.assert_almost_equal(total + leftover, 10000, decimal=4)

    # Cover the verbose parameter,
    allocation_verbose, leftover_verbose = da.lp_portfolio(verbose=True)
    assert allocation_verbose == allocation
    assert leftover_verbose == leftover
def test_lp_portfolio_allocation_short_reinvest():
    df = get_data()
    mu = mean_historical_return(df)
    S = sample_cov(df)
    ef = EfficientFrontier(mu, S, weight_bounds=(-1, 1))
    w = ef.max_sharpe()

    latest_prices = get_latest_prices(df)
    da = DiscreteAllocation(w, latest_prices, short_ratio=0.3)
    allocation, leftover = da.lp_portfolio(reinvest=True)

    assert allocation == {
        "GOOG": 1,
        "AAPL": 5,
        "FB": 10,
        "BABA": 6,
        "WMT": 3,
        "XOM": 6,
        "BBY": 7,
        "MA": 26,
        "PFE": 55,
        "SBUX": 10,
        "JPM": 1,
        "GE": -14,
        "AMD": -48,
        "BAC": -32,
        "GM": -9,
        "T": -5,
        "UAA": -8,
        "SHLD": -132,
        "RRC": -19,
    }
    long_total = 0
    short_total = 0
    for ticker, num in allocation.items():
        if num > 0:
            long_total += num * latest_prices[ticker]
        else:
            short_total -= num * latest_prices[ticker]
    np.testing.assert_almost_equal(long_total + short_total + leftover,
                                   16000,
                                   decimal=5)
Ejemplo n.º 16
0
 def rebal(self):
     prices = pd.DataFrame(
         [self.prices[d._name][:self.day] for d in self.datas]).T
     prices.columns = [d._name for d in self.datas]
     avg_returns = expected_returns.mean_historical_return(prices)
     cov_mat = risk_models.sample_cov(prices)
     # get weights maximizing the Sharpe ratio
     ef = EfficientFrontier(avg_returns, cov_mat)
     self.last_weights = copy.deepcopy(self.weights)
     self.weights = ef.max_sharpe()
     self.weight_chg = pd.Series(self.weights) - pd.Series(
         self.last_weights)
     self.cleaned_weights = ef.clean_weights()
     for i, d in enumerate(self.datas):
         self.rebalance_dict[d] = dict()
         self.rebalance_dict[d]['rebalanced'] = False
         for asset in self.p.assets:
             if asset[0] == d._name:
                 self.rebalance_dict[d]['target_percent'] = self.weights[
                     d._name] * 99  #less than 100%
Ejemplo n.º 17
0
def construct_price_df():
    dates, ticker_to_closing_prices = get_ticker_to_closing_prices(
        TEST_START_DATE, TEST_END_DATE)

    tickers = ticker_to_closing_prices.keys()
    prices = list(
        zip(*[ticker_to_closing_prices[ticker] for ticker in tickers]))
    df = pd.DataFrame(
        prices,
        index=dates,
        columns=tickers,
    )

    mu = mean_historical_return(df)
    S = CovarianceShrinkage(df).ledoit_wolf()

    ef = EfficientFrontier(mu, S)
    weights = ef.max_sharpe()
    cleaned_weights = ef.clean_weights()
    ef.portfolio_performance(verbose=True)
def test_cvar_example_short():
    df = get_data()
    mu = expected_returns.mean_historical_return(df)
    historical_rets = expected_returns.returns_from_prices(df).dropna()
    cv = EfficientCVaR(
        mu,
        historical_rets,
        weight_bounds=(-1, 1),
    )
    w = cv.efficient_return(0.2, market_neutral=True)
    assert isinstance(w, dict)
    assert set(w.keys()) == set(cv.tickers)
    np.testing.assert_almost_equal(cv.weights.sum(), 0)

    np.testing.assert_allclose(
        cv.portfolio_performance(),
        (0.2, 0.013406209257292611),
        rtol=1e-4,
        atol=1e-4,
    )
Ejemplo n.º 19
0
def test_greedy_portfolio_allocation_short():
    df = get_data()
    mu = mean_historical_return(df)
    S = sample_cov(df)
    ef = EfficientFrontier(mu, S, weight_bounds=(-1, 1))
    w = ef.max_sharpe()

    latest_prices = get_latest_prices(df)
    da = DiscreteAllocation(w, latest_prices)
    allocation, leftover = da.greedy_portfolio()

    assert da.allocation == {
        "MA": 15,
        "PFE": 45,
        "FB": 8,
        "BABA": 5,
        "AAPL": 4,
        "BBY": 8,
        "AMZN": 1,
        "SBUX": 9,
        "WMT": 2,
        "XOM": 2,
        "BAC": -32,
        "GM": -16,
        "GE": -43,
        "SHLD": -110,
        "AMD": -34,
        "JPM": -1,
        "T": -1,
        "UAA": -1,
    }
    long_total = 0
    short_total = 0
    for ticker, num in allocation.items():
        if num > 0:
            long_total += num * latest_prices[ticker]
        else:
            short_total -= num * latest_prices[ticker]
    np.testing.assert_almost_equal(long_total + short_total + leftover,
                                   13000,
                                   decimal=4)
def test_cvar_errors():
    df = get_data()
    mu = expected_returns.mean_historical_return(df)
    historical_rets = expected_returns.returns_from_prices(df)

    with pytest.warns(UserWarning):
        EfficientCVaR(mu, historical_rets)

    historical_rets = historical_rets.dropna(axis=0, how="any")
    assert EfficientCVaR(mu, historical_rets)

    cv = setup_efficient_cvar()

    with pytest.raises(NotImplementedError):
        cv.min_volatility()

    with pytest.raises(NotImplementedError):
        cv.max_sharpe()

    with pytest.raises(NotImplementedError):
        cv.max_quadratic_utility()

    with pytest.raises(ValueError):
        # Beta must be between 0 and 1
        cv = EfficientCVaR(mu, historical_rets, 1)

    with pytest.warns(UserWarning):
        cv = EfficientCVaR(mu, historical_rets, 0.1)

    with pytest.raises(OptimizationError):
        # Must be <= max expected return
        cv = EfficientCVaR(mu, historical_rets)
        cv.efficient_return(target_return=np.abs(mu).max() + 0.01)

    with pytest.raises(AttributeError):
        # list not supported.
        EfficientCVaR(mu, historical_rets.to_numpy().tolist())

    historical_rets = historical_rets.iloc[:, :-1]
    with pytest.raises(ValueError):
        EfficientCVaR(mu, historical_rets)
def handle_data(context, data):
    date = data.today()
    if date in context.balance_dates:
        temp = {}
        for code in context.stocks:
            history_price = data.history_bars(code,
                                              context.expected_return_days,
                                              '1d', 'close')
            if history_price is not None:
                temp.update({code: history_price})
        history_prices = pd.DataFrame(temp)
        mu = expected_returns.mean_historical_return(history_prices)
        if context.cov_method == 'sample':
            S = risk_models.sample_cov(history_prices)
        elif context.cov_method == 'semi':
            S = risk_models.semicovariance(history_prices)
        elif context.cov_method == 'exp_cov':
            S = risk_models.exp_cov(history_prices)

        ef = EfficientFrontier(mu, S)

        if context.opt_criterion == 'max_sharpe':
            weights = ef.max_sharpe()
        elif context.opt_criterion == 'efficient_return':
            weights = ef.efficient_return(context.target_return)
        elif context.opt_criterion == 'efficient_risk':
            weights = ef.efficient_risk(context.targe_risk,
                                        context.risk_free_rate)
        elif context.opt_criterion == 'min_volatility':
            weights = ef.min_volatility()

        if context.cleaned_weights is True:
            weights = ef.clean_weights()

        weight = []
        prices = []
        for code in context.stocks:
            weight.append(weights[code])
            prices.append(data.latest_price(code, "1d"))

        data.order_target_percent(context.stocks, weight, prices)
def test_cvar_example_weekly():
    beta = 0.95
    df = get_data()
    df = df.resample("W").first()
    mu = expected_returns.mean_historical_return(df, frequency=52)
    historical_rets = expected_returns.returns_from_prices(df).dropna()
    cv = EfficientCVaR(mu, historical_rets, beta=beta)
    cv.efficient_return(0.2)
    np.testing.assert_allclose(
        cv.portfolio_performance(),
        (0.2, 0.03447723250708958),
        rtol=1e-4,
        atol=1e-4,
    )

    cvar = cv.portfolio_performance()[1]
    portfolio_rets = historical_rets @ cv.weights

    var_hist = portfolio_rets.quantile(1 - beta)
    cvar_hist = -portfolio_rets[portfolio_rets < var_hist].mean()
    np.testing.assert_almost_equal(cvar_hist, cvar, decimal=3)
Ejemplo n.º 23
0
def test_es_example_short():
    df = get_data()
    mu = expected_returns.mean_historical_return(df)
    historical_rets = expected_returns.returns_from_prices(df).dropna()
    es = EfficientSemivariance(
        mu,
        historical_rets,
        weight_bounds=(-1, 1),
    )
    w = es.efficient_return(0.2, market_neutral=True)
    goog_weight = w["GOOG"]

    historical_rets["GOOG"] -= historical_rets["GOOG"].quantile(0.75)
    es = EfficientSemivariance(
        mu,
        historical_rets,
        weight_bounds=(-1, 1),
    )
    w = es.efficient_return(0.2, market_neutral=True)
    goog_weight2 = w["GOOG"]
    assert abs(goog_weight2) >= abs(goog_weight)
 def operate(self) -> tuple:
     """ポートフォリオを最適化する関数"""
     #平均リターンを求める
     #returns.mean() * 252
     mu = expected_returns.mean_historical_return(self.financial_data)
     #リスク(分散)を求める
     #Get the sample covariance matrix
     S = risk_models.sample_cov(self.financial_data)
     #効率的フロンティアの作成
     ef = EfficientFrontier(mu, S)
     weights = ef.min_volatility()
     cleaned_weights = ef.clean_weights()
     weight_keys = ["未選択", "未選択", "未選択", "未選択"]
     weight_values = ["ー", "ー", "ー", "ー"]
     count = 0
     for k, v in dict(cleaned_weights).items():
         weight_keys[count] = k
         weight_values[count] = v
         count += 1
     #最適ポートフォリオの投資比率の出力, リターン・リスク・シャープレシオの出力
     return weight_keys, weight_values, ef.portfolio_performance(
         verbose=False)
Ejemplo n.º 25
0
def handle_bar(context, api):

    date = api.now()

    #if date in context.balance_dates:
    history_prices = {}
    for stock in context.stocks:
        history_price = api.history_bars(stock, context.expected_return_days,
                                         '1d', 'close')
        history_prices.update({stock: history_price})

    history_prices = pd.DataFrame(history_prices)
    mu = expected_returns.mean_historical_return(history_prices)
    if context.cov_method == 'sample':
        S = risk_models.sample_cov(history_prices)
    elif context.cov_method == 'semi':
        S = risk_models.semicovariance(history_prices)
    elif context.cov_method == 'exp_cov':
        S = risk_models.exp_cov(history_prices)

    ef = EfficientFrontier(mu, S)

    if context.opt_criterion == 'max_sharpe':
        weights = ef.max_sharpe()
    elif context.opt_criterion == 'efficient_return':
        weights = ef.efficient_return(context.target_return)
    elif context.opt_criterion == 'efficient_risk':
        weights = ef.efficient_risk(context.targe_risk, context.risk_free_rate)
    elif context.opt_criterion == 'min_volatility':
        weights = ef.min_volatility()

    if context.cleaned_weights is True:
        weights = ef.clean_weights()
    prices = []
    weight = []
    for stock in context.stocks:
        weight.append(weights[stock])
        prices.append(api.latest_price(stock, "1d"))
    api.order_target_percent(stocks, weight, prices)
Ejemplo n.º 26
0
def GetPort(
):  #tickers = ['BSX','AES','BRK-B','SEE','QQQ','SPY'], first = 0, funds = 10000):
    ticks = request.args.get('tickers')
    tickers = list(ticks.split(" "))
    first = request.args.get('first')
    funds = request.args.get('Funds')

    thelen = len(tickers)
    price_data = []
    for ticker in range(thelen):
        prices = web.DataReader(tickers[ticker],
                                start='2015-01-01',
                                end='2020-10-17',
                                data_source='yahoo')
        price_data.append(prices.assign(ticker=ticker)[['Adj Close']])
    df_stocks = pd.concat(price_data, axis=1)
    df_stocks.columns = tickers

    mu = expected_returns.mean_historical_return(df_stocks)
    Sigma = risk_models.sample_cov(df_stocks)
    if int(first) == 1:
        ef = EfficientFrontier(mu, Sigma, weight_bounds=(0, 1))
    else:
        ef = EfficientFrontier(mu, Sigma, weight_bounds=(-1, 1))
    sharpe_pfolio = ef.max_sharpe()
    cleaned_weights = ef.clean_weights()
    latest_prices = get_latest_prices(df_stocks)

    da = DiscreteAllocation(cleaned_weights,
                            latest_prices,
                            total_portfolio_value=int(funds))
    allocation, leftover = da.lp_portfolio()

    new_alloc = {}
    for key in allocation:
        new_alloc[key] = str(allocation[key])

    allocjson = json.dumps(new_alloc)
    return jsonify(allocation=new_alloc, leftover=leftover)
Ejemplo n.º 27
0
def generate_portfolio(starting_investment, stock_price_history):

    # Reset the date as the index
    stock_price_history = stock_price_history.set_index(
        pd.DatetimeIndex(stock_price_history['Date'].values))
    #Remove the Date column
    stock_price_history.drop(columns=['Date'], axis=1, inplace=True)
    stock_price_history.dropna(axis=1, inplace=True)

    # Optimize the portfolio
    from pypfopt.efficient_frontier import EfficientFrontier
    from pypfopt import risk_models
    from pypfopt import expected_returns

    # Calculate the expected annualized returns and the annualized sample covariance matrix of the daily asset returns
    mu = expected_returns.mean_historical_return(stock_price_history)
    S = risk_models.sample_cov(stock_price_history)

    # Optimize for the maximal Sharpe ratio
    ef = EfficientFrontier(mu, S)  # Creates the Efficient Frontier Object
    weights = ef.max_sharpe()

    cleaned_weights = ef.clean_weights()
    #print(cleaned_weights)
    ef.portfolio_performance(verbose=True)

    # Get the descret allocation of each share per stock
    from pypfopt.discrete_allocation import DiscreteAllocation, get_latest_prices

    latest_prices = get_latest_prices(stock_price_history)
    weights = cleaned_weights
    da = DiscreteAllocation(weights,
                            latest_prices,
                            total_portfolio_value=starting_investment)
    allocation, leftover = da.lp_portfolio()
    print("Discrete allocation:", allocation)
    print("Funds Remaining: $", leftover)
    return (allocation, leftover)
Ejemplo n.º 28
0
def calculateInvestment(limit=10,
                        count=10,
                        write_to_file=True,
                        show_cla=False,
                        tpv=20000):
    symbols = getSymbolsFromDatabase()
    prices = createDataFrame(symbols[:limit], count)
    mu = expected_returns.mean_historical_return(prices)
    S = risk_models.CovarianceShrinkage(prices).ledoit_wolf()
    ef = EfficientFrontier(mu, S, weight_bounds=(-1, 1))
    ef.add_objective(objective_functions.L2_reg)
    ef.min_volatility()
    c_weights = ef.clean_weights()
    if write_to_file == True:
        ef.save_weights_to_file("weights.txt")
    if show_cla == True:
        cla = CLA(mu, S)
        ef_plot(cla)
    ef.portfolio_performance(verbose=True)
    latest_prices = disc_alloc.get_latest_prices(prices)
    allocation_minv, leftover = disc_alloc.DiscreteAllocation(
        c_weights, latest_prices, total_portfolio_value=tpv).lp_portfolio()
    return allocation_minv, leftover
Ejemplo n.º 29
0
def min_volatility(stocks_in_portfolio):
     stock_data = web.DataReader(stocks_in_portfolio,data_source='yahoo',start=start_date,end=end_date)['Adj Close']
     stock_data.sort_index(inplace=True)
     
     mu = expected_returns.mean_historical_return(stock_data)
     S = risk_models.sample_cov(stock_data)
     lower_bound=0.30/len(stocks_in_portfolio)

     # Optimise for maximal Sharpe ratio with no contraints
     ef = EfficientFrontier(mu,S,weight_bounds=(lower_bound,1))
     #Need to change the risk free rate 
     raw_weights = ef.min_volatility()
     cleaned_weights = ef.clean_weights()
     cleaned_weights_df=pd.DataFrame.from_dict(cleaned_weights, orient='index')
     #remove weights with 0% 
     cleaned_weights_df=cleaned_weights_df.loc[(cleaned_weights_df!=0).any(1)]
     #print("Portfolio having maximal sharpie ratio and with no contraints\n" )
    # print(cleaned_weights)
     final_return= ef.portfolio_performance(verbose=True)
     index=['Expected Annual Return','Expected Annual Volatility','Sharpe Ratio']
     final_return_df = pd.DataFrame(final_return,index=index)
     final_df=pd.concat([cleaned_weights_df,final_return_df])
     return final_df
Ejemplo n.º 30
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.º 31
0
def test_lp_portfolio_allocation():
    df = get_data()
    mu = mean_historical_return(df)
    S = sample_cov(df)
    ef = EfficientFrontier(mu, S)
    w = ef.max_sharpe()

    latest_prices = get_latest_prices(df)
    da = DiscreteAllocation(w, latest_prices, short_ratio=0.3)
    allocation, leftover = da.lp_portfolio()

    #  Gives differnt answers on different machines
    # assert allocation == {
    #     "AMD": 1,
    #     "GOOG": 1,
    #     "AAPL": 4,
    #     "FB": 12,
    #     "BABA": 4,
    #     "BBY": 1,
    #     "MA": 20,
    #     "PFE": 54,
    #     "SBUX": 1,
    # } or allocation == {
    #     "GOOG": 1,
    #     "AAPL": 4,
    #     "FB": 12,
    #     "BABA": 4,
    #     "BBY": 1,
    #     "MA": 20,
    #     "PFE": 54,
    #     "SBUX": 1,
    # }

    total = 0
    for ticker, num in allocation.items():
        total += num * latest_prices[ticker]
    np.testing.assert_almost_equal(total + leftover, 10000, decimal=4)
Ejemplo n.º 32
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
def test_rmse_decreases_with_value():
    # As total_portfolio_value increases, rmse should decrease.
    df = get_data()
    mu = mean_historical_return(df)
    S = sample_cov(df)
    ef = EfficientFrontier(mu, S)
    w = ef.max_sharpe()
    latest_prices = get_latest_prices(df)

    da1 = DiscreteAllocation(w, latest_prices, total_portfolio_value=10000)
    da1.greedy_portfolio()
    rmse1 = da1._allocation_rmse_error(verbose=False)
    da2 = DiscreteAllocation(w, latest_prices, total_portfolio_value=100000)
    da2.greedy_portfolio()
    rmse2 = da2._allocation_rmse_error(verbose=False)
    assert rmse2 < rmse1

    da3 = DiscreteAllocation(w, latest_prices, total_portfolio_value=10000)
    da3.lp_portfolio()
    rmse3 = da3._allocation_rmse_error(verbose=False)
    da4 = DiscreteAllocation(w, latest_prices, total_portfolio_value=100000)
    da4.lp_portfolio()
    rmse4 = da4._allocation_rmse_error(verbose=False)
    assert rmse4 < rmse3
Ejemplo n.º 34
0
 def asset_allocation(tickers, start_date):
     today = pd.datetime.today()
     if start_date == '1y':
         delta = today - pd.DateOffset(years=1)
         delta = delta.date()
         delta = delta.strftime('%Y-%m-%d')
     elif start_date == '3y':
         delta = today - pd.DateOffset(years=3)
         delta = delta.date()
         delta = delta.strftime('%Y-%m-%d')
     elif start_date == '5y':
         delta = today - pd.DateOffset(years=5)
         delta = delta.date()
         delta = delta.strftime('%Y-%m-%d')
     elif start_date == '10y':
         delta = today - pd.DateOffset(years=10)
         delta = delta.date()
         delta = delta.strftime('%Y-%m-%d')
     elif start_date == 'max':
         delta = today - pd.DateOffset(years=30)
         delta = delta.date()
         delta = delta.strftime('%Y-%m-%d')
     prices = ffn.get(tickers, start=delta)
     mu = expected_returns.mean_historical_return(prices)
     S = risk_models.sample_cov(prices)
     ef = EfficientFrontier(mu, S)
     raw_weights = ef.max_sharpe()
     cleaned_weights = ef.clean_weights()
     latest_prices = discrete_allocation.get_latest_prices(prices)
     da = DiscreteAllocation(cleaned_weights,
                             latest_prices,
                             total_portfolio_value=amount)
     allocation, leftover = da.lp_portfolio()
     st.subheader('Asset Allocation breakdown: ')
     st.write(allocation)
     st.write("Funds remaining: ${:.2f}".format(leftover))
Ejemplo n.º 35
0
    def __get_ef_allocation(self, portfolio_size, portfolio_value):
        """Method that returns optimal allocation based on Markowitz Portfolio theory."""
        df_hist = query_quotes_history()
        df = self.__get_momentum(df_hist)
        date = df.date.max()
        df_top = df.loc[df['date'] == date]
        df_top = df_top.sort_values(by='momentum',
                                    ascending=False).head(portfolio_size)

        universe = df_top['tickr'].tolist()
        df_u = df.loc[df['tickr'].isin(universe)]

        df_u = df_u.pivot_table(index='date',
                                columns='tickr',
                                values='close',
                                aggfunc='sum')

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

        # Optimise the portfolio for maximal Sharpe ratio
        # with regularization
        ef = EfficientFrontier(mu, S, gamma=1)
        ef.max_sharpe()
        cleaned_weights = ef.clean_weights()

        latest_prices = get_latest_prices(df_u)

        # Generate allocation
        da = DiscreteAllocation(cleaned_weights,
                                latest_prices,
                                total_portfolio_value=portfolio_value)

        allocations = pd.Series(da.lp_portfolio()[0], name='allocation')
        return allocations
Ejemplo n.º 36
0
def test_cdar_example_weekly():
    beta = 0.90
    df = get_data()
    df = df.resample("W").first()
    mu = expected_returns.mean_historical_return(df, frequency=52)
    historical_rets = expected_returns.returns_from_prices(df).dropna()
    cd = EfficientCDaR(mu, historical_rets, beta=beta)
    cd.efficient_return(0.21)
    np.testing.assert_allclose(
        cd.portfolio_performance(),
        (0.21, 0.045085),
        rtol=1e-4,
        atol=1e-4,
    )

    cdar = cd.portfolio_performance()[1]
    portfolio_rets = historical_rets @ cd.weights

    cum_rets = portfolio_rets.cumsum(0)
    drawdown = cum_rets.cummax() - cum_rets

    dar_hist = drawdown.quantile(beta)
    cdar_hist = drawdown[drawdown > dar_hist].mean()
    np.testing.assert_almost_equal(cdar_hist, cdar, decimal=3)
def test_portfolio_allocation():
    df = get_data()
    e_ret = mean_historical_return(df)
    cov = sample_cov(df)
    ef = EfficientFrontier(e_ret, cov)
    w = ef.max_sharpe()

    latest_prices = discrete_allocation.get_latest_prices(df)
    allocation, leftover = discrete_allocation.portfolio(w, latest_prices)
    assert allocation == {
        "MA": 14,
        "FB": 12,
        "PFE": 51,
        "BABA": 5,
        "AAPL": 5,
        "AMZN": 0,
        "BBY": 9,
        "SBUX": 6,
        "GOOG": 1,
    }
    total = 0
    for ticker, num in allocation.items():
        total += num * latest_prices[ticker]
    np.testing.assert_almost_equal(total + leftover, 10000)
def test_mean_historical_returns_frequency():
    df = get_data()
    mean = expected_returns.mean_historical_return(df)
    mean2 = expected_returns.mean_historical_return(df, frequency=52)
    np.testing.assert_array_almost_equal(mean / 252, mean2 / 52)
def test_ema_historical_return_limit():
    df = get_data()
    sma = expected_returns.mean_historical_return(df)
    ema = expected_returns.ema_historical_return(df, span=1e10)
    np.testing.assert_array_almost_equal(ema.values, sma.values)
Ejemplo n.º 40
0
import pandas as pd
import numpy as np
from pypfopt.efficient_frontier import EfficientFrontier
from pypfopt import risk_models
from pypfopt import expected_returns
from pypfopt.hierarchical_risk_parity import hrp_portfolio
from pypfopt.value_at_risk import CVAROpt
from pypfopt import discrete_allocation


# Reading in the data; preparing expected returns and a risk model
df = pd.read_csv("tests/stock_prices.csv", parse_dates=True, index_col="date")
returns = df.pct_change().dropna(how="all")
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 = discrete_allocation.get_latest_prices(df)
allocation, leftover = discrete_allocation.portfolio(weights, latest_prices)
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: {'MA': 14, 'FB': 12, 'PFE': 51, 'BABA': 5, 'AAPL': 5,