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)
def test_weight_plot_multi(): ef = setup_efficient_frontier() w1 = ef.min_volatility() ef = setup_efficient_frontier() w2 = ef.max_sharpe() fig, (ax1, ax2) = plt.subplots(2) plotting.plot_weights(w1, ax1, showfig=False) plotting.plot_weights(w2, ax2, showfig=False) assert len(fig.axes) == 2 assert len(fig.axes[0].findobj()) == 209 assert len(fig.axes[1].findobj()) == 209 plt.close()
def omptimizePortCLA(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) #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) if how == 'Sharpe': # Maximized on Sharpe Ratio cla = CLA( mu, S ) #Here the weight bounds are being used to allow short positions as well weights = cla.max_sharpe() cleaned_weights = dict(cla.clean_weights()) print("Weights of an optimal portfolio maximised on Sharpe Ratio:") print(cleaned_weights) cla.portfolio_performance(verbose=True) bpf.getDiscreteAllocations(df, weights) plot_ef(cla) plotting.plot_weights(weights) elif how == "Vol": # Minimized on Volatility cla = CLA(mu, S) cla.min_volatility() w = dict(cla.clean_weights()) print("Weights of an optimal portfolio minimized on Volatilty (Risk):") print(w) cla.portfolio_performance(verbose=True) bpf.getDiscreteAllocations(df, w) plot_ef(cla) plotting.plot_weights(w)
def test_weight_plot(): df = get_data() returns = df.pct_change().dropna(how="all") hrp = HRPOpt(returns) w = hrp.optimize() ax = plotting.plot_weights(w, showfig=False) assert len(ax.findobj()) == 197
def test_weight_plot_add_attribute(): plt.figure() ef = setup_efficient_frontier() w = ef.min_volatility() ax = plotting.plot_weights(w) ax.set_title("Test") assert len(ax.findobj()) == 209 plt.close()
def plot_stock_insights(self, scatter=False): ef = EfficientFrontier(self.mu, self.S) weights = ef.max_sharpe() cleaned_weights = ef.clean_weights() cla = CLA(self.mu, self.S) try: eff_front = plotting.plot_efficient_frontier(cla) eff_front.tick_params(axis='both', which='major', labelsize=5) eff_front.tick_params(axis='both', which='minor', labelsize=5) eff_front.get_figure().savefig(os.path.join( self.output_path, "efficient_frontier.png"), dpi=300) except: print("Failed to plot efficient frontier") cov = plotting.plot_covariance(self.S) weights_bar = plotting.plot_weights(cleaned_weights) if self.save_output: cov.tick_params(axis='both', which='major', labelsize=5) cov.tick_params(axis='both', which='minor', labelsize=5) cov.get_figure().savefig(os.path.join(self.output_path, "cov_matrix.png"), dpi=300) weights_bar.tick_params(axis='both', which='major', labelsize=5) weights_bar.tick_params(axis='both', which='minor', labelsize=5) weights_bar.get_figure().savefig(os.path.join( self.output_path, "weights_bar.png"), dpi=300) retscomp = self.stock_prices.pct_change() corrMatrix = retscomp.corr() corr_heat = sns.heatmap(corrMatrix, xticklabels=True, yticklabels=True) plt.title("Corr heatmap") if self.save_output: corr_heat.tick_params(axis='both', which='major', labelsize=5) corr_heat.tick_params(axis='both', which='minor', labelsize=5) fig = corr_heat.get_figure() fig.figsize = (10, 10) fig.savefig(os.path.join(self.output_path, "corr_heatmap.png"), dpi=300) plt.show() if scatter: plt.figure() plt.title("Corr scatter") self.scattermat = pd.plotting.scatter_matrix(retscomp, diagonal='kde', figsize=(10, 10)) if self.save_output: plt.savefig(os.path.join(self.output_path, "corr_scatter.png"), dpi=300) plt.show()
def optimizePortEfficient(port, weights, start, plot = False, short = False, printBasicStats=True, how = 'Sharpe'): #Getting Data df = bpf.getData(port, start) #Plotting the portfolio if plot: bpf.plotPort(df, port) if printBasicStats: bpf.basicStats(df, weights, start) #Optimization for Sharpe using Efficient Frontier if short: bounds = (-1,1) else: bounds = (0,1) mu = df.pct_change().mean() * 252 S = risk_models.sample_cov(df) #Method and constraints for optimization if how == 'Sharpe': # Maximized on Sharpe Ratio ef = EfficientFrontier(mu, S, weight_bounds=bounds) #Here the weight bounds are being used to allow short positions as well weights = ef.max_sharpe() cleaned_weights = dict(ef.clean_weights()) print("Weights of an optimal portfolio maximised on Sharpe Ratio:") print(cleaned_weights) ef.portfolio_performance(verbose = True) bpf.getDiscreteAllocations(df, weights) plotting.plot_weights(weights) return weights elif how == "Vol": # Minimized on Volatility efi = EfficientFrontier(mu, S, weight_bounds=bounds) w = dict(efi.min_volatility()) print("Weights of an optimal portfolio minimized on Volatilty (Risk):") print(w) efi.portfolio_performance(verbose = True) bpf.getDiscreteAllocations(df, w) plotting.plot_weights(w) return w elif how == "targetRisk": #Optimized for a given target risk efi = EfficientFrontier(mu, S, weight_bounds=bounds) efi.efficient_risk(0.25) w = dict(efi.clean_weights()) if w ==None: print("No portfolio possible at the given risk level") else: print("Weights of an optimal portfolio for given risk:") print(w) efi.portfolio_performance(verbose = True) bpf.getDiscreteAllocations(df, w) plotting.plot_weights(w) return w
def call_portfolios(trading_days, start_time, end_time, test_start_time = "", test_end_time = "", add_index=False): total_portfolio = [] portfolio_weights = [] portfolio_invests = [] performances = [] # Getting the S&P500 (benchmark) sp500 = pdr.DataReader('^GSPC', 'yahoo', start_time, end_time)['Close'] sp500 = sp500.rename('SP500') sp500 = sp500.to_frame() for i in range(0, len(stock_list.columns)): #for i in range(0, 1): stock = [] stock = stock_list.iloc[:,i].tolist() ### !!! Important: change the number to get the portfolio of interest (first one is 50% percentile, etc.) stock = [x for x in stock if str(x) != 'nan'] portfolio_name = stock_list.columns[i] # Getting stock data (maybe re-do to for loop, if there be problems with memory) temp = pdr.DataReader(stock, 'yahoo', start_time, end_time)['Close'] data = sp500.join(temp) del temp # Main dataset with all tickers and without S&P stocks = data.drop('SP500', 1) # Drop stocks where are less than 50% of data points available, if applicable if filter_recent_stocks[i]: stocks = stocks.loc[:, (stocks.count() >= stocks.count().max()/2)] risk_free_rate = 0.0085 # !!! Risk-free rate, 10Y US treasury bond, could be adjusted weight_bounds = weight_bounds_tuple[i] # taken from the tuple each iteration, defined at the beginning # !!! Different approaches could be taken from here mu = mean_historical_return(stocks) # Getting returns S = CovarianceShrinkage(stocks).ledoit_wolf() # Getting cov matrix current_weights = [0] * len(stocks.columns) # Main function to find optimal portfolio, determining optimal weights ef = EfficientFrontier(mu, S, weight_bounds=weight_bounds) ef.add_objective(objective_functions.transaction_cost, w_prev=current_weights, k=0.005) ef.add_objective(objective_functions.L2_reg, gamma=gamma) weights = ef.max_sharpe(risk_free_rate=risk_free_rate) # using max sharpe optimization cleaned_weights = ef.clean_weights() # weights with pretty formatting print(cleaned_weights) # Printing info on returns, variance & sharpe temp_tuple = ef.portfolio_performance(verbose=True) temp_dict = {} temp_dict['Portfolio'] = portfolio_name temp_dict['Return'] = "{:.4f}".format(temp_tuple[0]) temp_dict['Risk'] = "{:.4f}".format(temp_tuple[1]) temp_dict['Sharpe'] = "{:.4f}".format(temp_tuple[2]) performances.append(temp_dict) # Putting weights into pandas df max_sharpe_allocation = pd.DataFrame.from_dict(cleaned_weights, orient='index') max_sharpe_allocation.columns =['allocation_weight'] ### This function would change the weights to a number of shares based on the last price in the observable interval latest_prices = get_latest_prices(stocks) if add_index == False: da = DiscreteAllocation(weights, latest_prices, total_portfolio_value=total_portfolio_value) if discrete_algo_lp[i] == True: allocation, leftover = da.lp_portfolio() else: allocation, leftover = da.greedy_portfolio() print(allocation) print("Money left: " + str(leftover)) print(da._allocation_rmse_error()) # Adding discrete allocation to portfolio dataframe allocation = pd.DataFrame.from_dict(allocation, orient='index') allocation.columns =['allocation_discrete'] max_sharpe_allocation = max_sharpe_allocation.join(allocation) # Add some plots plot_covariance(S) plot_weights(weights) start_of_investment = str(latest_prices.name) if add_index == True: if np.any(start_of_investment in trading_days.values) == True: start_of_investment = trading_days[trading_days.index[trading_days == start_of_investment].tolist()[0] + 1] ### Function to crete a portfolio and test it on the new data portfolio, data_new = load_data(max_sharpe_allocation, test_start_time, test_end_time) tmp = create_index(test_start_time, test_end_time, start_of_investment, portfolio_name, portfolio, data_new) # Add all results to list total_portfolio.append(tmp[0]) portfolio_weights.append(tmp[1]) with open(p+'/portfolios/performance_index.txt', 'w') as outFile: for d in performances: line = str(i) + ": " + " ".join([str(key)+' : '+str(value) for key,value in d.items()]) + '\n' outFile.write(line) else: if np.any(start_of_investment in trading_days.values) == False: start_of_investment = trading_days[trading_days.index[trading_days == start_of_investment].tolist()[0] + 1] portfolio, data_new = load_data(max_sharpe_allocation, test_end_time, test_end_time) tmp2 = create_portfolio(start_of_investment, portfolio_name, portfolio, data_new) # Add all results to list portfolio_invests.append(tmp2) with open(p+'/portfolios/performance_investment.txt', 'w') as outFile: for d in performances: line = str(i) + ": " + " ".join([str(key)+' : '+str(value) for key,value in d.items()]) + '\n' outFile.write(line) return total_portfolio, portfolio_weights, portfolio_invests
# df = pd.read_csv("tests/resources/stock_prices.csv", parse_dates=True, index_col="date") df = pd.read_csv(os.path.join(path, 'stock_prices.csv'), parse_dates=True, index_col="Date") returns = df.pct_change().dropna() # 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("weights.csv") # saves to file print(cleaned_weights) ef.portfolio_performance(verbose=True) latest_prices = get_latest_prices(df) da = DiscreteAllocation(cleaned_weights, latest_prices, total_portfolio_value=600) allocation, leftover = da.lp_portfolio() print("Discrete allocation:", allocation) print("Funds remaining: ${:.2f}".format(leftover)) cla = CLA(mu, S) plotting.plot_efficient_frontier(cla) plotting.plot_covariance(S) plotting.plot_weights(cleaned_weights)