async def vol( self, ctx: discord.ext.commands.Context, ticker: str = None, expiry: str = None, min_sp: float = None, max_sp: float = None, ): """Display options volume for ticker and given expiration Parameters ----------- ticker: str ticker strike: float strike expiry: str accepts 0-9 or YYYY-MM-DD min_sp: float min strike price max_sp:float max strike price Sends a message to the discord user with the expiry dates if empty. The user can then select a reaction to trigger the selected date. """ logger.info("stocks.opt.vol %s %s %s %s", ticker, expiry, min_sp, max_sp) async with ctx.typing(): await asyncio.sleep(0.2) call_arg = (min_sp, max_sp) func_cmd = vol_command await expiry_dates_reaction(ctx, ticker, expiry, func_cmd, call_arg)
async def gtrades( self, ctx: discord.ext.commands.Context, ticker="", gov_type="", past_transactions_months="", raw="", ): """Displays government trades [quiverquant.com] Parameters ----------- ticker: str ticker, -h or help gov_type: str Possible arguments: congress, senate & house past_transactions_months: int Positive number of past transaction months raw: boolean True or false """ logger.info("stocks.gov.gtrades") await gtrades_command(ctx, ticker, gov_type, past_transactions_months, raw)
async def government_menu(self, ctx: discord.ext.commands.Context, ticker=""): """Stocks Context - Shows Government Menu Run `!help GovernmentCommands` to see the list of available commands. Returns ------- Sends a message to the discord user with the commands from the gov context. The user can then select a reaction to trigger a command. """ logger.info("!stocks.gov %s", ticker) text = ( "0️⃣ !stocks.gov.lasttrades <GOV_TYPE> <PAST_TRANSACTION_DAYS> " "<REPRESENTATIVE>\n" "1️⃣ !stocks.gov.topbuys <GOV_TYPE> <PAST_TRANSACTION_MONTHS>" "<NUM> <RAW>\n" "2️⃣ !stocks.gov.topsells <GOV_TYPE> <PAST_TRANSACTION_MONTHS>" "<NUM> <RAW>\n" "3️⃣ !stocks.gov.lastcontracts <PAST_TRANSACTION_DAYS> <NUM>\n" "4️⃣ !stocks.gov.qtrcontracts <ANALYSIS> <NUM>\n" "5️⃣ !stocks.gov.toplobbying <NUM> <RAW>\n") if ticker: text += ( f"6️⃣ !stocks.gov.gtrades {ticker} <GOV_TYPE> <PAST_TRANSACTION_MONTHS>" f"<RAW>\n" f"7️⃣ !stocks.gov.contracts {ticker} <PAST_TRANSACTION_DAYS> <RAW>\n" f"8️⃣ !stocks.gov.histcont {ticker}\n" f"9️⃣ !stocks.gov.lobbying {ticker} <NUM>\n") else: text += ("\nMore commands available when providing a ticker with:" "\n!stocks.gov <TICKER>") title = "Stocks: Government (GOV) Menu" embed = discord.Embed(title=title, description=text, colour=cfg.COLOR) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) msg = await ctx.send(embed=embed) emoji_list = ["0️⃣", "1️⃣", "2️⃣", "3️⃣", "4️⃣"] if ticker: emoji_list += ["5️⃣", "6️⃣", "7️⃣", "8️⃣", "9️⃣"] for emoji in emoji_list: await msg.add_reaction(emoji) def check(reaction, user): return user == ctx.message.author and str( reaction.emoji) in emoji_list try: reaction, _ = await gst_bot.wait_for("reaction_add", timeout=cfg.MENU_TIMEOUT, check=check) if reaction.emoji == "0️⃣": logger.info("Reaction selected: 0") await lasttrades_command(ctx) elif reaction.emoji == "1️⃣": logger.info("Reaction selected: 1") await topbuys_command(ctx) elif reaction.emoji == "2️⃣": logger.info("Reaction selected: 2") await topsells_command(ctx) elif reaction.emoji == "3️⃣": logger.info("Reaction selected: 3") await lastcontracts_command(ctx) elif reaction.emoji == "4️⃣": logger.info("Reaction selected: 4") await qtrcontracts_command(ctx) elif reaction.emoji == "5️⃣": logger.info("Reaction selected: 5") await toplobbying_command(ctx, ticker) elif reaction.emoji == "6️⃣": logger.info("Reaction selected: 6") await gtrades_command(ctx, ticker) elif reaction.emoji == "7️⃣": logger.info("Reaction selected: 7") await contracts_command(ctx, ticker) elif reaction.emoji == "8️⃣": logger.info("Reaction selected: 8") await histcont_command(ctx, ticker) elif reaction.emoji == "9️⃣": logger.info("Reaction selected: 9") await lobbying_command(ctx, ticker) for emoji in emoji_list: await msg.remove_reaction(emoji, ctx.bot.user) except asyncio.TimeoutError: for emoji in emoji_list: await msg.remove_reaction(emoji, ctx.bot.user) if cfg.DEBUG: embed = discord.Embed( description="Error timeout - you snooze you lose! 😋", colour=cfg.COLOR, title="TIMEOUT Stocks: Government (GOV) Menu", ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed)
async def presets_custom(self, ctx: discord.ext.commands.Context): """Displays every available preset""" logger.info("stocks.scr.presets_custom") await presets_custom_command(ctx)
async def scr(self, ctx: discord.ext.commands.Context, preset=""): """Screener Context Menu Run `!help ScreenerCommands` to see the list of available commands. Returns ------- Sends a message to the discord user with the commands from the screener context. The user can then select a reaction to trigger a command. """ logger.info("!stocks.scr") if preset != "" and preset not in so.all_presets: raise Exception("Invalid preset selected!") if preset: text = ( "0️⃣ !stocks.scr.presets_default\n" "1️⃣ !stocks.scr.presets_custom\n" "2️⃣ !stocks.scr.historical <SIGNAL> <START>\n" f"3️⃣ !stocks.scr.overview {preset} <SORT> <LIMIT> <ASCEND>\n" f"4️⃣ !stocks.scr.valuation {preset} <SORT> <LIMIT> <ASCEND>\n" f"5️⃣ !stocks.scr.financial {preset} <SORT> <LIMIT> <ASCEND>\n" f"6️⃣ !stocks.scr.ownership {preset} <SORT> <LIMIT> <ASCEND>\n" f"7️⃣ !stocks.scr.performance {preset} <SORT> <LIMIT> <ASCEND>\n" f"8️⃣ !stocks.scr.technical {preset} <SORT> <LIMIT> <ASCEND>") else: text = ( "0️⃣ !stocks.scr.presets_default\n" "1️⃣ !stocks.scr.presets_custom\n" "2️⃣ !stocks.scr.historical <SIGNAL> <START>\n" "3️⃣ !stocks.scr.overview <PRESET> <SORT> <LIMIT> <ASCEND>\n" "4️⃣ !stocks.scr.valuation <PRESET> <SORT> <LIMIT> <ASCEND>\n" "5️⃣ !stocks.scr.financial <PRESET> <SORT> <LIMIT> <ASCEND>\n" "6️⃣ !stocks.scr.ownership <PRESET> <SORT> <LIMIT> <ASCEND>\n" "7️⃣ !stocks.scr.performance <PRESET> <SORT> <LIMIT> <ASCEND>\n" "8️⃣ !stocks.scr.technical <PRESET> <SORT> <LIMIT> <ASCEND>") title = "Screener Menu" embed = discord.Embed(title=title, description=text, colour=cfg.COLOR) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) msg = await ctx.send(embed=embed) emoji_list = [ "0️⃣", "1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣", "8️⃣" ] for emoji in emoji_list: await msg.add_reaction(emoji) def check(reaction, user): return user == ctx.message.author and str( reaction.emoji) in emoji_list try: reaction, _ = await gst_bot.wait_for("reaction_add", timeout=cfg.MENU_TIMEOUT, check=check) if reaction.emoji == "0️⃣": logger.info("!stocks.scr. Reaction selected: 0") await presets_default_command(ctx) elif reaction.emoji == "1️⃣": logger.info("!stocks.scr. Reaction selected: 1") await presets_custom_command(ctx) elif reaction.emoji == "2️⃣": logger.info("!stocks.scr. Reaction selected: 2") await historical_command(ctx, preset) elif reaction.emoji == "3️⃣": logger.info("!stocks.scr. Reaction selected: 3") await overview_command(ctx, preset) elif reaction.emoji == "4️⃣": logger.info("!stocks.scr. Reaction selected: 4") await valuation_command(ctx, preset) elif reaction.emoji == "5️⃣": logger.info("!stocks.scr. Reaction selected: 5") await financial_command(ctx, preset) elif reaction.emoji == "6️⃣": logger.info("!stocks.scr. Reaction selected: 6") await ownership_command(ctx, preset) elif reaction.emoji == "7️⃣": logger.info("!stocks.scr. Reaction selected: 7") await performance_command(ctx, preset) elif reaction.emoji == "8️⃣": logger.info("!stocks.scr. Reaction selected: 8") await technical_command(ctx, preset) for emoji in emoji_list: await msg.remove_reaction(emoji, ctx.bot.user) except asyncio.TimeoutError: for emoji in emoji_list: await msg.remove_reaction(emoji, ctx.bot.user) if cfg.DEBUG: embed = discord.Embed( description="Error timeout - you snooze you lose! 😋", colour=cfg.COLOR, title="TIMEOUT Screener Menu", ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed)
async def opt( self, ctx: discord.ext.commands.Context, ticker="", expiration="", strike="", put="", ): """Stocks Context - Shows Options Menu Run `!help OptionsCommands` to see the list of available commands. Returns ------- Sends a message to the discord user with the commands from the stocks/options context. The user can then select a reaction to trigger a command. """ logger.info("!stocks.opt %s %s %s %s", ticker, expiration, strike, put) async with ctx.typing(): await asyncio.sleep(0.2) if TRADIER_TOKEN == "REPLACE_ME": # nosec dates = yfinance_model.option_expirations(ticker) else: dates = tradier_model.option_expirations(ticker) index_dates = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] if not ticker: current = 0 text = ( "```0️⃣ !stocks.opt.unu```\n" "Provide a ticker and expiration date with this menu,\n" "\ne.g.\n!stocks.opt TSLA 0-9\n!stocks.opt TSLA 2021-06-04" ) if (ticker != "") and (expiration == ""): current = 1 text = ("```0️⃣ !stocks.opt.unu\n" f"1️⃣ !stocks.opt.exp {ticker}\n" f"2️⃣ !stocks.opt.iv {ticker}\n```") if expiration: current = 2 exp = int(expiration.replace("-", "")) if exp > 9 and (expiration not in dates) and (exp not in index_dates): call_arg = (strike, put) func_cmd = opt_command expiry = None await expiry_dates_reaction(ctx, ticker, expiry, func_cmd, call_arg) return if exp in index_dates: expiration = dates[int(expiration)] hist = f"7️⃣ !stocks.opt.hist {ticker} (strike*) (c/p*) {expiration}\n\n* Required" if strike and put: hist = f"7️⃣ !stocks.opt.hist {ticker} {strike} {put} {expiration}" current = 3 text = ("```0️⃣ !stocks.opt.unu\n" f"1️⃣ !stocks.opt.exp {ticker}\n" f"2️⃣ !stocks.opt.iv {ticker}\n" f"3️⃣ !stocks.opt.calls {ticker} {expiration} \n" f"4️⃣ !stocks.opt.puts {ticker} {expiration} \n" f"5️⃣ !stocks.opt.oi {ticker} {expiration} \n" f"6️⃣ !stocks.opt.vol {ticker} {expiration} \n" f"{hist}```") if put == "p": put = bool(True) if put == "c": put = bool(False) title = "Stocks: Options Menu" embed = discord.Embed(title=title, description=text, colour=cfg.COLOR) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) msg = await ctx.send(embed=embed, delete_after=60.0) if current == 0: emoji_list = ["0️⃣"] if current == 1: emoji_list = ["0️⃣", "1️⃣", "2️⃣"] if current == 2: emoji_list = ["0️⃣", "1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣"] if current == 3: emoji_list = [ "0️⃣", "1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣" ] for emoji in emoji_list: await msg.add_reaction(emoji) def check(reaction, user): return user == ctx.message.author and str( reaction.emoji) in emoji_list try: reaction, _ = await gst_bot.wait_for("reaction_add", timeout=cfg.MENU_TIMEOUT, check=check) if reaction.emoji == "0️⃣": logger.info("Reaction selected: 0") await unu_command(ctx) elif reaction.emoji == "1️⃣": logger.info("Reaction selected: 1") await expirations_command(ctx, ticker) elif reaction.emoji == "2️⃣": logger.info("Reaction selected: 2") await iv_command(ctx, ticker) elif reaction.emoji == "3️⃣": logger.info("Reaction selected: 3") await calls_command(ctx, ticker, expiration) elif reaction.emoji == "4️⃣": logger.info("Reaction selected: 4") await puts_command(ctx, ticker, expiration) elif reaction.emoji == "5️⃣": logger.info("Reaction selected: 5") await oi_command(ctx, ticker, expiration) elif reaction.emoji == "6️⃣": logger.info("Reaction selected: 6") await vol_command(ctx, ticker, expiration) elif reaction.emoji == "7️⃣": logger.info("Reaction selected: 7") strike = float(strike) await hist_command(ctx, ticker, expiration, strike, put) for emoji in emoji_list: await msg.remove_reaction(emoji, ctx.bot.user) except asyncio.TimeoutError: for emoji in emoji_list: await msg.remove_reaction(emoji, ctx.bot.user) if cfg.DEBUG: embed = discord.Embed( description="Error timeout - you snooze you lose! 😋", colour=cfg.COLOR, title="TIMEOUT Stocks: Options Menu", ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed, delete_after=30.0)
async def hist( self, ctx: discord.ext.commands.Context, ticker: str = None, strike: float = None, put="", expiry: str = None, ): """Display chart of given option historical price [Tradier] Parameters ----------- ticker: str ticker strike: float strike put: bool c for call p for put expiry: str accepts 0-9 or YYYY-MM-DD Sends a message to the discord user with the expiry dates if empty. The user can then select a reaction to trigger the selected date. """ logger.info("!stocks.opt.hist %s %s %s %s", ticker, strike, put, expiry) async with ctx.typing(): await asyncio.sleep(0.2) try: error = "" if TRADIER_TOKEN == "REPLACE_ME": # nosec raise Exception("Tradier Token is required") if expiry in ("c", "p"): raise Exception( 'Invalid format.\n\nUse:\n```bash\n"!stocks.opt.hist {ticker} {strike} {c/p}"```' '```bash\n"!stocks.opt {ticker} {expiration} {strike} {c/p}"```' ) if strike is None or put == "": raise Exception( 'A strike and c/p is required\n```bash\n"!stocks.opt.hist {ticker} {strike} {c/p}"```' ) if put == "p": put = bool(True) if put == "c": put = bool(False) call_arg = ( strike, put, ) func_cmd = hist_command await expiry_dates_reaction(ctx, ticker, expiry, func_cmd, call_arg) except TypeError: error = ( 'Invalid format.\n\nUse:\n```bash\n"!stocks.opt.hist {ticker} {strike} {c/p}"```' '```bash\n"!stocks.opt {ticker} {expiration} {strike} {c/p}"```' ) except Exception as e: error = str(e) finally: if error: logger.error(error) embed = discord.Embed( title="ERROR Options: History", colour=cfg.COLOR, description=error, ) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed, delete_after=30.0)
async def expiry_dates_reaction(ctx, ticker, expiry, func_cmd, call_arg: tuple = None): if TRADIER_TOKEN == "REPLACE_ME": # nosec dates = yfinance_model.option_expirations(ticker) else: dates = tradier_model.option_expirations(ticker) index_dates = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] if expiry is not None: try: if expiry not in dates: exp = int(expiry.replace("-", "")) if (expiry not in dates) and (exp not in index_dates): raise Exception("Enter a valid expiration date.") if expiry in dates: if call_arg is None: await func_cmd(ctx, ticker, expiry) else: await func_cmd(ctx, ticker, expiry, *call_arg) return if exp in index_dates: expiry = dates[int(expiry)] if call_arg is None: await func_cmd(ctx, ticker, expiry) else: await func_cmd(ctx, ticker, expiry, *call_arg) return except Exception as e: embed = discord.Embed( title="ERROR Options: Expiry Date", 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=10.0) return if not dates: embed = discord.Embed( title="ERROR Options", colour=cfg.COLOR, description="Enter a valid stock ticker", ) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed, delete_after=10.0) return text = ("```0️⃣ " + dates[0] + "\n" "1️⃣ " + dates[1] + "\n" "2️⃣ " + dates[2] + "\n" "3️⃣ " + dates[3] + "\n" "4️⃣ " + dates[4] + "\n" "5️⃣ " + dates[5] + "\n" "6️⃣ " + dates[6] + "\n" "7️⃣ " + dates[7] + "\n" "8️⃣ " + dates[8] + "\n" "9️⃣ " + dates[9] + "```") title = " " + ticker.upper() + " Options: Expiry Date" embed = discord.Embed(title=title, description=text, colour=cfg.COLOR) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) msg = await ctx.send(embed=embed, delete_after=15.0) emoji_list = [ "0️⃣", "1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣", "8️⃣", "9️⃣" ] for emoji in emoji_list: await msg.add_reaction(emoji) def check(reaction, user): return user == ctx.message.author and str(reaction.emoji) in emoji_list try: reaction, _ = await gst_bot.wait_for("reaction_add", timeout=cfg.MENU_TIMEOUT, check=check) for N in range(0, 10): if reaction.emoji == emoji_list[N]: logger.info("Reaction selected: %d", N) expiry = dates[N] if call_arg is None: await func_cmd(ctx, ticker, expiry) else: await func_cmd(ctx, ticker, expiry, *call_arg) for emoji in emoji_list: await msg.remove_reaction(emoji, ctx.bot.user) except asyncio.TimeoutError: for emoji in emoji_list: await msg.remove_reaction(emoji, ctx.bot.user) if cfg.DEBUG: embed = discord.Embed( description="Error timeout - you snooze you lose! 😋", colour=cfg.COLOR, title="TIMEOUT " + ticker.upper() + " Options: Expiry Date", ) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed, delete_after=10.0)
async def on_reaction_add(reaction, user): if user == ctx.message.author and str(reaction.emoji) in emoji_list: if reaction.emoji == "0️⃣": logger.info("!stocks.ta. Reaction selected: 0") if current == 0: await view_command(ctx, ticker) elif current == 1: await rsi_command(ctx, ticker) elif current == 2: await adosc_command(ctx, ticker) elif reaction.emoji == "1️⃣": logger.info("!stocks.ta. Reaction selected: 1") if current == 0: await summary_command(ctx, ticker) elif current == 1: await stoch_command(ctx, ticker) elif current == 2: await obv_command(ctx, ticker) elif reaction.emoji == "2️⃣": logger.info("!stocks.ta. Reaction selected: 2") if current == 0: await recom_command(ctx, ticker) elif current == 1: await fisher_command(ctx, ticker) elif current == 2: await fib_command(ctx, ticker) elif reaction.emoji == "3️⃣": logger.info("!stocks.ta. Reaction selected: 3") if current == 0: await ema_command(ctx, ticker) elif current == 1: await cg_command(ctx, ticker) elif reaction.emoji == "4️⃣": logger.info("!stocks.ta. Reaction selected: 4") if current == 0: await sma_command(ctx, ticker) elif current == 1: await adx_command(ctx, ticker) elif reaction.emoji == "5️⃣": logger.info("!stocks.ta. Reaction selected: 5") if current == 0: await wma_command(ctx, ticker) elif current == 1: await aroon_command(ctx, ticker) elif reaction.emoji == "6️⃣": logger.info("!stocks.ta. Reaction selected: 6") if current == 0: await hma_command(ctx, ticker) elif current == 1: await bbands_command(ctx, ticker) elif reaction.emoji == "7️⃣": logger.info("!stocks.ta. Reaction selected: 7") if current == 0: await zlma_command(ctx, ticker) elif current == 1: await donchian_command(ctx, ticker) elif reaction.emoji == "8️⃣": logger.info("!stocks.ta. Reaction selected: 8") if current == 0: await cci_command(ctx, ticker) elif current == 1: await kc_command(ctx, ticker) elif reaction.emoji == "9️⃣": logger.info("!stocks.ta. Reaction selected: 9") if current == 0: await macd_command(ctx, ticker) elif current == 1: await ad_command(ctx, ticker) for emoji in emoji_list: await main_message.remove_reaction(emoji, ctx.bot.user) components = [ [ discord_components.Button( label="Prev", id="back", style=discord_components.ButtonStyle.green, disabled=True, ), discord_components.Button( label=f"Page {int(cols.index(cols[current]))}/{len(cols) - 1}", id="cur", style=discord_components.ButtonStyle.grey, disabled=True, ), discord_components.Button( label="Next", id="front", style=discord_components.ButtonStyle.green, disabled=True, ), ] ] await main_message.edit(components=components) return
async def ta(self, ctx: discord.ext.commands.Context, ticker=""): """Stocks Context - Shows Technical Analysis Menu Run `!help TechnicalAnalysisCommands` to see the list of available commands. Returns ------- Sends a message to the discord user with the commands from the stocks.ta context. The user can then select a reaction to trigger a command. """ logger.info("!stocks.ta %s", ticker) cols_temp = [] cols = [] if ticker == "": embed = discord.Embed( title="ERROR Stocks: Technical Analysis (TA) Menu", colour=cfg.COLOR, description="A stock ticker is required", ) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed) return stock = discordbot.helpers.load(ticker, datetime.now() - timedelta(days=365)) if stock.empty: embed = discord.Embed( title="ERROR Stocks: Technical Analysis (TA) Menu", colour=cfg.COLOR, description="Enter a valid stock ticker", ) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed) return text = ( f"0️⃣ !stocks.ta.view {ticker}\n" f"1️⃣ !stocks.ta.summary {ticker}\n" f"2️⃣ !stocks.ta.recom {ticker}\n" f"3️⃣ !stocks.ta.ema {ticker} <WINDOW> <OFFSET> <START> <END>\n" f"4️⃣ !stocks.ta.sma {ticker} <WINDOW> <OFFSET> <START> <END>\n" f"5️⃣ !stocks.ta.wma {ticker} <WINDOW> <OFFSET> <START> <END>\n" f"6️⃣ !stocks.ta.hma {ticker} <WINDOW> <OFFSET> <START> <END>\n" f"7️⃣ !stocks.ta.zlma {ticker} <WINDOW> <OFFSET> <START> <END>\n" f"8️⃣ !stocks.ta.cci {ticker} <LENGTH> <SCALAR> <START> <END>\n" f"9️⃣ !stocks.ta.macd {ticker} <FAST> <SLOW> <SIGNAL> <START> <END>" ) cols_temp.append(text) text = ( f"0️⃣ !stocks.ta.rsi {ticker} <LENGTH> <SCALAR> <DRIFT> <START> <END>\n" f"1️⃣ !stocks.ta.stoch {ticker} <FAST_K> <SLOW_D> <SLOW_K> <START> <END>\n" f"2️⃣ !stocks.ta.fisher {ticker} <LENGTH> <START> <END>\n" f"3️⃣ !stocks.ta.cg {ticker} <LENGTH> <START> <END>\n" f"4️⃣ !stocks.ta.adx {ticker} <LENGTH> <SCALAR> <DRIFT> <START> <END>\n" f"5️⃣ !stocks.ta.aroon {ticker} <LENGTH> <SCALAR> <START> <END>\n" f"6️⃣ !stocks.ta.bbands {ticker} <LENGTH> <SCALAR> <MA_MODE> <START> <END>\n" f"7️⃣ !stocks.ta.donchian {ticker} <LOWER_LENGTH> <UPPER_LENGTH> <START> <END>\n" f"8️⃣ !stocks.ta.kc {ticker} <LENGTH> <SCALAR> <MA_MODE> <START> <END>\n" f"9️⃣ !stocks.ta.ad {ticker} <OPEN> <START> <END>" ) cols_temp.append(text) text = ( f"0️⃣ !stocks.ta.adosc {ticker} <OPEN> <FAST> <SLOW> <START> <END>\n" f"1️⃣ !stocks.ta.obv {ticker} <START> <END>\n" f"2️⃣ !stocks.ta.fib {ticker} <START> <END>\n" ) cols_temp.append(text) for col in cols_temp: cols.append( discord.Embed( description=col, colour=cfg.COLOR, title="Stocks: Technical Analysis (TA) Menu", ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) ) emoji_list = [ "0️⃣", "1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣", "8️⃣", "9️⃣", ] current = 0 components = [ [ discord_components.Button( label="Prev", id="back", style=discord_components.ButtonStyle.red ), discord_components.Button( label=f"Page {int(cols.index(cols[current]))}/{len(cols) - 1}", id="cur", style=discord_components.ButtonStyle.green, disabled=True, ), discord_components.Button( label="Next", id="front", style=discord_components.ButtonStyle.green ), ] ] main_message = await ctx.send(embed=cols[current], components=components) for emoji in emoji_list: await main_message.add_reaction(emoji) while True: # Try and except blocks to catch timeout and break try: interaction = await gst_bot.wait_for( "button_click", check=lambda i: i.component.id in ["back", "front"], # You can add more timeout=cfg.MENU_TIMEOUT, # Some seconds of inactivity ) # Getting the right list index if interaction.component.id == "back": current -= 1 elif interaction.component.id == "front": current += 1 # If its out of index, go back to start / end if current == len(cols): current = 0 elif current < 0: current = len(cols) - 1 # Edit to new page + the center counter changes components = [ [ discord_components.Button( label="Prev", id="back", style=discord_components.ButtonStyle.red, ), discord_components.Button( label=f"Page {int(cols.index(cols[current]))}/{len(cols) - 1}", id="cur", style=discord_components.ButtonStyle.green, disabled=True, ), discord_components.Button( label="Next", id="front", style=discord_components.ButtonStyle.green, ), ] ] await interaction.edit_origin( embed=cols[current], components=components ) # pylint: disable=too-many-branches @gst_bot.event async def on_reaction_add(reaction, user): if user == ctx.message.author and str(reaction.emoji) in emoji_list: if reaction.emoji == "0️⃣": logger.info("!stocks.ta. Reaction selected: 0") if current == 0: await view_command(ctx, ticker) elif current == 1: await rsi_command(ctx, ticker) elif current == 2: await adosc_command(ctx, ticker) elif reaction.emoji == "1️⃣": logger.info("!stocks.ta. Reaction selected: 1") if current == 0: await summary_command(ctx, ticker) elif current == 1: await stoch_command(ctx, ticker) elif current == 2: await obv_command(ctx, ticker) elif reaction.emoji == "2️⃣": logger.info("!stocks.ta. Reaction selected: 2") if current == 0: await recom_command(ctx, ticker) elif current == 1: await fisher_command(ctx, ticker) elif current == 2: await fib_command(ctx, ticker) elif reaction.emoji == "3️⃣": logger.info("!stocks.ta. Reaction selected: 3") if current == 0: await ema_command(ctx, ticker) elif current == 1: await cg_command(ctx, ticker) elif reaction.emoji == "4️⃣": logger.info("!stocks.ta. Reaction selected: 4") if current == 0: await sma_command(ctx, ticker) elif current == 1: await adx_command(ctx, ticker) elif reaction.emoji == "5️⃣": logger.info("!stocks.ta. Reaction selected: 5") if current == 0: await wma_command(ctx, ticker) elif current == 1: await aroon_command(ctx, ticker) elif reaction.emoji == "6️⃣": logger.info("!stocks.ta. Reaction selected: 6") if current == 0: await hma_command(ctx, ticker) elif current == 1: await bbands_command(ctx, ticker) elif reaction.emoji == "7️⃣": logger.info("!stocks.ta. Reaction selected: 7") if current == 0: await zlma_command(ctx, ticker) elif current == 1: await donchian_command(ctx, ticker) elif reaction.emoji == "8️⃣": logger.info("!stocks.ta. Reaction selected: 8") if current == 0: await cci_command(ctx, ticker) elif current == 1: await kc_command(ctx, ticker) elif reaction.emoji == "9️⃣": logger.info("!stocks.ta. Reaction selected: 9") if current == 0: await macd_command(ctx, ticker) elif current == 1: await ad_command(ctx, ticker) for emoji in emoji_list: await main_message.remove_reaction(emoji, ctx.bot.user) components = [ [ discord_components.Button( label="Prev", id="back", style=discord_components.ButtonStyle.green, disabled=True, ), discord_components.Button( label=f"Page {int(cols.index(cols[current]))}/{len(cols) - 1}", id="cur", style=discord_components.ButtonStyle.grey, disabled=True, ), discord_components.Button( label="Next", id="front", style=discord_components.ButtonStyle.green, disabled=True, ), ] ] await main_message.edit(components=components) return except asyncio.TimeoutError: # Disable and get outta here components = [ [ discord_components.Button( label="Prev", id="back", style=discord_components.ButtonStyle.green, disabled=True, ), discord_components.Button( label=f"Page {int(cols.index(cols[current]))}/{len(cols) - 1}", id="cur", style=discord_components.ButtonStyle.grey, disabled=True, ), discord_components.Button( label="Next", id="front", style=discord_components.ButtonStyle.green, disabled=True, ), ] ] await main_message.edit(components=components) if cfg.DEBUG: embed = discord.Embed( description="Error timeout - you snooze you lose! 😋", colour=cfg.COLOR, title="TIMEOUT Stocks: Technical Analysis (TA) Menu", ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed) for emoji in emoji_list: await main_message.remove_reaction(emoji, ctx.bot.user) break
async def dark_pool_shorts_menu(self, ctx: discord.ext.commands.Context, ticker=""): """Stocks Context - Shows Dark Pool Shorts Menu Run `!help DarkPoolShortsCommands` to see the list of available commands. Returns ------- Sends a message to the discord user with the commands from the dps context. The user can then select a reaction to trigger a command. """ logger.info("!stocks.dps %s", ticker) if ticker: stock = yf.download(ticker, progress=False) if stock.empty: embed = discord.Embed( title="ERROR Stocks: Dark Pool and Short data", colour=cfg.COLOR, description="Stock ticker is invalid", ) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed) return text = ("0️⃣ !stocks.dps.shorted <NUM>\n" "1️⃣ !stocks.dps.hsi <NUM>\n" "2️⃣ !stocks.dps.pos <NUM> <SORT>\n" "3️⃣ !stocks.dps.sidtc <NUM> <SORT>\n") if ticker: text += (f"4️⃣ !stocks.dps.ftd {ticker} <DATE_START> <DATE_END>\n" f"5️⃣ !stocks.dps.dpotc {ticker}\n" f"6️⃣ !stocks.dps.spos {ticker}\n" f"7️⃣ !stocks.dps.psi {ticker}\n") else: text += ("\nMore commands available when providing a ticker with:" "\n!stocks.dps <TICKER>") title = "Stocks: Dark Pool Shorts (DPS) Menu" embed = discord.Embed(title=title, description=text, colour=cfg.COLOR) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) msg = await ctx.send(embed=embed) emoji_list = ["0️⃣", "1️⃣", "2️⃣", "3️⃣"] if ticker: emoji_list += ["4️⃣", "5️⃣", "6️⃣", "7️⃣"] for emoji in emoji_list: await msg.add_reaction(emoji) def check(reaction, user): return user == ctx.message.author and str( reaction.emoji) in emoji_list try: reaction, _ = await gst_bot.wait_for("reaction_add", timeout=cfg.MENU_TIMEOUT, check=check) if reaction.emoji == "0️⃣": logger.info("!stocks.dps. Reaction selected: 0") await shorted_command(ctx) elif reaction.emoji == "1️⃣": logger.info("!stocks.dps. Reaction selected: 1") await hsi_command(ctx) elif reaction.emoji == "2️⃣": logger.info("!stocks.dps. Reaction selected: 2") await pos_command(ctx) elif reaction.emoji == "3️⃣": logger.info("!stocks.dps. Reaction selected: 3") await sidtc_command(ctx) elif reaction.emoji == "4️⃣": logger.info("!stocks.dps. Reaction selected: 4") await ftd_command(ctx, ticker) elif reaction.emoji == "5️⃣": logger.info("!stocks.dps. Reaction selected: 5") await dpotc_command(ctx, ticker) elif reaction.emoji == "6️⃣": logger.info("!stocks.dps. Reaction selected: 6") await spos_command(ctx, ticker) elif reaction.emoji == "7️⃣": logger.info("!stocks.dps. Reaction selected: 7") await psi_command(ctx, ticker) for emoji in emoji_list: await msg.remove_reaction(emoji, ctx.bot.user) except asyncio.TimeoutError: for emoji in emoji_list: await msg.remove_reaction(emoji, ctx.bot.user) if cfg.DEBUG: embed = discord.Embed( description="Error timeout - you snooze you lose! 😋", colour=cfg.COLOR, title="TIMEOUT Stocks: Dark Pool Shorts (DPS) Menu", ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed)
async def due_diligence(self, ctx: discord.ext.commands.Context, ticker=""): """Due Diligence Context Menu Run `!help DueDiligenceCommands` to see the list of available commands. Returns ------- Sends a message to the discord user with the commands from the dd context. The user can then select a reaction to trigger a command. """ logger.info("!stocks.dd") if ticker == "": embed = discord.Embed( title="ERROR Stocks: Due Diligence (DD) Menu", colour=cfg.COLOR, description="A stock ticker is required", ) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) text = ( f"0️⃣ !stocks.dd.analyst {ticker}\n" f"1️⃣ !stocks.dd.pt {ticker} <RAW> <DATE_START>\n" f"2️⃣ !stocks.dd.est {ticker}\n" f"3️⃣ !stocks.dd.sec {ticker}\n" f"4️⃣ !stocks.dd.supplier {ticker}\n" f"5️⃣ !stocks.dd.customer {ticker}\n" f"6️⃣ !stocks.dd.arktrades {ticker}" ) title = "Stocks: Due Diligence (DD) Menu" embed = discord.Embed(title=title, description=text, colour=cfg.COLOR) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) msg = await ctx.send(embed=embed) emoji_list = ["0️⃣", "1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣"] for emoji in emoji_list: await msg.add_reaction(emoji) def check(reaction, user): return user == ctx.message.author and str(reaction.emoji) in emoji_list try: reaction, _ = await gst_bot.wait_for( "reaction_add", timeout=cfg.MENU_TIMEOUT, check=check ) if reaction.emoji == "0️⃣": logger.info("!stocks.dd. Reaction selected: 0") await analyst_command(ctx, ticker) elif reaction.emoji == "1️⃣": logger.info("!stocks.dd. Reaction selected: 1") await pt_command(ctx, ticker) elif reaction.emoji == "2️⃣": logger.info("!stocks.dd. Reaction selected: 2") await est_command(ctx, ticker) elif reaction.emoji == "3️⃣": logger.info("!stocks.dd. Reaction selected: 3") await sec_command(ctx, ticker) elif reaction.emoji == "4️⃣": logger.info("!stocks.dd. Reaction selected: 4") await supplier_command(ctx, ticker) elif reaction.emoji == "5️⃣": logger.info("!stocks.dd. Reaction selected: 5") await customer_command(ctx, ticker) elif reaction.emoji == "6️⃣": logger.info("!stocks.dd. Reaction selected: 6") await arktrades_command(ctx, ticker) for emoji in emoji_list: await msg.remove_reaction(emoji, ctx.bot.user) except asyncio.TimeoutError: for emoji in emoji_list: await msg.remove_reaction(emoji, ctx.bot.user) if cfg.DEBUG: embed = discord.Embed( description="Error timeout - you snooze you lose! 😋", colour=cfg.COLOR, title="TIMEOUT Stocks: Due Diligence (DD) Menu", ).set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) await ctx.send(embed=embed)