def __init__(self, title: str = "", choices: list = []): options = [] for c in choices: options.append(disnake.SelectOption(label=c)) if len(options) < 2: raise Exception( 'Please specify what to poll for\nFormat: `duration title;choice1;choice2;...;choiceN`' ) super().__init__(placeholder=title, min_values=1, max_values=1, options=options)
def create_select(self): """Creates one singular select from cogs""" options = [] dict_of_cogs = dict(zip(self.cogs[0], self.cogs[1])) class_list = list(dict_of_cogs.values()) loaded = [] for value in class_list: if value in self.bot.cogs: loaded.append(value) unloaded = list(set(class_list) - set(loaded)) loaded.sort() unloaded.sort() for file, cog in dict_of_cogs.items(): if cog in loaded: options.append(disnake.SelectOption(label=cog, value=file, emoji="✅")) else: options.append(disnake.SelectOption(label=cog, value=file, emoji="❌")) return options
def __init__(self, bot) -> None: self.manager = ReviewManager(bot=bot) components = [ disnake.ui.TextInput(custom_id="review_subject", label=Messages.review_subject_label), disnake.ui.Select( custom_id="review_anonym", options=[ disnake.SelectOption(label=Messages.review_anonym_label, value=True, default=True), disnake.SelectOption(label=Messages.review_signed_label, value=False), ], ), disnake.ui.Select( custom_id="review_tier", placeholder=Messages.review_tier_placeholder, options=[ disnake.SelectOption( label="A", value=0, description=Messages.review_tier_0_desc), disnake.SelectOption( label="B", value=1, description=Messages.review_tier_1_desc), disnake.SelectOption( label="C", value=2, description=Messages.review_tier_2_desc), disnake.SelectOption( label="D", value=3, description=Messages.review_tier_3_desc), disnake.SelectOption( label="E", value=4, description=Messages.review_tier_4_desc), ], ), disnake.ui.TextInput( custom_id="review_text", label=Messages.review_text_label, style=disnake.TextInputStyle.paragraph, required=False, ), ] super().__init__( title=Messages.review_modal_title, components=components, custom_id="review_modal", )
async def shorted_command(ctx, num: int = 10): """Show most shorted stocks [Yahoo Finance]""" try: # Debug user input if cfg.DEBUG: logger.debug("!stocks.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) # Debug user output if cfg.DEBUG: logger.debug(df.to_string()) # Output data df.dropna(how="all", axis=1, inplace=True) df = df.replace(float("NaN"), "") future_column_name = df["Symbol"] df = df.transpose() df.columns = future_column_name df.drop("Symbol") columns = [] choices = [ disnake.SelectOption(label="Overview", value="0", emoji="🟢"), ] initial_str = "Overview" i = 1 for col_name in df.columns.values: menu = f"\nPage {i}: {col_name}" initial_str += f"\nPage {i}: {col_name}" if i < 19: choices.append( disnake.SelectOption(label=menu, value=f"{i}", emoji="🟢"), ) if i == 20: choices.append( disnake.SelectOption(label="Max Reached", value=f"{i}", emoji="🟢"), ) i += 1 columns.append( disnake.Embed( title="Stocks: [Yahoo Finance] Most Shorted", description=initial_str, colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, )) for column in df.columns.values: columns.append( disnake.Embed( description="```" + df[column].fillna("").to_string() + "```", colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, )) await ctx.send(embed=columns[0], view=Menu(columns, choices)) except Exception as e: embed = disnake.Embed( title="ERROR Stocks: [Yahoo Finance] Most Shorted", colour=cfg.COLOR, description=e, ) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed, delete_after=30.0)
async def arktrades_command(ctx, ticker: str = "", num: int = 10): """Displays trades made by ark [cathiesark.com]""" try: # Debug user input if cfg.DEBUG: logger.debug("!stocks.dd.arktrades %s", ticker) if ticker: ark_holdings = ark_model.get_ark_trades_by_ticker(ticker) ark_holdings = ark_holdings.drop( columns=["ticker", "everything.profile.companyName"]) 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={ "direction": "B/S", "weight": "F %" }, inplace=True) ark_holdings.index = pd.Series( ark_holdings.index).apply(lambda x: x.strftime("%Y-%m-%d")) df = ark_holdings.head(num) dindex = len(df.head(num).index) formats = {"Close": "{:.2f}", "Total": "{:.2f}"} 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, 20 df_pg = [] embeds_img = [] dindex = len(df.index) while i < dindex: df_pg = df.iloc[i:end] df_pg.append(df_pg) fig = df2img.plot_dataframe( df_pg, fig_size=(900, (40 + (40 * 20))), col_width=[5, 10, 4, 4, 3, 4, 5], tbl_cells=dict(height=35, ), font=dict( family="Consolas", size=20, ), template="plotly_dark", paper_bgcolor="rgba(0, 0, 0, 0)", ) imagefile = f"disc-insider{i}.png" df2img.save_dataframe(fig=fig, filename=imagefile) image = Image.open(imagefile) image = autocrop_image(image, 0) image.save(imagefile, "PNG", quality=100) uploaded_image = gst_imgur.upload_image(imagefile, title="something") image_link = uploaded_image.link embeds_img.append(f"{image_link}", ) embeds.append(disnake.Embed( title=title, colour=cfg.COLOR, ), ) i2 += 1 i += 20 end += 20 os.remove(imagefile) # Author/Footer for i in range(0, i2): embeds[i].set_author( name=cfg.AUTHOR_NAME, url=cfg.AUTHOR_URL, icon_url=cfg.AUTHOR_ICON_URL, ) embeds[i].set_footer( text=cfg.AUTHOR_NAME, icon_url=cfg.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)}") options = [ disnake.SelectOption(label="Home", value="0", emoji="🟢"), ] await ctx.send(embed=embeds[0], view=Menu(embeds, options)) except Exception as e: embed = disnake.Embed( title=f"ERROR Stocks: [cathiesark.com] {ticker} Trades by Ark", colour=cfg.COLOR, description=e, ) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed, delete_after=30.0)
def overview_command(preset: str = "template", sort: str = "", limit: int = 5, ascend: bool = False): """Displays stocks with overview data such as Sector and Industry [Finviz]""" # Check for argument if preset == "template" or preset not in so.all_presets: raise Exception("Invalid preset selected!") # Debug if cfg.DEBUG: logger.debug("scr-overview %s %s %s %s", preset, sort, limit, ascend) # Check for argument if limit < 0: raise Exception("Number has to be above 0") # Output Data df_screen = get_screener_data( preset, "overview", limit, ascend, ) description = "" title = "Stocks: [Finviz] Overview Screener" if isinstance(df_screen, pd.DataFrame): if df_screen.empty: raise Exception("No data found.") df_screen = df_screen.dropna(axis="columns", how="all") if sort: if " ".join(sort) in so.d_cols_to_sort["overview"]: df_screen = df_screen.sort_values( by=[" ".join(sort)], ascending=ascend, na_position="last", ) else: similar_cmd = difflib.get_close_matches( " ".join(sort), so.d_cols_to_sort["overview"], n=1, cutoff=0.7, ) if similar_cmd: description = f"Replacing '{' '.join(sort)}' by '{similar_cmd[0]}' so table can be sorted.\n\n" df_screen = df_screen.sort_values( by=[similar_cmd[0]], ascending=ascend, na_position="last", ) else: raise ValueError( f"Wrong sort column provided! Select from: {', '.join(so.d_cols_to_sort['overview'])}" ) df_screen = df_screen.fillna("") future_column_name = df_screen["Ticker"] df_screen = df_screen.head(n=limit).transpose() df_screen.columns = future_column_name df_screen.drop("Ticker") embeds = [] choices = [ disnake.SelectOption(label="Overview", value="0", emoji="🟢"), ] initial_str = description + "Overview" i = 1 for column in df_screen.columns.values: menu = f"\nPage {i}: {column}" initial_str += f"\nPage {i}: {column}" if i < 19: choices.append( disnake.SelectOption(label=menu, value=f"{i}", emoji="🟢"), ) if i == 20: choices.append( disnake.SelectOption(label="Max Reached", value=f"{i}", emoji="🟢"), ) i += 1 reports = [f"{initial_str}"] embeds.append( disnake.Embed( title=title, description=initial_str, colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, )) for column in df_screen.columns.values: description = f"```{df_screen[column].fillna('')}```" embeds.append( disnake.Embed( title=title, description=description, colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, )) reports.append(f"{description}") return { "view": Menu, "title": title, "description": reports, "embed": embeds, "choices": choices, }
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 lastcontracts_command(past_transactions_days: int = 2, num: int = 20): """Displays last government contracts [quiverquant.com]""" # Debug user input if cfg.DEBUG: logger.debug("gov lastcontracts %s %s", past_transactions_days, num) df_contracts = quiverquant_model.get_government_trading("contracts") if df_contracts.empty: logger.debug("No government contracts found") raise Exception("No government contracts found") df_contracts.sort_values("Date", ascending=False) df_contracts["Date"] = pd.to_datetime(df_contracts["Date"]) df_contracts["Date"] = df_contracts["Date"].dt.date df_contracts.drop_duplicates(inplace=True) df_contracts = df_contracts[df_contracts["Date"].isin( df_contracts["Date"].unique()[:past_transactions_days])] df_contracts = df_contracts[["Date", "Ticker", "Amount", "Agency"]][:num] choices = [ disnake.SelectOption(label="Overview", value="0", emoji="🟢"), ] title = "Stocks: [quiverquant.com] Top buy government trading" initial_str = "Overview" i = 1 for col_name in df_contracts["Ticker"].values: menu = f"\nPage {i}: {col_name}" initial_str += f"\nPage {i}: {col_name}" choices.append( disnake.SelectOption(label=menu, value=f"{i}", emoji="🟢"), ) i += 1 embeds = [] df_contracts = df_contracts.T reports = [f"{initial_str}"] embeds.append( disnake.Embed( title=title, description=initial_str, colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, )) for column in df_contracts.columns.values: description = "```" + df_contracts[column].fillna( "").to_string() + "```" embeds.append( disnake.Embed( description=description, colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, )) reports.append(f"{description}") return { "view": Menu, "title": title, "description": reports, "embed": embeds, "choices": choices, }
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 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 shorted_command(num: int = 10): """Show most shorted stocks [Yahoo Finance]""" # Debug user input if cfg.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) # Debug user output if cfg.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"), "") future_column_name = df["Symbol"] df = df.transpose() df.columns = future_column_name df.drop("Symbol") embeds = [] choices = [ disnake.SelectOption(label="Overview", value="0", emoji="🟢"), ] initial_str = "Overview" i = 1 for col_name in df.columns.values: menu = f"\nPage {i}: {col_name}" initial_str += f"\nPage {i}: {col_name}" if i < 19: choices.append( disnake.SelectOption(label=menu, value=f"{i}", emoji="🟢"), ) if i == 20: choices.append( disnake.SelectOption(label="Max Reached", value=f"{i}", emoji="🟢"), ) i += 1 reports = [f"{initial_str}"] embeds.append( disnake.Embed( title=title, description=initial_str, colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) ) for column in df.columns.values: description = "```" + df[column].fillna("").to_string() + "```" embeds.append( disnake.Embed(description=description, colour=cfg.COLOR,).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) ) reports.append(f"{description}") return { "view": Menu, "title": title, "description": reports, "embed": embeds, "choices": choices, }
def hsi_command(num: int = 10): """Show top high short interest stocks of over 20% ratio [shortinterest.com]""" # Debug user input if cfg.DEBUG: logger.debug("dps-hsi %s", num) # Check for argument if num < 0: raise Exception("Number has to be above 0") # Retrieve data df = shortinterest_model.get_high_short_interest() df = df.iloc[1:].head(n=num) # Debug user output if cfg.DEBUG: logger.debug(df.to_string()) # Output data title = "Stocks: [highshortinterest.com] Top High Short Interest" future_column_name = df["Ticker"] df = df.transpose() df.columns = future_column_name df.drop("Ticker") embeds = [] choices = [ disnake.SelectOption(label="Overview", value="0", emoji="🟢"), ] initial_str = "Overview" i = 1 for col_name in df.columns.values: menu = f"\nPage {i}: {col_name}" initial_str += f"\nPage {i}: {col_name}" choices.append( disnake.SelectOption(label=menu, value=f"{i}", emoji="🟢"), ) i += 1 reports = [f"{initial_str}"] embeds.append( disnake.Embed( title=title, description=initial_str, colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, )) for column in df.columns.values: description = "```" + df[column].fillna("").to_string() + "```" embeds.append( disnake.Embed( title=title, description=description, colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, )) reports.append(f"{description}") return { "view": Menu, "title": title, "description": reports, "embed": embeds, "choices": choices, }
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 sidtc_command(sort="float", num: int = 10): """Short interest and days to cover [Stockgrid]""" # Debug if cfg.DEBUG: logger.debug("dps-sidtc %s %s", sort, num) # Check for argument possible_sorts = ("float", "dtc", "si") if sort not in possible_sorts: raise Exception(f"The possible sorts are: {', '.join(possible_sorts)}") if num < 0: raise Exception("Number has to be above 0") # Retrieve data df = stockgrid_model.get_short_interest_days_to_cover(sort) df = df.iloc[:num] # Debug user output if cfg.DEBUG: logger.debug(df.to_string()) # Output data title = "Stocks: [Stockgrid] Short Interest and Days to Cover" dp_date = df["Date"].values[0] df = df.drop(columns=["Date"]) df["Short Interest"] = df["Short Interest"] / 1_000_000 df.head() df.columns = [ "Ticker", "Float Short %", "Days to Cover", "Short Interest (1M)", ] future_column_name = df["Ticker"] df = df.transpose() df.columns = future_column_name df.drop("Ticker") embeds = [] choices = [ disnake.SelectOption(label="Overview", value="0", emoji="🟢"), ] initial_str = "Overview" i = 1 for col_name in df.columns.values: menu = f"\nPage {i}: {col_name}" initial_str += f"\nPage {i}: {col_name}" if i < 19: choices.append( disnake.SelectOption(label=menu, value=f"{i}", emoji="🟢"), ) if i == 20: choices.append( disnake.SelectOption(label="Max Reached", value=f"{i}", emoji="🟢"), ) i += 1 reports = [f"{initial_str}"] embeds.append( disnake.Embed( title="Dark Pool Shorts", description=initial_str, colour=cfg.COLOR ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) ) for column in df.columns.values: description = ( "```The following data corresponds to the date: " + dp_date + "\n\n" + df[column].fillna("").to_string() + "```", ) embeds.append( disnake.Embed( title=title, description=description, colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) ) reports.append(f"{description}") return { "view": Menu, "title": title, "description": reports, "embed": embeds, "choices": choices, }
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
async def lobbying_command(ctx, ticker="", num: int = 10): """Displays lobbying details [quiverquant.com]""" try: # Debug user input if cfg.DEBUG: logger.debug("!stocks.gov.lobbying %s", ticker) if ticker == "": raise Exception("A ticker is required") # Retrieve Data df_lobbying = quiverquant_model.get_government_trading( "corporate-lobbying", ticker=ticker) if df_lobbying.empty: logger.debug("No corporate lobbying found") return # Output Data report = "" choices = [ disnake.SelectOption(label="Overview", value="0", emoji="🟢"), ] for _, row in (df_lobbying.sort_values( by=["Date"], ascending=False).head(num).iterrows()): amount = ("$" + str(int(float(row["Amount"]))) if row["Amount"] is not None else "N/A") report += f"{row['Date']}: {row['Client']} {amount}" if row["Amount"] is not None: report += "\t" + row["Specific_Issue"].replace( "\n", " ").replace("\r", "") report += "\n" if len(report) <= 4000: embed = disnake.Embed( title= f"Stocks: [quiverquant.com] {ticker.upper()} Lobbying Details", description="```" + report + "```", colour=cfg.COLOR, ) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed) else: i = 0 str_start = 0 str_end = 4000 columns = [] while i <= len(report) / 4000: columns.append( disnake.Embed( title= f"Stocks: [quiverquant.com] {ticker.upper()} Lobbying Details", description="```" + report[str_start:str_end] + "```", colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, )) str_end = str_start str_start += 4000 i += 1 await ctx.send(embed=columns[0], view=Menu(columns, choices)) except Exception as e: embed = disnake.Embed( title= f"ERROR Stocks: [quiverquant.com] {ticker.upper()} Lobbying Details", colour=cfg.COLOR, description=e, ) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed, delete_after=30.0)
def lobbying_command(ticker="", num: int = 10): """Displays lobbying details [quiverquant.com]""" # Debug user input if cfg.DEBUG: logger.debug("gov-lobbying %s", ticker) if ticker == "": raise Exception("A ticker is required") # Retrieve Data df_lobbying = quiverquant_model.get_government_trading( "corporate-lobbying", ticker=ticker) if df_lobbying.empty: logger.debug("No corporate lobbying found") raise Exception("No corporate lobbying found") # Output Data report = "" title = (f"Stocks: [quiverquant.com] {ticker.upper()} Lobbying Details", ) choices = [ disnake.SelectOption(label="Overview", value="0", emoji="🟢"), ] for _, row in (df_lobbying.sort_values( by=["Date"], ascending=False).head(num).iterrows()): amount = ("$" + str(int(float(row["Amount"]))) if row["Amount"] is not None else "N/A") report += f"{row['Date']}: {row['Client']} {amount}" if row["Amount"] is not None: report += "\t" + row["Specific_Issue"].replace("\n", " ").replace( "\r", "") report += "\n" if len(report) <= 4000: description = f"```{report}```" embed = disnake.Embed( title=title, description=description, colour=cfg.COLOR, ) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) output: Dict[str, Any] = { "title": title, "description": description, } else: i = 0 str_start = 0 str_end = 4000 embeds = [] reports = [] while i <= len(report) / 4000: descript = f"```{report[str_start:str_end]}```" embeds.append( disnake.Embed( title=title, description=descript, colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, )) reports.append(f"{descript}") str_end = str_start str_start += 4000 i += 1 output = { "view": Menu, "title": title, "description": reports, "embed": embeds, "choices": choices, } return output
def pos_command(sort="dpp_dollar", ascending: bool = False, num: int = 10): """Dark pool short position [Stockgrid]""" # Debug user input if imps.DEBUG: logger.debug("dps-pos %s %s", sort, num) # Check for argument possible_sorts = ("sv", "sv_pct", "nsv", "nsv_dollar", "dpp", "dpp_dollar") if sort not in possible_sorts: raise Exception(f"The possible sorts are: {', '.join(possible_sorts)}") if num < 0: raise Exception("Number has to be above 0") # Retrieve data df = stockgrid_model.get_dark_pool_short_positions(sort, ascending) if df.empty: raise Exception("No available data found") df = df.iloc[:num] # Debug user output if imps.DEBUG: logger.debug(df.to_string()) # Output data title = "Stocks: [Stockgrid] Dark Pool Short Position" df = df.applymap(lambda x: lambda_long_number_format(x, 2)) df = df.drop(columns=["Date"]) formats = { "Short Volume %": "{}%", "Net Short Volume $": "${}", "Dark Pools Position $": "${}", } for col, f in formats.items(): df[col] = df[col].map(lambda x: f.format(x)) # pylint: disable=W0640 df["Short Volume"] = df.apply( lambda x: f"{x['Short Volume']} (<b>{x['Short Volume %']}</b>)", axis=1) df["Net Short Volume"] = df.apply( lambda x: f"{x['Net Short Volume']:>9} (<b>{x['Net Short Volume $']:>9}</b>)", axis=1, ) df["Dark Pools Position"] = df.apply( lambda x: f"{x['Dark Pools Position']:>9} (<b>{x['Dark Pools Position $']:>9}</b>)", axis=1, ) df = df.drop(columns=[ "Short Volume %", "Net Short Volume $", "Dark Pools Position $" ]) df.columns = [ "Ticker", "Short Vol.", "Net Short Vol.", "DP Position", ] 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=(720, (40 * dindex)), col_width=[2, 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)", ) fig.update_traces(cells=(dict(align=["center", "right"]))) imagefile = "dps-pos.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=(720, (40 * dindex)), col_width=[2, 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)", ) fig.update_traces(cells=(dict(align=["center", "right"]))) imagefile = imps.save_image("dps-pos.png", fig) output = { "title": title, "imagefile": imagefile, } return output
async def ownership_command(ctx, preset: str = "template", sort: str = "", limit: int = 5, ascend: bool = False): """Displays stocks based on own share float and ownership data [Finviz]""" try: # Check for argument if preset == "template" or preset not in so.all_presets: raise Exception("Invalid preset selected!") # Debug if cfg.DEBUG: logger.debug("!stocks.scr.ownership %s %s %s %s", preset, sort, limit, ascend) # Check for argument if limit < 0: raise Exception("Number has to be above 0") # Output Data df_screen = get_screener_data( preset, "ownership", limit, ascend, ) description = "" if isinstance(df_screen, pd.DataFrame): if df_screen.empty: return [] df_screen = df_screen.dropna(axis="columns", how="all") if sort: if " ".join(sort) in so.d_cols_to_sort["ownership"]: df_screen = df_screen.sort_values( by=[" ".join(sort)], ascending=ascend, na_position="last", ) else: similar_cmd = difflib.get_close_matches( " ".join(sort), so.d_cols_to_sort["ownership"], n=1, cutoff=0.7, ) if similar_cmd: description = f"Replacing '{' '.join(sort)}' by '{similar_cmd[0]}' so table can be sorted.\n\n" df_screen = df_screen.sort_values( by=[similar_cmd[0]], ascending=ascend, na_position="last", ) else: raise ValueError( f"Wrong sort column provided! Select from: {', '.join(so.d_cols_to_sort['ownership'])}" ) df_screen = df_screen.fillna("") future_column_name = df_screen["Ticker"] df_screen = df_screen.head(n=limit).transpose() df_screen.columns = future_column_name df_screen.drop("Ticker") columns = [] choices = [ disnake.SelectOption(label="Overview", value="0", emoji="🟢"), ] initial_str = description + "Overview" i = 1 for column in df_screen.columns.values: menu = f"\nPage {i}: {column}" initial_str += f"\nPage {i}: {column}" if i < 19: choices.append( disnake.SelectOption(label=menu, value=f"{i}", emoji="🟢"), ) if i == 20: choices.append( disnake.SelectOption(label="Max Reached", value=f"{i}", emoji="🟢"), ) i += 1 columns.append( disnake.Embed( title="Stocks: [Finviz] Ownership Screener", description=initial_str, colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, )) for column in df_screen.columns.values: columns.append( disnake.Embed( title="Stocks: [Finviz] Ownership Screener", description="```" + df_screen[column].fillna("").to_string() + "```", colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, )) await ctx.send(embed=columns[0], view=Menu(columns, choices)) except Exception as e: embed = disnake.Embed( title="ERROR Stocks: [Finviz] Ownership Screener", colour=cfg.COLOR, description=e, ) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed, delete_after=30.0)
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 cfg.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.set_index("strike", inplace=True) title = ( f"Stocks: {opt_type} Option Chain for {ticker.upper()} on {expiry} [yfinance]" ) embeds: list = [] # Output i, i2, end = 0, 0, 20 df_pg = [] embeds_img = [] dindex = len(df.index) while i < dindex: df_pg = df.iloc[i:end] df_pg.append(df_pg) fig = df2img.plot_dataframe( df_pg, fig_size=(1000, (40 + (40 * 20))), col_width=[3, 3, 3, 3], tbl_cells=dict(height=35, ), font=dict( family="Consolas", size=20, ), template="plotly_dark", paper_bgcolor="rgba(0, 0, 0, 0)", ) imagefile = save_image(f"opt-chain{i}.png", fig) uploaded_image = gst_imgur.upload_image(imagefile, title="something") image_link = uploaded_image.link embeds_img.append(f"{image_link}", ) embeds.append(disnake.Embed( title=title, colour=cfg.COLOR, ), ) i2 += 1 i += 20 end += 20 os.remove(imagefile) # Author/Footer for i in range(0, i2): embeds[i].set_author( name=cfg.AUTHOR_NAME, url=cfg.AUTHOR_URL, icon_url=cfg.AUTHOR_ICON_URL, ) embeds[i].set_footer( text=cfg.AUTHOR_NAME, icon_url=cfg.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": Menu, "title": title, "embed": embeds, "choices": choices, "embeds_img": embeds_img, }
async def ta(self, ctx: disnake.AppCmdInter): """Stocks Command List""" misctext = "```md\n[disc-fidelity]()\n" "[ins-last](ticker) <num>\n```" opttext = ( "```md\n[opt-unu]()\n" "[opt-iv](ticker)\n" "[opt-vsurf](ticker) <z>\n" "[opt-hist](ticker) <strike> <expiration> <opt-typ>\n" "[opt-oi](ticker) <expiration> <min-sp> <max-sp>\n" "[opt-vol](ticker) <expiration> <min-sp> <max-sp>\n" "[opt-overview](ticker) <expiration> <min-sp> <max-sp>\n" "[opt-chain](ticker) <expiration> <opt-typ> <min-sp> <max-sp>\n```" ) tatext = ( "```md\n[ta-summary](ticker)\n" "[ta-view](ticker)\n" "[ta-recom](ticker)\n" "[ta-obv](ticker) <START> <END>\n" "[ta-fib](ticker) <START> <END>\n" "[ta-ad](ticker) <OPEN> <START> <END>\n" "[ta-cg](ticker) <LENGTH> <START> <END>\n" "[ta-fisher](ticker) <LENGTH> <START> <END>\n" "[ta-cci](ticker) <LENGTH> <SCALAR> <START> <END>\n" "[ta-ema](ticker) <WINDOW> <OFFSET> <START> <END>\n" "[ta-sma](ticker) <WINDOW> <OFFSET> <START> <END>\n" "[ta-wma](ticker) <WINDOW> <OFFSET> <START> <END>\n" "[ta-hma](ticker) <WINDOW> <OFFSET> <START> <END>\n" "[ta-zlma](ticker) <WINDOW> <OFFSET> <START> <END>\n" "[ta-aroon](ticker) <LENGTH> <SCALAR> <START> <END>\n" "[ta-adosc](ticker) <OPEN> <FAST> <SLOW> <START> <END>\n" "[ta-macd](ticker) <FAST> <SLOW> <SIGNAL> <START> <END>\n" "[ta-kc](ticker) <LENGTH> <SCALAR> <MA_MODE> <START> <END>\n" "[ta-adx](ticker) <LENGTH> <SCALAR> <DRIFT> <START> <END>\n" "[ta-rsi](ticker) <LENGTH> <SCALAR> <DRIFT> <START> <END>\n" "[ta-stoch](ticker) <FAST_K> <SLOW_D> <SLOW_K> <START> <END>\n" "[ta-bbands](ticker) <LENGTH> <SCALAR> <MA_MODE> <START> <END>\n" "[ta-donchian](ticker) <LWR_LENGTH> <UPR_LENGTH> <START> <END>\n```" ) ddtext = ("```md\n[dd-est](ticker)\n" "[dd-sec](ticker)\n" "[dd-analyst](ticker)\n" "[dd-supplier](ticker)\n" "[dd-customer](ticker)\n" "[dd-arktrades](ticker)\n" "[dd-pt](ticker) <RAW> <DATE_START>\n```") dpstext = ("```md\n[dps.hsi]() <NUM>\n" "[dps.shorted](NUM)\n" "[dps.psi](ticker)\n" "[dps.spos](ticker)\n" "[dps.dpotc](ticker)\n" "[dps.pos]() <NUM> <SORT>\n" "[dps.sidtc]() <NUM> <SORT>\n" "[dps.ftd](ticker) <DATE_START> <DATE_END>\n```") scrtext = ("```md\n[scr.presets_default]()\n" "[scr.presets_custom]()\n" "[scr.historical](SIGNAL) <START>\n" "[scr.overview](PRESET) <SORT> <LIMIT> <ASCEND>\n" "[scr.technical](PRESET) <SORT> <LIMIT> <ASCEND>\n" "[scr.valuation](PRESET) <SORT> <LIMIT> <ASCEND>\n" "[scr.financial](PRESET) <SORT> <LIMIT> <ASCEND>\n" "[scr.ownership](PRESET) <SORT> <LIMIT> <ASCEND>\n" "[scr.performance](PRESET) <SORT> <LIMIT> <ASCEND>\n```") govtext = ("```md\n[gov-histcont](ticker)\n" "[gov-lobbying](ticker) <NUM>\n" "[gov-toplobbying]() <NUM> <RAW>\n" "[gov-lastcontracts]() <DAYS> <NUM>\n" "[gov-contracts](ticker) <DAYS> <RAW>\n" "[gov-qtrcontracts]() <ANALYSIS> <NUM>\n" "[gov-lasttrades]() <GOV_TYPE> <DAYS> <REP>\n" "[gov-gtrades](ticker) <GOV_TYPE> <MONTHS> <RAW>\n" "[gov-topbuys]() <GOV_TYPE> <MONTHS> <NUM> <RAW>\n" "[gov-topsells]() <GOV_TYPE> <MONTHS> <NUM> <RAW>\n```" "\n`<DAYS> = Past Transaction Days`\n" "`<MONTHS> = Past Transaction Months`") econtext = ("```md\n[econ-softs]()\n" "[econ-meats]()\n" "[econ-energy]()\n" "[econ-metals]()\n" "[econ-grains]()\n" "[econ-futures]()\n" "[econ-usbonds]()\n" "[econ-glbonds]()\n" "[econ-indices]()\n" "[econ-overview]()\n" "[econ-feargreed]()\n" "[econ-currencies]()\n" "[econ-valuation]() <GROUP>\n" "[econ-performance]() <GROUP>\n```") options = [disnake.SelectOption(label="Home", value="0", emoji="🟢")] embeds = [ disnake.Embed( title="Stocks: Technical Analysis Command List", description=tatext, color=cfg.COLOR, ), disnake.Embed( description=(f"**Options Command List**\n{opttext}\n" f"**Dark Pool Shorts Command List**\n{dpstext}\n" f"**Due Diligence Command List**\n{ddtext}\n"), color=cfg.COLOR, ), disnake.Embed( description=(f"**Screener Command List**\n{scrtext}\n" f"**Government Command List**\n{govtext}\n"), color=cfg.COLOR, ), disnake.Embed( description=(f"**Economy Command List**\n{econtext}\n" f"**Other Command List**\n{misctext}\n"), color=cfg.COLOR, ), disnake.Embed( title="No Manipulation Here", description="```diff\n- Nothing to SEC here..... Yet.\n```", color=cfg.COLOR, ), ] embeds[0].set_author( name=cfg.AUTHOR_NAME, url=cfg.AUTHOR_URL, icon_url=cfg.AUTHOR_ICON_URL, ) embeds[0].set_footer( text=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) embeds[0].set_footer(text=f"Page 1 of {len(embeds)}") await ctx.send(embed=embeds[0], view=Menu(embeds, options))
def holdings_command(etf="", num: int = 15): """Display ETF Holdings. [Source: StockAnalysis]""" if imps.DEBUG: logger.debug("etfs") holdings = stockanalysis_model.get_etf_holdings(etf.upper()) holdings = holdings.iloc[:num] if holdings.empty: raise Exception("No company holdings found!\n") title = f"ETF: {etf.upper()} Holdings" dindex = len(holdings.index) if dindex > 15: embeds: list = [] # Output i, i2, end = 0, 0, 15 df_pg, embeds_img, images_list = [], [], [] while i < dindex: df_pg = holdings.iloc[i:end] df_pg.append(df_pg) fig = imps.plot_df( df_pg, fig_size=(500, (40 + (40 * dindex))), col_width=[1, 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", "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( holdings, fig_size=(500, (40 + (40 * dindex))), col_width=[1, 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", "right"]))) imagefile = imps.save_image("etf-holdings.png", fig) output = { "title": title, "imagefile": imagefile, } return output
def borrowed_command(ticker: str = ""): """Displays borrowed shares available and fee [Stocksera.com]""" # Debug user input if imps.DEBUG: logger.debug("dd borrowed %s", ticker) # Check for argument if ticker == "": raise Exception("Stock ticker is required") df = pd.DataFrame( requests.get( f"https://stocksera.pythonanywhere.com/api/borrowed_shares/{ticker}" ).json() ) if df.empty: raise Exception("No Data Found") title = f"{ticker.upper()} Shares Available to Borrow [Stocksera]" df = df.head(200) df["changed"] = df["available"].astype(int).diff() df = df[df["changed"] != 0.0] df = df.drop(columns="changed") formats = {"fee": "{:.2f}%", "available": "{:,}"} for col, value in formats.items(): df[col] = df[col].map(lambda x: value.format(x)) # pylint: disable=W0640 df = df.rename(columns={"ticker": " ", "date_updated": "Updated"}) df.set_index(" ", inplace=True) df.columns = df.columns.str.capitalize() 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.iloc[i:end] df_pg.append(df_pg) fig = imps.plot_df( df_pg, fig_size=(550, (40 + (40 * len(df.index)))), col_width=[1, 1, 1.5, 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", "right", "right", "center"])) ) imagefile = "dd_borrowed.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=(550, (40 + (40 * len(df.index)))), col_width=[1, 1, 1.5, 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", "right", "right", "center"]))) imagefile = "dd_borrowed.png" imagefile = imps.save_image(imagefile, fig) output = { "title": title, "imagefile": imagefile, } return output
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, }
async def pos_command(ctx, sort="dpp_dollar", num: int = 10): """Dark pool short position [Stockgrid]""" try: # Debug user input if cfg.DEBUG: logger.debug("!stocks.dps.pos %s %s", sort, num) # Check for argument possible_sorts = ("sv", "sv_pct", "nsv", "nsv_dollar", "dpp", "dpp_dollar") if sort not in possible_sorts: raise Exception( f"The possible sorts are: {', '.join(possible_sorts)}") if num < 0: raise Exception("Number has to be above 0") # Retrieve data df = stockgrid_model.get_dark_pool_short_positions(sort, False) df = df.iloc[:num] # Debug user output if cfg.DEBUG: logger.debug(df.to_string()) # Output data dp_date = df["Date"].values[0] df = df.drop(columns=["Date"]) df["Net Short Volume $"] = df["Net Short Volume $"] / 100_000_000 df["Short Volume"] = df["Short Volume"] / 1_000_000 df["Net Short Volume"] = df["Net Short Volume"] / 1_000_000 df["Short Volume %"] = df["Short Volume %"] * 100 df["Dark Pools Position $"] = df["Dark Pools Position $"] / ( 1_000_000_000) df["Dark Pools Position"] = df["Dark Pools Position"] / 1_000_000 df.columns = [ "Ticker", "Short Vol. (1M)", "Short Vol. %", "Net Short Vol. (1M)", "Net Short Vol. ($100M)", "DP Position (1M)", "DP Position ($1B)", ] future_column_name = df["Ticker"] df = df.transpose() df.columns = future_column_name df.drop("Ticker") columns = [] choices = [ disnake.SelectOption(label="Overview", value="0", emoji="🟢"), ] initial_str = "Overview" i = 1 for col_name in df.columns.values: menu = f"\nPage {i}: {col_name}" initial_str += f"\nPage {i}: {col_name}" if i < 19: choices.append( disnake.SelectOption(label=menu, value=f"{i}", emoji="🟢"), ) if i == 20: choices.append( disnake.SelectOption(label="Max Reached", value=f"{i}", emoji="🟢"), ) i += 1 columns.append( disnake.Embed( title="Stocks: [Stockgrid] Dark Pool Short Position", description=initial_str, colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, )) for column in df.columns.values: columns.append( disnake.Embed( title="High Short Interest", description= "```The following data corresponds to the date: " + dp_date + "\n\n" + df[column].fillna("").to_string() + "```", colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, )) await ctx.send(embed=columns[0], view=Menu(columns, choices)) except Exception as e: embed = disnake.Embed( title="ERROR Stocks: [Stockgrid] Dark Pool Short Position", colour=cfg.COLOR, description=e, ) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed, delete_after=30.0)
def est_command(ticker: str = ""): """Displays earning estimates [Business Insider]""" # Debug if cfg.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 cfg.DEBUG: logger.debug(df_year_estimates.to_string()) logger.debug(df_quarter_earnings.to_string()) logger.debug(df_quarter_revenues.to_string()) dindex = len(df_year_estimates.index) fig = df2img.plot_dataframe( df_year_estimates, fig_size=(1200, (40 + (60 * dindex))), col_width=[12, 4, 4, 4, 4], tbl_cells=dict(height=35, ), font=dict( family="Consolas", size=20, ), template="plotly_dark", paper_bgcolor="rgba(0, 0, 0, 0)", ) imagefile = save_image("estimates.png", fig) uploaded_image = gst_imgur.upload_image(imagefile, title="something") link_estimates = uploaded_image.link os.remove(imagefile) fig = df2img.plot_dataframe( df_quarter_earnings, fig_size=(1200, (40 + (40 * 20))), col_width=[5, 5, 4, 4, 5, 4], tbl_cells=dict(height=35, ), font=dict( family="Consolas", size=20, ), template="plotly_dark", paper_bgcolor="rgba(0, 0, 0, 0)", ) imagefile = save_image("earnings.png", fig) uploaded_image = gst_imgur.upload_image(imagefile, title="something") link_earnings = uploaded_image.link os.remove(imagefile) fig = df2img.plot_dataframe( df_quarter_revenues, fig_size=(1200, (40 + (40 * 20))), col_width=[5, 5, 4, 4, 5, 4], tbl_cells=dict(height=35, ), font=dict( family="Consolas", size=20, ), template="plotly_dark", paper_bgcolor="rgba(0, 0, 0, 0)", ) imagefile = save_image("revenues.png", fig) uploaded_image = gst_imgur.upload_image(imagefile, title="something") link_revenues = uploaded_image.link os.remove(imagefile) embeds = [ disnake.Embed( title=f"**{ticker.upper()} Year Estimates**", color=cfg.COLOR, ), disnake.Embed( title=f"**{ticker.upper()} Quarter Earnings**", colour=cfg.COLOR, ), disnake.Embed( title=f"**{ticker.upper()} Quarter Revenues**", colour=cfg.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": Menu, "titles": titles, "embed": embeds, "choices": choices, "embeds_img": embeds_img, }
def options_run( ticker, url, expiry, dates, df_bcinfo, calls, puts, df_opt, current_price, min_strike, max_strike, min_strike2, max_strike2, max_pain, ): """Options Overview""" titles, reports, embeds, embeds_img, choices, images_list = [], [], [], [], [], [] fig = go.Figure() dmax = df_opt[["OI_call", "OI_put"]].values.max() dmin = df_opt[["OI_call", "OI_put"]].values.min() fig.add_trace( go.Scatter( x=df_opt.index, y=df_opt["OI_call"], name="Calls", mode="lines+markers", line=dict(color="#00ACFF", width=3), )) fig.add_trace( go.Scatter( x=df_opt.index, y=df_opt["OI_put"], name="Puts", mode="lines+markers", line=dict(color="#e4003a", width=3), )) fig.add_trace( go.Scatter( x=[current_price, current_price], y=[dmin, dmax], mode="lines", line=dict(color="gold", width=2), name="Current Price", )) fig.add_trace( go.Scatter( x=[max_pain, max_pain], y=[dmin, dmax], mode="lines", line=dict(color="grey", width=3, dash="dash"), name=f"Max Pain: {max_pain}", )) if imps.PLT_WATERMARK: fig.add_layout_image(imps.PLT_WATERMARK) fig.update_xaxes( range=[min_strike, max_strike], constrain="domain", ) fig.update_layout( margin=dict(l=0, r=0, t=60, b=20), template=imps.PLT_SCAT_STYLE_TEMPLATE, title=f"Open Interest for {ticker.upper()} expiring {expiry}", title_x=0.5, legend_title="", xaxis_title="Strike", yaxis_title="Open Interest (1k)", xaxis=dict(rangeslider=dict(visible=False), ), font=imps.PLT_FONT, legend=dict(yanchor="top", y=0.99, xanchor="left", x=0.01), dragmode="pan", ) imagefile = "opt-oi.png" plt_link = "" if imps.INTERACTIVE: plt_link = imps.inter_chart(fig, imagefile, callback=False) reports.append(plt_link) fig.update_layout( width=800, height=500, ) imagefile = imps.image_border(imagefile, fig=fig) if imps.IMAGES_URL or not imps.IMG_HOST_ACTIVE: image_link_oi = imps.multi_image(imagefile) images_list.append(imagefile) else: image_link_oi = imps.multi_image(imagefile) calls_df = calls[columns].rename(columns=column_map) calls_df = calls_df[calls_df["strike"] >= min_strike2] calls_df = calls_df[calls_df["strike"] <= max_strike2] calls_df["iv"] = pd.to_numeric(calls_df["iv"].astype(float)) formats = {"iv": "{:.2f}"} for col, f in formats.items(): calls_df[col] = calls_df[col].map(lambda x: f.format(x)) calls_df = calls_df.fillna("") calls_df.set_index("strike", inplace=True) if "^" not in ticker: if "-" in df_bcinfo.iloc[0, 1]: iv = f"```diff\n- {df_bcinfo.iloc[0, 1]}\n```" else: iv = f"```yaml\n {df_bcinfo.iloc[0, 1]}\n```" pfix, sfix = f"{ticker.upper()} ", f" expiring {expiry}" if expiry == dates[0]: pfix = f"{ticker.upper()} Weekly " sfix = "" titles.append(f"{ticker.upper()} Overview", ) titles.append(f"{pfix}Open Interest{sfix}", ) embeds.append( disnake.Embed( title=f"{ticker.upper()} Overview", color=imps.COLOR, ), ) embeds.append( disnake.Embed( title=f"{pfix}Open Interest{sfix}", description=plt_link, colour=imps.COLOR, ), ) choices.append( disnake.SelectOption(label=f"{ticker.upper()} Overview", value="0", emoji="🟢"), ) choices.append( disnake.SelectOption(label=f"{pfix}Open Interest{sfix}", value="1", emoji="🟢"), ) i, i2, end = 0, 0, 20 df_calls = [] dindex = len(calls_df.index) while i < dindex: df_calls = calls_df.iloc[i:end] df_calls.append(df_calls) figc = imps.plot_df( df_calls, fig_size=(1000, (40 + (40 * 20))), col_width=[3, 3, 3, 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)", ) imagefile = "opt-calls.png" imagefile = imps.save_image(imagefile, figc) 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}", ) titles.append(f"{pfix}Calls{sfix}", ) embeds.append( disnake.Embed( title=f"{pfix}Calls{sfix}", colour=imps.COLOR, ), ) i2 += 1 i += 20 end += 20 # Add Calls page field i, page, puts_page = 2, 0, 3 i3 = i2 + 2 choices.append( disnake.SelectOption(label="Calls Page 1", value="2", emoji="🟢"), ) for i in range(2, i3): page += 1 puts_page += 1 embeds[i].add_field(name=f"Calls Page {page}", value="_ _", inline=True) puts_df = puts[columns].rename(columns=column_map) puts_df = puts_df[puts_df["strike"] >= min_strike2] puts_df = puts_df[puts_df["strike"] <= max_strike2] puts_df["iv"] = pd.to_numeric(puts_df["iv"].astype(float)) formats = {"iv": "{:.2f}"} for col, f in formats.items(): puts_df[col] = puts_df[col].map(lambda x: f.format(x)) # pylint: disable=W0640 puts_df = puts_df.fillna("") puts_df.set_index("strike", inplace=True) pfix, sfix = f"{ticker.upper()} ", f" expiring {expiry}" if expiry == dates[0]: pfix = f"{ticker.upper()} Weekly " sfix = "" # Puts Pages i, end = 0, 20 df_puts = [] dindex = len(puts_df.index) while i < dindex: df_puts = puts_df.iloc[i:end] df_puts.append(df_puts) figp = imps.plot_df( df_puts, fig_size=(1000, (40 + (40 * 20))), col_width=[3, 3, 3, 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)", ) imagefile = "opt-puts.png" imagefile = imps.save_image(imagefile, figp) 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}", ) titles.append(f"{pfix}Puts{sfix}", ) embeds.append( disnake.Embed( title=f"{pfix}Puts{sfix}", colour=imps.COLOR, ), ) i2 += 1 i += 20 end += 20 # Add Puts page field i, page = 0, 0 puts_page -= 1 i2 += 2 choices.append( disnake.SelectOption(label="Puts Page 1", value=f"{puts_page}", emoji="🟢"), ) for i in range(puts_page, i2): page += 1 embeds[i].add_field(name=f"Puts Page {page}", value="_ _", inline=True) # 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, ) # Set images to Pages i = 0 img_i = 0 embeds[1].set_image(url=image_link_oi) for i in range(2, i2): embeds[i].set_image(url=embeds_img[img_i]) img_i += 1 i += 1 if url: embeds[0].set_thumbnail(url=f"{url}") else: embeds[0].set_thumbnail(url=imps.AUTHOR_ICON_URL) # Overview Section if "^" not in ticker: reports.append( f"{'':^5}*{df_bcinfo.iloc[0, 0]:^25}*{'':^5}*{df_bcinfo.iloc[1, 0]:^25}*{'':^5}\n" ) reports.append( f"{'':^8}{df_bcinfo.iloc[0, 1]:^25}{'':^5}{df_bcinfo.iloc[1, 1]:^25}\n" ) i, i2 = 2, 3 while i < 11: text = ( f"{'':^5}*{df_bcinfo.iloc[i, 0]:^25}*{'':^5}*{df_bcinfo.iloc[i2, 0]:^25}*{'':^5}\n" f"{'':^5}{df_bcinfo.iloc[i, 1]:^30}{'':^5}{df_bcinfo.iloc[i2, 1]:^25}{'':^10}\n" ) reports.append(text) i += 1 i2 += 1 embeds[0].add_field(name=f"{df_bcinfo.iloc[0, 0]}", value=iv, inline=False) embeds[0].add_field( name=f"•{df_bcinfo.iloc[1, 0]}", value=f"```css\n{df_bcinfo.iloc[1, 1]}\n```", inline=True, ) for N in range(2, 6): embeds[0].add_field( name=f"_ _ _ _ _ _ _ _ _ _ •{df_bcinfo.iloc[N, 0]}", value=f"```css\n{df_bcinfo.iloc[N, 1]}\n```", inline=True, ) embeds[0].add_field(name="_ _", value="_ _", inline=False) for N in range(6, 8): embeds[0].add_field( name=f"_ _ _ _ _ _ _ _ _ _ •{df_bcinfo.iloc[N, 0]}", value=f"```css\n{df_bcinfo.iloc[N, 1]}\n```", inline=True, ) embeds[0].add_field(name="_ _", value="_ _", inline=False) for N in range(8, 10): embeds[0].add_field( name=f"_ _ _ _ _ _ _ _ _ _ •{df_bcinfo.iloc[N, 0]}", value=f"```css\n{df_bcinfo.iloc[N, 1]}\n```", inline=True, ) embeds[0].add_field(name="_ _", value="_ _", inline=False) for N in range(10, 12): embeds[0].add_field( name=f"_ _ _ _ _ _ _ _ _ _ •{df_bcinfo.iloc[N, 0]}", value=f"```css\n{df_bcinfo.iloc[N, 1]}\n```", inline=True, ) embeds[0].set_footer(text=f"Page 1 of {len(embeds)}") return titles, reports, embeds, choices, embeds_img, images_list
def reverse_repo_command(days: int = 50): """Displays Reverse Repo [Stocksera.com]""" # Debug user input if imps.DEBUG: logger.debug("dd repo %s", days) df = pd.DataFrame( requests.get( f"https://stocksera.pythonanywhere.com/api/reverse_repo/?days={str(days)}" ).json() ) if df.empty: raise Exception("No Data Found") title = "Reverse Repo [Stocksera]" df["Difference"] = df["Amount"].diff().fillna(0) formats = { "Amount": "${:.2f}B", "Average": "${:.2f}B", "Difference": "<b>${:.2f}B</b>", } for col, value in formats.items(): df[col] = df[col].map(lambda x: value.format(x)) # pylint: disable=W0640 df = df.drop(columns="Moving Avg") df = df.sort_values(by="Date", ascending=False) font_color = ["white"] * 4 + [ [ "#e4003a" if boolv else "#00ACFF" for boolv in df["Difference"].str.contains("-") ] # type: ignore ] df.set_index("Date", inplace=True) df.columns = df.columns.str.capitalize() 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.iloc[i:end] font_color = ["white"] * 4 + [ [ "#e4003a" if boolv else "#00ACFF" for boolv in df_pg["Difference"].str.contains("-") ] # type: ignore ] df_pg.append(df_pg) fig = imps.plot_df( df_pg, fig_size=(650, (40 + (40 * len(df.index)))), col_width=[1.8, 1.5, 1.7, 1.3, 1.8], 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", "center", "right"], font=dict(color=font_color), ) ) ) imagefile = "dd_r_repo.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=(650, (40 + (40 * len(df.index)))), col_width=[1.8, 1.5, 1.7, 1.3, 1.8], 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", "center", "right"], font=dict(color=font_color), ) ) ) imagefile = "dd_r_repo.png" imagefile = imps.save_image(imagefile, fig) output = { "title": title, "imagefile": imagefile, } return output
def ownership_command( preset: str = "template", sort: str = "", limit: int = 5, ascend: bool = False ): """Displays stocks based on own share float and ownership data [Finviz]""" # Check for argument if preset == "template" or preset not in so.all_presets: raise Exception("Invalid preset selected!") # Debug if imps.DEBUG: logger.debug("scr-ownership %s %s %s %s", preset, sort, limit, ascend) # Check for argument if limit < 0: raise Exception("Number has to be above 0") # Output Data df_screen = get_screener_data( preset, "ownership", limit, ascend, ) title = "Stocks: [Finviz] Ownership Screener" if isinstance(df_screen, pd.DataFrame): if df_screen.empty: raise Exception("No data found.") df_screen = df_screen.dropna(axis="columns", how="all") if sort: if sort in so.d_cols_to_sort["ownership"]: df_screen = df_screen.sort_values( by=sort, ascending=ascend, na_position="last", ) else: similar_cmd = difflib.get_close_matches( " ".join(sort), so.d_cols_to_sort["ownership"], n=1, cutoff=0.7, ) if similar_cmd: df_screen = df_screen.sort_values( by=[similar_cmd[0]], ascending=ascend, na_position="last", ) else: raise ValueError( f"Wrong sort column provided! Select from: {', '.join(so.d_cols_to_sort['ownership'])}" ) df_screen.set_index("Ticker", inplace=True) df_screen = df_screen.head(n=limit) df_screen = df_screen.fillna("-") dindex = len(df_screen.index) df_screen = df_screen.applymap(lambda x: lambda_long_number_format(x, 2)) if dindex > 5: embeds: list = [] # Output i, i2, end = 0, 0, 5 df_pg, embeds_img, images_list = pd.DataFrame(), [], [] while i < dindex: df_pg = df_screen.iloc[i:end] df_pg.append(df_pg) fig = imps.plot_df( df_pg.transpose(), fig_size=(800, 720), col_width=[2, 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", "right"]))) imagefile = "scr_ownership.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 += 5 end += 5 # 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_screen.transpose(), fig_size=(800, 720), col_width=[2, 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", "right"]))) imagefile = imps.save_image("scr_ownership.png", fig) output = { "title": title, "imagefile": imagefile, } return output
async def lasttrades_command(ctx, gov_type="", past_days: int = 5, representative=""): """Displays trades made by the congress/senate/house [quiverquant.com]""" try: # Debug user input if cfg.DEBUG: logger.debug( "!stocks.gov.lasttrades %s %s %s", gov_type, past_days, representative, ) possible_args = ["congress", "senate", "house"] if gov_type == "": gov_type = "congress" elif gov_type not in possible_args: raise Exception( "Enter a valid government argument, options are: congress, senate and house" ) # Retrieve Data df_gov = quiverquant_model.get_government_trading(gov_type) # Output Data if df_gov.empty: raise Exception(f"No {gov_type} trading data found") df_gov = df_gov.sort_values("TransactionDate", ascending=False) df_gov = df_gov[df_gov["TransactionDate"].isin( df_gov["TransactionDate"].unique()[:past_days])] if gov_type == "congress": df_gov = df_gov[[ "TransactionDate", "Ticker", "Representative", "Transaction", "Range", "House", "ReportDate", ]].rename( columns={ "TransactionDate": "Transaction Date", "ReportDate": "Report Date", }) else: df_gov = df_gov[[ "TransactionDate", "Ticker", "Representative", "Transaction", "Range", ]].rename(columns={"TransactionDate": "Transaction Date"}) if representative: df_gov_rep = df_gov[df_gov["Representative"].str.split().str[0] == representative] if df_gov_rep.empty: raise Exception( f"No representative {representative} found in the past {past_days}" f" days. The following are available: " f"{', '.join(df_gov['Representative'].str.split().str[0].unique())}" ) choices = [ disnake.SelectOption(label="Overview", value="0", emoji="🟢"), ] initial_str = "Overview" i = 1 for col_name in df_gov_rep["Ticker"].values: menu = f"\nPage {i}: {col_name}" initial_str += f"\nPage {i}: {col_name}" if i < 19: choices.append( disnake.SelectOption(label=menu, value=f"{i}", emoji="🟢"), ) if i == 20: choices.append( disnake.SelectOption(label="Max Reached", value=f"{i}", emoji="🟢"), ) i += 1 columns = [] df_gov_rep = df_gov_rep.T columns.append( disnake.Embed( title= f"Stocks: [quiverquant.com] Trades by {representative}", description=initial_str, colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, )) for column in df_gov_rep.columns.values: columns.append( disnake.Embed( description="```" + df_gov_rep[column].fillna("").to_string() + "```", colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, )) await ctx.send(embed=columns[0], view=Menu(columns, choices)) else: choices = [ disnake.SelectOption(label="Overview", value="0", emoji="🟢"), ] initial_str = "Overview" i = 1 for col_name in df_gov["Ticker"].values: menu = f"\nPage {i}: {col_name}" initial_str += f"\nPage {i}: {col_name}" if i < 19: choices.append( disnake.SelectOption(label=menu, value=f"{i}", emoji="🟢"), ) if i == 20: choices.append( disnake.SelectOption(label="Max Reached", value=f"{i}", emoji="🟢"), ) i += 1 columns = [] df_gov = df_gov.T columns.append( disnake.Embed( title= f"Stocks: [quiverquant.com] Trades for {gov_type.upper()}", description=initial_str, colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, )) for column in df_gov.columns.values: columns.append( disnake.Embed( description="```" + df_gov[column].fillna("").to_string() + "```", colour=cfg.COLOR, ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, )) await ctx.send(embed=columns[0], view=Menu(columns, choices)) except Exception as e: embed = disnake.Embed( title= f"ERROR Stocks: [quiverquant.com] Trades by {gov_type.upper()}", colour=cfg.COLOR, description=e, ) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed, delete_after=30.0)