def assign_strategy(filtered_stocks: pd.DataFrame, algo: str, n_stocks: int) -> tuple: filtered_stocks = filtered_stocks.sample(n=n_stocks, axis=1) returns = returns_from_prices(filtered_stocks, log_returns=False) mu = mean_historical_return(filtered_stocks) assert len(mu) == n_stocks s = CovarianceShrinkage(filtered_stocks).ledoit_wolf() if algo == "hrp": return (hrp_strategy, "Hierarchical Risk Parity", { 'returns': returns }, mu, s) elif algo == "ef-sharpe": return (ef_sharpe_strategy, "Efficient Frontier - max. sharpe", { 'returns': mu, 'cov_matrix': s }, mu, s) elif algo == "ef-risk": return (ef_risk_strategy, "Efficient Frontier - efficient risk", { 'returns': mu, 'cov_matrix': s, 'target_volatility': 5.0 }, mu, s) elif algo == "ef-minvol": return (ef_minvol_strategy, "Efficient Frontier - minimum volatility", { 'returns': mu, 'cov_matrix': s }, mu, s) else: assert False
def get_mean_variance_share_allocation(): dates, ticker_to_closing_prices = get_ticker_to_closing_prices( START_DATE, TEST_START_DATE - timedelta(days=1)) 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() _, ticker_to_closing_prices_at_test_start = get_ticker_to_closing_prices( TEST_START_DATE, TEST_END_DATE) prices_at_test_start = pd.Series([ float(ticker_to_closing_prices_at_test_start[ticker][0]) for ticker in tickers ], index=tickers) da = DiscreteAllocation(weights, prices_at_test_start, total_portfolio_value=INITIAL_PORTFOLIO_VAL) allocation, leftover = da.lp_portfolio() for ticker in tickers: if ticker not in allocation: allocation[ticker] = 0 return allocation
def run_allocation(date, duration): df = pd.DataFrame(columns=symbols) for symbol in symbols: try: data = get_all_binance(symbol, date, duration, save=False) df[symbol] = data["close"] except BinanceAPIException: print("Symbol was : " + symbol) df = df.apply(pd.to_numeric) df.fillna(0) print(df) mu = mean_historical_return(df) S = CovarianceShrinkage(df).ledoit_wolf() ef = EfficientFrontier(mu, S) weights = ef.max_sharpe() #aws, graphql, table'a ekle cleaned_weights = ef.clean_weights() print(ef.portfolio_performance(verbose=True)) lists = sorted(weights.items()) # sorted by key, return a list of tuples lists = {x: y for x, y in lists if y > 0} f = open("Coin" + duration + ".txt", "w") f.write(str(lists)) f.close() print(weights) s3 = boto3.client('s3') with open("Coin" + duration + ".txt", "rb") as f: s3.upload_fileobj(f, "model-predictions", "Coin" + duration + ".txt")
def run_iteration( ld: LazyDictionary, strategy, first_prices, latest_prices, filtered_stocks, **kwargs, ): assert ld is not None strategy(ld, **kwargs) ld["optimizer_performance"] = lambda ld: portfolio_performance(ld) ld["allocator"] = lambda ld: DiscreteAllocation( ld["raw_weights"], first_prices, total_portfolio_value=ld["total_portfolio_value"], ) ld["portfolio"] = lambda ld: ld["allocator"].greedy_portfolio( ) # greedy_portfolio returns (dict, float) tuple ld["cleaned_weights"] = lambda ld: clean_weights(ld["raw_weights"], ld[ "portfolio"][0], first_prices, latest_prices) ld["latest_prices"] = latest_prices ld["len_latest_prices"] = lambda ld: len(ld["latest_prices"]) # only plot covmatrix/corr for significant holdings to ensure readability ld["m"] = lambda ld: CovarianceShrinkage(filtered_stocks[list(ld[ "cleaned_weights"].keys())[:30]]).ledoit_wolf()
def calculate(self, date, universe): prices = universe.pricing['price'].unstack()[self.assets].iloc[-self.window:] mu = mean_historical_return(prices) S = CovarianceShrinkage(prices).ledoit_wolf() ef = EfficientFrontier(mu, S) weights = ef.min_volatility() weights = pd.Series(weights, index=self.assets) return weights
def __init__(self, prices, risk_free=0.00): self.prices = prices self.assets = prices.columns self.num_of_assets = len(prices.columns) self.e_returns = expected_returns.mean_historical_return(prices) self.returns = prices.pct_change().dropna() self.cum_returns = ((1 + self.returns).cumprod() - 1) self.correlation = self.returns.corr('pearson') self.covariance = CovarianceShrinkage(prices).ledoit_wolf() self.rf = risk_free
def wf(self, train, optimizer, test, test_months, annual_risk_free_rate=0.02): """Walk-Forward backtesting method Args: train (pandas.Series): training data optimizer (str): portfolio optimizer for PyPortfolioOpt test (pandas.Series): test data test_months (int): number of testing months annual_risk_free_rate (float, optional): annual risk free rate used in calculating Sharpe ratio. Defaults to 0.02. Returns: [pandas.Series, float]: expected and realised asset performance """ if optimizer == "hrp": returns = train.pct_change().dropna() hrp = HRPOpt(returns) weights = hrp.optimize() weights = pd.Series(weights) performance = hrp.portfolio_performance(verbose=True) realised_annual_return = sum( weights * ((test.iloc[-1] / test.iloc[0])**(12 / test_months) - 1)) realised_annual_volatility = sum( weights * np.std(test.pct_change().dropna()) * np.sqrt(251)) realised_sharpe_ratio = ( realised_annual_return - annual_risk_free_rate) / realised_annual_volatility return weights, performance, realised_annual_return, realised_annual_volatility, realised_sharpe_ratio else: mu = mean_historical_return(train) S = CovarianceShrinkage(train).ledoit_wolf() ef = EfficientFrontier(mu, S) weights = ef.max_sharpe( ) if optimizer == "msr" else ef.min_volatility() weights = pd.Series(weights) performance = ef.portfolio_performance() realised_annual_return = sum( weights * ((test.iloc[-1] / test.iloc[0])**(12 / test_months) - 1)) realised_annual_volatility = sum( weights * np.std(test.pct_change().dropna()) * np.sqrt(251)) realised_sharpe_ratio = ( realised_annual_return - annual_risk_free_rate) / realised_annual_volatility return weights, performance, realised_annual_return, realised_annual_volatility, realised_sharpe_ratio
def approximated_max_kelly(data): """Find a approximated solution of the portofolio based on kelly criterion.""" returns_data = data.pct_change().dropna() sigma = CovarianceShrinkage(data).shrunk_covariance(delta=1e-2) mu = returns_data.mean(axis=0) A = 0.5 * sigma A = np.hstack((A, np.ones((sigma.shape[0], 1)))) A = np.vstack((A, np.ones((1, sigma.shape[0] + 1)))) A[-1, -1] = 0.0 B = np.hstack((mu, [1])) w = np.dot(np.linalg.inv(A), B) return pd.DataFrame([w[:-1]], columns=data.columns)
def get_portfolio(universe, df_tr, port_value, cutoff, df_m): '''create a portfolio using the stocks from the universe and the closing prices from df_tr with a given portfolio value and a weight cutoff value using the value of a momemntum indicator to limit the quantity of the stocks''' df_t = select_columns(df_tr, universe) mu = capm_returns(df_t) S = CovarianceShrinkage(df_t).ledoit_wolf() # Optimize the portfolio for min volatility ef = EfficientFrontier(mu, S) # Use regularization (gamma=1) weights = ef.min_volatility() #weights = ef.max_sharpe() cleaned_weights = ef.clean_weights(cutoff=cutoff) # Allocate latest_prices = get_latest_prices(df_t) da = DiscreteAllocation(cleaned_weights, latest_prices, total_portfolio_value=port_value) allocation = da.greedy_portfolio()[0] non_trading_cash = da.greedy_portfolio()[1] # Put the stocks and the number of shares from the portfolio into a df symbol_list = [] mom = [] w = [] num_shares_list = [] l_price = [] tot_cash = [] for symbol, num_shares in allocation.items(): symbol_list.append(symbol) mom.append(df_m[df_m['stock'] == symbol].values[0]) w.append(round(cleaned_weights[symbol], 4)) num_shares_list.append(num_shares) l_price.append(latest_prices[symbol]) tot_cash.append(num_shares * latest_prices[symbol]) df_buy = pd.DataFrame() df_buy['stock'] = symbol_list df_buy['momentum'] = mom df_buy['weights'] = w df_buy['shares'] = num_shares_list df_buy['price'] = l_price df_buy['value'] = tot_cash df_buy = df_buy.append( { 'stock': 'CASH', 'momentum': 0, 'weights': round(1 - df_buy['weights'].sum(), 4), 'shares': 1, 'price': round(non_trading_cash, 2), 'value': round(non_trading_cash, 2) }, ignore_index=True) df_buy = df_buy.set_index('stock') return df_buy, non_trading_cash
def get_portfolio_weights(df, clean=False, req_return=0.02): """ Returns the portfolio weights, following Markowitz's Modern Portfolio Theory to maximize sharpe ratio. """ mu = mean_historical_return(df) S = CovarianceShrinkage(df).ledoit_wolf() ef = EfficientFrontier(mu, S) weights = ef.max_sharpe(risk_free_rate=req_return) if clean: weights = ef.clean_weights() # weights = _fix_weights(weights) return weights
def __init__(self, weights, prices, risk_free=0.00): self.weights = weights self.prices = prices self.assets = prices.columns self.num_of_assets = len(prices.columns) self.returns = prices.pct_change().dropna() self.e_returns = expected_returns.mean_historical_return(prices) self.allocation = pd.DataFrame.from_dict(self.weights, orient='index', columns=['portfolio']) self.port_returns = self.returns.dot(self.allocation) self.port_cum_returns = ((1 + self.port_returns).cumprod() - 1) self.covariance = CovarianceShrinkage(prices).ledoit_wolf() self.rf = risk_free
def assign_strategy(ld: LazyDictionary, algo: str) -> tuple: assert ld is not None # use of black-litterman is based on https://github.com/robertmartin8/PyPortfolioOpt/blob/master/cookbook/4-Black-Litterman-Allocation.ipynb # print(market_prices) ld["s"] = CovarianceShrinkage(ld["filtered_stocks"]).ledoit_wolf() ld["delta"] = market_implied_risk_aversion(ld["market_prices"]) # use BlackLitterman model to compute returns - hopefully better estimate of returns than extrapolation of historical prices # market_prior = market_implied_prior_returns(ld["market_caps"], delta, ld["s"]) ld["bl"] = lambda ld: BlackLittermanModel( ld["s"], pi="market", market_caps=ld["market_caps"], risk_aversion=abs(ld["delta"]), absolute_views={}, ) ld["posterior_total_returns"] = lambda ld: ld["bl"].bl_returns() ld["posterior_s"] = lambda ld: ld["bl"].bl_cov() ld["mu"] = lambda ld: mean_historical_return(ld["filtered_stocks"]) ld["returns_from_prices"] = lambda ld: returns_from_prices(ld[ "filtered_stocks"]) use_bl = ld["returns_by"] != "by_prices" kwargs = ({ "returns": ld["mu"] } if use_bl else { "returns": ld["posterior_total_returns"] }) if algo != "hrp": kwargs["cov_matrix"] = ld["s"] if not use_bl else ld["posterior_s"] else: # algo is HRP kwargs = {"returns": ld["returns_from_prices"]} if algo == "hrp": ld["title"] = "Hierarchical Risk Parity" return (hrp_strategy, kwargs) elif algo == "ef-sharpe": ld["title"] = "Efficient Frontier - max. sharpe" return (ef_sharpe_strategy, kwargs) elif algo == "ef-risk": ld["title"] = "Efficient Frontier - efficient risk" kwargs["target_volatility"] = 5.0 return (ef_risk_strategy, kwargs) elif algo == "ef-minvol": ld["title"] = "Efficient Frontier - minimum volatility" return (ef_minvol_strategy, kwargs) else: assert False
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
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 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
import pandas as pd import numpy as np from pypfopt.efficient_frontier import EfficientFrontier from pypfopt.objective_functions import negative_cvar from pypfopt.risk_models import CovarianceShrinkage ##Importar série de dados df = pd.read_excel(r'C:\Users\Jhona\OneDrive\Área de Trabalho\PRBR11.xlsx', index_col='Data') ##Obter os retornos dos ativos returns = pd.DataFrame() for i in df: returns[i] = df[i].pct_change().dropna() ##Criar a matrix de covariância eficiente covMatrix = CovarianceShrinkage(df) e_cov = covMatrix.ledoit_wolf() ##Fronteira ef = EfficientFrontier(None, e_cov) ##Encontrando o CVaR 95% minimizando optimal_weights = ef.custom_objective(negative_cvar, returns) print(optimal_weights)
a = tod - d backtest_type = "wf" tickers = ['BA', 'AMD', 'AAPL'] start = dt.datetime(2021, 3, 1) end = dt.datetime(2021, 3, 30) ohlc = yf.download(tickers, start=start, end=end) prices = ohlc["Adj Close"].dropna(how="all") df = prices from pypfopt.expected_returns import mean_historical_return from pypfopt.risk_models import CovarianceShrinkage mu = mean_historical_return(df) S = CovarianceShrinkage(df).ledoit_wolf() from pypfopt.efficient_frontier import EfficientFrontier ef = EfficientFrontier(mu, S) weights = ef.max_sharpe() cleaned_weights = ef.clean_weights() # ef.save_weights_to_file("weights.txt") # saves to file print(cleaned_weights) ef.portfolio_performance(verbose=True); ##################################################################################### # an example from pyportfolioopt # if you already have expected returns and risk model from pypfopt.efficient_frontier import EfficientFrontier
def rebalnce_portfolios(): p = abspath(getsourcefile(lambda: 0)) p = p.rsplit('/', 1)[0] os.chdir(p) print('Working Directory is: %s' % os.getcwd()) file_path = p + '/results_2015-2019/' # !!! Editable Folder with files with weights start_time = '2015-01-01' # !!! start date, editable end_time = (datetime.today() - timedelta(days=1)).strftime( '%Y-%m-%d') # last day = day before today # Lists of files with portfolio weights files = [f for f in listdir(file_path) if isfile(join(file_path, f))] files = [f for f in files if f.startswith('portfolio_investment')] files = [file_path + f for f in files] files = sorted(files) weight_bounds_tuple = ( (0.0, 0.1), (0.0, 0.1), (0.0, 0.15), (0.0, 0.05), (0.0, 0.05), (0.01, 0.1) ) # !!! Weights to be adjusted for every iteration by arbitrary value gamma = 0.05 total_portfolio_value = 20000 for i in range(0, len(files)): portfolio = pd.read_csv(files[i], index_col=0).iloc[:, 0:6] tickers = portfolio.iloc[:, 2].tolist( ) # tickers inside portfolio (they will be updated) # Getting stock data (maybe re-do to for loop, if there be problems with memory) temp = pdr.DataReader(tickers, 'yahoo', start_time, end_time)['Close'] current_weights = portfolio['allocation_weight'].to_list() 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(temp) # Getting returns S = CovarianceShrinkage(temp).ledoit_wolf() # Getting cov matrix # 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 ef.portfolio_performance(verbose=True) ### 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(temp) da = DiscreteAllocation(weights, latest_prices, total_portfolio_value=total_portfolio_value) allocation, leftover = da.lp_portfolio() print(allocation) print("Money left: " + str(leftover)) print(da._allocation_rmse_error()) allocation = pd.DataFrame.from_dict(allocation, orient='index') allocation.columns = ['allocation_discrete'] weights = pd.DataFrame.from_dict(weights, orient='index') weights.columns = ['allocation_weight'] latest_prices = pd.DataFrame(latest_prices) latest_prices.columns = ['buy_price'] tickers = pd.DataFrame(tickers) tickers.columns = ['ticker'] tickers.index = tickers['ticker'] result = pd.concat([weights, allocation, tickers, latest_prices], axis=1) result['buy_investment'] = result['allocation_discrete'] * result[ 'buy_price'] result['actual_allocation'] = result['buy_investment'] / result[ 'buy_investment'].sum() # Get paths & filenames for saving with replacing old csv files n = files[i].split('_')[-1] s = file_path + 'portfolio_ticker_' + n result.to_csv(s)
def cv(self, back_test_months, data, optimizer, test_months, annual_risk_free_rate=0.02): """Cross-Validation backtesting method Args: back_test_months (int): number of backtesting months data (pandas.Series): data that includes both training and testing data optimizer (str): portfolio optimizer for PyPortfolioOpt test_months (int): number of testing months annual_risk_free_rate (float, optional): annual risk free rate used in calculating Sharpe ratio. Defaults to 0.02. Returns: [pandas.Series, float]: expected and realised asset performance """ embargo = np.round_(0.01 * len(data), decimals=0) all_weights = np.zeros((back_test_months, np.shape(data)[1])) all_realised_annual_return = np.zeros(back_test_months) all_realised_annual_volatility = np.zeros(back_test_months) all_realised_sharpe_ratio = np.zeros(back_test_months) for i in range(back_test_months): test_start = i * len(data) / back_test_months test_end = test_start + len(data) / back_test_months - 1 test = data.iloc[int(test_start):int(test_end), :] train = data.iloc[np.r_[0:int(test_start), int(test_end) + int(embargo):len(data)], :] if optimizer == "hrp": train_returns = train.pct_change().dropna() hrp = HRPOpt(train_returns) weights = hrp.optimize() weights = pd.Series(weights) all_weights[i] = weights performance = hrp.portfolio_performance(verbose=True) else: mu = mean_historical_return(train) S = CovarianceShrinkage(train).ledoit_wolf() ef = EfficientFrontier(mu, S) weights = ef.max_sharpe( ) if optimizer == "msr" else ef.min_volatility() weights = pd.Series(weights) all_weights[i] = weights performance = ef.portfolio_performance() all_realised_annual_return[i] = sum(all_weights[i] * ((test.iloc[ (len(test) - 1)] / test.iloc[0])**(12 / test_months) - 1)) all_realised_annual_volatility[i] = sum( all_weights[i] * np.std(test.pct_change().dropna()) * np.sqrt(251)) all_realised_sharpe_ratio = ( all_realised_annual_return[i] - annual_risk_free_rate) / all_realised_annual_volatility[i] weights = np.mean(all_weights) realised_annual_return = np.mean(all_realised_annual_return) realised_annual_volatility = np.mean(all_realised_annual_volatility) realised_sharpe_ratio = np.mean(all_realised_sharpe_ratio) return weights, performance, realised_annual_return, realised_annual_volatility, realised_sharpe_ratio
def main(): dashboard = st.sidebar.selectbox('Which Dashboard to open?', ('All Stocks', 'Strategies', 'Analysis', 'Portfolio', 'Pattern', 'Update Stocks')) cursor = connection.cursor() if dashboard == 'All Stocks': st.title(dashboard) print(f'Inside dashboard : {dashboard}') cursor.execute('''select symbol from stock''') stocks_symbols = cursor.fetchall() stocks = [item for t in stocks_symbols for item in t] symbol_search = st.sidebar.text_input("Stock name ") symbol = st.sidebar.selectbox("Select the Stock", stocks) if symbol_search != "": symbol = symbol_search result = get_quote(symbol) #data = json.loads(result['data'][0]) #df = pd.json_normalize(data['data']) st.dataframe(pd.DataFrame(result['data'])) # elif dashboard == 'Pattern': # stocks= {} # print(f'Inside dashboard : {dashboard}') # st.title(dashboard) # cursor.execute('''select symbol from stock''') # stocks_symbols = cursor.fetchall() # stocks = [item for t in stocks_symbols for item in t] # symbol = st.sidebar.selectbox("Select the Stock",stocks) # df = pd.read_sql("select open,high,low,close,symbol from stock_price where symbol ='"+symbol+"'", connection) # cursor.execute('''select key,name from patterns''') # patterns = cursor.fetchall() # # patterns = [item for t in patterns for item in t] # for pattern in patterns: # pattern_function = getattr(tb,pattern[0]) # result = pattern_function(df['Open'],df['High'],df['Low'],df['Close']) # last = result.tail(1).values[0] # if last>0: # st.write("Patter name : "+pattern[1]) # st.write("BULLISH") # elif last<0: # st.write("Patter name : "+pattern[1]) # st.write("BEARISH") elif dashboard == 'Strategies': print(f'Inside dashboard : {dashboard}') st.title(dashboard) cursor.execute('''select name from strategy''') strategies = cursor.fetchall() strategies = [item for t in strategies for item in t] strategy = st.sidebar.selectbox("Select the Strategy", strategies) cursor.execute('''select name from sectors''') sectors = cursor.fetchall() sectors = [item for t in sectors for item in t] sector = st.sidebar.selectbox("Select the Sector", sectors) if sector == 'All': cursor.execute('''select symbol from stock''') stocks = cursor.fetchall() stock_in_sector = [item for t in stocks for item in t] else: df = pd.read_csv("nifty Sectors/" + sector + ".csv") stock_in_sector = pd.Series(df['Symbol']) st.header("Strategy selected: " + strategy) if strategy == 'TTM Squeeze': if sector != "": my_bar = st.progress(0) percent_complete = 1 i = 1 for stock in stock_in_sector: percent_complete = int((i / len(stock_in_sector)) * 100) i = i + 1 df = pd.read_sql( "select * from stock_price where symbol= '" + stock + "'", connection) if df.empty: continue # st.dataframe(df) #if len(df.squeeze_on.tail()) > 3: if df.iloc[-3]['squeeze_on'] and not df.iloc[-1][ 'squeeze_on'] and (df.iloc[-1]['OBV'] * 2) > df.iloc[-1]['OBV_EMA']: mess = "{} is coming out of squeezer".format(stock) st.subheader(mess) st.dataframe( df.sort_values(by=['Date'], ascending=False)) newdf = df candlestick = go.Candlestick(x=newdf['Date'], open=newdf['Open'], high=newdf['High'], low=newdf['Low'], close=newdf['Close']) upper_band = go.Scatter(x=newdf['Date'], y=newdf['upper_band'], name='Upper Bollinger Band', line={'color': 'red'}) lower_band = go.Scatter(x=newdf['Date'], y=newdf['lower_band'], name='Lower Bollinger Band', line={'color': 'red'}) upper_keltner = go.Scatter( x=newdf['Date'], y=newdf['upper_keltner'], name='Upper Keltner Channel', line={'color': 'blue'}) lower_keltner = go.Scatter( x=newdf['Date'], y=newdf['lower_keltner'], name='Lower Keltner Channel', line={'color': 'blue'}) OBV = go.Scatter(x=newdf['Date'], y=newdf['OBV'], name='On Balace Volume', line={'color': 'black'}) OBV_EMA = go.Scatter(x=newdf['Date'], y=newdf['OBV_EMA'], name='On Balace Volume EMA', line={'color': 'green'}) fig_vol = go.Figure(data=[OBV, OBV_EMA]) fig = go.Figure(data=[ candlestick, upper_band, lower_band, upper_keltner, lower_keltner ]) fig.layout.xaxis.type = 'category' fig.layout.xaxis.rangeslider.visible = False first, last = st.beta_columns(2) first.plotly_chart(fig) last.plotly_chart(fig_vol) my_bar.progress(percent_complete) if percent_complete == 100: st.balloons() elif strategy == 'On Balance Volume(OBV)': if sector != "": my_bar = st.progress(0) percent_complete = 1 i = 1 for stock in stock_in_sector: percent_complete = int((i / len(stock_in_sector)) * 100) i = i + 1 df = pd.read_sql( "select * from stock_price where symbol= '" + stock + "'", connection) if df.empty: continue newdf = df if newdf.iloc[-1]['OBV'] > newdf.iloc[-1][ 'OBV_EMA'] and newdf.iloc[-1]['Close'] > newdf.iloc[ -1]['21ema'] and newdf.iloc[-1][ 'Close'] > newdf.iloc[-1]['VWAP']: mess = "{} is above OBV, 20EMA and VWAP ".format( stock) st.subheader(mess) candlestick = go.Candlestick(x=newdf['Date'], open=newdf['Open'], high=newdf['High'], low=newdf['Low'], close=newdf['Close']) OBV = go.Scatter(x=newdf['Date'], y=newdf['OBV'], name='Volume', line={'color': 'yellow'}) OBV_EMA = go.Scatter(x=newdf['Date'], y=newdf['OBV_EMA'], name='Volume EMA', line={'color': 'green'}) fig = go.Figure(data=[OBV, OBV_EMA]) fig.layout.xaxis.type = 'category' fig.layout.xaxis.rangeslider.visible = False figPrice = go.Figure(data=[candlestick]) figPrice.layout.xaxis.type = 'category' figPrice.layout.xaxis.rangeslider.visible = False first, last = st.beta_columns(2) first.plotly_chart(fig) last.plotly_chart(figPrice) my_bar.progress(percent_complete) if percent_complete == 100: st.balloons() elif strategy == 'SuperTrend': if sector != "": my_bar = st.progress(0) percent_complete = 1 i = 1 for stock in stock_in_sector[:3]: st.subheader(stock) percent_complete = int((i / len(stock_in_sector)) * 100) i = i + 1 df = pd.read_sql( "select * from stock_price where symbol= '" + stock + "'", connection) if df.empty: continue df = supertrend.run_supertrend(df, 10, 3) df['in_uptrend'] = True for current in range(1, len(df.Close)): previous = current - 1 if df['Close'][current] > df['upperband'][previous]: df['in_uptrend'][current] = True elif df['Close'][current] < df['Lowerband'][previous]: df['in_uptrend'][current] = False else: df['in_uptrend'][current] = df['in_uptrend'][ previous] if df['in_uptrend'][current] and df['Lowerband'][ current] < df['Lowerband'][previous]: df['Lowerband'][current] = df['Lowerband'][ previous] if not df['in_uptrend'][ current] and df['upperband'][current] > df[ 'upperband'][previous]: df['upperband'][current] = df['upperband'][ previous] candlestick = go.Candlestick(x=df['Date'], open=df['Open'], high=df['High'], low=df['Low'], close=df['Close']) upper_band = go.Scatter(x=df['Date'], y=df['upperband'], name='Upper Band', line={'color': 'red'}) lower_band = go.Scatter(x=df['Date'], y=df['Lowerband'], name='Lower Band', line={'color': 'red'}) fig = go.Figure(data=[candlestick, upper_band, lower_band]) fig.layout.xaxis.type = 'category' fig.layout.xaxis.rangeslider.visible = False st.plotly_chart(fig) my_bar.progress(percent_complete) if percent_complete == 100: st.balloons() elif strategy == 'Support & Resistence': if sector != "": my_bar = st.progress(0) percent_complete = 1 i = 1 for stock in stock_in_sector: percent_complete = int((i / len(stock_in_sector)) * 100) i = i + 1 df = pd.read_sql( "select * from stock_price where symbol= '" + stock + "'", connection) if df.empty: continue s = np.mean(df['High'] - df['Low']) df['Date'] = pd.to_datetime(df.index) df['Date'] = df['Date'].apply(mpl_dates.date2num) df = df.loc[:, ['Date', 'Open', 'High', 'Low', 'Close']] def isFarFromLevel(l): return np.sum([abs(l - x) < s for x in levels]) == 0 levels = [] def isSupport(df, i): support = df['Low'][i] < df['Low'][ i - 1] and df['Low'][i] < df['Low'][ i + 1] and df['Low'][i + 1] < df['Low'][ i + 2] and df['Low'][i - 1] < df['Low'][i - 2] return support def isResistance(df, i): resistance = df['High'][i] > df['High'][i - 1] and df[ 'High'][i] > df['High'][i + 1] and df['High'][ i + 1] > df['High'][i + 2] and df['High'][ i - 1] > df['High'][i - 2] return resistance for i in range(2, df.shape[0] - 2): if isSupport(df, i): l = df['Low'][i] if isFarFromLevel(l): levels.append((i, l)) elif isResistance(df, i): l = df['High'][i] if isFarFromLevel(l): levels.append((i, l)) elif strategy == 'Breakout': if sector != "": my_bar = st.progress(0) percent_complete = 1 i = 1 def is_consolidating(df, percentage=2): recent_candlesticks = df[-15:] max_close = recent_candlesticks['Close'].max() min_close = recent_candlesticks['Close'].min() threshold = 1 - (percentage / 100) if min_close > (max_close * threshold): return True return False def is_breaking_out(df, percentage=2.5): last_close = df[-1:]['Close'].values[0] if is_consolidating(df[:-1], percentage=percentage): recent_closes = df[-16:-1] if last_close > recent_closes['Close'].max(): return True return False percentage = st.slider('Slide me to select percentage', min_value=1, max_value=10) for stock in stock_in_sector: percent_complete = int((i / len(stock_in_sector)) * 100) i = i + 1 df = pd.read_sql( "select * from stock_price where symbol= '" + stock + "'", connection) if df.empty: continue if is_breaking_out(df, percentage): newdf = df st.subheader(f'{stock} is breaking out...') candlestick = go.Candlestick(x=newdf['Date'], open=newdf['Open'], high=newdf['High'], low=newdf['Low'], close=newdf['Close']) OBV = go.Scatter(x=newdf['Date'], y=newdf['OBV'], name='On Balace Volume', line={'color': 'black'}) OBV_EMA = go.Scatter(x=newdf['Date'], y=newdf['OBV_EMA'], name='On Balace Volume EMA', line={'color': 'green'}) fig_vol = go.Figure(data=[OBV, OBV_EMA]) fig = go.Figure(data=[candlestick]) fig.layout.xaxis.type = 'category' fig.layout.xaxis.rangeslider.visible = False first, last = st.beta_columns(2) first.plotly_chart(fig) last.plotly_chart(fig_vol) my_bar.progress(percent_complete) if percent_complete == 100: st.balloons() elif dashboard == 'Portfolio': print(f'Inside dashboard : {dashboard}') st.title(dashboard) cursor.execute('''select name from sectors''') sectors = cursor.fetchall() sectors = [item for t in sectors for item in t] sector = st.sidebar.selectbox("Select the Sector", sectors) alldf = pd.read_sql("select * from stock_price", connection) if sector == 'All': cursor.execute('''select symbol from stock''') stocks = cursor.fetchall() stock_in_sector = [item for t in stocks for item in t] alldf = alldf.loc[alldf['Symbol'].isin(stock_in_sector)] else: df = pd.read_csv("nifty Sectors/" + sector + ".csv") alldf = alldf.loc[alldf['Symbol'].isin(df['Symbol'])] #alldf = alldf.set_index(pd.DatetimeIndex(df['Date'].values)) #alldf.drop(columns = ['Date'], axis =1, inplace=True) assets = alldf.Symbol.unique() alldf = alldf.set_index('Date') alldf = alldf.pivot_table(index='Date', columns=['Symbol'], values='Close') alldf = alldf.set_index(pd.DatetimeIndex(alldf.index.values)) alldf = alldf.dropna(axis=1) #medals.reindex_axis(['Gold', 'Silver', 'Bronze'], axis=1) st.subheader("Stocks") st.write(alldf) #mu = expected_returns.mean_historical_return(alldf) #s = risk_models.sample_cov(alldf) span = st.slider('Slide me to select span', min_value=1, max_value=500) mu = expected_returns.ema_historical_return(alldf, span=span) st.subheader("Returns") st.write(mu) s = CovarianceShrinkage(alldf).shrunk_covariance() ef = EfficientFrontier(mu, s) weight = ef.max_sharpe() clean_weight = ef.clean_weights() expectedreturn, volatility, Sharperatio = ef.portfolio_performance( verbose=False) st.subheader("Expected annual return: " + str(round(expectedreturn, 2) * 100) + '%') st.subheader("Annual volatility: " + str(round(volatility, 2) * 100) + '%') st.subheader("Sharpe Ratio: " + str(round(Sharperatio, 2))) funds = st.slider('PortFolio Value:', min_value=50000, max_value=500000) latest_prices = get_latest_prices(alldf) weights = clean_weight da = DiscreteAllocation(weights, latest_prices, total_portfolio_value=funds) allocation, leftover = da.lp_portfolio() st.subheader("Weight") st.write(pd.DataFrame(weights, columns=weights.keys(), index=[0])) st.subheader("Discreate Allocation") st.write(pd.DataFrame(allocation, columns=allocation.keys(), index=[0])) st.subheader("Funds Reamaning:" + str(round(leftover, 2))) elif dashboard == 'Update Stocks': print(f'Inside dashboard : {dashboard}') st.title(dashboard) icon('update') if st.button('Update Tables'): status = nse.updateTableList(connection) if status == 'Success': st.balloons() if st.button('Update Stocks Price'): status = update_stock.updateStockPrice(st, connection) if status == 'Success': st.balloons() if st.button('Create Stocks Tables'): status = update_stock.updateTables(connection) if status == 'Success': st.balloons()
# "FB", "AAPL", "COST", "WMT", "KR", "JPM", # "BAC", "HSBC"] # portfolio = combine_stocks(stocks) # portfolio.to_csv("portfolio.csv", index=False) portfolio = pd.read_csv("portfolio.csv") print(portfolio.head()) from pypfopt.efficient_frontier import EfficientFrontier from pypfopt.expected_returns import mean_historical_return from pypfopt.risk_models import CovarianceShrinkage mu = mean_historical_return(portfolio) S = CovarianceShrinkage(portfolio).ledoit_wolf() ef = EfficientFrontier(mu, S) weights = ef.max_sharpe() cleaned_weights = ef.clean_weights() print(dict(cleaned_weights)) ef.portfolio_performance(verbose=True) from pypfopt.discrete_allocation import DiscreteAllocation, get_latest_prices latest_prices = get_latest_prices(portfolio) da = DiscreteAllocation(cleaned_weights, latest_prices,
df_m = df_m.sort_values(by='momentum', ascending=False) if len(df_m[(df_m['momentum'] > minimum_momentum - 0.5 * dev) & ( df_m['momentum'] < minimum_momentum + 1.9 * dev)]) < portfolio_size: df_m = df_m.head(portfolio_size) else: df_m = df_m[(df_m['momentum'] > minimum_momentum - 0.5 * dev) & ( df_m['momentum'] < minimum_momentum + 1.9 * dev)].head(portfolio_size) # Set the universe to the top momentum stocks for the period universe = df_m['stock'].tolist() # Create a df with just the stocks from the universe df_t = select_columns(df_tr, universe) # -----Χαρτοφυλάκιο Νο1 γενικό # Calculate portofolio mu and S mu = capm_returns(df_t) S = CovarianceShrinkage(df_t).ledoit_wolf() # Optimise the portfolio for maximal Sharpe ratio ef = EfficientFrontier(mu, S) # Use regularization (gamma=1) weights = ef.min_volatility() cleaned_weights = ef.clean_weights(cutoff=cutoff, rounding=3) ef.portfolio_performance() st.subheader('Βελτιστοποιημένο Χαρτοφυλάκιο') st.write( 'Το προτεινόμενο χαρτοφυλάκιο από τις ιστορικές τιμές των επιλεγμένων μετοχών έχει τα παρακάτω χαρακτηριστικά' ) st.write('Αρχική Αξία Χαρτοφυλακίου : ' + str(port_value) + '€') st.write('Sharpe Ratio: ' + str(round(ef.portfolio_performance()[2], 2))) st.write('Απόδοση Χαρτοφυλακίου: ' + str(round(ef.portfolio_performance()[0] * 100, 2)) + '%') st.write('Μεταβλητότητα Χαρτοφυλακίου: ' +
response = table.scan(FilterExpression=Attr('date').gt(prev)) items = response['Items'] while 'LastEvaluatedKey' in response: response = table.scan(ExclusiveStartKey=response['LastEvaluatedKey']) items.extend(response['Items']) dfitems = pd.DataFrame(items, columns=['code', 'date', 'price']) f = dfitems.drop_duplicates(subset=['date', 'code'], keep='last') filtered = dfitems.pivot(index='date', columns='code', values='price') cols = filtered.columns filtered[cols] = filtered[cols].apply(pd.to_numeric, errors='coerce') filtered = filtered.dropna() print(filtered) mu = mean_historical_return(filtered) S = CovarianceShrinkage(filtered).ledoit_wolf() ef = EfficientFrontier(mu, S) max_sharpe = ef.max_sharpe() max_sharpe_performance = ef.portfolio_performance() minVolFrontier = EfficientFrontier(mu, S) min_volatility = minVolFrontier.min_volatility() min_vol_performance = minVolFrontier.portfolio_performance() print(max_sharpe_performance, "MAX SHARPE PERFORMANCE") print(min_vol_performance, "MIN VOL PERFORMANCE") addModelPrediction("max_sharpe_ratio", max_sharpe_performance[2], max_sharpe_performance[0], max_sharpe_performance[1], max_sharpe) addModelPrediction("min_volatility", min_vol_performance[2],
def portfolio_all(df): coins = ['ripple','bitcoin','ethereum','litecoin','iota','bitcoin_cash'] #coins = ['bitcoin'] stocks = df.dropna()[coins] log_ret = np.log(stocks/stocks.shift(1)) np.random.seed(42) num_ports = 6000 all_weights = np.zeros((num_ports, len(stocks.columns))) ret_arr = np.zeros(num_ports) vol_arr = np.zeros(num_ports) sharpe_arr = np.zeros(num_ports) for x in range(num_ports): # Weights weights = np.array(np.random.random(len(stocks.columns))) weights = weights/np.sum(weights) # Save weights all_weights[x,:] = weights # Expected return ret_arr[x] = np.sum( (log_ret.mean() * weights * int(252))) # Expected volatility vol_arr[x] = np.sqrt(np.dot(weights.T, np.dot(log_ret.cov()*int(252), weights))) # Sharpe Ratio sharpe_arr[x] = ret_arr[x]/vol_arr[x] max_sr_ret = ret_arr[sharpe_arr.argmax()] max_sr_vol = vol_arr[sharpe_arr.argmax()] logging.info(vol_arr) logging.info(ret_arr) fig = go.Figure(data=go.Scatter(x=vol_arr, y=ret_arr, mode='markers', marker=dict( size=8, color=sharpe_arr, #set color equal to a variable colorscale='Viridis', # one of plotly colorscales showscale=True ) )) fig.add_trace( go.Scatter( mode='markers', x=[max_sr_vol], y=[max_sr_ret], marker=dict( color='Red', size=10 ), showlegend=False ) ) logging.info("Saving portfolio graph...") plio.write_html(fig,'/appdata/portgraphstatic.html', include_plotlyjs=True) logging.info("Getting portfolio info") mu = mean_historical_return(stocks,frequency=int(252)) S = CovarianceShrinkage(stocks).ledoit_wolf() ef = EfficientFrontier(mu, S) weights = ef.max_sharpe() logging.info(weights) perf = ef.portfolio_performance(verbose=True) portinfo={'weights':weights, 'performance':{'Return':perf[0],'Volatility':perf[1],'Sharpe Ratio':perf[2]}} logging.info(type(portinfo)) with open('/appdata/portinfo.json', 'w') as f: json.dump(portinfo, f)
plt.xlabel('Year', fontsize=14) plt.grid(which="major", color='k', linestyle='-.', linewidth=0.5) plt.show() #plot() return data df = multi_stock() from pypfopt.expected_returns import mean_historical_return from pypfopt.risk_models import CovarianceShrinkage mu = mean_historical_return( df) # pandas series of estimated expected returns for each asset S = CovarianceShrinkage(df).ledoit_wolf() #estimated covariance matrix print(mu) print(S) # define a loop to iterate through all the different objective functions from pypfopt import objective_functions as objfunc print() print('max sharpe') from pypfopt.efficient_frontier import EfficientFrontier ef = EfficientFrontier(mu, S) ef.add_objective( objfunc.L2_reg, gamma=0.1) # incentivize optimizer to choose non zero weights weights = ef.max_sharpe() x = ef.portfolio_performance(verbose=True)
def port_rets(cls, list): global weightedreturns global Stock_data_frames global Portfolio global Portfolio_returns cls.weight = list #Create panel for stocks returns cls.Stock_data_frames = pd.concat(FinancialInfo.frames, axis=1) cls.Stock_data_frames.dropna(inplace=True) #Create panel for stocks' close price cls.Stock_close_prices = pd.concat(FinancialInfo.prices, axis=1) cls.Stock_close_prices.dropna(inplace=True) # Compute the annualized average historical return cls.mean_returns_avg = mean_historical_return(cls.Stock_close_prices, frequency=252) # Calculate the portfolio annual simple return cls.simple_returns_annual = np.sum( cls.Stock_data_frames.mean() * cls.weight) * 252 # Calculate the log returns cls.log_returns = np.log(cls.Stock_close_prices / cls.Stock_close_prices.shift(1)) cls.log_returns.dropna(inplace=True) # Calculate the annualized log returns and covariance cls.log_returns_annualized = cls.log_returns.mean() * 252 cls.log_returns_covariance = cls.log_returns.cov() * 252 #Create panel for stocks return multipled by their weights in portfolio cls.weightedreturns = FinancialInfo.Stock_data_frames.mul( FinancialInfo.weight, axis=1) cls.cummulativereturns = ( (1 + FinancialInfo.weightedreturns.sum(axis=1)).cumprod() - 1) # cummulativereturns = weightedreturns.sum(axis = 1) portfolio_weights_ew = np.repeat(1 / FinancialInfo.num_stocks, FinancialInfo.num_stocks) # cummulativereturns_ew = FinancialInfo.Stock_data_frames.iloc[:,0:FinancialInfo.num_stocks].mul(portfolio_weights_ew, axis = 1).sum(axis =1) # FinancialInfo.cummulativereturns.plot(color = 'Red') # cummulativereturns_ew.plot(color = 'Blue') #Calculate portfolio volatility cls.cov_mat = FinancialInfo.Stock_data_frames.cov() cls.cov_mat_annual = cls.cov_mat * 252 cls.portfolio_weights = np.array(FinancialInfo.weight) cls.portfolio_volatility = np.sqrt( np.dot(cls.portfolio_weights.T, np.dot(cls.cov_mat_annual, cls.portfolio_weights))) # print (f'The volatility of this portfoliois: {portfolio_volatility}') FinancialInfo.vol_list.append(cls.portfolio_volatility) cls.pfvol = pd.DataFrame(FinancialInfo.vol_list) # Create the covariance shrinkage instance variable cls.cov_shrinkage = CovarianceShrinkage(cls.Stock_close_prices) cls.e_cov = cls.cov_shrinkage.ledoit_wolf() #Create the sum of returns of portfolio's stocks cls.Portfolio_returns = FinancialInfo.weightedreturns.sum(axis=1, skipna=True) cls.Portfolio = pd.DataFrame(data=cls.Portfolio_returns, columns=['Portfolio']) cls.Portfolio.drop(cls.Portfolio.index[0], inplace=True) # Annualized portfolio volatility 30-day windows cls.returns_windowed = cls.Portfolio_returns.rolling(30) cls.volatility_series = cls.returns_windowed.std() * np.sqrt(252) #Create a total accmulative returns cls.total_returns = cls.Portfolio_returns.sum() #Calculate sharpe ratio cls.Portfolio_sharpe = (cls.total_returns - FinancialInfo.risk_free ) / cls.portfolio_volatility # print (f'The total returns for this portfolio is: {total_returns}') FinancialInfo.returns_list.append(cls.total_returns) cls.pfreturns = pd.DataFrame(FinancialInfo.returns_list) FinancialInfo.sharpe_list.append(cls.Portfolio_sharpe) cls.pfsharpe = pd.DataFrame(FinancialInfo.sharpe_list) #Create a dataframe with total returns, sharpe ratio, and volatility FinancialInfo.wList.append(cls.weight) cls.df = pd.DataFrame(np.array(FinancialInfo.wList), columns=FinancialInfo.symbol_list) cls.df.insert(FinancialInfo.num_stocks, 'Returns', cls.pfreturns) cls.df.insert(FinancialInfo.num_stocks + 1, 'Volatility', cls.pfvol) cls.df.insert(FinancialInfo.num_stocks + 2, 'Sharpe', cls.pfsharpe) #Sorting the dataframe by Sharpe ratio cls.df_sorted = cls.df.sort_values(by=['Sharpe'], ascending=False) cls.MSR_weights = cls.df_sorted.iloc[0, 0:FinancialInfo.num_stocks] cls.MSR_weights_array = np.array(cls.MSR_weights) cls.MSRreturns = FinancialInfo.Stock_data_frames.iloc[:, 0:FinancialInfo. num_stocks].mul( cls. MSR_weights_array, axis=1).sum( axis=1) # cls.MSRreturns.plot(color = 'Orange') #Sorting the dataframe by volatility cls.df_vol_sorted = cls.df.sort_values(by=['Volatility'], ascending=True) cls.GMV_weights = cls.df_vol_sorted.iloc[0, 0:FinancialInfo.num_stocks] cls.GMV_weights_array = np.array(cls.GMV_weights) cls.GMVreturns = FinancialInfo.Stock_data_frames.iloc[:, 0:FinancialInfo. num_stocks].mul( cls. GMV_weights_array, axis=1).sum( axis=1)
weightsmo = st.sidebar.checkbox( 'Επιλεγμένο επιλέγει τον υπολογισμό των βαρών με βάση τον μέγιστο Sharpe Ratio αλλιώς με την ελάχιστη διακύμανση.', value=True) allocmo = st.sidebar.checkbox( 'Επιλεγμένο επιλέγει τον υπολογισμό του μοντέλου του greedy_portfolio αλλιώς επιλέγει το lp_portfolio.', value=True) cutoff = st.sidebar.slider( 'Ελάχιστο Ποσοστό Συμμετοχής μιας Μετοχής στο Χαρτοφυλάκιο.', 0.01, 0.30, 0.10) c1, c2, c3, c4 = st.beta_columns((1, 1, 1, 1)) #-----Χαρτοφυλάκιο Νο1 γενικό #Calculate portofolio mu and S mu = expected_returns.mean_historical_return(df_t) if riskmo: S = CovarianceShrinkage(df_t).ledoit_wolf() else: S = risk_models.sample_cov(df_t) # Optimise the portfolio ef = EfficientFrontier(mu, S, gamma=2) # Use regularization (gamma=1) if weightsmo: weights = ef.max_sharpe() else: weights = ef.min_volatility() cleaned_weights = ef.clean_weights(cutoff=cutoff, rounding=3) ef.portfolio_performance() c1.subheader('Χαρτοφυλάκιο Νο1') c1.write( 'Το προτινόμενο χαρτοφυλάκιο από τις ιστορικές τιμές των επιλεγμένων μετοχών έχει τα παρακάτω χαρακτηριστικά' )
def next(self): # Pass counter_period days to compute return if self.counter < self.counter_period: self.counter += 1 else: # Get data to dataframe in order to feed Pyopt appended_data = [] for i, d in enumerate(self.datas): dt, dn = self.datetime.date(), d._name get = lambda mydata: mydata.get(0, self.counter_period) time = [d.num2date(x) for x in get(d.datetime)] df = pd.DataFrame({dn: get(d.close)}, index=time) appended_data.append(df) df = pd.concat(appended_data, axis=1) # df is dataframe of n assets for i, d in enumerate(self.datas): dt, dn = self.datetime.date(), d._name if d.close[0] > self.inds[d]['sma_50'][0] and self.inds[d][ 'sma_50'][0] > self.inds[d]['sma_200']: if dn in self.selected_assets: pass else: self.selected_assets.append(dn) else: if dn in self.selected_assets: self.selected_assets.remove(dn) # Create dataframe of selected_assets portfolio portfolio_today = df[self.selected_assets] # Because there are some days having no assets in portfolio may cause error if strategy == 'Risk_parity': x_t = [0.25, 0.25, 0.25, 0.25] cons = ({ 'type': 'eq', 'fun': total_weight_constraint }, { 'type': 'ineq', 'fun': long_only_constraint }) res = minimize(risk_budget_objective, w0, args=[V, x_t], method='SLSQP', constraints=cons, options={'disp': True}) w_rb = np.asmatrix(res.x) elif strategy == 'M_Max_sharpe': try: mu = mean_historical_return(portfolio_today) S = CovarianceShrinkage(portfolio_today).ledoit_wolf() ef = EfficientFrontier(mu, S) weights = ef.max_sharpe() cleaned_weights = ef.clean_weights() # Rebalance monthly if self.day_counter % 24 == 0: for key, value in cleaned_weights.items(): self.order_target_percent(key, target=value) print( 'on {} asset of portfolio is {} with value {}'. format(self.datetime.date(), key, value)) self.day_counter += 1 except: pass
# In[75]: # The average historical return is usually available as a proxy for expected returns, but is not always accurate--a more # thorough estimate of expected returns requires an assumption about the return distribution, which we'll discuss in the context # of Loss Distributions later in the course. # In[76]: df4.head(10) # In[77]: # Import the CovarianceShrinkage object, it reduces/shrinks the errors/residuals while calculating the covariance matrix # Create the CovarianceShrinkage instance variable cs = CovarianceShrinkage(df4) # In[78]: # Difference in calculating covariance matrix through covariance shrinkage and through sample cov() method # Compute the sample covariance matrix of returns sample_cov = df4.pct_change().cov() * 252 # Compute the efficient covariance matrix of returns e_cov = cs.ledoit_wolf() # Display both the sample covariance_matrix and the efficient e_cov estimate print("Sample Covariance Matrix\n", sample_cov, "\n") print("Efficient Covariance Matrix\n", e_cov, "\n") # In[79]:
# path2 = r"D:\TimerSeriesAnalysis\AMZN.csv" path2 = r"D:\TimerSeriesAnalysis" with changepath(path2): df = pd.read_csv("AMZN.csv", parse_dates=True, index_col="Date") # Compute the annualized average historical return mu = mean_historical_return(assets, frequency=252) # Plot the annualized average historical return plt.plot(mu, linestyle='None', marker='o') plt.show() # Create the CovarianceShrinkage instance variable # this is bette, because it shrinks the errors, and give annualized covariance cs = CovarianceShrinkage(assets).ledoit_wolf() # Compute the sample covariance matrix of returns sample_covariance = assets.pct_change().cov() * 252 # Create the EfficientFrontier instance variable ef = EfficientFrontier(mu, cs) # Compute the Weights portfolio that maximises the Sharpe ratio weights = ef.max_sharpe() # clean_weights() method truncates tiny weights to zero and rounds others cw = ef.clean_weights() with changepath(path): ef.save_weights_to_file("weights.txt") # saves to file