def test_ema_historical_return(): df = get_data() mean = expected_returns.ema_historical_return(df) assert isinstance(mean, pd.Series) assert list(mean.index) == list(df.columns) assert mean.notnull().all() assert mean.dtype == "float64" # Test the (warning triggering) case that input is not a dataFrame mean_np = expected_returns.ema_historical_return(df.to_numpy()) mean_np.name = mean.name # These will differ. reset_mean = mean.reset_index(drop=True) # Index labels would be tickers. pd.testing.assert_series_equal(mean_np, reset_mean)
def get_mu_sigma(prices, returns_model='mean_historical_return', risk_model='ledoit_wolf', frequency=252, span=500): """Get mu (returns) and sigma (asset risk) given a expected returns model and risk model prices (pd.DataFrame) – adjusted closing prices of the asset, each row is a date and each column is a ticker/id. returns_model (string, optional) - Model for estimating expected returns of assets, either 'mean_historical_return' or 'ema_historical_return' (default: mean_historical_return) risk_model (string, optional) - Risk model to quantify risk: sample_cov, ledoit_wolf, defaults to ledoit_wolf, as recommended by Quantopian in their lecture series on quantitative finance. frequency (int, optional) – number of time periods in a year, defaults to 252 (the number of trading days in a year) span (int, optional) – Applicable only for 'ema_historical_return' expected returns. The time-span for the EMA, defaults to 500-day EMA) """ CHOICES_EXPECTED_RETURNS = { 'mean_historical_return': expected_returns.mean_historical_return(prices, frequency), 'ema_historical_return': expected_returns.ema_historical_return(prices, frequency, span) } CHOICES_RISK_MODEL = { 'sample_cov': risk_models.sample_cov(prices), 'ledoit_wolf': risk_models.CovarianceShrinkage(prices).ledoit_wolf() } mu = CHOICES_EXPECTED_RETURNS.get(returns_model.lower(), None) S = CHOICES_RISK_MODEL.get(risk_model.lower(), None) if mu is None: raise Exception('Expected returns model %s is not supported. Only mean_historical_return and ema_historical_return are supported currently.' % risk_model) if S is None: raise Exception('Risk model %s is not supported. Only sample_cov and ledoit_wolf are supported currently.' % risk_model) return mu, S
def test_ema_historical_return_limit(): df = get_data() sma = expected_returns.mean_historical_return(df, compounding=False) ema = expected_returns.ema_historical_return(df, compounding=False, span=1e10) np.testing.assert_array_almost_equal(ema.values, sma.values)
def test_ema_historical_return(): df = get_data() mean = expected_returns.ema_historical_return(df) assert isinstance(mean, pd.Series) assert list(mean.index) == list(df.columns) assert mean.notnull().all() assert mean.dtype == "float64"
def portfolio_optimization(): optimal_path = "optimal_weights.txt" if not os.path.exists(optimal_path): data_path = os.path.join("tickers_data", "all_data.csv") if not os.path.exists(data_path): data = get_data.load_data( ) # [["Ticker", "close"]].groupby(["Ticker"]).T else: data = pd.read_csv(data_path) data_series = pd.pivot_table(data, index="datetime", columns="Ticker", values="close") # print(data_series.head()) mu = expected_returns.ema_historical_return(data_series) cov = risk_models.exp_cov(data_series) # plotting.plot_covariance(cov, plot_correlation=True) # print(mu, cov) ef = efficient_frontier.EfficientFrontier(mu, cov, weight_bounds=(0, 1)) ef.add_objective(objective_functions.L2_reg, gamma=1) ef.max_sharpe(0.02) weights_portfolio = ef.weights # ef.max_sharpe(risk_free_rate=0.002) # ef.max_sharpe() dict_keys = data_series.columns.values.tolist() # print(dict_keys) weights = {} for key, value in zip(dict_keys, weights_portfolio): # print(f"{key} - {value}") weights[key] = value # print("SORTED WEIGHTS") sorted_weights = dict( sorted(weights.items(), key=lambda item: item[1], reverse=True)) '''for key in sorted_weights.keys(): print(f"{key} - {sorted_weights[key]}") ''' cleaned_weights = { k: v for k, v in sorted_weights.items() if v > 10e-4 } with open(optimal_path, "w") as file: file.write(json.dumps(cleaned_weights)) # plt.pie(cleaned_weights.values(), labels=cleaned_weights.keys()) # plt.show() else: with open(optimal_path, "r") as file: cleaned_weights = json.loads(file.read()) return cleaned_weights
def optimize_max_sharpe(returns_df, lowerbound=0, upperbound=1): wb = (lowerbound, upperbound) ema_returns_df = ema_historical_return(prices_from_returns(returns_df)) returns_cov_df = returns_df.cov() EFOptimizer = EfficientFrontier(ema_returns_df, returns_cov_df, weight_bounds=wb) weights_dict = EFOptimizer.max_sharpe() return weights_dict
def optimMarkowitz(datatrain, datatest, pmin, pmax, optimmodel, returnmodel, riskmodel, Gam, rf): try: if returnmodel == 'historical': mu = expected_returns.mean_historical_return(datatrain) elif returnmodel == 'emahistorical': mu = expected_returns.ema_historical_return(datatrain) if riskmodel == 'historicalcov': S = risk_models.sample_cov(datatrain) elif riskmodel == 'exphistoricalcov': S = risk_models.exp_cov(datatrain) ef = EfficientFrontier(mu, S, weight_bounds=(pmin, pmax)) #gamma>0 permet de forcer l'optimiseur à utiliser plus de titres ef.add_objective(objective_functions.L2_reg, gamma=Gam) if optimmodel == 'min_volatility': ef.min_volatility() elif optimmodel == 'max_sharpe': ef.max_sharpe(risk_free_rate=rf) cleaned_weights = ef.clean_weights() #round and clean ... ef.save_weights_to_file( '/Users/Maxime/AMUNDI/PortMgmnt/ModulePyPortfolioOpt/OptimiseurProjet/weights.csv' ) # save to file perf = ef.portfolio_performance(verbose=True, risk_free_rate=rf) weightsfinal = pd.read_csv( '/Users/Maxime/AMUNDI/PortMgmnt/ModulePyPortfolioOpt/OptimiseurProjet/weights.csv', header=None) #For the following chart poids = weightsfinal.to_numpy() poids = poids[:, 1] RankedDataFrame = pd.DataFrame(index=datatest.index) for i, rows in weightsfinal.iterrows(): RankedDataFrame[rows[0]] = datatest[rows[0]] weightsfinal.rename(columns={ 0: ' Asset Class', 1: 'Poids' }, inplace=True) weightsfinal['Poids'] = round(weightsfinal['Poids'] * 100, 4) except ValueError: print('Le modèle spécifié est incorrect') return poids, RankedDataFrame, cleaned_weights, S, mu, perf
def get_weights(data, start_date, end_date, columns, n_threads=1, fixed='sharpe', value=0.05): """ :param data: DataFrame, Full data without missing values, columns are identifiers for different funds, index is datetime. :param start_date: str Start date to estimate mu and sigma. :param end_date: str End date to estimate mu and sigma. :param columns: list, ['id1', 'id2',..., 'idn'] Identifiers of funds to use to optimize. :param n_threads: int Number of threads. :param fixed: str, 'sharpe' or 'volatility' or 'return' Optimization constraints, defaults to 'sharpe'. :param value: float Optimization constraints. No need to set if fixed is 'sharpe', defaults to 0.05. :return: tuple, (float, float, float, dict) The closest answer given fixed constraints. (return, volatility, Sharpe ratio, weights) weights == {'id1':w1, 'id2':w2, ..., 'idn':wn} """ while start_date not in data.index: splits = start_date.split('-') y, m, d = int(splits[0]), int(splits[1]), int(splits[2]) start_date = (datetime.datetime(y, m, d) + datetime.timedelta(days=1)).strftime('%Y-%m-%d') while end_date not in data.index: splits = end_date.split('-') y, m, d = int(splits[0]), int(splits[1]), int(splits[2]) end_date = (datetime.datetime(y, m, d) + datetime.timedelta(days=-1)).strftime('%Y-%m-%d') # print(start_date) # print(end_date) subdata = data.loc[start_date:end_date, columns] optimizer = PortfolioOptimizer( expected_returns.ema_historical_return(subdata), risk_models.CovarianceShrinkage(subdata).ledoit_wolf()) optimizer.optimize(n_threads=n_threads) return optimizer.get_fixed_ans(fixed, value)
def test_bl_returns_all_views(): df = get_data() prior = expected_returns.ema_historical_return(df) S = risk_models.CovarianceShrinkage(df).ledoit_wolf() views = pd.Series(0.1, index=S.columns) bl = BlackLittermanModel(S, pi=prior, Q=views) posterior_rets = bl.bl_returns() assert isinstance(posterior_rets, pd.Series) assert list(posterior_rets.index) == list(df.columns) assert posterior_rets.notnull().all() assert posterior_rets.dtype == "float64" np.testing.assert_array_almost_equal( posterior_rets, np.array( [ 0.11774473, 0.1709139, 0.12180833, 0.21202423, 0.28120945, -0.2787358, 0.17274774, 0.12714698, 0.25492005, 0.11229777, 0.07182723, -0.01521839, -0.21235465, 0.06399515, -0.11738365, 0.28865661, 0.23828607, 0.12038049, 0.2331218, 0.10485376, ] ), )
def test_bl_returns_all_views(): df = get_data() prior = expected_returns.ema_historical_return(df) S = risk_models.CovarianceShrinkage(df).ledoit_wolf() views = pd.Series(0.1, index=S.columns) bl = BlackLittermanModel(S, pi=prior, Q=views) posterior_rets = bl.bl_returns() assert isinstance(posterior_rets, pd.Series) assert list(posterior_rets.index) == list(df.columns) assert posterior_rets.notnull().all() assert posterior_rets.dtype == "float64" np.testing.assert_array_almost_equal( posterior_rets, np.array( [ 0.11168648, 0.16782938, 0.12516799, 0.24067997, 0.32848296, -0.22789895, 0.16311297, 0.11928542, 0.25414308, 0.11007738, 0.06282615, -0.03140218, -0.16977172, 0.05254821, -0.10463884, 0.32173375, 0.26399864, 0.1118594, 0.22999558, 0.08977448, ] ), )
def cli(risk_free_rate, start, span, verbose, tickers): # Read in price data thelen = len(tickers) price_data = [] successful_tickers = [] for ticker in range(thelen): click.echo(tickers[ticker]) try: prices = web.DataReader(tickers[ticker], start=start, data_source='yahoo') if verbose >= 1: click.echo(tickers[ticker] + ':') click.echo(prices) price_data.append(prices.assign(ticker=ticker)[['Adj Close']]) successful_tickers.append(tickers[ticker]) except: pass df = pd.concat(price_data, axis=1) df.columns = successful_tickers df.head() #Checking if any NaN values in the data nullin_df = pd.DataFrame(df, columns=tickers) print(nullin_df.isnull().sum()) # Calculate expected returns and sample covariance mu = expected_returns.ema_historical_return(df, span=span) S = risk_models.sample_cov(df) # Optimise for maximal Sharpe ratio ef = EfficientFrontier( mu, S) #weight bounds in negative allows shorting of stocks raw_weights = ef.max_sharpe(risk_free_rate=risk_free_rate) cleaned_weights = ef.clean_weights() click.echo(cleaned_weights) ef.portfolio_performance(verbose=True)
def get_max_sharpe_recent_weights(self, exp_span, target_return=2.0): mu = expected_returns.ema_historical_return(self.pf, span=exp_span, frequency=252) sigma = risk_models.exp_cov(self.pf, span=exp_span, frequency=252) ef = EfficientFrontier(mu, sigma) try: # ef.efficient_return(target_return) ef.max_sharpe() clean_weights_maxSR = ef.clean_weights() print('the optimal weights for recent max_SR portfolio is \n{}'. format(clean_weights_maxSR)) ef.portfolio_performance(verbose=True) out = [] for weight in list(clean_weights_maxSR.values()): if weight == 0: out.append(0) else: out.append(weight) return out except: return [0] * len(self.stock_list)
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)
plt.show() fig.savefig("Markovitz' portfolio with maximum return.png") # Calculating weights for the minimum volatility portfolio raw_weights_minvol = ef.min_volatility() cleaned_weights_minvol = ef.clean_weights() # Showing portfolio performance print(cleaned_weights_minvol) ef.portfolio_performance(verbose=True) size = list(cleaned_weights_minvol.values()) print(size) plt.pie(size, labels=l, autopct='%1.1f%%') plt.title('Min Risk') plt.show() #Calculating an exponentially weighted portfolio Sigma_ew = risk_models.exp_cov(df, span=180, frequency=252) mu_ew = expected_returns.ema_historical_return(df, frequency=252, span=180) # Calculate the efficient frontier ef_ew = EfficientFrontier(mu_ew, Sigma_ew) # Calculate weights for the maximum sharpe ratio optimization raw_weights_maxsharpe_ew = ef_ew.max_sharpe() # Show portfolio performance ef_ew.portfolio_performance(verbose=True) size = list(raw_weights_maxsharpe_ew.values()) print(size) plt.pie(size, labels=l, autopct='%1.1f%%') plt.title('Max Return EW') plt.show()
def efficient_frontier_data_layout(id_list): # 模拟用户选择基金 # id_list = list(adjusted_net_value.columns) # id_list = random.sample(id_list, 20) best_frontier = optimizer.efficient_frontier('all') vol_list = best_frontier[1] + fix_random_data[1] ret_list = best_frontier[0] + fix_random_data[0] sharp_ratio_list = best_frontier[2] + fix_random_data[2] trace = [] if id_list is None: trace.append( go.Scatter(x=best_frontier[1], y=best_frontier[0], opacity=0.75, hoverinfo='text', text=get_text_info(best_frontier), mode='lines', line={'color': 'red'}, name='Best recommend')) trace.append( go.Scatter(x=vol_list, y=ret_list, opacity=0.75, hoverinfo='skip', mode='markers', marker={ 'color': sharp_ratio_list, 'colorscale': 'Viridis', }, showlegend=False)) else: choose_data_value = adjusted_net_value[id_list] op = PortfolioOptimizer( expected_returns.ema_historical_return(choose_data_value), risk_models.CovarianceShrinkage(choose_data_value).ledoit_wolf()) op.optimize() all_risk = op.get_all_ans()[2] mid_risk = (all_risk[0] + all_risk[-1]) / 2 _, _, _, choose_weights = op.get_fixed_ans(fixed='volatility', value=mid_risk) choose_data = op.get_random_samples(choose_weights) choose_frontier = op.efficient_frontier(id_list) best_start = 30 if len(id_list) < 40 else 0 best_frontier = [x[best_start:] for x in best_frontier] trace.append( go.Scatter(x=best_frontier[1], y=best_frontier[0], opacity=0.75, hoverinfo='text', text=get_text_info(best_frontier), mode='lines', line={'color': 'red'}, name='Best recommend')) trace.append( go.Scatter(x=choose_frontier[1], y=choose_frontier[0], opacity=0.75, hoverinfo='text', text=get_text_info(choose_frontier), mode='lines', line={'color': 'green'}, customdata=choose_frontier[3], name='Your choice')) trace.append( go.Scatter(x=choose_data[1], y=choose_data[0], opacity=0.75, hoverinfo='skip', mode='markers', marker={ 'color': choose_data[2], 'colorscale': 'Viridis', }, showlegend=False)) return { 'data': trace, 'layout': { 'legend': { 'x': -0.01 }, 'title': { 'text': 'Efficient Frontier', }, 'xaxis': { 'title': 'Annualised Volatility', 'tickformat': '%' }, 'yaxis': { 'title': 'Annualised returns', 'tickformat': '%' }, 'hovermode': 'closest' } }
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()
def create_xl_EFPortfolio(df, lb, ub, resample_rule): dfReSample = create_epochs(df, resample_rule) """ # Create a dictionary of time periods (or 'epochs') epochs = { '0' : {'start': '1-1-2005', 'end': '31-12-2006'}, '1' : {'start': '1-1-2007', 'end': '31-12-2008'}, '2' : {'start': '1-1-2009', 'end': '31-12-2010'} } """ epochs = dfReSample.to_dict('index') # Compute the efficient covariance for each epoch e_return = {} e_cov = {} efficient_portfolio = {} liW = [] liR = [] for x in epochs.keys(): period = df.loc[epochs[x]['start']:epochs[x]['end']] j = (x + 1) / len(epochs.keys()) sys.stdout.write('\r') sys.stdout.write("[%-20s] %d%%" % ('=' * int(20 * j), 100 * j)) sys.stdout.flush() try: # Compute the annualized average (mean) historical return # mu = expected_returns.mean_historical_return(period)#, frequency = 252) mu = expected_returns.ema_historical_return(period, frequency=252, span=500) # Compute the efficient covariance matrix Sigma = risk_models.CovarianceShrinkage(period).ledoit_wolf() # Initialize the Crtical Line Algorithm object efficient_portfolio[x] = CLA(mu, Sigma, weight_bounds=(lb, ub)) efficient_portfolio[x].max_sharpe() # min_volatility() cleaned_weights = efficient_portfolio[x].clean_weights() e_return[x] = mu e_cov[x] = Sigma liW.append(pd.DataFrame({'epochs': x, 'weights': cleaned_weights})) liR.append(pd.DataFrame({'epochs': x, 'returns': mu})) except Exception as e: sys.stdout.write('\r') sys.stdout.write('%s%s %s%s%s\n' % ('#', x, 'error:', epochs[x], e)) dfWeightsEF = pd.concat(liW) dfWeightsEF.reset_index(inplace=True) dfWeightsEF.columns = ['asset', 'epochs', 'weights'] dfWeightsEF = dfWeightsEF.pivot(index='epochs', columns='asset', values='weights') dfReturnsEF = pd.concat(liR) dfReturnsEF.reset_index(inplace=True) dfReturnsEF.columns = ['asset', 'epochs', 'returns'] dfReturnsEF = dfReturnsEF.pivot(index='epochs', columns='asset', values='returns') dfWeightsEF.to_excel(r"weightsEF.xlsx") dfReturnsEF.to_excel(r"returnsEF.xlsx") dfReturns = df.pct_change().dropna() dfNAV = pd.merge(dfWeightsEF, dfReSample, left_index=True, right_index=True) dfNAV = dfNAV.drop(columns=['start']) dfNAV.set_index('end', inplace=True) dfNAV.index.names = ['DATE'] dfNAV = dfNAV.resample('D').ffill() dfNAV = dfNAV.loc[dfNAV.index.isin(dfReturns.index.tolist())] dfReturns = dfReturns.loc[dfReturns.index.isin(dfNAV.index.tolist())] dfNAV['RET'] = (dfNAV.values * dfReturns.values).sum(axis=1).tolist() dfNAV['NAV'] = (1 + dfNAV['RET']).cumprod() dfNAV = pd.merge(dfNAV, dfReturns, left_index=True, right_index=True, suffixes=('_weight', '_return')) dfNAV.to_excel(r"navEF.xlsx") return
raw_weights_maxsharpe = ef.max_sharpe() cleaned_weights_maxsharpe = ef.clean_weights() print(raw_weights_maxsharpe, cleaned_weights_maxsharpe) # Calculate weights for the minimum volatility portfolio raw_weights_minvol = ef.min_volatility() cleaned_weights_minvol = ef.clean_weights() # Show portfolio performance print(cleaned_weights_minvol) ef.portfolio_performance(verbose=True) # Define exponentially weightedSigma and mu using stock_prices Sigma = risk_models.exp_cov(stock_prices, span=180, frequency=252) mu = expected_returns.ema_historical_return(stock_prices, frequency=252, span=180) # Calculate the efficient frontier ef = EfficientFrontier(mu, Sigma) # Calculate weights for the maximum sharpe ratio optimization raw_weights_maxsharpe = ef.max_sharpe() # Show portfolio performance ef.portfolio_performance(verbose=True) # datacamp hack import inspect print(inspect.getsource(function))
def test_ema_historical_return_frequency(): df = get_data() mean = expected_returns.ema_historical_return(df) mean2 = expected_returns.ema_historical_return(df, frequency=52) np.testing.assert_array_almost_equal(mean / 252, mean2 / 52)
elif 'daily_profit' in tdata.columns and not np.isnan( tdata['daily_profit']).all(): # 日结 data_list.append( (tdata[['daily_profit']] / 10000 + 1).cumprod(axis=1).rename(columns={ 'daily_profit': filename[0:6] }, index=str).astype('float')) else: print("BAD file: " + filename) data = pd.concat(data_list, axis=1) print(data.info()) # efficient frontier mu = expected_returns.ema_historical_return(data) print(np.isnan(mu).any()) S = risk_models.CovarianceShrinkage(data).ledoit_wolf() print(np.isnan(S).any().any()) ef = EfficientFrontier(mu, S) if args.volatility < 0: print(ef.max_sharpe(args.risk_free_rate)) else: print(ef.efficient_risk(args.volatility, args.risk_free_rate)) ef.portfolio_performance(True) print(str(time() - start) + " s")