Bot UX playground (#1082)

* Minify the help command

* Add help command for the dps menu

* Blacker the black code

* Add bot log handling

* improve screener on discordbot

* improve screener code of discordbot

* linter

* line length

* fix bug with window size on discordbot

* pylint and black fixes

* black linter

* fix and improve options menu

* Add usage example and fall back to using docstrings as help messages

* Make logger create new files on every launch

* Add usage instructions to menus and commands

* Update docstrings

* Fix arktrades command not handling limit numbers

* Add forgotten help message to the economy command

* Send "you snooze you loose" message only if debug flag is on

Co-authored-by: DidierRLopes <dro.lopes@campus.fct.unl.pt>
This commit is contained in:
Theodore Aptekarev
2021-12-24 00:30:50 +03:00
committed by GitHub
parent e56cdcc49c
commit 17c9b01fad
9 changed files with 369 additions and 185 deletions

View File

@@ -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)

View File

@@ -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))

View File

@@ -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()

View File

@@ -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):

View File

@@ -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")

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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)