diff --git a/discordbot/economy/economy_menu.py b/discordbot/economy/economy_menu.py index 92b13314552..ecce218cba3 100644 --- a/discordbot/economy/economy_menu.py +++ b/discordbot/economy/economy_menu.py @@ -126,6 +126,8 @@ class EconomyCommands(discord.ext.commands.Cog): async def economy(self, ctx: discord.ext.commands.Context): """Economy Context Menu + Run `!help EconomyCommands` to see the list of available commands. + Returns ------- Sends a message to the discord user with the commands from the economy context. @@ -359,15 +361,16 @@ class EconomyCommands(discord.ext.commands.Cog): ] ] await main_message.edit(components=components) - embed = discord.Embed( - description="Error timeout - you snooze you lose! 😋", - colour=cfg.COLOR, - title="TIMEOUT Economy Menu", - ).set_author( - name=cfg.AUTHOR_NAME, - icon_url=cfg.AUTHOR_ICON_URL, - ) - await ctx.send(embed=embed) + if cfg.DEBUG: + embed = discord.Embed( + description="Error timeout - you snooze you lose! 😋", + colour=cfg.COLOR, + title="TIMEOUT Economy 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) diff --git a/discordbot/generic_commands.py b/discordbot/generic_commands.py index 9e16869e02b..0b2ab16b106 100644 --- a/discordbot/generic_commands.py +++ b/discordbot/generic_commands.py @@ -8,6 +8,11 @@ class GenericCommands(discord.ext.commands.Cog): def __init__(self, bot: discord.ext.commands.Bot): self.bot = bot + bot.help_command.cog = self + + def cog_unload(self): + self.bot.help_command = None + @discord.ext.commands.command(name="about") async def about(self, ctx: discord.ext.commands.Context): """About Gamestonk Terminal""" @@ -49,6 +54,35 @@ class GenericCommands(discord.ext.commands.Cog): await ctx.send(embed=embed) + @discord.ext.commands.command(name="usage") + async def usage(self, ctx: discord.ext.commands.Context): + usage_instructions_message = """ +``` +- Every command starts with an exclamation point "!". + +- Any command can be triggered from the chat. For example: + + !about + or + !stocks.dps.spos tsla + or + !stocks.ta.recom tsla + +- Help is available for all menus and functions. + + Call help for individual menus like this: + !help DarkPoolShortsCommands + + Call help for individual commands like this: + !help stocks.dps + +- Call the help command to see the list of available menus: + + !help +``` + """ + await ctx.send(usage_instructions_message) + def setup(bot: discord.ext.commands.Bot): bot.add_cog(GenericCommands(bot)) diff --git a/discordbot/run_discordbot.py b/discordbot/run_discordbot.py index c6fb2b47304..77db4348137 100644 --- a/discordbot/run_discordbot.py +++ b/discordbot/run_discordbot.py @@ -1,24 +1,69 @@ +import difflib +import logging import os import sys -import difflib +from datetime import datetime + import discord import discord_components import pyimgur + import config_discordbot as cfg +# Logging +logger = logging.getLogger("discord") +logging.basicConfig(level=logging.INFO) # DEBUG/INFO/WARNING/ERROR/CRITICAL +handler = logging.FileHandler( + filename=os.path.join( + os.path.dirname(__file__), "..", "logs", f"{datetime.now()}_bot.log" + ), + encoding="utf-8", + mode="w", +) +handler.setFormatter( + logging.Formatter("%(asctime)s:%(levelname)s:%(name)s: %(message)s") +) +logger.addHandler(handler) + activity = discord.Game( name="Gamestonk Terminal: https://github.com/GamestonkTerminal/GamestonkTerminal" ) + +class GSTHelpCommand(discord.ext.commands.MinimalHelpCommand): + """Custom Help Command.""" + + def get_command_signature(self, command): + command_syntax = f"{self.clean_prefix}{command.qualified_name}" + command_usage = command.usage if command.usage is not None else "" + signature_text = f""" + Example usage: + `{command_syntax} {command_usage}`""" + return signature_text + + def add_bot_commands_formatting(self, commands, heading): + """Add a minified bot heading with commands to the output.""" + if commands: + menu_header = heading.replace("Commands", " category") + self.paginator.add_line( + f"__**{menu_header}**__ " + f"contains {len(commands)} commands." + ) + self.paginator.add_line(f"\t\t`!help {heading}` for info and options.") + + gst_bot = discord.ext.commands.Bot( - command_prefix=cfg.COMMAND_PREFIX, intents=discord.Intents.all(), activity=activity + command_prefix=cfg.COMMAND_PREFIX, + help_command=GSTHelpCommand(sort_commands=False, commands_heading="list:"), + intents=discord.Intents.all(), + activity=activity, ) discord_components.DiscordComponents(gst_bot) if cfg.IMGUR_CLIENT_ID == "REPLACE_ME" or cfg.DISCORD_BOT_TOKEN == "REPLACE_ME": print( - f"Update IMGUR_CLIENT_ID or DISCORD_BOT_TOKEN or both in { os.path.join('discordbot', 'config_discordbot') } \n" + "Update IMGUR_CLIENT_ID or DISCORD_BOT_TOKEN or both in " + + f"{ os.path.join('discordbot', 'config_discordbot') } \n" ) sys.exit() diff --git a/discordbot/stocks/dark_pool_shorts/dps_menu.py b/discordbot/stocks/dark_pool_shorts/dps_menu.py index c08c1572857..d43db4f55b3 100644 --- a/discordbot/stocks/dark_pool_shorts/dps_menu.py +++ b/discordbot/stocks/dark_pool_shorts/dps_menu.py @@ -20,8 +20,15 @@ class DarkPoolShortsCommands(discord.ext.commands.Cog): def __init__(self, bot: discord.ext.commands.Bot): self.bot = bot + self.bot.help_command.cog = self - @discord.ext.commands.command(name="stocks.dps.shorted") + def cog_unload(self): + self.bot.help_command = None + + @discord.ext.commands.command( + name="stocks.dps.shorted", + usage="[num]", + ) async def shorted(self, ctx: discord.ext.commands.Context, num="10"): """Show most shorted stocks [Yahoo Finance] @@ -32,7 +39,10 @@ class DarkPoolShortsCommands(discord.ext.commands.Cog): """ await shorted_command(ctx, num) - @discord.ext.commands.command(name="stocks.dps.hsi") + @discord.ext.commands.command( + name="stocks.dps.hsi", + usage="[num]", + ) async def hsi(self, ctx: discord.ext.commands.Context, num="10"): """Show top high short interest stocks of over 20% ratio [shortinterest.com] @@ -43,14 +53,18 @@ class DarkPoolShortsCommands(discord.ext.commands.Cog): """ await hsi_command(ctx, num) - @discord.ext.commands.command(name="stocks.dps.pos") + @discord.ext.commands.command( + name="stocks.dps.pos", + usage="[sort] [num]", + ) async def pos(self, ctx: discord.ext.commands.Context, sort="dpp_dollar", num="10"): """Dark pool short position [Stockgrid] Parameters ----------- sort: str - Field for which to sort. Possible are: sv, sv_pct, nsv, nsv_dollar, dpp, dpp_dollar. + Field for which to sort. Possible are: `sv`, `sv_pct`, `nsv`, `nsv_dollar`, + `dpp` and `dpp_dollar`. These correspond to Short Vol. (1M), Short Vol. %%, Net Short Vol. (1M), Net Short Vol. ($100M), DP Position (1M), DP Position ($1B), respectively. num: int @@ -58,21 +72,27 @@ class DarkPoolShortsCommands(discord.ext.commands.Cog): """ await pos_command(ctx, sort, num) - @discord.ext.commands.command(name="stocks.dps.sidtc") + @discord.ext.commands.command( + name="stocks.dps.sidtc", + usage="[sort] [num]", + ) async def sidtc(self, ctx: discord.ext.commands.Context, sort="float", num="10"): """Short interest and days to cover [Stockgrid] Parameters ----------- sort: str - Field for which to sort. Possible are: float, dtc, si. + Field for which to sort. Possible are: `float`, `dtc`, `si`. These correspond to Float Short %%, Days to Cover, Short Interest, respectively. num: int Number of top tickers to show """ await sidtc_command(ctx, sort, num) - @discord.ext.commands.command(name="stocks.dps.ftd") + @discord.ext.commands.command( + name="stocks.dps.ftd", + usage="[ticker] [start] [end]", + ) async def ftd(self, ctx: discord.ext.commands.Context, ticker="", start="", end=""): """Fails-to-deliver data [SEC] @@ -81,13 +101,16 @@ class DarkPoolShortsCommands(discord.ext.commands.Cog): ticker: str Stock ticker start: datetime - Start of date + Starting date in YYYY-MM-DD format end: datetime - End of date + Ending date in YYYY-MM-DD format """ await ftd_command(ctx, ticker, start, end) - @discord.ext.commands.command(name="stocks.dps.dpotc") + @discord.ext.commands.command( + name="stocks.dps.dpotc", + usage=["ticker"], + ) async def dpotc(self, ctx: discord.ext.commands.Context, ticker=""): """Dark pools (ATS) vs OTC data [FINRA] @@ -98,7 +121,10 @@ class DarkPoolShortsCommands(discord.ext.commands.Cog): """ await dpotc_command(ctx, ticker) - @discord.ext.commands.command(name="stocks.dps.spos") + @discord.ext.commands.command( + name="stocks.dps.spos", + usage="[ticker]", + ) async def spos(self, ctx: discord.ext.commands.Context, ticker=""): """Net short vs position [Stockgrid] @@ -109,7 +135,10 @@ class DarkPoolShortsCommands(discord.ext.commands.Cog): """ await spos_command(ctx, ticker) - @discord.ext.commands.command(name="stocks.dps.psi") + @discord.ext.commands.command( + name="stocks.dps.psi", + usage="[ticker]", + ) async def psi(self, ctx: discord.ext.commands.Context, ticker=""): """Price vs short interest volume [Stockgrid] @@ -120,11 +149,16 @@ class DarkPoolShortsCommands(discord.ext.commands.Cog): """ await psi_command(ctx, ticker) - @discord.ext.commands.command(name="stocks.dps") + @discord.ext.commands.command( + name="stocks.dps", + usage="[ticker]", + ) # pylint: disable=too-many-branches 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. @@ -231,15 +265,16 @@ class DarkPoolShortsCommands(discord.ext.commands.Cog): except asyncio.TimeoutError: for emoji in emoji_list: await msg.remove_reaction(emoji, ctx.bot.user) - 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) + 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) def setup(bot: discord.ext.commands.Bot): diff --git a/discordbot/stocks/due_diligence/arktrades.py b/discordbot/stocks/due_diligence/arktrades.py index 651314cadb9..da487cb93f4 100644 --- a/discordbot/stocks/due_diligence/arktrades.py +++ b/discordbot/stocks/due_diligence/arktrades.py @@ -20,7 +20,7 @@ async def arktrades_command(ctx, ticker="", num=""): else: if not num.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") - num = float(num) + num = int(num) if ticker == "": raise Exception("A ticker is required") diff --git a/discordbot/stocks/due_diligence/dd_menu.py b/discordbot/stocks/due_diligence/dd_menu.py index 9d9ca0f7975..cc831a945a9 100644 --- a/discordbot/stocks/due_diligence/dd_menu.py +++ b/discordbot/stocks/due_diligence/dd_menu.py @@ -19,92 +19,94 @@ class DueDiligenceCommands(discord.ext.commands.Cog): def __init__(self, bot: discord.ext.commands.Bot): self.bot = bot - @discord.ext.commands.command(name="stocks.dd.analyst") + @discord.ext.commands.command(name="stocks.dd.analyst", usage="[ticker]") async def analyst(self, ctx: discord.ext.commands.Context, ticker=""): """Displays analyst recommendations [Finviz] Parameters ----------- ticker: str - ticker, -h or help + ticker """ await analyst_command(ctx, ticker) - @discord.ext.commands.command(name="stocks.dd.pt") + @discord.ext.commands.command(name="stocks.dd.pt", usage="[ticker] [raw] [start]") async def pt(self, ctx: discord.ext.commands.Context, ticker="", raw="", start=""): """Displays chart with price targets [Business Insiders] Parameters ----------- ticker: str - ticker, -h or help + ticker raw: boolean True or false start: - date (in date format for start date) + Starting date in YYYY-MM-DD format """ await pt_command(ctx, ticker, raw, start) - @discord.ext.commands.command(name="stocks.dd.est") + @discord.ext.commands.command(name="stocks.dd.est", usage="[ticker]") async def est(self, ctx: discord.ext.commands.Context, ticker=""): """Displays earning estimates [Business Insider] Parameters ----------- ticker: str - ticker, -h or help + ticker """ await est_command(ctx, ticker) - @discord.ext.commands.command(name="stocks.dd.sec") + @discord.ext.commands.command(name="stocks.dd.sec", usage="[ticker]") async def sec(self, ctx: discord.ext.commands.Context, ticker=""): """Displays sec filings [Market Watch] Parameters ----------- ticker: str - ticker, -h or help + ticker """ await sec_command(ctx, ticker) - @discord.ext.commands.command(name="stocks.dd.supplier") + @discord.ext.commands.command(name="stocks.dd.supplier", usage="[ticker]") async def supplier(self, ctx: discord.ext.commands.Context, ticker=""): """Displays suppliers of the company [CSIMarket] Parameters ----------- ticker: str - ticker, -h or help + ticker """ await supplier_command(ctx, ticker) - @discord.ext.commands.command(name="stocks.dd.customer") + @discord.ext.commands.command(name="stocks.dd.customer", usage="[ticker]") async def customer(self, ctx: discord.ext.commands.Context, ticker=""): """Displays customers of the company [CSIMarket] Parameters ----------- ticker: str - ticker, -h or help + ticker """ await customer_command(ctx, ticker) - @discord.ext.commands.command(name="stocks.dd.arktrades") + @discord.ext.commands.command(name="stocks.dd.arktrades", usage="[ticker] [num]") async def arktrades(self, ctx: discord.ext.commands.Context, ticker="", num=""): """Displays trades made by ark [cathiesark.com] Parameters ----------- ticker: str - ticker, -h or help + ticker num: int number of rows displayed """ await arktrades_command(ctx, ticker, num) @discord.ext.commands.command(name="stocks.dd") - async def economy(self, ctx: discord.ext.commands.Context, ticker=""): - """Economy Context Menu + 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 ------- @@ -191,15 +193,16 @@ class DueDiligenceCommands(discord.ext.commands.Cog): except asyncio.TimeoutError: for emoji in emoji_list: await msg.remove_reaction(emoji, ctx.bot.user) - 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) + 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) def setup(bot: discord.ext.commands.Bot): diff --git a/discordbot/stocks/options/options_menu.py b/discordbot/stocks/options/options_menu.py index 65b289938b8..67b2469a426 100644 --- a/discordbot/stocks/options/options_menu.py +++ b/discordbot/stocks/options/options_menu.py @@ -16,7 +16,7 @@ class OptionsCommands(discord.ext.commands.Cog): def __init__(self, bot: discord.ext.commands.Bot): self.bot = bot - @discord.ext.commands.command(name="stocks.opt.exp") + @discord.ext.commands.command(name="stocks.opt.exp", usage="[ticker]") async def expirations(self, ctx: discord.ext.commands.Context, ticker=""): """Get available expirations [yfinance] @@ -27,7 +27,9 @@ class OptionsCommands(discord.ext.commands.Cog): """ await expirations_command(ctx, ticker) - @discord.ext.commands.command(name="stocks.opt.calls") + @discord.ext.commands.command( + name="stocks.opt.calls", usage="[ticker] [expiration]" + ) async def calls( self, ctx: discord.ext.commands.Context, ticker="", expiration: str = "" ): @@ -42,7 +44,7 @@ class OptionsCommands(discord.ext.commands.Cog): """ await calls_command(ctx, ticker, expiration) - @discord.ext.commands.command(name="stocks.opt.puts") + @discord.ext.commands.command(name="stocks.opt.puts", usage="[ticker] [expiration]") async def puts( self, ctx: discord.ext.commands.Context, ticker="", expiration: str = "" ): @@ -57,7 +59,7 @@ class OptionsCommands(discord.ext.commands.Cog): """ await puts_command(ctx, ticker, expiration) - @discord.ext.commands.command(name="stocks.opt.oi") + @discord.ext.commands.command(name="stocks.opt.oi", usage="[ticker] [expiration]") async def oi( self, ctx: discord.ext.commands.Context, ticker="", expiration: str = "" ): @@ -76,6 +78,8 @@ class OptionsCommands(discord.ext.commands.Cog): async def opt(self, ctx: discord.ext.commands.Context, ticker="", expiration=""): """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. @@ -153,15 +157,16 @@ class OptionsCommands(discord.ext.commands.Cog): except asyncio.TimeoutError: for emoji in emoji_list: await msg.remove_reaction(emoji, ctx.bot.user) - 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) + 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) def setup(bot: discord.ext.commands.Bot): diff --git a/discordbot/stocks/screener/screener_menu.py b/discordbot/stocks/screener/screener_menu.py index 24437febf01..d1b8cf5f8ac 100644 --- a/discordbot/stocks/screener/screener_menu.py +++ b/discordbot/stocks/screener/screener_menu.py @@ -36,7 +36,9 @@ class ScreenerCommands(discord.ext.commands.Cog): """Displays every available preset""" await presets_custom_command(ctx) - @discord.ext.commands.command(name="stocks.scr.historical") + @discord.ext.commands.command( + name="stocks.scr.historical", usage="[signal] [start]" + ) async def historical( self, ctx: discord.ext.commands.Context, @@ -50,11 +52,13 @@ class ScreenerCommands(discord.ext.commands.Cog): signal: str Signal. Default: most_volatile start: - date (in date format for start date) + Starting date in YYYY-MM-DD format """ await historical_command(ctx, signal, start) - @discord.ext.commands.command(name="stocks.scr.overview") + @discord.ext.commands.command( + name="stocks.scr.overview", usage="[preset] [sort] [limit] [ascend]" + ) async def overview( self, ctx: discord.ext.commands.Context, @@ -78,7 +82,9 @@ class ScreenerCommands(discord.ext.commands.Cog): """ await overview_command(ctx, preset, sort, limit, ascend) - @discord.ext.commands.command(name="stocks.scr.valuation") + @discord.ext.commands.command( + name="stocks.scr.valuation", usage="[preset] [sort] [limit] [ascend]" + ) async def valuation( self, ctx: discord.ext.commands.Context, @@ -102,7 +108,9 @@ class ScreenerCommands(discord.ext.commands.Cog): """ await valuation_command(ctx, preset, sort, limit, ascend) - @discord.ext.commands.command(name="stocks.scr.financial") + @discord.ext.commands.command( + name="stocks.scr.financial", usage="[preset] [sort] [limit] [ascend]" + ) async def financial( self, ctx: discord.ext.commands.Context, @@ -126,7 +134,9 @@ class ScreenerCommands(discord.ext.commands.Cog): """ await financial_command(ctx, preset, sort, limit, ascend) - @discord.ext.commands.command(name="stocks.scr.ownership") + @discord.ext.commands.command( + name="stocks.scr.ownership", usage="[preset] [sort] [limit] [ascend]" + ) async def ownership( self, ctx: discord.ext.commands.Context, @@ -150,7 +160,9 @@ class ScreenerCommands(discord.ext.commands.Cog): """ await ownership_command(ctx, preset, sort, limit, ascend) - @discord.ext.commands.command(name="stocks.scr.performance") + @discord.ext.commands.command( + name="stocks.scr.performance", usage="[preset] [sort] [limit] [ascend]" + ) async def performance( self, ctx: discord.ext.commands.Context, @@ -174,7 +186,9 @@ class ScreenerCommands(discord.ext.commands.Cog): """ await performance_command(ctx, preset, sort, limit, ascend) - @discord.ext.commands.command(name="stocks.scr.technical") + @discord.ext.commands.command( + name="stocks.scr.technical", usage="[preset] [sort] [limit] [ascend]" + ) async def technical( self, ctx: discord.ext.commands.Context, @@ -202,6 +216,8 @@ class ScreenerCommands(discord.ext.commands.Cog): 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. @@ -302,15 +318,16 @@ class ScreenerCommands(discord.ext.commands.Cog): except asyncio.TimeoutError: for emoji in emoji_list: await msg.remove_reaction(emoji, ctx.bot.user) - 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) + 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) def setup(bot: discord.ext.commands.Bot): diff --git a/discordbot/stocks/technical_analysis/ta_menu.py b/discordbot/stocks/technical_analysis/ta_menu.py index 30854033828..7c1520b7efc 100644 --- a/discordbot/stocks/technical_analysis/ta_menu.py +++ b/discordbot/stocks/technical_analysis/ta_menu.py @@ -39,7 +39,9 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): def __init__(self, bot: discord.ext.commands.Bot): self.bot = bot - @discord.ext.commands.command(name="stocks.ta.ema") + @discord.ext.commands.command( + name="stocks.ta.ema", usage="[ticker] [window] [offset] [start] [end]" + ) async def ema( self, ctx: discord.ext.commands.Context, @@ -54,20 +56,22 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker window: int window length. Default: 20, 50 offset: int offset. Default: 0 start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await ema_command(ctx, ticker, window, offset, start, end) - @discord.ext.commands.command(name="stocks.ta.sma") + @discord.ext.commands.command( + name="stocks.ta.sma", usage="[ticker] [window] [offset] [start] [end]" + ) async def sma( self, ctx: discord.ext.commands.Context, @@ -82,20 +86,22 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker window: int window length. Default: 20, 50 offset: int offset. Default: 0 start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await sma_command(ctx, ticker, window, offset, start, end) - @discord.ext.commands.command(name="stocks.ta.wma") + @discord.ext.commands.command( + name="stocks.ta.wma", usage="[ticker] [window] [offset] [start] [end]" + ) async def wma( self, ctx: discord.ext.commands.Context, @@ -110,20 +116,22 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker window: int window length. Default: 20, 50 offset: int offset. Default: 0 start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await wma_command(ctx, ticker, window, offset, start, end) - @discord.ext.commands.command(name="stocks.ta.hma") + @discord.ext.commands.command( + name="stocks.ta.hma", usage="[ticker] [window] [offset] [start] [end]" + ) async def hma( self, ctx: discord.ext.commands.Context, @@ -138,20 +146,22 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker window: int window length. Default: 20, 50 offset: int offset. Default: 0 start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await hma_command(ctx, ticker, window, offset, start, end) - @discord.ext.commands.command(name="stocks.ta.zlma") + @discord.ext.commands.command( + name="stocks.ta.zlma", usage="[ticker] [window] [offset] [start] [end]" + ) async def zlma( self, ctx: discord.ext.commands.Context, @@ -166,20 +176,22 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker window: int window length. Default: 20 offset: int offset. Default: 0 start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await zlma_command(ctx, ticker, window, offset, start, end) - @discord.ext.commands.command(name="stocks.ta.cci") + @discord.ext.commands.command( + name="stocks.ta.cci", usage="[ticker] [length] [scalar] [start] [end]" + ) async def cci( self, ctx: discord.ext.commands.Context, @@ -194,20 +206,22 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker length: int window length. Default: 14 scalar: int scalar. Default: 0.015 start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await cci_command(ctx, ticker, length, scalar, start, end) - @discord.ext.commands.command(name="stocks.ta.macd") + @discord.ext.commands.command( + name="stocks.ta.macd", usage="[ticker] [fast] [slow] [signal] [start] [end]" + ) async def macd( self, ctx: discord.ext.commands.Context, @@ -223,7 +237,7 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker fast: int fast period. Default: 12 slow: int @@ -231,14 +245,16 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): signal: int signal period. Default: 9 start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await macd_command(ctx, ticker, fast, slow, signal, start, end) - @discord.ext.commands.command(name="stocks.ta.rsi") + @discord.ext.commands.command( + name="stocks.ta.rsi", usage="[ticker] [length] [scalar] [drift] [start] [end]" + ) async def rsi( self, ctx: discord.ext.commands.Context, @@ -254,7 +270,7 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker length: int length. Default: 14 scalar: int @@ -262,14 +278,17 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): drift: int drift. Default: 1 start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await rsi_command(ctx, ticker, length, scalar, drift, start, end) - @discord.ext.commands.command(name="stocks.ta.stoch") + @discord.ext.commands.command( + name="stocks.ta.stoch", + usage="[ticker] [fast_k] [slow_d] [slow_k] [start] [end]", + ) async def stoch( self, ctx: discord.ext.commands.Context, @@ -285,7 +304,7 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker fast_k: int fast_k moving average period. Default: 14 slow_d: int @@ -293,14 +312,16 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): slow_k: int slow_k moving average period. Default: 3 start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await stoch_command(ctx, ticker, fast_k, slow_d, slow_k, start, end) - @discord.ext.commands.command(name="stocks.ta.fisher") + @discord.ext.commands.command( + name="stocks.ta.fisher", usage="[ticker] [length] [start] [end]" + ) async def fisher( self, ctx: discord.ext.commands.Context, @@ -314,18 +335,20 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker length: int length. Default: 14 start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await fisher_command(ctx, ticker, length, start, end) - @discord.ext.commands.command(name="stocks.ta.cg") + @discord.ext.commands.command( + name="stocks.ta.cg", usage="[ticker] [length] [start] [end]" + ) async def cg( self, ctx: discord.ext.commands.Context, @@ -339,18 +362,20 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker length: int length. Default: 14 start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await cg_command(ctx, ticker, length, start, end) - @discord.ext.commands.command(name="stocks.ta.adx") + @discord.ext.commands.command( + name="stocks.ta.adx", usage="[ticker] [length] [scalar] [drift] [start] [end]" + ) async def adx( self, ctx: discord.ext.commands.Context, @@ -366,7 +391,7 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker length: int length. Default: 14 scalar: int @@ -374,14 +399,16 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): drift: int drift. Default: 1 start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await adx_command(ctx, ticker, length, scalar, drift, start, end) - @discord.ext.commands.command(name="stocks.ta.aroon") + @discord.ext.commands.command( + name="stocks.ta.aroon", usage="[ticker] [length] [scalar] [start] [end]" + ) async def aroon( self, ctx: discord.ext.commands.Context, @@ -396,20 +423,22 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker length: int length. Default: 25 scalar: int scalar. Default: 100 start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await aroon_command(ctx, ticker, length, scalar, start, end) - @discord.ext.commands.command(name="stocks.ta.bbands") + @discord.ext.commands.command( + name="stocks.ta.bbands", usage="[ticker] [length] [std] [ma_mode] [start] [end]" + ) async def bbands( self, ctx: discord.ext.commands.Context, @@ -425,7 +454,7 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker length: int length. Default: 5 std: int @@ -433,14 +462,17 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): ma_mode: str mode of moving average. Default: sma start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await bbands_command(ctx, ticker, length, std, ma_mode, start, end) - @discord.ext.commands.command(name="stocks.ta.donchian") + @discord.ext.commands.command( + name="stocks.ta.donchian", + usage="[ticker] [upper_length] [lower_length] [start] [end]", + ) async def donchian( self, ctx: discord.ext.commands.Context, @@ -455,21 +487,24 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker upper_length: int length. Default: 25 lower_length: int standard deviation. Default: 100 start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await donchian_command(ctx, ticker, upper_length, lower_length, start, end) # pylint: disable=too-many-arguments - @discord.ext.commands.command(name="stocks.ta.kc") + @discord.ext.commands.command( + name="stocks.ta.kc", + usage="[ticker] [length] [scalar] [ma_mode] [offset] [start] [end]", + ) async def kc( self, ctx: discord.ext.commands.Context, @@ -486,7 +521,7 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker length: int length. Default: 20 scalar: int @@ -496,14 +531,16 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): offset: int offset value. Default: 0 start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await kc_command(ctx, ticker, length, scalar, ma_mode, offset, start, end) - @discord.ext.commands.command(name="stocks.ta.ad") + @discord.ext.commands.command( + name="stocks.ta.ad", usage="[ticker] [is_open] [start] [end]" + ) async def ad( self, ctx: discord.ext.commands.Context, @@ -517,18 +554,20 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker is_open: bool whether open price is used. Default: False start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await ad_command(ctx, ticker, is_open, start, end) - @discord.ext.commands.command(name="stocks.ta.adosc") + @discord.ext.commands.command( + name="stocks.ta.adosc", usage="[ticker] [is_open] [fast] [slow] [start] [end]" + ) async def adosc( self, ctx: discord.ext.commands.Context, @@ -544,7 +583,7 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker is_open: bool whether open price is used. Default: False fast: int @@ -552,41 +591,41 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): slow: int slow value. Default: 10 start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await adosc_command(ctx, ticker, is_open, fast, slow, start, end) - @discord.ext.commands.command(name="stocks.ta.obv") + @discord.ext.commands.command(name="stocks.ta.obv", usage="[ticker] [start] [end]") async def obv(self, ctx: discord.ext.commands.Context, ticker="", start="", end=""): """Displays chart with on balance volume [Yahoo Finance] Parameters ----------- ticker: str - ticker, -h or help + ticker start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await obv_command(ctx, ticker, start, end) - @discord.ext.commands.command(name="stocks.ta.fib") + @discord.ext.commands.command(name="stocks.ta.fib", usage="[ticker] [start] [end]") async def fib(self, ctx: discord.ext.commands.Context, ticker="", start="", end=""): """Displays chart with fibonacci retracement [Yahoo Finance] Parameters ----------- ticker: str - ticker, -h or help + ticker start: - date (in date format for start date) + Starting date in YYYY-MM-DD format end: - date (in date format for end date) + Ending date in YYYY-MM-DD format """ await fib_command(ctx, ticker, start, end) @@ -598,31 +637,31 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): Parameters ----------- ticker: str - ticker, -h or help + ticker """ await view_command(ctx, ticker) - @discord.ext.commands.command(name="stocks.ta.summary") + @discord.ext.commands.command(name="stocks.ta.summary", usage="[ticker]") async def summary(self, ctx: discord.ext.commands.Context, ticker=""): """Displays text of a given stocks ta summary [FinBrain API] Parameters ----------- ticker: str - ticker, -h or help + ticker """ await summary_command(ctx, ticker) - @discord.ext.commands.command(name="stocks.ta.recom") + @discord.ext.commands.command(name="stocks.ta.recom", usage="[ticker]") async def recom(self, ctx: discord.ext.commands.Context, ticker=""): """Displays text of a given stocks recommendation based on ta [Tradingview API] Parameters ----------- ticker: str - ticker, -h or help + ticker """ await recom_command(ctx, ticker) @@ -632,6 +671,8 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): 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. @@ -930,15 +971,16 @@ class TechnicalAnalysisCommands(discord.ext.commands.Cog): ] ] await main_message.edit(components=components) - 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) + 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)