def main(): returns, cov_mat, avg_rets = pfopt.create_test_data() section("Example returns") print(returns.head(10)) print("...") section("Average returns") print(avg_rets) section("Covariance matrix") print(cov_mat) section("Minimum variance portfolio (long only)") weights = pfopt.min_var_portfolio(cov_mat) print_portfolio_info(returns, avg_rets, weights) section("Minimum variance portfolio (long/short)") weights = pfopt.min_var_portfolio(cov_mat, allow_short=True) print_portfolio_info(returns, avg_rets, weights) # Define some target return, here the 70% quantile of the average returns target_ret = avg_rets.quantile(0.7) section("Markowitz portfolio (long only, target return: {:.5f})".format( target_ret)) weights = pfopt.markowitz_portfolio(cov_mat, avg_rets, target_ret) print_portfolio_info(returns, avg_rets, weights) section("Markowitz portfolio (long/short, target return: {:.5f})".format( target_ret)) weights = pfopt.markowitz_portfolio(cov_mat, avg_rets, target_ret, allow_short=True) print_portfolio_info(returns, avg_rets, weights) section( "Markowitz portfolio (market neutral, target return: {:.5f})".format( target_ret)) weights = pfopt.markowitz_portfolio(cov_mat, avg_rets, target_ret, allow_short=True, market_neutral=True) print_portfolio_info(returns, avg_rets, weights) section("Tangency portfolio (long only)") weights = pfopt.tangency_portfolio(cov_mat, avg_rets) weights = pfopt.truncate_weights(weights) # Truncate some tiny weights print_portfolio_info(returns, avg_rets, weights) section("Tangency portfolio (long/short)") weights = pfopt.tangency_portfolio(cov_mat, avg_rets, allow_short=True) print_portfolio_info(returns, avg_rets, weights)
def main(): # returns, cov_mat, avg_rets = pfopt.create_test_data(num_days=1000) returns, cov_mat, avg_rets = load_data() # yy = returns['asset_a'] # xx = [ii for ii in range(len(yy))] # plt.plot(xx, yy) # plt.hlines(avg_rets[0], xmin=0, xmax=100, colors='black') # plt.show() # return 0 section("Example returns") print(returns.head(5)) print("...") section("Average returns") print(avg_rets) section("Covariance matrix") print(cov_mat) section("Minimum variance portfolio (long only)") weights = pfopt.min_var_portfolio(cov_mat) print_portfolio_info(returns, avg_rets, weights) section("Minimum variance portfolio (long/short)") weights = pfopt.min_var_portfolio(cov_mat, allow_short=True) print_portfolio_info(returns, avg_rets, weights) # Define some target return, here the 70% quantile of the average returns target_ret = avg_rets.quantile(0.7) section("Markowitz portfolio (long only, target return: {:.5f})".format(target_ret)) weights = pfopt.markowitz_portfolio(cov_mat, avg_rets, target_ret) print_portfolio_info(returns, avg_rets, weights) section("Markowitz portfolio (long/short, target return: {:.5f})".format(target_ret)) weights = pfopt.markowitz_portfolio(cov_mat, avg_rets, target_ret, allow_short=True) print_portfolio_info(returns, avg_rets, weights) section("Markowitz portfolio (market neutral, target return: {:.5f})".format(target_ret)) weights = pfopt.markowitz_portfolio(cov_mat, avg_rets, target_ret, allow_short=True, market_neutral=True) print_portfolio_info(returns, avg_rets, weights) section("Tangency portfolio (long only)") weights = pfopt.tangency_portfolio(cov_mat, avg_rets) weights = pfopt.truncate_weights(weights) # Truncate some tiny weights print_portfolio_info(returns, avg_rets, weights) section("Tangency portfolio (long/short)") weights = pfopt.tangency_portfolio(cov_mat, avg_rets, allow_short=True) print_portfolio_info(returns, avg_rets, weights)
def markowitz_portfolios(self): pf = self.panelframe returns = (pf['Close'] - pf['Close'].shift(1)) / pf['Close'].shift(1) returns.fillna(0, inplace=True) market = returns['market'] returns = returns.iloc[:, :-1] cov_mat = np.cov(returns, rowvar=False, ddof=1) cov_mat = pd.DataFrame(cov_mat, columns=returns.keys(), index=returns.keys()) avg_rets = returns.mean(0).astype(np.float64) mrk = [] weights = pfopt.min_var_portfolio(cov_mat) case = self._one_pfopt_case(cov_mat, returns, market, weights, 'Minimum variance portfolio') mrk.append(case) for t in [0.50, 0.75, 0.90]: target = avg_rets.quantile(t) weights = pfopt.markowitz_portfolio(cov_mat, avg_rets, target) case = self._one_pfopt_case( cov_mat, returns, market, weights, 'Target: more than {:.0f}% of stock returns'.format(t * 100)) mrk.append(case) weights = pfopt.tangency_portfolio(cov_mat, avg_rets) case = self._one_pfopt_case(cov_mat, returns, market, weights, 'Tangency portfolio') mrk.append(case) return mrk
def main(): raw_tickers = input('Enter stocks separated by a comma: ') investment = int(input("Enter total investment to allocate: ")) stock_tickers = raw_tickers.split(", ") print(stock_tickers) listed_prices, returns, cov_mat, avg_rets = gd.get_stock_data( stock_tickers) section("Example returns") print(returns.head(10)) print("...") section("Average returns") print(avg_rets) section("Covariance matrix") print(cov_mat) section("Minimum variance portfolio (long only)") weights = pfopt.min_var_portfolio(cov_mat) print_portfolio_info(returns, avg_rets, weights) allocation = investment * weights print(allocation) # Define some target return, here the 70% quantile of the average returns target_ret = avg_rets.quantile(0.7) section("Markowitz portfolio (long only, target return: {:.5f})".format( target_ret)) weights = pfopt.markowitz_portfolio(cov_mat, avg_rets, target_ret) print_portfolio_info(returns, avg_rets, weights) allocation = investment * weights print(allocation)
def test_long_only(self): returns, cov_mat, avg_rets = create_test_data() calc_weights = pfopt.min_var_portfolio(cov_mat).values exp_weights = [0.29428271128647232, 0.19221596707310873, 0.13820590476491501, 0.20879394627003695, 0.16650147060546697] self.assertTrue(np.allclose(calc_weights, exp_weights))
def test_allow_short(self): returns, cov_mat, avg_rets = create_test_data() calc_weights = pfopt.min_var_portfolio(cov_mat, allow_short=True).values exp_weights = [0.29428401463312454, 0.19221716939564482, 0.13820233202108606, 0.20879490895467365, 0.16650157499547097] self.assertTrue(np.allclose(calc_weights, exp_weights))
def main(): returns, cov_mat, avg_rets = pfopt.create_test_data() section("Example returns") print(returns.head(10)) print("...") section("Average returns") print(avg_rets) section("Covariance matrix") print(cov_mat) section("Minimum variance portfolio (long only)") weights = pfopt.min_var_portfolio(cov_mat) print_portfolio_info(returns, avg_rets, weights) section("Minimum variance portfolio (long/short)") weights = pfopt.min_var_portfolio(cov_mat, allow_short=True) print_portfolio_info(returns, avg_rets, weights) # Define some target return, here the 70% quantile of the average returns target_ret = avg_rets.quantile(0.7) section("Markowitz portfolio (long only, target return: {:.5f})".format(target_ret)) weights = pfopt.markowitz_portfolio(cov_mat, avg_rets, target_ret) print_portfolio_info(returns, avg_rets, weights) section("Markowitz portfolio (long/short, target return: {:.5f})".format(target_ret)) weights = pfopt.markowitz_portfolio(cov_mat, avg_rets, target_ret, allow_short=True) print_portfolio_info(returns, avg_rets, weights) section("Markowitz portfolio (market neutral, target return: {:.5f})".format(target_ret)) weights = pfopt.markowitz_portfolio(cov_mat, avg_rets, target_ret, allow_short=True, market_neutral=True) print_portfolio_info(returns, avg_rets, weights) section("Tangency portfolio (long only)") weights = pfopt.tangency_portfolio(cov_mat, avg_rets) weights = pfopt.truncate_weights(weights) # Truncate some tiny weights print_portfolio_info(returns, avg_rets, weights) section("Tangency portfolio (long/short)") weights = pfopt.tangency_portfolio(cov_mat, avg_rets, allow_short=True) print_portfolio_info(returns, avg_rets, weights)
def trade(self, reward_offset, log=None): """ Steps through time and trades available stocks in a minimum variance portfolio. Arguments: reward_offset -- the periods after which to calculate the reward (e.g. if we act at time t then we calculate realised asset returns between t and t + reward_offset) log -- a list if log messages should be added or None if not needed """ if self.__random: self.learn(255, reward_offset) actions_taken = dict() i = 0 current_date = self.__environment.advance() while current_date: state = self.__environment.sense() actions = pd.Series(self.__learner.get_actions()) if self.__random: actions = actions.apply( lambda x: random.choice(self.__actions)) actions_taken[current_date] = pd.Series(actions) if i <= reward_offset or i % reward_offset != 0: current_date = self.__environment.advance() i += 1 continue buy_actions = actions.loc[actions == 'BUY'].index if len(buy_actions) == 0: self.__portfolio.rebalance(current_date, pd.Series({'CASH': 1.0})) else: current_returns = self.__returns.ix[:current_date][buy_actions] min_var_portfolio = pfopt.min_var_portfolio( current_returns.cov()) self.__portfolio.rebalance(current_date, min_var_portfolio) date_to = self.__returns.index[255 + i - 1] date_from = self.__returns.index[255 + i - 1 - reward_offset] self.__reward(date_from, date_to, actions_taken[date_from], log=log) current_date = self.__environment.advance() i += 1
def markowitz_portfolios(self): """ Estimate Markowitz portfolios Inputs: daily returns by stock, avg returns by stock, cov_matrix """ # pf = self._daily # returns = (pf['close'] - pf['close'].shift(1))/pf['close'].shift(1) # returns.fillna(0, inplace=True) # market = returns['market'] # returns = returns.iloc[:, :-1] # cov_mat = np.cov(returns, rowvar=False, ddof=1) # cov_mat = pd.DataFrame( # cov_mat, # columns=returns.keys(), # index=returns.keys()) # avg_rets = returns.mean(0).astype(np.float64) # prepare inputs returns = self.stocks_daily market = returns['SPY'] returns.drop('SPY', axis=1, inplace=True) avg_rets = returns.mean(0).astype(np.float64) cov_mat = self.stocks_covar cov_mat.drop('SPY', axis=0, inplace=True) cov_mat.drop('SPY', axis=1, inplace=True) mrk = [] weights = pfopt.min_var_portfolio(cov_mat) case = self._one_pfopt_case(returns, market, weights, 'Minimum variance portfolio') mrk.append(case) for t in [0.50, 0.75, 0.90]: target = avg_rets.quantile(t) weights = pfopt.markowitz_portfolio(cov_mat, avg_rets, target) case = self._one_pfopt_case( returns, market, weights, 'Target: more than {:.0f}% of stock returns'.format(t * 100)) mrk.append(case) weights = pfopt.tangency_portfolio(cov_mat, avg_rets) case = self._one_pfopt_case(returns, market, weights, 'Tangency portfolio') mrk.append(case) return mrk
def min_variance(df_daily_returns): #***************** Minimum variance portfolio *********************** cov_mat = df_daily_returns.cov() avg_rets = df_daily_returns.mean() weights = pfopt.min_var_portfolio(cov_mat) weights = pfopt.truncate_weights(weights) # Truncate some tiny weights weights = weights[weights != 0] weights = weights.round(decimals=4) ret = (weights * avg_rets).sum() ret = ret.round(decimals=4) std = (weights * df_daily_returns).sum(1).std() std = std.round(decimals=4) return weights, ret, std
print('-' * len(caption)) def print_portfolio_info(returns, avg_rets, weights): """ Print information on expected portfolio performance. """ ret = (weights * avg_rets).sum() std = (weights * returns).sum(1).std() sharpe = ret / std print("Optimal weights:\n{}\n".format(weights)) print("Expected return: {}".format(ret)) print("Expected variance: {}".format(std**2)) print("Expected Sharpe: {}".format(sharpe)) # Define some target return, here the 70% quantile of the average returns target_ret = avg_rets.quantile(0.9) weights = pfopt.min_var_portfolio(cov_mat) print_portfolio_info(returns, avg_rets, weights) section("Markowitz portfolio (long only, target return: {:.5f})".format( target_ret)) weights = pfopt.markowitz_portfolio(cov_mat, avg_rets, target_ret) print_portfolio_info(returns, avg_rets, weights) section("Tangency portfolio (long only)") weights = pfopt.tangency_portfolio(cov_mat, avg_rets) weights = pfopt.truncate_weights(weights) # Truncate some tiny weights print_portfolio_info(returns, avg_rets, weights)
def optimize(self, data, portfolio_version_id): # data = request.get_json() strDateFrom = data['dateFrom'] strDateTo = data['dateTo'] # access to database in MySql assets = db.session.query(PortfolioAsset).filter_by( version_id=portfolio_version_id).join(Asset).all() # check if user exists if len(assets) == 0: return {} stocks = [] for asset in assets: stocks.append(asset.asset.ticker) # request data from datareader and store them in prices (pandas data form) req = {'tickers': stocks, 'start': strDateFrom, 'end': strDateTo} prices = DataReader().read_data_pd_format(req) # convert daily stock prices into daily returns returns = prices.pct_change(-1) # drop infs and nans returns = returns.replace([np.inf, -np.inf], np.nan) returns = returns.dropna() # estimate mean return and covariance matrix ExpRet = returns.mean() CovRet = returns.cov() # compute portfolios with min var and max return minvar_port = popt.min_var_portfolio(CovRet) minret = max(np.dot(minvar_port, ExpRet), 0) maxret = max(ExpRet) # calculate range of attainable returns for optimal portfolios mus = np.linspace(start=minret, stop=maxret, num=100) # calculate efficient frontier portfolios = [ popt.markowitz_portfolio(CovRet, ExpRet, mu) for mu in mus ] dts, portfolio_indexes = self.get_value_indexes(prices, portfolios) # expected returns exRet = [np.dot(portfolio, ExpRet) * 252 for portfolio in portfolios] # expected volatility exVol = [ np.sqrt(np.dot(np.dot(portfolio, CovRet), portfolio) * 252) for portfolio in portfolios ] return { 'assets': stocks, 'portfolios': pd.Series(portfolios).to_json(orient='values'), 'annualizedExpectedReturns': exRet, 'annualizedExpectedVolatility': exVol, 'dates': dts.tolist(), 'portfolio_indexes': np.array(portfolio_indexes).tolist() }
print(exp_rets) print(cov_mat) #计算: #计算目标收益的权重 (markowitz_portfolio方法) portfolio_1 = opt.markowitz_portfolio(cov_mat, exp_rets, 0.2, allow_short=False, market_neutral=False) #需输入协方差矩阵cov_mat,年预期收益exp_rets,0.2代表想要的年收益,allow_short表示是否允许做空,market_neutral表示是否具有市场中性 print(portfolio_1) #得到的结果表示若要实现0.2的年收益,则分别需买入这些股票的比重分别为 #计算最小方差的权重 (opt.min_var_portfolio) portfolio_mv = opt.min_var_portfolio(cov_mat, allow_short=False) print(portfolio_mv) #计算最优组合的权重 (opt.tangency_portfolio) (夏普比率最高的比重) portfolio_tp = opt.tangency_portfolio( cov_mat, exp_rets, allow_short=False) #需输入协方差矩阵cov_mat,年预期收益exp_rets print(portfolio_tp) #去除少于0.01权重的股票,低于0.01权重的不建议购买 weigth_t = opt.truncate_weights(portfolio_tp, min_weight=0.01, rescale=True) print(weigth_t) #计算组合风险 import numpy as np Portfolio_v = np.dot(weigth_t.T, np.dot(cov_mat,