class getData(): def __init__(self): self.engine = create_engine('postgresql://*****:*****@localhost:5432/nyse_financials') self.api = al.alpaca2Login().getApi() self.fin_db = "financials" self.earnings_db = "earning_dates" self.sentiment_db = "sentiment" self.nothingToGet = True self.db = Database() # df = pd.DataFrame() def get_bars(self, symbol, interval, limit, after): # print(after.isoformat()) data = self.api.get_barset(symbol, interval, limit, after=after.isoformat()) data = data.df[symbol] print(data) return data def get_sentiment(self, days_before=0, days_after=30): from stocknews import StockNews self.get_sentiment_from_csv() symbols = self.db.get_symbols() # print(symbols) sn = StockNews(symbols, wt_key='0d57e2849d73713e95f395c7440380ff') df_sum, r_count = sn.summarize() print("rows: " + str(r_count)) self.save_sentiment(df_sum) print("get sentiment ends") # print(df_new) return df_sum def get_sentiment_from_csv(self): df = pd.read_csv("./data/data.csv", sep=";") print(df) self.save_sentiment(df) def save_sentiment(self, df_sum): """[summary] !!!! WARNING this method ends with exiting whole script Args: df_sum ([type]): [description] """ try: dfdb = pd.read_sql(self.sentiment_db, con=self.engine) df_new = df_sum.append(dfdb, ignore_index=True) except: df_new = df_sum print("Database sentiment doesnt exists") try: df_new.drop(columns=['index','open','close','high','low','volume','change'], inplace=True) except KeyError : print("some columns to drop hasnt been found") df_new.drop_duplicates( subset=["id","stock", "news_dt"], inplace=True, keep="first") df_new.to_sql(self.sentiment_db, con=self.engine, if_exists='replace', index=True) print("Sentiment saved") exit() # return df_new def get_earnings(self, days_before = 0, days_after = 30): from yahoo_earnings_calendar import YahooEarningsCalendar dfdb = pd.read_sql(self.earnings_db, con=self.engine) yec = YahooEarningsCalendar() dfd = pd.DataFrame(yec.earnings_between( datetime.now() - timedelta(days=days_before), datetime.now() + timedelta(days=days_after))) df_new = dfd.append(dfdb, ignore_index=True) df_new.drop_duplicates(subset=["ticker","startdatetime","startdatetimetype"], inplace=True, keep="first") #save DATAFRAME to database df_new.to_sql(self.earnings_db, con=self.engine, if_exists='replace', index=False) print(df_new) return df_new # def convertUnixTimeToDate(columns,df): # for col in columns: # df[col] = pd.to_datetime(df[col],unit="s") # return df def fill_database(self, dfs,interval, limit, table_name, after): self.nothingToGet = True for row in dfs['Symbol']: if row: row = str.strip(row) print(row) # check last date for specific symbol dfp = pd.read_sql('select MAX("index") as last_time from '+ table_name + ' where sym = \'' + row + '\' ', con=self.engine) if dfp.iloc[0].last_time is not None: after = dfp.iloc[0].last_time # get data from ALPACA df = self.get_bars(row, interval, limit, after) if len(df) > 0: self.nothingToGet = False # add symbol df["sym"] = row #add sector # dff = pd.read_sql('select sector from '+ self.fin_db + ' where symbol = \'' + row + '\' and sector is not null limit 1', con=self.engine) # if len(dff) > 0 and dff.iloc[0].sector: # df["sector"] = dff.iloc[0].sector df.index.rename('index', inplace = True) #save DATAFRAME to database df.to_sql(table_name, con=self.engine, if_exists='append', index = True) if table_name == TableName.MIN15: self.save_bar_as_last_in_day(df) def get_last_working_day(self): offset = max(0, (datetime.today().weekday() + 6) % 7 - 3) timedelta2 = timedelta(offset) # most_recent = datetime.today().replace(hour=0, minute=0, second=0, microsecond=0) - timedelta2 most_recent = datetime.today() - timedelta2 return most_recent def save_bar_as_last_in_day(self,last_bar:pd.DataFrame): last_day = self.db.get_last_n_days( sym=last_bar.iloc[-1].sym, n_days_back=1, table=TableName.DAY) last_day.iloc[-1].close = last_bar.iloc[-1].close last_day.iloc[-1].high = last_day.iloc[-1].high if last_day.iloc[-1].high > last_bar.iloc[-1].high else last_bar.iloc[-1].high last_day.iloc[-1].low = last_day.iloc[-1].low if last_day.iloc[-1].low < last_bar.iloc[-1].low else last_bar.iloc[-1].low last_day.to_sql(TableName.DAY, con=self.engine, if_exists='replace', index=False) # param interval could be 1,5,15, 0 - for day def start_download(self, min_interval, start_date, infinity = False): dfs = pd.read_csv("./datasets/RevolutStock.csv", delimiter="|") print(start_date) min_interval = int(min_interval) if min_interval > 0: db_name = 'p_'+ str(min_interval) +'min' else: db_name = 'p_day' while True: try: if min_interval > 0: self.fill_database(dfs,str(min_interval) + "Min",1000, 'p_'+ str(min_interval) +'min', start_date) else: self.fill_database(dfs,"day",1000, 'p_day', start_date) if infinity and self.nothingToGet: break Utils.countdown(60) except KeyboardInterrupt: print("END by keybord interruption") exit() except: print("Unexpected error:", sys.exc_info()[0]) print("Waiting 3 minutes and try it again") Utils.countdown(60) print("DONE")
class RunData(): selected_stock = None timetick = None time_from = None time_to = None selected = {} action_type = None types = ["sector-stats", "stock-detail", "stocks-stats"] sw = StockWhisperer() inday_days = 2 def __init__(self): self.db = Database() self.symbols = self.db.get_symbols(TableName.DAY) self.sectors = self.db.get_sectors(TableName.DAY) self.sm = StockMess() self.ss = SectorStats() self.app = self.get_home_page() self.submit = None # self.fig = None # print(self.df) # def load_data(self, option, time_from = "-180d", time_to = None): # df = self.db.load_data( # "p_day", symbols=option, time_from=time_from, time_to = time_to) # df = FinI.add_indicators(sdf.retype(df)) # return df def testing_mess(self): self.sm.stocks = self.db.load_data( table_name=TableName.DAY, symbols=["PLUG"], time_from=self.time_from, time_to=self.time_to, ) self.sm.get_subj_mess("Base Fund: ", "PLUG") def get_home_page(self): query_params = st.experimental_get_query_params() if len(query_params) > 0 and query_params.get("type")[0] == "detail": st.set_page_config(initial_sidebar_state="collapsed", page_title=query_params.get("sym")[0], layout="wide") else: st.set_page_config(layout="wide") self.hide_footer() self.left_menu() # self.testing_mess() self.action_router(query_params) async def prepare_detail_tasks(self, sym=None): tasks = [] tasks.append(asyncio.ensure_future(self.get_price_detail(sym=sym))) tasks.append(asyncio.ensure_future( self.get_inday_price_graph(sym=sym))) tasks.append(asyncio.ensure_future(self.get_fund_detail(sym=sym))) await asyncio.gather(*tasks, return_exceptions=True) def left_menu(self): self.time_from = st.sidebar.text_input("Time from now -1m, -1h, -1d,", value="-120d") self.time_to = st.sidebar.text_input("Time to 1m, 1h, 1d,") self.selected_sector = st.sidebar.selectbox('Select sector', self.sectors) self.selected_stock = st.sidebar.selectbox('Select stock', self.symbols) self.inday_days = st.sidebar.number_input('inday chart days', value=2) if self.selected_stock == 0: self.selected_stock = "TSLA" # loop = asyncio.get_event_loop() # task = None # try: # task = loop.create_task(self.watch()) # except KeyboardInterrupt: # task.cancel() # print('after async') # st.sidebar.text_area("websocket",self.timetick) # self.action_type = st.sidebar.selectbox( # 'Seeect Type', # self.types) # self.submit = st.sidebar.button("Submit", "submit") def action_router(self, query_params=None): if st.sidebar.button('stock-detail') or ( len(query_params) > 0 and query_params.get("type")[0] == "detail"): asyncio.new_event_loop().run_until_complete( self.prepare_detail_tasks(sym=query_params.get("sym")[0] if len(query_params) > 0 else None)) if st.sidebar.button('top-sectors'): self.top_sectors(time_from=self.time_from, time_to=self.time_to) if st.sidebar.button('top-industries'): self.top_sectors(time_from=self.time_from, time_to=self.time_to, is_industries=True) if st.sidebar.button('top-stocks'): self.top_stocks(time_from=self.time_from, time_to=self.time_to) if st.sidebar.button('bottom-stocks'): self.top_stocks(time_from=self.time_from, time_to=self.time_to, ascending=True) if st.sidebar.button("find-stocks-to-buy"): self.find_stocks_to_buy() if st.sidebar.button("Last-Financials"): self.last_financials() def last_financials(self): df = self.db.get_last_financials() df.dropna(inplace=True, axis='columns', how="all") df.drop(columns=['zip','city','phone','longBusinessSummary','companyOfficers','maxAge','address1','previousClose', \ 'regularMarketOpen','regularMarketDayHigh','navPrice','totalAssets','regularMarketPreviousClose','open','yield', \ 'priceHint', 'currency', 'dayLow', 'ask', 'askSize','website','longName', \ 'exchange'], inplace=True) df.set_index(df.symbol, inplace=True) st.dataframe(df, height=2000) def find_stocks_to_buy(self): st.title("Stocks to buy") self.sw.time_from = self.time_from if self.sectors is not None: self.sw.sectors = [self.sectors] self.sw = StockWhisperer() try: output = self.sw.find_stocks(TableName.DAY, False) except KeyboardInterrupt: st.write("stopped by keyboard") stocks = output[[ "close", "open", "high", "low", "volume", "amount", "flpd", "sym" ]] # print(stocks) self.print_stocks_list(stocks, True, from_top=0, show_stocks_num=50) def show_sectors(self, stocks, is_industries=False): fig = px.bar(stocks, y='flpd', x=stocks.index) # fig.update_traces(texttemplate=stocks.sector, textposition='inside') fig.update_layout(uniformtext_minsize=8, uniformtext_mode='hide', barmode='group') st.plotly_chart( fig, use_container_width=True, use_container_height=True, template="plotly_dark", ) # st.bar_chart(stocks) def top_sectors(self, ascending=False, time_from=None, time_to=None, is_industries=False): # st.write(time_to) # st.write(time_from) title = "Top industries" if is_industries else "Top sectors" separator = " | " st.title(title + str(time_from)) if not time_from: time_from = "-7d" table = TableName.DAY if time_from.find("m") > -1 or time_from.find("m") > -1: table = TableName.MIN15 stocks = self.ss.classify_sectors_uptrend(table_name=table, time_from=time_from, time_to=time_to, from_db=True, is_industries=is_industries, separator=separator) if stocks is not None and len(stocks) > 0: stocks = stocks.sort_values(by='flpd', ascending=ascending) stocks.drop( columns=["close", "open", "high", "low", "volume", "amount"], inplace=True) self.show_sectors(stocks, is_industries=is_industries) for idx, row in stocks.iterrows(): st.write(str(idx) + ": " + str(round(row.flpd, 2)) + "%") self.top_stocks(group=idx, ascending=ascending, time_from=time_from, time_to=time_to, table=table, is_industries=is_industries, separator=separator) else: st.write("No data") def top_stocks(self, group=None, ascending=False, time_from=None, time_to=None, table=None, from_top=0, show_stocks_num=20, is_industries=False, separator=None): st.empty() table = TableName.DAY if time_from.find("m") > -1: table = TableName.MIN15 subject = "Loosers: " if ascending else "Gainers: " if isinstance(group, str): industry = str.split(group, separator) group = industry[1] if len(industry) > 1 else industry[0] group = [group] if is_industries: stocks = self.db.load_data( table_name=table, industries=group, time_from=time_from, time_to=time_to, ) else: stocks = self.db.load_data( table_name=table, sectors=group, time_from=time_from, time_to=time_to, ) # self.stocks = FinI.add_change(self.stocks) stocks = Utils.add_first_last_perc_diff(stocks) self.print_stocks_list(stocks, ascending, from_top=from_top, show_stocks_num=show_stocks_num) def print_stocks_list(self, stocks, ascending, from_top=0, show_stocks_num=20): if stocks is not None and len(stocks) > 0: stocks = stocks.groupby(by="sym").mean() stocks = stocks.sort_values(by='flpd', ascending=ascending) top_stocks = stocks.iloc[from_top:(from_top + show_stocks_num)] top_stocks = self.fill_with_mess(top_stocks) reduced_top_stocks = top_stocks.drop( columns=["open", "high", "low", "amount"]) reduced_top_stocks["detail"] = '<a href="/?type=detail&sym=' + \ reduced_top_stocks.index + '" target="_blank"> ' + \ reduced_top_stocks.index + '</a>' reduced_top_stocks["news"] = '<a href="https://finance.yahoo.com/quote/' + \ reduced_top_stocks.index + '" target="_blank"> yahoo </a>' reduced_top_stocks["rating"] = '<a href="https://zacks.com/stock/quote/' + \ reduced_top_stocks.index + '" target="_blank"> zacks </a>' st.write(reduced_top_stocks.to_html(escape=False, index=False), unsafe_allow_html=True) # selected_indices = st.multiselect('Select rows:', stocks.index) # selected_rows = stocks.loc[selected_indices] # self.top_stocks_list = top_stocks.index.tolist() # self.draw_chart_values(top_stocks) #send_mails # asyncio.run(self.sm.mail_stats(top_stocks, subject)) else: print('No stocks has been found') def fill_with_mess(self, stocks): mess_block = [] for index, row in stocks.iterrows(): self.sm.set_fundamentals(index) # st.write(index) mess, curr_price, days_to_earnings = self.sm.get_subj_mess( "", index) mess_block.append(mess) # print(stocks.loc[index]) stocks["fund"] = mess_block return stocks def set_time_to(self): if self.time_from is None: time_from = "-180d" else: time_from = self.time_from return time_from async def get_inday_price_graph(self, sym=None): if sym is None: sym = self.selected_stock inday_df = self.db.get_last_n_days(sym, n_days_back=self.inday_days, table=TableName.MIN15) inday_df = FinI.add_indicators(sdf.retype(inday_df)) await self.inday_price_graph(sym, inday_df) async def get_price_detail(self, sym=None): if sym is None: sym = self.selected_stock time_from = self.set_time_to() df = self.db.load_data( table_name=TableName.DAY, symbols=sym, time_from=time_from, time_to=self.time_to, ) m_df_spy = self.db.load_data(table_name=TableName.DAY, time_from=time_from, time_to=self.time_to, symbols=["SPY"]) m_df_spy["oc_mean"] = (m_df_spy.close + m_df_spy.open) / 2 # self.stocks = FinI.add_change(self.stocks) df = FinI.add_indicators(sdf.retype(df)) await self.price_graph(sym, df, m_df_spy=m_df_spy) # self.macd_rsi_graph(option, df) self._max_width_() # await asyncio.sleep(0.001) async def get_fund_detail(self, sym=None): if sym is None: sym = self.selected_stock self.sm.set_fundamentals(sym) time_from = self.set_time_to() self.sm.stocks = self.db.load_data( table_name=TableName.DAY, symbols=sym, time_from=time_from, time_to=self.time_to, ) mess, curr_price, days_to_earnings = self.sm.get_subj_mess( "Base Fund: ", sym) st.write(mess) await st.write( self.sm.get_fund_mess(self.sm.financials, curr_price, self.sm.earnings, self.sm.sentiment, days_to_earnings, self.sm.stocks)) def macd_rsi_graph(self, option, df): data = PlotP.plot_rsi(df, ax="y") data += PlotP.plot_macd_boll(df=df, ax="y2") fig = go.Figure(data=data) fig.update_layout(autosize=True, height=400, yaxis=dict(title="RSI", titlefont=dict(color="green"), tickfont=dict(color="green")), yaxis2=dict(title="macd", titlefont=dict(color="#8888ff"), tickfont=dict(color="#8888ff"), anchor="free", overlaying="y", side="left", position=0)) # Create figure with secondary y-axis st.plotly_chart(fig, use_container_width=True) def gainers(self): pass def hide_footer(self): hide_streamlit_style = """ <style> #MainMenu {visibility: visible;} footer {visibility: hidden;} </style> """ st.markdown(hide_streamlit_style, unsafe_allow_html=True) # def sector_stats(self, time_from, time_to, loosers): # stocks = self.ss.classify_sectors_uptrend(table_name =TableName.DAY) # stocks = stocks.sort_values(by='flpd', ascending=loosers) # if False: # self.sw.sectors = [self.sw.stocks.iloc[:-1].index[0]] # self.sw.top_stocks(table_name=None, top_losers=loosers) def inday_price_graph(self, option, df, ax="y2"): st.write("In day chart: -" + str(self.inday_days) + "d") sets = [{ 'x': df["index"], 'open': df.open, 'close': df.close, 'high': df.high, 'low': df.low, 'yaxis': ax, "hovertext": "", 'type': 'candlestick' }] sets += [{ 'x': df["index"], 'y': df.boll, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 1, 'color': 'green' }, 'name': 'Boll' }] sets += [{ 'x': df["index"], 'y': df.boll + df.boll_2, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 0.3, 'color': 'green', "dash": "dot" }, 'name': '-' }] sets += [{ 'x': df["index"], 'y': df.boll + df.boll_3, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 0.3, 'color': 'green', "dash": "dot" }, 'name': '-' }] # sets += [{'x': df["index"], 'y': df.boll + df.boll_5, 'yaxis': ax, 'type': 'scatter', # 'mode': 'lines', 'line': {'width': 0.3, 'color': 'green'}, 'name': '-'}] sets += [{ 'x': df["index"], 'y': df.boll + df.boll_6, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 0.3, 'color': 'green', "dash": "dot" }, 'name': '-' }] sets += [{ 'x': df["index"], 'y': df.boll - df.boll_2, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 0.3, 'color': 'green', "dash": "dot" }, 'name': '-' }] sets += [{ 'x': df["index"], 'y': df.boll - df.boll_3, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 0.3, 'color': 'green', "dash": "dot" }, 'name': '-' }] # sets += [{'x': df["index"], 'y': df.boll - df.boll_5, 'yaxis': ax, 'type': 'scatter', # 'mode': 'lines', 'line': {'width': 0.3, 'color': 'green'}, 'name': '-'}] sets += [{ 'x': df["index"], 'y': df.boll - df.boll_6, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 0.3, 'color': 'green', "dash": "dot" }, 'name': '-' }] sets += [{ 'x': df["index"], 'y': df.boll_ub, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 1, 'color': 'green' }, 'name': 'Boll UP' }] sets += [{ 'x': df["index"], 'y': df.boll, 'yaxis': ax, 'type': 'scatter', "fill": 'tonexty', 'line': { 'width': 0, }, "fillcolor": 'rgba(128, 255, 128,0.2)' }] sets += [{ 'x': df["index"], 'y': df.boll_lb, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 1, 'color': 'green' }, 'name': 'Boll Down' }] sets += [{ 'x': df["index"], 'y': df.boll, 'yaxis': ax, 'type': 'scatter', "fill": 'tonexty', 'line': { 'width': 0, }, "fillcolor": 'rgba(128, 255, 128,0.2)' }] sets += [{ 'x': df["index"], 'y': df.sma9, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 1, 'color': 'blue' }, 'name': 'sma9' }] sets += [{ 'x': df["index"], 'y': df.sma50, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 1, 'color': 'darkblue' }, 'name': 'sma50' }] sets += [{ 'x': df["index"], 'y': df.sma100, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 1, 'color': 'orange' }, 'name': 'sma100' }] df = FinI.add_levels(df) for i, r in df.iterrows(): if r.price_level is not None: sets += [{ 'x': [r["index"], df.iloc[-1]["index"]], 'y': [r.price_level, r.price_level], 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 1, 'color': 'brown', "dash": "dot" }, 'name': '' }] # print(levels) # sets += [{'x': df["index"], 'y': df.price_level, 'yaxis': ax, 'type': 'scatter', # 'mode': 'lines', 'line': {'width': 1, 'color': 'orange'}, 'name': 'sma100'}] # data += PlotP.plot_rsi(df, ax="y2") # data += PlotP.plot_macd_boll(df=df, ax="y3") # st.area(df, x=df["index"], y=df.boll, color="continent", # line_group="country") # fig = go.Figure(data=sets) fig = make_subplots(rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.009, horizontal_spacing=0.009, row_width=[0.1, 0.5], specs=[[{ "secondary_y": True }], [{ "secondary_y": True }]]) fig.add_traces(data=sets, cols=1, rows=1) # data = PlotP.plot_rsi(df, ax="y") # fig.add_traces(data, 3, 1) # data = PlotP.plot_macd_boll(df=df, ax="y2") # fig.add_traces(data, 3, 1) df.loc[df.open > df.close, "vol_color"] = "red" df.loc[df.open <= df.close, "vol_color"] = "green" # print(df.vol_color) fig.add_trace( { 'x': df["index"], 'y': df.volume, 'type': 'bar', 'name': 'Volume', 'marker_color': df.vol_color }, 2, 1, secondary_y=False, ) # fig['layout']['margin'] = {'l': 30, 'r': 10, 'b': 50, 't': 25} fig.update_yaxes(showgrid=True, zeroline=False, showticklabels=True, showspikes=True, spikemode='across', spikesnap='cursor', showline=True, spikedash='dash', spikethickness=0.5) fig.update_xaxes(showgrid=True, zeroline=False, rangeslider_visible=False, showticklabels=True, showspikes=True, showline=True, spikemode='across', spikesnap='cursor', spikedash='dash', spikethickness=0.5) fig.update_layout(autosize=True, height=600, hoverdistance=1, hovermode='y', spikedistance=10000) st.plotly_chart( fig, use_container_width=True, use_container_height=True, template="plotly_dark", ) # st.line_chart(df.close) def price_graph(self, option, df, m_df_spy=None, ax="y2"): st.write("Days chart: " + str(self.time_from)) sets = [{ 'x': df.index, 'open': df.open, 'close': df.close, 'high': df.high, 'low': df.low, 'yaxis': ax, "hovertext": "", 'type': 'candlestick' }] sets += [{ 'x': df.index, 'y': df.boll, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 1, 'color': 'green' }, 'name': 'Boll' }] sets += [{ 'x': df.index, 'y': df.boll + df.boll_2, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 0.3, 'color': 'green', "dash": "dot" }, 'name': '-' }] sets += [{ 'x': df.index, 'y': df.boll + df.boll_3, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 0.3, 'color': 'green', "dash": "dot" }, 'name': '-' }] # sets += [{'x': df.index, 'y': df.boll + df.boll_5, 'yaxis': ax, 'type': 'scatter', # 'mode': 'lines', 'line': {'width': 0.3, 'color': 'green'}, 'name': '-'}] sets += [{ 'x': df.index, 'y': df.boll + df.boll_6, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 0.3, 'color': 'green', "dash": "dot" }, 'name': '-' }] sets += [{ 'x': df.index, 'y': df.boll - df.boll_2, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 0.3, 'color': 'green', "dash": "dot" }, 'name': '-' }] sets += [{ 'x': df.index, 'y': df.boll - df.boll_3, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 0.3, 'color': 'green', "dash": "dot" }, 'name': '-' }] # sets += [{'x': df.index, 'y': df.boll - df.boll_5, 'yaxis': ax, 'type': 'scatter', # 'mode': 'lines', 'line': {'width': 0.3, 'color': 'green'}, 'name': '-'}] sets += [{ 'x': df.index, 'y': df.boll - df.boll_6, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 0.3, 'color': 'green', "dash": "dot" }, 'name': '-' }] sets += [{ 'x': df.index, 'y': df.boll_ub, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 1, 'color': 'green' }, 'name': 'Boll UP' }] sets += [{ 'x': df.index, 'y': df.boll, 'yaxis': ax, 'type': 'scatter', "fill": 'tonexty', 'line': { 'width': 0, }, "fillcolor": 'rgba(128, 255, 128,0.2)' }] sets += [{ 'x': df.index, 'y': df.boll_lb, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 1, 'color': 'green' }, 'name': 'Boll Down' }] sets += [{ 'x': df.index, 'y': df.boll, 'yaxis': ax, 'type': 'scatter', "fill": 'tonexty', 'line': { 'width': 0, }, "fillcolor": 'rgba(255, 128, 128,0.2)' }] sets += [{ 'x': df.index, 'y': df.sma9, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 1, 'color': 'blue' }, 'name': 'sma9' }] sets += [{ 'x': df.index, 'y': df.sma50, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 1, 'color': 'darkblue' }, 'name': 'sma50' }] sets += [{ 'x': df.index, 'y': df.sma100, 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 1, 'color': 'orange' }, 'name': 'sma100' }] df = FinI.add_levels(df) for i, r in df.iterrows(): if r.price_level is not None: sets += [{ 'x': [i, df.iloc[-1].name], 'y': [r.price_level, r.price_level], 'yaxis': ax, 'type': 'scatter', 'mode': 'lines', 'line': { 'width': 1, 'color': 'brown', "dash": "dot" }, 'name': '' }] # print(levels) # sets += [{'x': df.index, 'y': df.price_level, 'yaxis': ax, 'type': 'scatter', # 'mode': 'lines', 'line': {'width': 1, 'color': 'orange'}, 'name': 'sma100'}] # data += PlotP.plot_rsi(df, ax="y2") # data += PlotP.plot_macd_boll(df=df, ax="y3") # st.area(df, x=df.index, y=df.boll, color="continent", # line_group="country") # fig = go.Figure(data=sets) fig = make_subplots(rows=3, cols=1, shared_xaxes=True, vertical_spacing=0.009, horizontal_spacing=0.009, row_width=[0.2, 0.1, 0.5], specs=[[{ "secondary_y": True }], [{ "secondary_y": True }], [{ "secondary_y": True }]]) fig.add_traces(data=sets, cols=1, rows=1) if m_df_spy is not None: fig.add_trace( { 'x': m_df_spy.index, 'y': m_df_spy.oc_mean, 'type': 'scatter', 'yaxis': "y", 'mode': 'lines', 'line': { 'width': 1, 'color': 'red' }, 'name': 'SPY' }, 1, 1, secondary_y=True, ) # data = PlotP.plot_rsi(df, ax="y") # fig.add_traces(data, 3, 1) mb = PlotP.plot_macd_boll(df=df, ax="y") fig.add_traces( data=mb, rows=3, cols=1, ) rsi = PlotP.plot_rsi(df=df, ax="y3") fig.add_traces(data=rsi, rows=3, cols=1, secondary_ys=[True, True, True, True, True]) df.loc[df.open > df.close, "vol_color"] = "red" df.loc[df.open <= df.close, "vol_color"] = "green" # print(df.vol_color) fig.add_trace( { 'x': df.index, 'y': df.volume, 'type': 'bar', 'name': 'Volume', 'marker_color': df.vol_color }, 2, 1, secondary_y=False, ) # fig['layout']['margin'] = {'l': 30, 'r': 10, 'b': 50, 't': 25} fig.update_yaxes(showgrid=True, zeroline=False, showticklabels=True, showspikes=True, spikemode='across', spikesnap='cursor', showline=True, spikedash='dash', spikethickness=0.5) fig.update_xaxes(showgrid=True, zeroline=False, rangeslider_visible=False, showticklabels=True, showspikes=True, showline=True, spikemode='across', spikesnap='cursor', spikedash='dash', spikethickness=0.5) fig.update_layout( autosize=True, height=600, hoverdistance=1, hovermode='y', spikedistance=10000, ) st.plotly_chart( fig, use_container_width=True, use_container_height=True, template="plotly_dark", ) # st.line_chart(df.close) def _max_width_(self): max_width_str = f"max-width: 2000px;max-height:1000px;" st.markdown( f""" <style> .reportview-container .main .block-container{{ {max_width_str} }} </style> """, unsafe_allow_html=True, )