def futures_command(): """Futures [Yahoo Finance]""" # Debug user input if imps.DEBUG: logger.debug("futures") # Retrieve data req = pd.read_html( requests.get( "https://finance.yahoo.com/commodities", headers={ "User-Agent": get_user_agent() }, ).text) df = req[0] # Check for argument if df.empty: raise Exception("No available data found") title = "Futures [yfinance]" df["Last Price"] = pd.to_numeric(df["Last Price"].astype(float)) df["Change"] = pd.to_numeric(df["Change"].astype(float)) formats = { "Last Price": "${:.2f}", "Change": "${:.2f}", } for col, value in formats.items(): df[col] = df[col].map(lambda x: value.format(x)) # pylint: disable=W0640 df = df.fillna("") df["Change"] = df.apply( lambda x: f"{x['Change']} (<b>{x['% Change']}</b>)", axis=1) df.drop(columns="Symbol") df = df.rename(columns={"Name": " "}) df.set_index(" ", inplace=True) df = df[["Last Price", "Change"]] font_color = ["white"] * 2 + [[ "#e4003a" if boolv else "#00ACFF" for boolv in df["Change"].str.contains("-") ]] dindex = len(df.index) if dindex > 15: embeds: list = [] # Output i, i2, end = 0, 0, 15 df_pg, embeds_img, images_list = pd.DataFrame(), [], [] while i < dindex: df_pg = df[["Last Price", "Change"]].iloc[i:end] df_pg.append(df_pg) font_color = ["white"] * 2 + [[ "#e4003a" if boolv else "#00ACFF" for boolv in df_pg["Change"].str.contains("-") ]] fig = imps.plot_df( df_pg, fig_size=(620, (40 + (45 * len(df.index)))), col_width=[4.2, 1.8, 2.5], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) fig.update_traces(cells=(dict( align=["center", "right"], font=dict(color=font_color), ))) imagefile = "econ-futures.png" imagefile = imps.save_image(imagefile, fig) if imps.IMAGES_URL or not imps.IMG_HOST_ACTIVE: image_link = imps.multi_image(imagefile) images_list.append(imagefile) else: image_link = imps.multi_image(imagefile) embeds_img.append(f"{image_link}", ) embeds.append(disnake.Embed( title=title, colour=imps.COLOR, ), ) i2 += 1 i += 15 end += 15 # Author/Footer for i in range(0, i2): embeds[i].set_author( name=imps.AUTHOR_NAME, url=imps.AUTHOR_URL, icon_url=imps.AUTHOR_ICON_URL, ) embeds[i].set_footer( text=imps.AUTHOR_NAME, icon_url=imps.AUTHOR_ICON_URL, ) i = 0 for i in range(0, i2): embeds[i].set_image(url=embeds_img[i]) i += 1 embeds[0].set_footer(text=f"Page 1 of {len(embeds)}") choices = [ disnake.SelectOption(label="Home", value="0", emoji="🟢"), ] output = { "view": imps.Menu, "title": title, "embed": embeds, "choices": choices, "embeds_img": embeds_img, "images_list": images_list, } else: fig = imps.plot_df( df, fig_size=(620, (40 + (45 * len(df.index)))), col_width=[4.2, 1.8, 2.5], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) fig.update_traces(cells=(dict( align=["center", "right"], font=dict(color=font_color), ))) imagefile = "econ-futures.png" imagefile = imps.save_image(imagefile, fig) output = { "title": title, "imagefile": imagefile, } return output
def earnings_command(): """Display Upcoming Earnings. [Source: Seeking Alpha]""" # Debug if imps.DEBUG: logger.debug("earnings") df_earnings = seeking_alpha_model.get_next_earnings(2) for n_days, earning_date in enumerate(df_earnings.index.unique()): df_earn = df_earnings[earning_date == df_earnings.index][[ "Ticker", "Name" ]].dropna() df_earn.index = df_earn["Ticker"].values df_earn.drop(columns=["Ticker"], inplace=True) title = f"Earnings on {earning_date.date()}" dindex = len(df_earn.index) if dindex > 15: embeds: list = [] # Output i, i2, end = 0, 0, 15 df_pg, embeds_img, images_list = [], [], [] while i < dindex: df_pg = df_earn.iloc[i:end] df_pg.append(df_pg) fig = imps.plot_df( df_pg, fig_size=(800, (40 + (40 * dindex))), col_width=[1, 5], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) fig.update_traces(cells=(dict(align=["center", "left"]))) imagefile = "disc-upcoming.png" imagefile = imps.save_image(imagefile, fig) if imps.IMAGES_URL or not imps.IMG_HOST_ACTIVE: image_link = imps.multi_image(imagefile) images_list.append(imagefile) else: image_link = imps.multi_image(imagefile) embeds_img.append(f"{image_link}", ) embeds.append(disnake.Embed( title=title, colour=imps.COLOR, ), ) i2 += 1 i += 15 end += 15 # Author/Footer for i in range(0, i2): embeds[i].set_author( name=imps.AUTHOR_NAME, url=imps.AUTHOR_URL, icon_url=imps.AUTHOR_ICON_URL, ) embeds[i].set_footer( text=imps.AUTHOR_NAME, icon_url=imps.AUTHOR_ICON_URL, ) i = 0 for i in range(0, i2): embeds[i].set_image(url=embeds_img[i]) i += 1 embeds[0].set_footer(text=f"Page 1 of {len(embeds)}") choices = [ disnake.SelectOption(label="Home", value="0", emoji="🟢"), ] output = { "view": imps.Menu, "title": title, "embed": embeds, "choices": choices, "embeds_img": embeds_img, "images_list": images_list, } else: fig = imps.plot_df( df_earn, fig_size=(800, (40 + (40 * dindex))), col_width=[1, 5], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) fig.update_traces(cells=(dict(align=["center", "left"]))) imagefile = imps.save_image("disc-upcoming.png", fig) output = { "title": title, "imagefile": imagefile, } return output
def lins_command(ticker: str = "", num: int = 30): """Display insider activity for a given stock ticker. [Source: Finviz] Parameters ---------- ticker : Stock Ticker num : Number of latest insider activity to display """ # Debug if imps.DEBUG: logger.debug("disc-lins %s", num) d_finviz_insider = finviz_model.get_last_insider_activity(ticker) df = pd.DataFrame.from_dict(d_finviz_insider) df.set_index("Date", inplace=True) df = df[[ "Relationship", "Transaction", "#Shares", "Cost", "Value ($)", "#Shares Total", "Insider Trading", "SEC Form 4", ]] df = df.head(num) df = df.replace(to_replace="Option Exercise", value="Opt Ex.", regex=True) title = f"Insider Trading for {ticker.upper()}" embeds: list = [] i, i2, end = 0, 0, 15 df_pg, embeds_img, images_list = [], [], [] while i < len(df.index): df_pg = df.iloc[i:end] df_pg.append(df_pg) fig = imps.plot_df( df_pg, fig_size=(1400, (40 + (45 * 20))), col_width=[4, 10, 4, 4, 3.5, 5.3, 6, 8, 7], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) fig.update_traces(cells=(dict(align=[ "center", "center", "center", "right", "right", "right", "right", "center", ]))) imagefile = imps.save_image("disc-insider.png", fig) if imps.IMAGES_URL or not imps.IMG_HOST_ACTIVE: image_link = imps.multi_image(imagefile) images_list.append(imagefile) else: image_link = imps.multi_image(imagefile) embeds_img.append(f"{image_link}", ) embeds.append(disnake.Embed( title=title, colour=imps.COLOR, ), ) i2 += 1 i += 15 end += 15 # Author/Footer for i in range(0, i2): embeds[i].set_author( name=imps.AUTHOR_NAME, url=imps.AUTHOR_URL, icon_url=imps.AUTHOR_ICON_URL, ) embeds[i].set_footer( text=imps.AUTHOR_NAME, icon_url=imps.AUTHOR_ICON_URL, ) i = 0 for i in range(0, i2): embeds[i].set_image(url=embeds_img[i]) i += 1 embeds[0].set_footer(text=f"Page 1 of {len(embeds)}") choices = [ disnake.SelectOption(label="Home", value="0", emoji="🟢"), ] return { "view": imps.Menu, "title": title, "embed": embeds, "choices": choices, "embeds_img": embeds_img, "images_list": images_list, }
def chain_command( ticker: str = None, expiry: str = None, opt_type: str = None, min_sp: float = None, max_sp: float = None, ): """Show calls/puts for given ticker and expiration""" # Debug if imps.DEBUG: logger.debug("opt chain %s %s %s %s %s", ticker, expiry, opt_type, min_sp, max_sp) # Check for argument if not ticker: raise Exception("Stock ticker is required") dates = yfinance_model.option_expirations(ticker) if not dates: raise Exception("Stock ticker is invalid") options = yfinance_model.get_option_chain(ticker, str(expiry)) calls_df = options.calls.fillna(0) puts_df = options.puts.fillna(0) column_map = { "openInterest": "oi", "volume": "vol", "impliedVolatility": "iv" } columns = [ "strike", "bid", "ask", "volume", "openInterest", "impliedVolatility", ] if opt_type == "Calls": df = calls_df[columns].rename(columns=column_map) if opt_type == "Puts": df = puts_df[columns].rename(columns=column_map) min_strike = np.percentile(df["strike"], 1) max_strike = np.percentile(df["strike"], 100) if min_sp: min_strike = min_sp if max_sp: max_strike = max_sp if min_sp > max_sp: # type: ignore min_sp, max_sp = max_strike, min_strike df = df[df["strike"] >= min_strike] df = df[df["strike"] <= max_strike] df["iv"] = pd.to_numeric(df["iv"].astype(float)) formats = {"iv": "{:.2f}"} for col, f in formats.items(): df[col] = df[col].map(lambda x: f.format(x)) # pylint: disable=W0640 df.columns = df.columns.str.capitalize() df.set_index("Strike", inplace=True) title = ( f"Stocks: {opt_type} Option Chain for {ticker.upper()} on\n{expiry} [yfinance]" ) embeds: list = [] # Output i, i2, end = 0, 0, 20 df_pg, embeds_img, images_list = [], [], [] while i < len(df.index): df_pg = df.iloc[i:end] df_pg.append(df_pg) fig = imps.plot_df( df_pg, fig_size=(570, (40 + (40 * 20))), col_width=[3.1, 3.1, 3.1, 3.5], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) fig.update_traces(cells=(dict(align=["center", "right"]))) imagefile = "opt-chain.png" imagefile = imps.save_image(imagefile, fig) if imps.IMAGES_URL or not imps.IMG_HOST_ACTIVE: image_link = imps.multi_image(imagefile) images_list.append(imagefile) else: image_link = imps.multi_image(imagefile) embeds_img.append(f"{image_link}", ) embeds.append(disnake.Embed( title=title, colour=imps.COLOR, ), ) i2 += 1 i += 20 end += 20 # Author/Footer for i in range(0, i2): embeds[i].set_author( name=imps.AUTHOR_NAME, url=imps.AUTHOR_URL, icon_url=imps.AUTHOR_ICON_URL, ) embeds[i].set_footer( text=imps.AUTHOR_NAME, icon_url=imps.AUTHOR_ICON_URL, ) i = 0 for i in range(0, i2): embeds[i].set_image(url=embeds_img[i]) i += 1 embeds[0].set_footer(text=f"Page 1 of {len(embeds)}") choices = [ disnake.SelectOption(label="Home", value="0", emoji="🟢"), ] return { "view": imps.Menu, "title": title, "embed": embeds, "choices": choices, "embeds_img": embeds_img, "images_list": images_list, }
def performance_command(economy_group="sector"): """Performance of sectors, industry, country [Finviz]""" d_economy_group = { "sector": "Sector", "industry": "Industry", "basic_materials": "Industry (Basic Materials)", "communication_services": "Industry (Communication Services)", "consumer_cyclical": "Industry (Consumer Cyclical)", "consumer_defensive": "Industry (Consumer Defensive)", "energy": "Industry (Energy)", "financial": "Industry (Financial)", "healthcare": "Industry (Healthcare)", "industrials": "Industry (Industrials)", "real_estate": "Industry (Real Estate)", "technology": "Industry (Technology)", "utilities": "Industry (Utilities)", "country": "Country (U.S. listed stocks only)", "capitalization": "Capitalization", } # Debug user input if imps.DEBUG: logger.debug("econ-performance %s", economy_group) # Select default group if not economy_group: if imps.DEBUG: logger.debug("Use default economy_group: 'sector'") economy_group = "sector" # Check for argument possible_groups = list(d_economy_group.keys()) if economy_group not in possible_groups: possible_group_list = ", ".join(possible_groups) raise Exception(f"Select a valid group from {possible_group_list}") # nosec group = d_economy_group[economy_group] # Retrieve data df_group = finviz_model.get_valuation_performance_data(group, "performance") # Check for argument if df_group.empty: raise Exception("No available data found") # Output data df = pd.DataFrame(df_group) df["Volume"] = df["Volume"] / 1_000_000 df["Avg Volume"] = df["Avg Volume"] / 1_000_000 formats = { "Perf Month": "{:.2f}", "Perf Quart": "{:.2f}%", "Perf Half": "{:.2f}%", "Perf Year": "{:.2f}%", "Perf YTD": "{:.2f}%", "Avg Volume": "{:.0f}M", "Change": "{:.2f}%", "Volume": "{:.0f}M", } for col, value in formats.items(): df[col] = df[col].map(lambda x: value.format(x)) # pylint: disable=W0640 df = df.set_axis( [ "Name", "Week", "Month", "3 Mouth", "6 Mouth", "1 Year", "YTD", "Recom", "Avg Volume", "Rel Volume", "Change", "Volume", ], axis="columns", ) df.set_index("Name", inplace=True) df = df.fillna("-") df = df.applymap(lambda x: lambda_long_number_format(x, 2)) title = f"Economy: [WSJ] Performance {group}" dindex = len(df.index) if dindex > 2: embeds: list = [] # Output i, i2, end = 0, 0, 2 df_pg, embeds_img, images_list = pd.DataFrame(), [], [] while i < dindex: df_pg = df.iloc[i:end] df_pg.append(df_pg) fig = imps.plot_df( df_pg.transpose(), fig_size=(800, 720), col_width=[6, 10], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) fig.update_traces(cells=(dict(align=["center", "right"]))) imagefile = "econ_performance.png" imagefile = imps.save_image(imagefile, fig) if imps.IMAGES_URL or not imps.IMG_HOST_ACTIVE: image_link = imps.multi_image(imagefile) images_list.append(imagefile) else: image_link = imps.multi_image(imagefile) embeds_img.append( f"{image_link}", ) embeds.append( disnake.Embed( title=title, colour=imps.COLOR, ), ) i2 += 1 i += 2 end += 2 # Author/Footer for i in range(0, i2): embeds[i].set_author( name=imps.AUTHOR_NAME, url=imps.AUTHOR_URL, icon_url=imps.AUTHOR_ICON_URL, ) embeds[i].set_footer( text=imps.AUTHOR_NAME, icon_url=imps.AUTHOR_ICON_URL, ) i = 0 for i in range(0, i2): embeds[i].set_image(url=embeds_img[i]) i += 1 embeds[0].set_footer(text=f"Page 1 of {len(embeds)}") choices = [ disnake.SelectOption(label="Home", value="0", emoji="🟢"), ] output = { "view": imps.Menu, "title": title, "embed": embeds, "choices": choices, "embeds_img": embeds_img, "images_list": images_list, } else: fig = imps.plot_df( df.transpose(), fig_size=(800, 720), col_width=[6, 10], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) fig.update_traces(cells=(dict(align=["center", "right"]))) imagefile = imps.save_image("econ_performance.png", fig) output = { "title": title, "imagefile": imagefile, } return output
def arktrades_command(ticker: str = "", num: int = 30): """Displays trades made by ark [cathiesark.com]""" # Debug user input if imps.DEBUG: logger.debug("dd arktrades %s", ticker) if ticker: ark_holdings = ark_model.get_ark_trades_by_ticker(ticker) if ark_holdings.empty: raise Exception( "Issue getting data from cathiesark.com. Likely no trades found.\n" ) ark_holdings["Total"] = ark_holdings["Total"] / 1_000_000 ark_holdings.rename( columns={ "shares": "Shares", "direction": "B/S", "weight": "Weight", "fund": "Fund", }, inplace=True, ) ark_holdings = ark_holdings.drop( columns=["ticker", "everything.profile.companyName"]) ark_holdings.index = pd.Series( ark_holdings.index).apply(lambda x: x.strftime("%Y-%m-%d")) df = ark_holdings.head(num) df = df.fillna(0) formats = {"Weight": "{:.2f}", "Close": "${:.2f}", "Total": "{:.2f}M"} for col, f in formats.items(): df[col] = df[col].map(lambda x: f.format(x)) # pylint: disable=W0640 title = f"Stocks: [cathiesark.com] {ticker.upper()} Trades by Ark" embeds: list = [] i, i2, end = 0, 0, 15 df_pg, embeds_img, images_list = [], [], [] while i < len(df.index): df_pg = df.iloc[i:end] df_pg.append(df_pg) fig = imps.plot_df( df_pg, fig_size=(900, (40 + (40 * 20))), col_width=[5, 8, 4, 4, 3, 5, 5], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) imagefile = imps.save_image("dd-arktrades.png", fig) if imps.IMAGES_URL or not imps.IMG_HOST_ACTIVE: image_link = imps.multi_image(imagefile) images_list.append(imagefile) else: image_link = imps.multi_image(imagefile) embeds_img.append(f"{image_link}", ) embeds.append(disnake.Embed( title=title, colour=imps.COLOR, ), ) i2 += 1 i += 15 end += 15 # Author/Footer for i in range(0, i2): embeds[i].set_author( name=imps.AUTHOR_NAME, url=imps.AUTHOR_URL, icon_url=imps.AUTHOR_ICON_URL, ) embeds[i].set_footer( text=imps.AUTHOR_NAME, icon_url=imps.AUTHOR_ICON_URL, ) i = 0 for i in range(0, i2): embeds[i].set_image(url=embeds_img[i]) i += 1 embeds[0].set_footer(text=f"Page 1 of {len(embeds)}") choices = [ disnake.SelectOption(label="Home", value="0", emoji="🟢"), ] return { "view": imps.Menu, "title": title, "embed": embeds, "choices": choices, "embeds_img": embeds_img, "images_list": images_list, }
def ford_command(): """Display Orders by Fidelity Customers. [Source: Fidelity]""" # Debug if imps.DEBUG: logger.debug("disc ford") order_header, df_orders = fidelity_model.get_orders() # pylint: disable=W0612 df_orders = df_orders.head(n=30).iloc[:, :-1] df_orders = df_orders.applymap(str) font_color = (["white"] * 2 + [[ "#e4003a" if boolv else "#00ACFF" for boolv in df_orders["Price Change"].str.contains("-") ]] + [["white"] * 3]) df_orders = df_orders.rename(columns={ "# Buy Orders": "# Buy's", "# Sell Orders": "# Sell's" }) df_orders.set_index("Symbol", inplace=True) df_orders = df_orders.apply(lambda x: x.str.slice(0, 30)) title = "Fidelity Customer Orders" dindex = len(df_orders.index) embeds: list = [] # Output i, i2, end = 0, 0, 15 df_pg, embeds_img, images_list = [], [], [] while i < dindex: df_pg = df_orders.iloc[i:end] df_pg.append(df_pg) fig = imps.plot_df( df_pg, fig_size=(900, (40 + (40 * dindex))), col_width=[1, 2.4, 2.35, 4, 1.5, 1.5], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) fig.update_traces(cells=(dict( align=["center", "center", "center", "center", "right"], font=dict(color=font_color), ))) imagefile = "disc-ford.png" imagefile = imps.save_image(imagefile, fig) if imps.IMAGES_URL or not imps.IMG_HOST_ACTIVE: image_link = imps.multi_image(imagefile) images_list.append(imagefile) else: image_link = imps.multi_image(imagefile) embeds_img.append(f"{image_link}", ) embeds.append(disnake.Embed( title=title, colour=imps.COLOR, ), ) i2 += 1 i += 15 end += 15 # Author/Footer for i in range(0, i2): embeds[i].set_author( name=imps.AUTHOR_NAME, url=imps.AUTHOR_URL, icon_url=imps.AUTHOR_ICON_URL, ) embeds[i].set_footer( text=imps.AUTHOR_NAME, icon_url=imps.AUTHOR_ICON_URL, ) i = 0 for i in range(0, i2): embeds[i].set_image(url=embeds_img[i]) i += 1 embeds[0].set_footer(text=f"Page 1 of {len(embeds)}") choices = [ disnake.SelectOption(label="Home", value="0", emoji="🟢"), ] return { "view": imps.Menu, "title": title, "embed": embeds, "choices": choices, "embeds_img": embeds_img, "images_list": images_list, }
def etfs_disc_command(sort="gainers"): """Displays ETF's Top Gainers/Decliners, Most Active [Wall Street Journal]""" # Debug if imps.DEBUG: logger.debug("etfs") df_etfs = wsj_model.etf_movers(sort, export=True) if df_etfs.empty: raise Exception("No available data found") prfx = "Most" if sort == "active" else "Top" title = f"ETF Movers ({prfx} {sort.capitalize()})" df_etfs["Price"] = pd.to_numeric(df_etfs["Price"].astype(float)) df_etfs["Price"] = df_etfs.apply(lambda x: f"${x['Price']:.2f}", axis=1) df_etfs["Change"] = df_etfs.apply( lambda x: f"${x['Chg']:.2f} (<b>{x['%Chg']:.2f}%</b>)", axis=1 ) df_etfs.set_index(" ", inplace=True) df_etfs = df_etfs.drop(columns=["Chg", "%Chg"]) df_etfs = df_etfs[ [ "Name", "Price", "Change", "Vol", ] ] dindex = len(df_etfs.index) if dindex > 15: embeds: list = [] # Output i, i2, end = 0, 0, 15 df_pg, embeds_img, images_list = [], [], [] while i < dindex: df_pg = df_etfs.iloc[i:end] df_pg.append(df_pg) fig = imps.plot_df( df_pg, fig_size=(820, (40 + (40 * dindex))), col_width=[1.1, 9, 1.5, 3, 1.5], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) fig.update_traces(cells=(dict(align=["center", "center", "right"]))) imagefile = "disc-etfs.png" imagefile = imps.save_image(imagefile, fig) if imps.IMAGES_URL or not imps.IMG_HOST_ACTIVE: image_link = imps.multi_image(imagefile) images_list.append(imagefile) else: image_link = imps.multi_image(imagefile) embeds_img.append( f"{image_link}", ) embeds.append( disnake.Embed( title=title, colour=imps.COLOR, ), ) i2 += 1 i += 15 end += 15 # Author/Footer for i in range(0, i2): embeds[i].set_author( name=imps.AUTHOR_NAME, url=imps.AUTHOR_URL, icon_url=imps.AUTHOR_ICON_URL, ) embeds[i].set_footer( text=imps.AUTHOR_NAME, icon_url=imps.AUTHOR_ICON_URL, ) i = 0 for i in range(0, i2): embeds[i].set_image(url=embeds_img[i]) i += 1 embeds[0].set_footer(text=f"Page 1 of {len(embeds)}") choices = [ disnake.SelectOption(label="Home", value="0", emoji="🟢"), ] output = { "view": imps.Menu, "title": title, "embed": embeds, "choices": choices, "embeds_img": embeds_img, "images_list": images_list, } else: fig = imps.plot_df( df_etfs, fig_size=(820, (40 + (40 * dindex))), col_width=[1, 9, 1.5, 3, 1.5], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) fig.update_traces(cells=(dict(align=["center", "center", "right"]))) imagefile = imps.save_image("disc-etfs.png", fig) output = { "title": title, "imagefile": imagefile, } return output
def shorted_command(num: int = 10): """Show most shorted stocks [Yahoo Finance]""" # Debug user input if imps.DEBUG: logger.debug("dps shorted %s", num) # Check for argument if num < 0: raise Exception("Number has to be above 0") # Retrieve data df = yahoofinance_model.get_most_shorted().head(num) if df.empty: raise Exception("No available data found") # Debug user output if imps.DEBUG: logger.debug(df.to_string()) # Output data title = "Stocks: [Yahoo Finance] Most Shorted" df.dropna(how="all", axis=1, inplace=True) df = df.replace(float("NaN"), "") # Convert and format: str into float for col in ["Volume", "Avg Vol (3 month)"]: df[col] = [ imps.unit_finder.sub(imps.unit_replacer, x) for x in df[col] ] df[col] = pd.to_numeric(df[col].astype(float)) df[col] = df[col].map(lambda x: lambda_long_number_format(x, 2)) for col in ["Price (Intraday)", "Change"]: df[col] = df[col].apply(lambda x: f"${x:.2f}") # Format "%% Change" columns then combine it into "Change" df["% Change"] = df.apply(lambda x: f"(<b>{x['% Change']}</b>)", axis=1) df["Change"] = df.apply(lambda x: f"{x['Change']} {x['% Change']}", axis=1) # Combine "Volume" columns df["Volume"] = df.apply( lambda x: f"{x['Volume']:>8} (<b>{x['Avg Vol (3 month)']:>8}</b>)", axis=1, ) df = df.drop(columns=["% Change", "Avg Vol (3 month)", "PE Ratio (TTM)"]) df.columns = [ "Ticker", "Name", "Price", "Change", "Volume (Avg)", "Mkt Cap", ] df.set_index("Ticker", inplace=True) dindex = len(df.index) if dindex > 15: embeds: list = [] # Output i, i2, end = 0, 0, 15 df_pg, embeds_img, images_list = [], [], [] while i < dindex: df_pg = df.iloc[i:end] df_pg.append(df_pg) fig = imps.plot_df( df_pg, fig_size=(950, (45 * dindex)), col_width=[2.1, 10, 2.5, 5, 5.2, 3], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) fig.update_traces(cells=(dict( align=["center", "center", "right"]))) imagefile = "etf-holdings.png" imagefile = imps.save_image(imagefile, fig) if imps.IMAGES_URL or not imps.IMG_HOST_ACTIVE: image_link = imps.multi_image(imagefile) images_list.append(imagefile) else: image_link = imps.multi_image(imagefile) embeds_img.append(f"{image_link}", ) embeds.append(disnake.Embed( title=title, colour=imps.COLOR, ), ) i2 += 1 i += 15 end += 15 # Author/Footer for i in range(0, i2): embeds[i].set_author( name=imps.AUTHOR_NAME, url=imps.AUTHOR_URL, icon_url=imps.AUTHOR_ICON_URL, ) embeds[i].set_footer( text=imps.AUTHOR_NAME, icon_url=imps.AUTHOR_ICON_URL, ) i = 0 for i in range(0, i2): embeds[i].set_image(url=embeds_img[i]) i += 1 embeds[0].set_footer(text=f"Page 1 of {len(embeds)}") choices = [ disnake.SelectOption(label="Home", value="0", emoji="🟢"), ] output = { "view": imps.Menu, "title": title, "embed": embeds, "choices": choices, "embeds_img": embeds_img, "images_list": images_list, } else: fig = imps.plot_df( df, fig_size=(950, (45 * dindex)), col_width=[2.1, 10, 2.5, 5, 5.2, 3], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) fig.update_traces(cells=(dict(align=["center", "center", "right"]))) imagefile = imps.save_image("etf-holdings.png", fig) output = { "title": title, "imagefile": imagefile, } return output
def unu_command(num: int = 20): """Unusual Options""" # Debug if imps.DEBUG: logger.debug("opt unu %s", num) pages = np.arange(0, num // 20 + 1) data_list = [] for page_num in pages: r = requests.get( f"https://app.fdscanner.com/api2/unusualvolume?p=0&page_size=20&page={int(page_num)}", headers={"User-Agent": get_user_agent()}, ) if r.status_code != 200: logger.debug("Error in fdscanner request") return pd.DataFrame(), "request error" data_list.append(r.json()) ticker, expiry, option_strike, option_type, ask, bid, oi, vol, voi = ( [], [], [], [], [], [], [], [], [], ) for data in data_list: for entry in data["data"]: ticker.append(entry["tk"]) expiry.append(entry["expiry"]) option_strike.append(float(entry["s"])) option_type.append("Put" if entry["t"] == "P" else "Call") ask.append(entry["a"]) bid.append(entry["b"]) oi.append(entry["oi"]) vol.append(entry["v"]) voi.append(entry["vol/oi"]) df = pd.DataFrame({ "Ticker": ticker, "Exp": expiry, "Strike": option_strike, "Type": option_type, "Vol/OI": voi, "Vol": vol, "OI": oi, }) if df.empty: raise Exception("No data found!\n") title = "Unusual Options" df.set_index("Ticker", inplace=True) dindex = len(df.index) if dindex > 15: embeds: list = [] # Output i, i2, end = 0, 0, 20 df_pg, embeds_img, images_list = [], [], [] while i < dindex: df_pg = df.iloc[i:end] df_pg.append(df_pg) fig = imps.plot_df( df_pg, fig_size=(650, (40 + (40 * dindex))), col_width=[3, 4, 3, 2.5, 2.5, 2, 2], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) fig.update_traces(cells=(dict( align=["center", "center", "right", "center", "right"]))) imagefile = "opt-unu.png" imagefile = imps.save_image(imagefile, fig) if imps.IMAGES_URL or not imps.IMG_HOST_ACTIVE: image_link = imps.multi_image(imagefile) images_list.append(imagefile) else: image_link = imps.multi_image(imagefile) embeds_img.append(f"{image_link}", ) embeds.append(disnake.Embed( title=title, colour=imps.COLOR, ), ) i2 += 1 i += 20 end += 20 # Author/Footer for i in range(0, i2): embeds[i].set_author( name=imps.AUTHOR_NAME, url=imps.AUTHOR_URL, icon_url=imps.AUTHOR_ICON_URL, ) embeds[i].set_footer( text=imps.AUTHOR_NAME, icon_url=imps.AUTHOR_ICON_URL, ) i = 0 for i in range(0, i2): embeds[i].set_image(url=embeds_img[i]) i += 1 embeds[0].set_footer(text=f"Page 1 of {len(embeds)}") choices = [ disnake.SelectOption(label="Home", value="0", emoji="🟢"), ] output = { "view": imps.Menu, "title": title, "embed": embeds, "choices": choices, "embeds_img": embeds_img, "images_list": images_list, } else: fig = imps.plot_df( df, fig_size=(650, (40 + (40 * dindex))), col_width=[3, 4, 3, 2.5, 2.5, 2, 2], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) fig.update_traces(cells=(dict( align=["center", "center", "right", "center", "right"]))) imagefile = imps.save_image("opt-unu.png", fig) output = { "title": "Unusual Options", "imagefile": imagefile, } return output
def by_ticker_command(ticker="", sort="fund_percent", num: int = 15): """Display ETF Holdings. [Source: StockAnalysis]""" # Debug if imps.DEBUG: logger.debug("etfs") options = uc.ChromeOptions() options.headless = True options.add_argument("--headless") options.add_argument("--incognito") driver = uc.Chrome(options=options, version_main=98) driver.set_window_size(1920, 1080) driver.get(f"http://etf.com/stock/{ticker.upper()}/") time.sleep(2) driver.find_element(By.XPATH, "(//div[@id='inactiveResult'])[3]").click() soup5 = bs4.BeautifulSoup(driver.page_source, "html.parser") r_ticker, r_holdings, r_name, r_market = [], [], [], [] table1 = soup5.find("table", id="StockTable") table = table1.find("tbody") for x in table.find_all("tr"): r_ticker.append(x.find("td").text) r_name.append(x.find("td").findNext("td").text) r_holdings.append( x.find("td").findNext("td").findNext("td").findNext("td").text) r_market.append( x.find("td").findNext("td").findNext("td").findNext("td").findNext( "td").text) driver.quit() df = pd.DataFrame({ "Ticker": r_ticker, "Name": r_name, "Holdings": r_holdings, "Market Value": r_market, }) if df.empty: raise Exception("No company holdings found!\n") if sort == "mkt_value": key = imps.natsort.index_natsorted( df["Market Value"], key=lambda x: imps.unit_finder.sub(imps.unit_replacer, x), reverse=True, ) df = df.reindex(key) df = df.iloc[:num] df.set_index("Ticker", inplace=True) title = f"ETF's Holding {ticker.upper()}" dindex = len(df.index) if dindex > 15: embeds: list = [] # Output i, i2, end = 0, 0, 15 df_pg, embeds_img, images_list = [], [], [] while i < dindex: df_pg = df.iloc[i:end] df_pg.append(df_pg) fig = imps.plot_df( df_pg, fig_size=(800, (40 * dindex)), col_width=[0.6, 3.5, 0.65, 1.1], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) fig.update_traces(cells=(dict( align=["center", "center", "center", "right"]))) imagefile = "etf-byticker.png" imagefile = imps.save_image(imagefile, fig) if imps.IMAGES_URL or not imps.IMG_HOST_ACTIVE: image_link = imps.multi_image(imagefile) images_list.append(imagefile) else: image_link = imps.multi_image(imagefile) embeds_img.append(f"{image_link}", ) embeds.append(disnake.Embed( title=title, colour=imps.COLOR, ), ) i2 += 1 i += 15 end += 15 # Author/Footer for i in range(0, i2): embeds[i].set_author( name=imps.AUTHOR_NAME, url=imps.AUTHOR_URL, icon_url=imps.AUTHOR_ICON_URL, ) embeds[i].set_footer( text=imps.AUTHOR_NAME, icon_url=imps.AUTHOR_ICON_URL, ) i = 0 for i in range(0, i2): embeds[i].set_image(url=embeds_img[i]) i += 1 embeds[0].set_footer(text=f"Page 1 of {len(embeds)}") choices = [ disnake.SelectOption(label="Home", value="0", emoji="🟢"), ] output = { "view": imps.Menu, "title": title, "embed": embeds, "choices": choices, "embeds_img": embeds_img, "images_list": images_list, } else: fig = imps.plot_df( df, fig_size=(800, (40 * dindex)), col_width=[0.6, 3.5, 0.65, 1.1], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) fig.update_traces(cells=(dict( align=["center", "center", "center", "right"]))) imagefile = imps.save_image("etf-holdings.png", fig) output = { "title": title, "imagefile": imagefile, } return output
def est_command(ticker: str = ""): """Displays earning estimates [Business Insider]""" # Debug if imps.DEBUG: logger.debug("dd est %s", ticker) # Check for argument if ticker == "": raise Exception("Stock ticker is required") ( df_year_estimates, df_quarter_earnings, df_quarter_revenues, ) = business_insider_model.get_estimates(ticker) if (df_quarter_revenues.empty and df_year_estimates.empty and df_quarter_earnings.empty): raise Exception("Enter a valid ticker") # Debug user output if imps.DEBUG: logger.debug(df_year_estimates.to_string()) logger.debug(df_quarter_earnings.to_string()) logger.debug(df_quarter_revenues.to_string()) images_list = [] dindex = len(df_year_estimates.index) fig = imps.plot_df( df_year_estimates, fig_size=(900, (40 + (60 * dindex))), col_width=[9, 4, 4, 4, 4], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) imagefile = imps.save_image("estimates.png", fig) if imps.IMAGES_URL or not imps.IMG_HOST_ACTIVE: link_estimates = imps.multi_image(imagefile) images_list.append(imagefile) else: link_estimates = imps.multi_image(imagefile) fig = imps.plot_df( df_quarter_earnings, fig_size=(900, (40 + (40 * 20))), col_width=[5, 5, 4, 4, 5, 4], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) imagefile = imps.save_image("earnings.png", fig) if imps.IMAGES_URL or not imps.IMG_HOST_ACTIVE: link_earnings = imps.multi_image(imagefile) images_list.append(imagefile) else: link_earnings = imps.multi_image(imagefile) fig = imps.plot_df( df_quarter_revenues, fig_size=(900, (40 + (40 * 20))), col_width=[5, 5, 4, 4, 5, 4], tbl_header=imps.PLT_TBL_HEADER, tbl_cells=imps.PLT_TBL_CELLS, font=imps.PLT_TBL_FONT, row_fill_color=imps.PLT_TBL_ROW_COLORS, paper_bgcolor="rgba(0, 0, 0, 0)", ) imagefile = imps.save_image("revenues.png", fig) if imps.IMAGES_URL or not imps.IMG_HOST_ACTIVE: link_revenues = imps.multi_image(imagefile) images_list.append(imagefile) else: link_revenues = imps.multi_image(imagefile) embeds = [ disnake.Embed( title=f"**{ticker.upper()} Year Estimates**", color=imps.COLOR, ), disnake.Embed( title=f"**{ticker.upper()} Quarter Earnings**", colour=imps.COLOR, ), disnake.Embed( title=f"**{ticker.upper()} Quarter Revenues**", colour=imps.COLOR, ), ] embeds[0].set_image(url=link_estimates) embeds[1].set_image(url=link_earnings) embeds[2].set_image(url=link_revenues) titles = [ f"**{ticker.upper()} Year Estimates**", f"**{ticker.upper()} Quarter Earnings**", f"**{ticker.upper()} Quarter Revenues**", ] embeds_img = [ f"{link_estimates}", f"{link_earnings}", f"{link_revenues}", ] # Output data choices = [ disnake.SelectOption(label=f"{ticker.upper()} Year Estimates", value="0", emoji="🟢"), disnake.SelectOption(label=f"{ticker.upper()} Quarter Earnings", value="1", emoji="🟢"), disnake.SelectOption(label=f"{ticker.upper()} Quarter Revenues", value="2", emoji="🟢"), ] return { "view": imps.Menu, "titles": titles, "embed": embeds, "choices": choices, "embeds_img": embeds_img, "images_list": images_list, }