Major improvements to discord architecture (#887)

* fix circular-imports on discordbot

* Add pip install package to discord readme

* improve valuation and performance commands

* fix GST_PATH of config_discord

* fix feargreed discordbot

* Improve economy commands

* add data output to bot

* improve shorted command

* fix shorted command

* fix hsi discord command

* improve dps.pos command

* fix sidtc discord cmd

* fix discord ftd command

* fix dps.dpotc command

* improve dps spos

* check for ticker validity

* Improve psi discord command

* improve discord cmds

* refactor economy discord cmds
This commit is contained in:
DidierRLopes
2021-11-01 01:43:02 +00:00
committed by GitHub
parent 3bcb6d0292
commit c5c3b8eee9
21 changed files with 1608 additions and 2197 deletions

11
discordbot/README.md vendored
View File

@@ -25,30 +25,31 @@ Next, go into the discordbot folder with `cd discordbot` and install the followi
pip install discord
pip install discord_components
pip install pyimgur
pip install python-dotenv
```
## Registering Applications
### DISCORD
1. Login into your discord account in https://discord.com/developers/applications
1. Login into your discord account in https://discord.com/developers/applications
2. On the "Applications" tab, select "New Application" and name it something like "GST Bot". This will create a new application.
3. For creating a bot, we need to go into the "GST Bot" application previously created, and on the "Bot" tab select "Add Bot". Note: On this same page you can manage the bot permissions with regards to the server it will be added.
4. Next we need to obtain the "Client ID". For that we choose the "OAuth2" tab and copy our "Client ID" under "Client".
5. At this stage the bot is created and we are ready to invite it to one of our servers. To do so we need to access:
https://discord.com/oauth2/authorize?client_id=CLIENTID&scope=bot, where **CLIENTID** is replaced by the value copied above.
https://discord.com/oauth2/authorize?client_id=CLIENTID&scope=bot, where **CLIENTID** is replaced by the value copied above.
6. If everything went well, you should see a window popup where the Bot that was just created asks to which of your own servers do you want to add it to.
**NOTE:** If you haven't managed the bot permissions on the Bot tab previously you can do it via this link generator https://discordapi.com/permissions.html
**NOTE:** If you haven't managed the bot permissions on the Bot tab previously you can do it via this link generator https://discordapi.com/permissions.html
### IMGUR
1. Login into your https://imgur.com account. Create one if you don't have it.
2. Access https://api.imgur.com/oauth2/addclient to create your application.
3. Select "OAuth 2 authorization without a callback URL" when creating such.
4. You will receive a client ID and client secret once you submit the form.
4. You will receive a client ID and client secret once you submit the form.
**NOTE:** Registering is free for all open source projects and if your discord bot uses fewer than 1250 uploads per day.
**NOTE:** Registering is free for all open source projects and if your discord bot uses fewer than 1250 uploads per day.
## Discord Configs

View File

@@ -1,31 +1,33 @@
import os
import sys
import discord
from dotenv import load_dotenv
env_files = [f for f in os.listdir() if f.endswith(".env")]
if env_files:
load_dotenv(env_files[0])
# Relative path to the terminal
sys.path.append("..")
# https://discord.com/developers/applications/
DISCORD_BOT_TOKEN = os.getenv("GT_DISCORD_BOT_TOKEN") or "REPLACE_ME"
# https://apidocs.imgur.com
IMGUR_CLIENT_ID = os.getenv("GT_IMGUR_CLIENT_ID") or "REPLACE_ME"
# Settings
COMMAND_PREFIX = "!"
DATE_FORMAT = "%Y-%m-%d"
COLOR = discord.Color.from_rgb(0, 206, 154)
MENU_TIMEOUT = 30
DEBUG = True
AUTHOR_NAME = "Gamestonk Terminal"
AUTHOR_ICON_URL = (
"https://github.com/GamestonkTerminal/GamestonkTerminal/"
"blob/main/images/gst_logo_green_white_background.png?raw=true"
)
import os
import sys
import discord
from dotenv import load_dotenv
env_files = [f for f in os.listdir() if f.endswith(".env")]
if env_files:
load_dotenv(env_files[0])
# Relative path to the terminal
sys.path.append("..")
# https://discord.com/developers/applications/
DISCORD_BOT_TOKEN = os.getenv("GT_DISCORD_BOT_TOKEN") or "REPLACE_ME"
# https://apidocs.imgur.com
IMGUR_CLIENT_ID = os.getenv("GT_IMGUR_CLIENT_ID") or "REPLACE_ME"
# Settings
COMMAND_PREFIX = "!"
DATE_FORMAT = "%Y-%m-%d"
COLOR = discord.Color.from_rgb(0, 206, 154)
MENU_TIMEOUT = 30
DEBUG = True
GST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
AUTHOR_NAME = "Gamestonk Terminal"
AUTHOR_ICON_URL = (
"https://github.com/GamestonkTerminal/GamestonkTerminal/"
"blob/main/images/gst_logo_green_white_background.png?raw=true"
)

View File

@@ -1,73 +1,51 @@
import discord
import config_discordbot as cfg
from gamestonk_terminal.economy import wsj_model
async def currencies_command(ctx, arg=""):
"""Gets the currencies data from GST and sends it
Parameters
-----------
arg: str
-h or help
Returns
-------
discord message
Sends a message containing an embed of currencies data to the users
"""
try:
# Debug
if cfg.DEBUG:
print(f"!stocks.economy.currencies {arg}")
# Help
if arg == "-h" or arg == "help":
help_txt = "Currencies [Source: Wall St. Journal]\n"
embed = discord.Embed(
title="Economy: [WSJ] Currencies HELP",
description=help_txt,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
else:
df_data = wsj_model.global_currencies()
if df_data.empty:
df_data_str = "No currencies data available"
else:
df_data_str = "```" + df_data.to_string(index=False) + "```"
embed = discord.Embed(
title="Economy: [WSJ] Currencies",
description=df_data_str,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
except Exception as e:
title = "INTERNAL ERROR"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"Try updating the bot, make sure DEBUG is True in the config "
"and restart it.\nIf the error still occurs open a issue at: "
"https://github.com/GamestonkTerminal/GamestonkTerminal/issues"
f"\n{e}"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(e)
import discord
import config_discordbot as cfg
from gamestonk_terminal.economy import wsj_model
async def currencies_command(ctx):
"""Currencies overview [Wall St. Journal]"""
try:
# Debug user input
if cfg.DEBUG:
print("\n!economy.currencies")
# Retrieve data
df_data = wsj_model.global_currencies()
# Debug user output
if cfg.DEBUG:
print(df_data.to_string())
# Output data
if df_data.empty:
df_data_str = "No currencies data available"
else:
df_data_str = "```" + df_data.to_string(index=False) + "```"
embed = discord.Embed(
title="Economy: [WSJ] Currencies",
description=df_data_str,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
except Exception as e:
embed = discord.Embed(
title="ERROR Economy: [WSJ] Currencies",
colour=cfg.COLOR,
description=e,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)

View File

@@ -2,6 +2,9 @@ import asyncio
import discord
import config_discordbot as cfg
# pylint: disable=wrong-import-order
from discordbot import gst_bot
from economy.feargreed import feargreed_command
from economy.overview import overview_command
from economy.indices import indices_command
@@ -11,7 +14,6 @@ from economy.glbonds import glbonds_command
from economy.currencies import currencies_command
from economy.valuation import valuation_command
from economy.performance import performance_command
from discordbot import gst_bot
class EconomyCommands(discord.ext.commands.Cog):
@@ -21,49 +23,73 @@ class EconomyCommands(discord.ext.commands.Cog):
self.bot = bot
@discord.ext.commands.command(name="economy.feargreed")
async def feargreed(self, ctx: discord.ext.commands.Context, arg=""):
"""CNN Fear and Greed Index [CNN]"""
await feargreed_command(ctx, arg)
async def feargreed(self, ctx: discord.ext.commands.Context, indicator=""):
"""CNN Fear and Greed Index [CNN]
Parameters
-----------
indicator: str
Possible indicatores are: jbd, mv, pco, mm, sps, spb, shd. Which stand for
Junk Bond Demand, Market Volatility, Put and Call Options, Market Momentum,
Stock Price Strength, Stock Price Breadth, Safe Heaven Demand.
"""
await feargreed_command(ctx, indicator)
@discord.ext.commands.command(name="economy.overview")
async def overview(self, ctx: discord.ext.commands.Context, arg=""):
async def overview(self, ctx: discord.ext.commands.Context):
"""Market data overview [Wall St. Journal]"""
await overview_command(ctx, arg)
await overview_command(ctx)
@discord.ext.commands.command(name="economy.indices")
async def indices(self, ctx: discord.ext.commands.Context, arg=""):
async def indices(self, ctx: discord.ext.commands.Context):
"""US indices overview [Wall St. Journal]"""
await indices_command(ctx, arg)
await indices_command(ctx)
@discord.ext.commands.command(name="economy.futures")
async def futures(self, ctx: discord.ext.commands.Context, arg=""):
async def futures(self, ctx: discord.ext.commands.Context):
"""Futures and commodities overview [Wall St. Journal]"""
await futures_command(ctx, arg)
await futures_command(ctx)
@discord.ext.commands.command(name="economy.usbonds")
async def usbonds(self, ctx: discord.ext.commands.Context, arg=""):
async def usbonds(self, ctx: discord.ext.commands.Context):
"""US bonds overview [Wall St. Journal]"""
await usbonds_command(ctx, arg)
await usbonds_command(ctx)
@discord.ext.commands.command(name="economy.glbonds")
async def glbonds(self, ctx: discord.ext.commands.Context, arg=""):
async def glbonds(self, ctx: discord.ext.commands.Context):
"""Global bonds overview [Wall St. Journal]"""
await glbonds_command(ctx, arg)
await glbonds_command(ctx)
@discord.ext.commands.command(name="economy.currencies")
async def currencies(self, ctx: discord.ext.commands.Context, arg=""):
async def currencies(self, ctx: discord.ext.commands.Context):
"""Currencies overview [Wall St. Journal]"""
await currencies_command(ctx, arg)
await currencies_command(ctx)
@discord.ext.commands.command(name="economy.valuation")
async def valuation(self, ctx: discord.ext.commands.Context, arg=""):
"""Valuation of sectors, industry, country [Finviz]"""
await valuation_command(ctx, arg)
async def valuation(self, ctx: discord.ext.commands.Context, economy_group=""):
"""Valuation of sectors, industry, country [Finviz]
Parameters
-----------
economy_group: str
Possible groups are: sector, industry, basic_materials, communication_services,
consumer_cyclical, consumer_defensive, energy, financial, healthcare, industrials,
real_estate, technology, utilities, country, capitalization.
"""
await valuation_command(ctx, economy_group)
@discord.ext.commands.command(name="economy.performance")
async def performance(self, ctx: discord.ext.commands.Context, arg=""):
"""Performance of sectors, industry, country [Finviz]"""
await performance_command(ctx, arg)
async def performance(self, ctx: discord.ext.commands.Context, economy_group=""):
"""Performance of sectors, industry, country [Finviz]
Parameters
-----------
economy_group: str
Possible groups are: sector, industry, basic_materials, communication_services,
consumer_cyclical, consumer_defensive, energy, financial, healthcare, industrials,
real_estate, technology, utilities, country, capitalization.
"""
await performance_command(ctx, economy_group)
@discord.ext.commands.command(name="economy")
async def economy(self, ctx: discord.ext.commands.Context):

View File

@@ -1,113 +1,87 @@
import discord
import matplotlib.pyplot as plt
import os
import datetime
import config_discordbot as cfg
from discordbot import gst_imgur
from gamestonk_terminal.economy import cnn_view, cnn_model
async def feargreed_command(ctx, arg=""):
"""Gets the fear greed data from GST and sends it
Parameters
-----------
arg: str
-h or help
Returns
-------
discord message
Sends a message containing an image of the fear & greed indicator to the user
"""
try:
# Debug
if cfg.DEBUG:
print(f"!stocks.economy.feargreed {arg}")
# Help
if arg == "-h" or arg == "help":
help_txt = """CNN Fear And Greed indicator or index. From Junk Bond Demand, Market Volatility,
Put and Call Options, Market Momentum Stock Price Strength, Stock Price Breadth,
Safe Heaven Demand, and Index. [Source: CNN Business]\n"""
embed = discord.Embed(
title="Economy: [CNN] Fear Geed Index HELP",
description=help_txt,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
else:
plt.ion()
fig = plt.figure(figsize=[1, 1], dpi=10)
report, _ = cnn_model.get_feargreed_report("", fig)
cnn_view.fear_and_greed_index(indicator="", export="png")
plt.close("all")
now = datetime.datetime.now()
image_path = os.path.join(
cfg.GST_PATH,
"exports",
"economy",
f"feargreed_{now.strftime('%Y%m%d_%H%M%S')}.png",
)
i = 0
while not os.path.exists(image_path) and i < 10:
now -= datetime.timedelta(seconds=1)
image_path = os.path.join(
cfg.GST_PATH,
"exports",
"economy",
f"feargreed_{now.strftime('%Y%m%d_%H%M%S')}.png",
)
i += 1
embed = discord.Embed(
title="Economy: [CNN] Fear Geed Index",
description=report,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
if os.path.exists(image_path):
uploaded_image = gst_imgur.upload_image(
image_path, title="FearGreed Charts"
)
embed.set_image(url=uploaded_image.link)
else:
# report = "Error: The image could not be found"
print("Error with uploading the the image to Imgur.")
plt.close("all")
await ctx.send(embed=embed)
except Exception as e:
title = "INTERNAL ERROR"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"Try updating the bot, make sure DEBUG is True in the config "
"and restart it.\nIf the error still occurs open a issue at: "
"https://github.com/GamestonkTerminal/GamestonkTerminal/issues"
f"\n{e}"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(e)
import os
import datetime
import matplotlib.pyplot as plt
import discord
import config_discordbot as cfg
from discordbot import gst_imgur
from gamestonk_terminal.economy import cnn_view, cnn_model
async def feargreed_command(ctx, indicator=""):
"""CNN Fear and Greed Index [CNN]"""
try:
# Debug user input
if cfg.DEBUG:
print(f"\n!economy.feargreed {indicator}")
# Check for argument
possible_indicators = ("", "jbd", "mv", "pco", "mm", "sps", "spb", "shd")
if indicator not in possible_indicators:
raise Exception(
f"Select a valid indicator from {', '.join(possible_indicators)}"
)
# Retrieve data
fig = plt.figure(figsize=[1, 1], dpi=10)
report, _ = cnn_model.get_feargreed_report(indicator, fig)
cnn_view.fear_and_greed_index(indicator=indicator, export="png")
plt.close("all")
# Output data
now = datetime.datetime.now()
image_path = os.path.join(
cfg.GST_PATH,
"exports",
"economy",
f"feargreed_{now.strftime('%Y%m%d_%H%M%S')}.png",
)
i = 0
while not os.path.exists(image_path) and i < 10:
now -= datetime.timedelta(seconds=1)
image_path = os.path.join(
cfg.GST_PATH,
"exports",
"economy",
f"feargreed_{now.strftime('%Y%m%d_%H%M%S')}.png",
)
i += 1
embed = discord.Embed(
title="Economy: [CNN] Fear Geed Index",
description=report,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
if os.path.exists(image_path):
uploaded_image = gst_imgur.upload_image(
image_path, title="FearGreed Charts"
)
embed.set_image(url=uploaded_image.link)
else:
if cfg.DEBUG:
print("Error with uploading the the image to Imgur.")
await ctx.send(embed=embed)
except Exception as e:
embed = discord.Embed(
title="ERROR Economy: [CNN] Feargreed",
colour=cfg.COLOR,
description=e,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)

View File

@@ -1,73 +1,51 @@
import discord
import config_discordbot as cfg
from gamestonk_terminal.economy import wsj_model
async def futures_command(ctx, arg=""):
"""Gets the futures data from GST and sends it
Parameters
-----------
arg: str
-h or help
Returns
-------
discord message
Sends a message containing an embed of futures data to the user
"""
try:
# Debug
if cfg.DEBUG:
print(f"!stocks.economy.futures {arg}")
# Help
if arg == "-h" or arg == "help":
help_txt = "Futures/Commodities [Source: Wall St. Journal]\n"
embed = discord.Embed(
title="Economy: [WSJ] Futures/Commodities HELP",
description=help_txt,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
else:
df_data = wsj_model.top_commodities()
if df_data.empty:
df_data_str = "No futures/commodities data available"
else:
df_data_str = "```" + df_data.to_string(index=False) + "```"
embed = discord.Embed(
title="Economy: [WSJ] Futures/Commodities",
description=df_data_str,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
except Exception as e:
title = "INTERNAL ERROR"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"Try updating the bot, make sure DEBUG is True in the config "
"and restart it.\nIf the error still occurs open a issue at: "
"https://github.com/GamestonkTerminal/GamestonkTerminal/issues"
f"\n{e}"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(e)
import discord
import config_discordbot as cfg
from gamestonk_terminal.economy import wsj_model
async def futures_command(ctx):
"""Futures and commodities overview [Wall St. Journal]"""
try:
# Debug user input
if cfg.DEBUG:
print("\n!economy.futures")
# Retrieve data
df_data = wsj_model.top_commodities()
# Debug user output
if cfg.DEBUG:
print(df_data.to_string())
# Output data
if df_data.empty:
df_data_str = "No futures/commodities data available"
else:
df_data_str = "```" + df_data.to_string(index=False) + "```"
embed = discord.Embed(
title="Economy: [WSJ] Futures/Commodities",
description=df_data_str,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
except Exception as e:
embed = discord.Embed(
title="ERROR Economy: [WSJ] Futures/Commodities",
colour=cfg.COLOR,
description=e,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)

View File

@@ -1,72 +1,51 @@
import discord
import config_discordbot as cfg
from gamestonk_terminal.economy import wsj_model
async def glbonds_command(ctx, arg=""):
"""Gets the global bonds data from GST and sends it
Parameters
-----------
arg: str
-h or help
Returns
-------
discord message
Sends a message containing an embed of global bonds data to the user
"""
try:
# Debug
if cfg.DEBUG:
print(f"!stocks.economy.glbonds {arg}")
# Help
if arg == "-h" or arg == "help":
help_txt = "Global Bonds [Source: Wall St. Journal]\n"
embed = discord.Embed(
title="Economy: [WSJ] Global Bonds HELP",
description=help_txt,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
else:
df_data = wsj_model.global_bonds()
if df_data.empty:
df_data_str = "No global bonds data available"
else:
df_data_str = "```" + df_data.to_string(index=False) + "```"
embed = discord.Embed(
title="Economy: [WSJ] Global Bonds",
description=df_data_str,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
except Exception as e:
title = "INTERNAL ERROR"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"Try updating the bot, make sure DEBUG is True in the config "
"and restart it.\nIf the error still occurs open a issue at: "
"https://github.com/GamestonkTerminal/GamestonkTerminal/issues"
f"\n{e}"
)
if cfg.DEBUG:
print(e)
import discord
import config_discordbot as cfg
from gamestonk_terminal.economy import wsj_model
async def glbonds_command(ctx):
"""Global bonds overview [Wall St. Journal]"""
try:
# Debug user input
if cfg.DEBUG:
print("\n!economy.glbonds")
# Retrieve data
df_data = wsj_model.global_bonds()
# Debug user output
if cfg.DEBUG:
print(df_data.to_string())
# Output data
if df_data.empty:
df_data_str = "No global bonds data available"
else:
df_data_str = "```" + df_data.to_string(index=False) + "```"
embed = discord.Embed(
title="Economy: [WSJ] Global Bonds",
description=df_data_str,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
except Exception as e:
embed = discord.Embed(
title="ERROR Economy: [WSJ] Global Bonds",
colour=cfg.COLOR,
description=e,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)

View File

@@ -1,73 +1,51 @@
import discord
import config_discordbot as cfg
from gamestonk_terminal.economy import wsj_model
async def indices_command(ctx, arg=""):
"""Gets the indices data from GST and sends it
Parameters
-----------
arg: str
-h or help
Returns
-------
discord message
Sends a message containing an embed of indices data to the user
"""
try:
# Debug
if cfg.DEBUG:
print("!stocks.economy.indices {arg}")
# Help
if arg == "-h" or arg == "help":
help_txt = "US Indices [Source: Wall St. Journal]\n"
embed = discord.Embed(
title="Economy: [WSJ] US Indices HELP",
description=help_txt,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
else:
df_data = wsj_model.us_indices()
if df_data.empty:
df_data_str = "No indices data available"
else:
df_data_str = "```" + df_data.to_string(index=False) + "```"
embed = discord.Embed(
title="Economy: [WSJ] US Indices",
description=df_data_str,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
except Exception as e:
title = "INTERNAL ERROR"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"Try updating the bot, make sure DEBUG is True in the config "
"and restart it.\nIf the error still occurs open a issue at: "
"https://github.com/GamestonkTerminal/GamestonkTerminal/issues"
f"\n{e}"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(e)
import discord
import config_discordbot as cfg
from gamestonk_terminal.economy import wsj_model
async def indices_command(ctx):
"""US indices overview [Wall St. Journal]"""
try:
# Debug user input
if cfg.DEBUG:
print("\n!economy.indices")
# Retrieve data
df_data = wsj_model.us_indices()
# Debug user output
if cfg.DEBUG:
print(df_data.to_string())
# Output data
if df_data.empty:
df_data_str = "No indices data available"
else:
df_data_str = "```" + df_data.to_string(index=False) + "```"
embed = discord.Embed(
title="Economy: [WSJ] US Indices",
description=df_data_str,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
except Exception as e:
embed = discord.Embed(
title="ERROR Economy: [WSJ] US Indices",
colour=cfg.COLOR,
description=e,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)

View File

@@ -1,73 +1,51 @@
import discord
import config_discordbot as cfg
from gamestonk_terminal.economy import wsj_model
async def overview_command(ctx, arg=""):
"""Gets the market overview data from GST and sends it
Parameters
-----------
arg: str
-h or help
Returns
-------
discord message
Sends a message containing an embed of market overview data to the user
"""
try:
# Debug
if cfg.DEBUG:
print(f"!stocks.economy.overview {arg}")
# Help
if arg == "-h" or arg == "help":
help_txt = "Market Overview [Source: Wall St. Journal]\n"
embed = discord.Embed(
title="Economy: [WSJ] Market Overview HELP",
description=help_txt,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
else:
df_data = wsj_model.market_overview()
if df_data.empty:
df_data_str = "No overview data available"
else:
df_data_str = "```" + df_data.to_string(index=False) + "```"
embed = discord.Embed(
title="Economy: [WSJ] Market Overview",
description=df_data_str,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
except Exception as e:
title = "INTERNAL ERROR"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"Try updating the bot, make sure DEBUG is True in the config "
"and restart it.\nIf the error still occurs open a issue at: "
"https://github.com/GamestonkTerminal/GamestonkTerminal/issues"
f"\n{e}"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(e)
import discord
import config_discordbot as cfg
from gamestonk_terminal.economy import wsj_model
async def overview_command(ctx):
"""Market data overview [Wall St. Journal]"""
try:
# Debug user input
if cfg.DEBUG:
print("\n!economy.overview")
# Retrieve data
df_data = wsj_model.market_overview()
# Debug user output
if cfg.DEBUG:
print(df_data.to_string())
# Output data
if df_data.empty:
df_data_str = "No overview data available"
else:
df_data_str = "```" + df_data.to_string(index=False) + "```"
embed = discord.Embed(
title="Economy: [WSJ] Market Overview",
description=df_data_str,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
except Exception as e:
embed = discord.Embed(
title="ERROR Economy: [WSK] Market Overview",
colour=cfg.COLOR,
description=e,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)

View File

@@ -1,143 +1,101 @@
import discord
import config_discordbot as cfg
from helpers import pagination
from gamestonk_terminal.economy import finviz_model
async def performance_command(ctx, arg="sector"):
"""Gets the performance data of a entered sector from GST and sends it
Parameters
-----------
arg: str
sector (or any other input in the economy_group), -h or help
Returns
-------
discord message
Sends a message containing an embed of the performance data of the given arg
with pagination to the user
"""
economy_group = {
"sector": "Sector",
"industry": "Industry",
"basic_materials": "Industry (Basic Materials)",
"communication services": "Industry (Communication Services)",
"consumer_cyclical": "Industry (Consumer Cyclical)",
"consumer_defensive": "Industry (Consumer Defensive)",
"energy": "Industry (Energy)",
"financial": "Industry (Financial)",
"healthcare": "Industry (Healthcare)",
"industrials": "Industry (Industrials)",
"real_estate": "Industry (Real Estate)",
"technology": "Industry (Technology)",
"utilities": "Industry (Utilities)",
"country": "Country (U.S. listed stocks only)",
"capitalization": "Capitalization",
}
try:
# Debug
if cfg.DEBUG:
print(f"!stocks.economy.performance {arg}")
# Help
if arg == "-h" or arg == "help":
help_txt = "Group performance [Source: Finviz]\n"
possible_args = ""
for k, v in economy_group.items():
possible_args += f"\n{k}: {v}"
help_txt += "\nPossible arguments:\n"
help_txt += "<GROUP> Groups to get data from. Default: sector\n"
help_txt += f"The choices are:{possible_args}"
embed = discord.Embed(
title="Economy: [Finviz] Performance HELP",
description=help_txt,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
else:
# Parse argument
try:
group = economy_group[arg]
except KeyError:
title = "ERROR Economy: [Finviz] Performance"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
f"Entered group argument: {arg}"
"\nEnter a valid group argument, example: sector"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print("ERROR: Bad group argument entered")
return
df_group = finviz_model.get_valuation_performance_data(group, "performance")
future_column_name = df_group["Name"]
df_group = df_group.transpose()
df_group.columns = future_column_name
df_group.drop("Name")
columns = []
initial_str = "Page 0: Overview"
i = 1
for col_name in df_group.columns.values:
initial_str += f"\nPage {i}: {col_name}"
i += 1
columns.append(
discord.Embed(
title=f"Economy: [Finviz] Performance {group}",
description=initial_str,
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
for column in df_group.columns.values:
columns.append(
discord.Embed(
description="```"
+ df_group[column].fillna("").to_string()
+ "```",
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
await pagination(columns, ctx)
except Exception as e:
title = "INTERNAL ERROR"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"Try updating the bot, make sure DEBUG is True in the config "
"and restart it.\nIf the error still occurs open a issue at: "
"https://github.com/GamestonkTerminal/GamestonkTerminal/issues"
f"\n{e}"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(e)
import discord
import config_discordbot as cfg
from helpers import pagination
from gamestonk_terminal.economy import finviz_model
async def performance_command(ctx, economy_group="sector"):
"""Performance of sectors, industry, country [Finviz]"""
d_economy_group = {
"sector": "Sector",
"industry": "Industry",
"basic_materials": "Industry (Basic Materials)",
"communication_services": "Industry (Communication Services)",
"consumer_cyclical": "Industry (Consumer Cyclical)",
"consumer_defensive": "Industry (Consumer Defensive)",
"energy": "Industry (Energy)",
"financial": "Industry (Financial)",
"healthcare": "Industry (Healthcare)",
"industrials": "Industry (Industrials)",
"real_estate": "Industry (Real Estate)",
"technology": "Industry (Technology)",
"utilities": "Industry (Utilities)",
"country": "Country (U.S. listed stocks only)",
"capitalization": "Capitalization",
}
try:
# Debug user input
if cfg.DEBUG:
print(f"\n!economy.performance {economy_group}")
# Select default group
if not economy_group:
if cfg.DEBUG:
print("Use default economy_group: 'sector'")
economy_group = "sector"
# Check for argument
possible_groups = list(d_economy_group.keys())
if economy_group not in possible_groups:
raise Exception(f"Select a valid group from {', '.join(possible_groups)}")
group = d_economy_group[economy_group]
# Retrieve data
df_group = finviz_model.get_valuation_performance_data(group, "performance")
# Debug user output
if cfg.DEBUG:
print(df_group.to_string())
# Output data
future_column_name = df_group["Name"]
df_group = df_group.transpose()
df_group.columns = future_column_name
df_group.drop("Name")
columns = []
initial_str = "Page 0: Overview"
i = 1
for col_name in df_group.columns.values:
initial_str += f"\nPage {i}: {col_name}"
i += 1
columns.append(
discord.Embed(
title=f"Economy: [Finviz] Performance {group}",
description=initial_str,
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
for column in df_group.columns.values:
columns.append(
discord.Embed(
description="```" + df_group[column].fillna("").to_string() + "```",
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
await pagination(columns, ctx)
except Exception as e:
embed = discord.Embed(
title="ERROR Economy: [Finviz] Performance",
colour=cfg.COLOR,
description=e,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)

View File

@@ -1,75 +1,51 @@
import discord
import config_discordbot as cfg
from gamestonk_terminal.economy import wsj_model
async def usbonds_command(ctx, arg=""):
"""Gets the US bond data from GST and sends it
Parameters
-----------
arg: str
-h or help
Returns
-------
discord message
Sends a message containing an embed of US bond data to the user
"""
try:
# Debug
if cfg.DEBUG:
print(f"!stocks.economy.usbonds {arg}")
# Help
if arg == "-h" or arg == "help":
help_txt = "US Bonds [Source: Wall St. Journal]\n"
embed = discord.Embed(
title="Economy: [WSJ] US Bonds HELP",
description=help_txt,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
else:
df_data = wsj_model.us_bonds()
if df_data.empty:
df_data_str = "No US bonds data available"
else:
df_data_str = "```" + df_data.to_string(index=False) + "```"
embed = discord.Embed(
title="Economy: [WSJ] US Bonds",
description=df_data_str,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
except Exception as e:
title = "INTERNAL ERROR"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"Try updating the bot, make sure DEBUG is True in the config "
"and restart it.\nIf the error still occurs open a issue at: "
"https://github.com/GamestonkTerminal/GamestonkTerminal/issues"
f"\n{e}"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(e)
import discord
import config_discordbot as cfg
from gamestonk_terminal.economy import wsj_model
async def usbonds_command(ctx):
"""US bonds overview [Wall St. Journal]"""
try:
# Debug user input
if cfg.DEBUG:
print("\n!economy.usbonds")
# Retrieve data
df_data = wsj_model.us_bonds()
# Debug user output
if cfg.DEBUG:
print(df_data.to_string())
# Output data
if df_data.empty:
df_data_str = "No US bonds data available"
else:
df_data_str = "```" + df_data.to_string(index=False) + "```"
embed = discord.Embed(
title="Economy: [WSJ] US Bonds",
description=df_data_str,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
except Exception as e:
embed = discord.Embed(
title="ERROR Economy: [WSJ] US Bonds",
colour=cfg.COLOR,
description=e,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)

View File

@@ -1,143 +1,102 @@
import discord
import config_discordbot as cfg
from helpers import pagination
from gamestonk_terminal.economy import finviz_model
async def valuation_command(ctx, arg="sector"):
"""Gets the valuation data of a entered sector from GST and sends it
Parameters
-----------
arg: str
sector (or any other input in the economy_group), -h or help
Returns
-------
discord message
Sends a message containing an embed of the valuation data of the given arg
with pagination to the user
"""
economy_group = {
"sector": "Sector",
"industry": "Industry",
"basic_materials": "Industry (Basic Materials)",
"communication services": "Industry (Communication Services)",
"consumer_cyclical": "Industry (Consumer Cyclical)",
"consumer_defensive": "Industry (Consumer Defensive)",
"energy": "Industry (Energy)",
"financial": "Industry (Financial)",
"healthcare": "Industry (Healthcare)",
"industrials": "Industry (Industrials)",
"real_estate": "Industry (Real Estate)",
"technology": "Industry (Technology)",
"utilities": "Industry (Utilities)",
"country": "Country (U.S. listed stocks only)",
"capitalization": "Capitalization",
}
try:
# Debug
if cfg.DEBUG:
print(f"!stocks.economy.performance {arg}")
# Help
if arg == "-h" or arg == "help":
help_txt = "Group valuation [Source: Finviz]\n"
possible_args = ""
for k, v in economy_group.items():
possible_args += f"\n{k}: {v}"
help_txt += "\nPossible arguments:\n"
help_txt += "<GROUP> Groups to get data from. Default: sector\n"
help_txt += f"The choices are:{possible_args}"
embed = discord.Embed(
title="Economy: [Finviz] Valuation HELP",
description=help_txt,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
else:
try:
# Parse argument
group = economy_group[arg]
except KeyError:
title = "ERROR Economy: [Finviz] Performance"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
f"Entered group argument: {arg}"
"\nEnter a valid group argument, example: sector"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print("ERROR: Bad group argument entered")
return
df_group = finviz_model.get_valuation_performance_data(group, "valuation")
future_column_name = df_group["Name"]
df_group = df_group.transpose()
df_group.columns = future_column_name
df_group.drop("Name")
columns = []
initial_str = "Page 0: Overview"
i = 1
for col_name in df_group.columns.values:
initial_str += f"\nPage {i}: {col_name}"
i += 1
columns.append(
discord.Embed(
title=f"Economy: [Finviz] Valuation {group}",
description=initial_str,
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
for column in df_group.columns.values:
columns.append(
discord.Embed(
description="```"
+ df_group[column].fillna("").to_string()
+ "```",
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
await pagination(columns, ctx)
except Exception as e:
title = "INTERNAL ERROR"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"Try updating the bot, make sure DEBUG is True in the config "
"and restart it.\nIf the error still occurs open a issue at: "
"https://github.com/GamestonkTerminal/GamestonkTerminal/issues"
f"\n{e}"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(e)
import discord
import config_discordbot as cfg
from helpers import pagination
from gamestonk_terminal.economy import finviz_model
async def valuation_command(ctx, economy_group="sector"):
"""Valuation of sectors, industry, country [Finviz]"""
d_economy_group = {
"sector": "Sector",
"industry": "Industry",
"basic_materials": "Industry (Basic Materials)",
"communication_services": "Industry (Communication Services)",
"consumer_cyclical": "Industry (Consumer Cyclical)",
"consumer_defensive": "Industry (Consumer Defensive)",
"energy": "Industry (Energy)",
"financial": "Industry (Financial)",
"healthcare": "Industry (Healthcare)",
"industrials": "Industry (Industrials)",
"real_estate": "Industry (Real Estate)",
"technology": "Industry (Technology)",
"utilities": "Industry (Utilities)",
"country": "Country (U.S. listed stocks only)",
"capitalization": "Capitalization",
}
try:
# Debug user input
if cfg.DEBUG:
print(f"\n!economy.valuation {economy_group}")
# Select default group
if economy_group == "":
if cfg.DEBUG:
print("Use default economy_group: 'sector'")
economy_group = "sector"
# Check for argument
possible_groups = list(d_economy_group.keys())
if economy_group not in possible_groups:
raise Exception(f"Select a valid group from {', '.join(possible_groups)}")
group = d_economy_group[economy_group]
# Retrieve data
df_group = finviz_model.get_valuation_performance_data(group, "valuation")
# Debug user output
if cfg.DEBUG:
print(df_group.to_string())
# Output data
future_column_name = df_group["Name"]
df_group = df_group.transpose()
df_group.columns = future_column_name
df_group.drop("Name")
columns = []
initial_str = "Page 0: Overview"
i = 1
for col_name in df_group.columns.values:
initial_str += f"\nPage {i}: {col_name}"
i += 1
columns.append(
discord.Embed(
title=f"Economy: [Finviz] Valuation {group}",
description=initial_str,
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
for column in df_group.columns.values:
columns.append(
discord.Embed(
description="```" + df_group[column].fillna("").to_string() + "```",
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
await pagination(columns, ctx)
except Exception as e:
embed = discord.Embed(
title="ERROR Economy: [Finviz] Valuation",
colour=cfg.COLOR,
description=e,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)

View File

@@ -1,189 +1,138 @@
import discord
import config_discordbot as cfg
from discordbot import gst_imgur
from matplotlib import pyplot as plt
import matplotlib.dates as mdates
import os
from gamestonk_terminal.config_plot import PLOT_DPI
from gamestonk_terminal.stocks.dark_pool_shorts import finra_model
async def dpotc_command(ctx, arg=""):
"""Displays barchart of dark pool (ATS) and OTC (Non ATS) data and sends it
Parameters
-----------
arg: str
ticker, -h or help
Returns
-------
discord message
Sends a message containing an image displaying a barchart of dark pool
(ATS) and OTC (Non ATS) data to the user
"""
try:
# Debug
if cfg.DEBUG:
print(f"!stocks.dps.dpotc {arg}")
# Help
if arg == "-h" or arg == "help":
help_txt = "Display barchart of dark pool (ATS) and OTC (Non ATS) data. [Source: FINRA]\n"
help_txt += "\nPossible arguments:\n"
help_txt += "<TICKER> Stock ticker. REQUIRED!\n"
embed = discord.Embed(
title="Stocks: [FINRA] Dark Pools (ATS) vs OTC HELP",
description=help_txt,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
else:
if arg == "":
title = "ERROR Stocks: [FINRA] Dark Pools (ATS) vs OTC"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"No ticker entered.\nEnter a valid ticker, example: GME"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print("ERROR: No ticker entered")
return
# Parse argument
ticker = arg.upper()
plt.ion()
title = "Stocks: [FINRA] Dark Pools (ATS) vs OTC " + ticker
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
try:
ats, otc = finra_model.getTickerFINRAdata(ticker)
except Exception as e:
title = "ERROR Stocks: [FINRA] Dark Pools (ATS) vs OTC " + ticker
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
f"Ticker given: {arg}\nEnter a valid ticker, example: GME"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(f"POSSIBLE ERROR: Wrong ticker parameter entered\n{e}")
return
if ats.empty and otc.empty:
return embed.set_description("No data found.")
_, _ = plt.subplots(dpi=PLOT_DPI)
plt.subplot(3, 1, (1, 2))
if not ats.empty and not otc.empty:
plt.bar(
ats.index,
(ats["totalWeeklyShareQuantity"] + otc["totalWeeklyShareQuantity"])
/ 1_000_000,
color="tab:orange",
)
plt.bar(
otc.index,
otc["totalWeeklyShareQuantity"] / 1_000_000,
color="tab:blue",
)
plt.legend(["ATS", "OTC"])
elif not ats.empty:
plt.bar(
ats.index,
ats["totalWeeklyShareQuantity"] / 1_000_000,
color="tab:orange",
)
plt.legend(["ATS"])
elif not otc.empty:
plt.bar(
otc.index,
otc["totalWeeklyShareQuantity"] / 1_000_000,
color="tab:blue",
)
plt.legend(["OTC"])
plt.ylabel("Total Weekly Shares [Million]")
plt.grid(b=True, which="major", color="#666666", linestyle="-", alpha=0.2)
plt.title(f"Dark Pools (ATS) vs OTC (Non-ATS) Data for {ticker}")
plt.subplot(313)
if not ats.empty:
plt.plot(
ats.index,
ats["totalWeeklyShareQuantity"] / ats["totalWeeklyTradeCount"],
color="tab:orange",
)
plt.legend(["ATS"])
if not otc.empty:
plt.plot(
otc.index,
otc["totalWeeklyShareQuantity"] / otc["totalWeeklyTradeCount"],
color="tab:blue",
)
plt.legend(["ATS", "OTC"])
else:
plt.plot(
otc.index,
otc["totalWeeklyShareQuantity"] / otc["totalWeeklyTradeCount"],
color="tab:blue",
)
plt.legend(["OTC"])
plt.ylabel("Shares per Trade")
plt.grid(b=True, which="major", color="#666666", linestyle="-", alpha=0.2)
plt.gcf().autofmt_xdate()
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%m/%d"))
plt.gca().xaxis.set_major_locator(mdates.DayLocator(interval=4))
plt.xlabel("Weeks")
file_name = ticker + "_dpotc.png"
plt.savefig(file_name)
plt.close("all")
uploaded_image = gst_imgur.upload_image(file_name, title="something")
image_link = uploaded_image.link
embed.set_image(url=image_link)
os.remove(file_name)
await ctx.send(embed=embed)
except Exception as e:
title = "INTERNAL ERROR"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"Try updating the bot, make sure DEBUG is True in the config "
"and restart it.\nIf the error still occurs open a issue at: "
"https://github.com/GamestonkTerminal/GamestonkTerminal/issues"
f"\n{e}"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(e)
import os
import matplotlib.dates as mdates
import discord
import yfinance as yf
import config_discordbot as cfg
from matplotlib import pyplot as plt
from discordbot import gst_imgur
from gamestonk_terminal.config_plot import PLOT_DPI
from gamestonk_terminal.stocks.dark_pool_shorts import finra_model
async def dpotc_command(ctx, ticker=""):
"""Dark pools (ATS) vs OTC data [FINRA]"""
try:
# Debug user input
if cfg.DEBUG:
print(f"\n!stocks.dps.dpotc {ticker}")
# Check for argument
if ticker == "":
raise Exception("Stock ticker is required")
ticker = ticker.upper()
stock = yf.download(ticker, progress=False)
if stock.empty:
raise Exception("Stock ticker is invalid")
# Retrieve data
ats, otc = finra_model.getTickerFINRAdata(ticker)
# Debug user output
if cfg.DEBUG:
print(ats.to_string())
print(otc.to_string())
# Output data
title = f"Stocks: [FINRA] Dark Pools (ATS) vs OTC {ticker}"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
if ats.empty and otc.empty:
embed = embed.set_description("No data found.")
_, _ = plt.subplots(dpi=PLOT_DPI)
plt.subplot(3, 1, (1, 2))
if not ats.empty and not otc.empty:
plt.bar(
ats.index,
(ats["totalWeeklyShareQuantity"] + otc["totalWeeklyShareQuantity"])
/ 1_000_000,
color="tab:orange",
)
plt.bar(
otc.index,
otc["totalWeeklyShareQuantity"] / 1_000_000,
color="tab:blue",
)
plt.legend(["ATS", "OTC"])
elif not ats.empty:
plt.bar(
ats.index,
ats["totalWeeklyShareQuantity"] / 1_000_000,
color="tab:orange",
)
plt.legend(["ATS"])
elif not otc.empty:
plt.bar(
otc.index,
otc["totalWeeklyShareQuantity"] / 1_000_000,
color="tab:blue",
)
plt.legend(["OTC"])
plt.ylabel("Total Weekly Shares [Million]")
plt.grid(b=True, which="major", color="#666666", linestyle="-", alpha=0.2)
plt.title(f"Dark Pools (ATS) vs OTC (Non-ATS) Data for {ticker}")
plt.subplot(313)
if not ats.empty:
plt.plot(
ats.index,
ats["totalWeeklyShareQuantity"] / ats["totalWeeklyTradeCount"],
color="tab:orange",
)
plt.legend(["ATS"])
if not otc.empty:
plt.plot(
otc.index,
otc["totalWeeklyShareQuantity"] / otc["totalWeeklyTradeCount"],
color="tab:blue",
)
plt.legend(["ATS", "OTC"])
else:
plt.plot(
otc.index,
otc["totalWeeklyShareQuantity"] / otc["totalWeeklyTradeCount"],
color="tab:blue",
)
plt.legend(["OTC"])
plt.ylabel("Shares per Trade")
plt.grid(b=True, which="major", color="#666666", linestyle="-", alpha=0.2)
plt.gcf().autofmt_xdate()
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%m/%d"))
plt.gca().xaxis.set_major_locator(mdates.DayLocator(interval=4))
plt.xlabel("Weeks")
file_name = ticker + "_dpotc.png"
plt.savefig(file_name)
plt.close("all")
uploaded_image = gst_imgur.upload_image(file_name, title="something")
image_link = uploaded_image.link
embed.set_image(url=image_link)
os.remove(file_name)
await ctx.send(embed=embed)
except Exception as e:
embed = discord.Embed(
title=f"ERROR Stocks: [FINRA] Dark Pools (ATS) vs OTC {ticker}",
colour=cfg.COLOR,
description=e,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)

View File

@@ -1,6 +1,10 @@
import asyncio
import discord
import config_discordbot as cfg
import yfinance as yf
# pylint: disable=wrong-import-order,too-many-branches
from discordbot import gst_bot
from stocks.dark_pool_shorts.shorted import shorted_command
from stocks.dark_pool_shorts.ftd import ftd_command
@@ -10,7 +14,6 @@ from stocks.dark_pool_shorts.psi import psi_command
from stocks.dark_pool_shorts.hsi import hsi_command
from stocks.dark_pool_shorts.pos import pos_command
from stocks.dark_pool_shorts.sidtc import sidtc_command
from discordbot import gst_bot
class DarkPoolShortsCommands(discord.ext.commands.Cog):
@@ -20,47 +23,106 @@ class DarkPoolShortsCommands(discord.ext.commands.Cog):
self.bot = bot
@discord.ext.commands.command(name="stocks.dps.shorted")
async def shorted(self, ctx: discord.ext.commands.Context, arg=""):
"""Show most shorted stocks [Yahoo Finance]"""
await shorted_command(ctx, arg)
async def shorted(self, ctx: discord.ext.commands.Context, num="10"):
"""Show most shorted stocks [Yahoo Finance]
Parameters
-----------
num: int
Number of the most shorted stocks to retrieve
"""
await shorted_command(ctx, num)
@discord.ext.commands.command(name="stocks.dps.hsi")
async def hsi(self, ctx: discord.ext.commands.Context, arg=""):
"""Show top high short interest stocks of over 20% ratio [shortinterest.com]"""
await hsi_command(ctx, arg)
async def hsi(self, ctx: discord.ext.commands.Context, num="10"):
"""Show top high short interest stocks of over 20% ratio [shortinterest.com]
Parameters
-----------
num: int
Number of top stocks to print
"""
await hsi_command(ctx, num)
@discord.ext.commands.command(name="stocks.dps.pos")
async def pos(self, ctx: discord.ext.commands.Context, arg="", arg2=""):
"""Dark pool short position [Stockgrid]"""
await pos_command(ctx, arg, arg2)
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.
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
Number of top tickers to show
"""
await pos_command(ctx, sort, num)
@discord.ext.commands.command(name="stocks.dps.sidtc")
async def sidtc(self, ctx: discord.ext.commands.Context, arg="", arg2=""):
"""Short interest and days to cover [Stockgrid]"""
await sidtc_command(ctx, arg, arg2)
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.
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")
async def ftd(self, ctx: discord.ext.commands.Context, arg, arg2="", arg3=""):
"""Fails-to-deliver data [SEC]"""
await ftd_command(ctx, arg, arg2, arg3)
async def ftd(self, ctx: discord.ext.commands.Context, ticker="", start="", end=""):
"""Fails-to-deliver data [SEC]
Parameters
----------
ticker: str
Stock ticker
start: datetime
Start of date
end: datetime
End of date
"""
await ftd_command(ctx, ticker, start, end)
@discord.ext.commands.command(name="stocks.dps.dpotc")
async def dpotc(self, ctx: discord.ext.commands.Context, arg):
"""Dark pools (ATS) vs OTC data [FINRA]"""
await dpotc_command(ctx, arg)
async def dpotc(self, ctx: discord.ext.commands.Context, ticker=""):
"""Dark pools (ATS) vs OTC data [FINRA]
Parameters
----------
ticker: str
Stock ticker
"""
await dpotc_command(ctx, ticker)
@discord.ext.commands.command(name="stocks.dps.spos")
async def spos(self, ctx: discord.ext.commands.Context, arg):
"""Net short vs position [Stockgrid]"""
await spos_command(ctx, arg)
async def spos(self, ctx: discord.ext.commands.Context, ticker=""):
"""Net short vs position [Stockgrid]
Parameters
----------
ticker: str
Stock ticker
"""
await spos_command(ctx, ticker)
@discord.ext.commands.command(name="stocks.dps.psi")
async def psi(self, ctx: discord.ext.commands.Context, arg):
"""Price vs short interest volume [Stockgrid]"""
await psi_command(ctx, arg)
async def psi(self, ctx: discord.ext.commands.Context, ticker=""):
"""Price vs short interest volume [Stockgrid]
Parameters
----------
ticker: str
Stock ticker
"""
await psi_command(ctx, ticker)
@discord.ext.commands.command(name="stocks.dps")
async def dark_pool_shorts_menu(self, ctx: discord.ext.commands.Context, arg=""):
async def dark_pool_shorts_menu(self, ctx: discord.ext.commands.Context, ticker=""):
"""Stocks Context - Shows Dark Pool Shorts Menu
Returns
@@ -70,7 +132,23 @@ class DarkPoolShortsCommands(discord.ext.commands.Cog):
"""
if cfg.DEBUG:
print("!stocks.dps")
print(f"\n!stocks.dps {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"
@@ -78,12 +156,12 @@ class DarkPoolShortsCommands(discord.ext.commands.Cog):
"2️⃣ !stocks.dps.pos <NUM> <SORT>\n"
"3️⃣ !stocks.dps.sidtc <NUM> <SORT>\n"
)
if arg:
if ticker:
text += (
f"4️⃣ !stocks.dps.ftd {arg} <DATE_START> <DATE_END>\n"
f"5️⃣ !stocks.dps.dpotc {arg}\n"
f"6️⃣ !stocks.dps.spos {arg}\n"
f"7️⃣ !stocks.dps.psi {arg}\n"
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 += (
@@ -101,7 +179,7 @@ class DarkPoolShortsCommands(discord.ext.commands.Cog):
emoji_list = ["0️⃣", "1️⃣", "2️⃣", "3️⃣"]
if arg:
if ticker:
emoji_list += ["4️⃣", "5️⃣", "6️⃣", "7️⃣"]
for emoji in emoji_list:
@@ -133,19 +211,19 @@ class DarkPoolShortsCommands(discord.ext.commands.Cog):
elif reaction.emoji == "4️⃣":
if cfg.DEBUG:
print("Reaction selected: 4")
await ftd_command(ctx, arg)
await ftd_command(ctx, ticker)
elif reaction.emoji == "5️⃣":
if cfg.DEBUG:
print("Reaction selected: 5")
await dpotc_command(ctx, arg)
await dpotc_command(ctx, ticker)
elif reaction.emoji == "6️⃣":
if cfg.DEBUG:
print("Reaction selected: 6")
await spos_command(ctx, arg)
await spos_command(ctx, ticker)
elif reaction.emoji == "7️⃣":
if cfg.DEBUG:
print("Reaction selected: 7")
await psi_command(ctx, arg)
await psi_command(ctx, ticker)
for emoji in emoji_list:
await msg.remove_reaction(emoji, ctx.bot.user)

View File

@@ -1,179 +1,96 @@
import discord
import config_discordbot as cfg
from discordbot import gst_imgur
from datetime import datetime, timedelta
from matplotlib import pyplot as plt
import matplotlib.dates as mdates
import os
import helpers
from gamestonk_terminal.stocks.dark_pool_shorts import sec_model
async def ftd_command(ctx, arg="", arg2="", arg3=""):
"""Displays barchart of fail of deliver data of a given stock and sends it
Parameters
-----------
arg: str
ticker, -h or help
arg2:
date (in date format for start date)
arg3:
date (in date format for end date)
Returns
-------
discord message
Sends a message containing an image displaying a barchart fail to
deliver data to the user during a given time period
"""
try:
# Debug
if cfg.DEBUG:
print(f"!stocks.dps.ftd {arg} {arg2} {arg3}")
# Help
if arg == "-h" or arg == "help":
help_txt = (
"Display fails-to-deliver data for a given ticker. [Source: SEC]\n"
)
help_txt += "\nPossible arguments:\n"
help_txt += "<TICKER> Stock ticker. REQUIRED!\n"
help_txt += "<DATE_START> Start of data. Default: 1 year ago\n"
help_txt += "<DATE_END> End of data. Default: today\n"
embed = discord.Embed(
title="Stocks: [SEC] Failure-to-deliver HELP",
description=help_txt,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
else:
if arg == "":
title = "ERROR Stocks: [SEC] Failure-to-deliver"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"No ticker entered.\nEnter a valid ticker, example: GME"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print("ERROR: No ticker entered")
return
# Parse argument
ticker = arg.upper()
if arg2 == "":
start = datetime.now() - timedelta(days=365)
else:
try:
start = datetime.strptime(arg2, cfg.DATE_FORMAT)
except Exception as e:
title = "ERROR Stocks: [SEC] Failure-to-deliver"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
f"Start Date given: {arg2}"
f"\nEnter a valid start date using the format: {cfg.DATE_FORMAT}"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(f"ERROR: Wrong start date parameter entered\n{e}")
return
if arg3 == "":
end = datetime.now()
else:
try:
end = datetime.strptime(arg3, cfg.DATE_FORMAT)
except Exception as e:
title = "ERROR Stocks: [SEC] Failure-to-deliver"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
f"End Date given: {arg3}"
f"\nEnter a valid end date using the format: {cfg.DATE_FORMAT}"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(f"ERROR: Wrong end date parameter entered\n{e}")
return
plt.ion()
try:
ftds_data = sec_model.get_fails_to_deliver(ticker, start, end, 0)
except Exception as e:
title = f"ERROR Stocks: [SEC] Failure-to-deliver {ticker}"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
f"Ticker given: {arg}" "\nEnter a valid ticker, example: GME"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(f"POSSIBLE ERROR: Wrong ticker parameter entered\n{e}")
return
plt.bar(
ftds_data["SETTLEMENT DATE"],
ftds_data["QUANTITY (FAILS)"] / 1000,
)
plt.ylabel("Shares [K]")
plt.title(f"Fails-to-deliver Data for {ticker}")
plt.grid(b=True, which="major", color="#666666", linestyle="-", alpha=0.2)
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%Y/%m/%d"))
plt.gca().xaxis.set_major_locator(mdates.DayLocator(interval=7))
plt.gcf().autofmt_xdate()
plt.xlabel("Days")
_ = plt.gca().twinx()
stock = helpers.load(ticker, start)
stock_ftd = stock[stock.index > start]
stock_ftd = stock_ftd[stock_ftd.index < end]
plt.plot(stock_ftd.index, stock_ftd["Adj Close"], color="tab:orange")
plt.ylabel("Share Price [$]")
plt.savefig("dps_ftd.png")
plt.close("all")
uploaded_image = gst_imgur.upload_image("dps_ftd.png", title="something")
image_link = uploaded_image.link
title = "Stocks: [SEC] Failure-to-deliver " + ticker
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_image(url=image_link)
os.remove("dps_ftd.png")
await ctx.send(embed=embed)
except Exception as e:
title = "INTERNAL ERROR"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"Try updating the bot, make sure DEBUG is True in the config "
"and restart it.\nIf the error still occurs open a issue at: "
"https://github.com/GamestonkTerminal/GamestonkTerminal/issues"
f"\n{e}"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(e)
import os
from datetime import datetime, timedelta
import discord
import yfinance as yf
import config_discordbot as cfg
import helpers
from matplotlib import pyplot as plt
import matplotlib.dates as mdates
from discordbot import gst_imgur
from gamestonk_terminal.stocks.dark_pool_shorts import sec_model
async def ftd_command(ctx, ticker="", start="", end=""):
"""Fails-to-deliver data [SEC]"""
try:
# Debug user input
if cfg.DEBUG:
print(f"\n!stocks.dps.ftd {ticker} {start} {end}")
# Check for argument
if ticker == "":
raise Exception("Stock ticker is required")
ticker = ticker.upper()
stock = yf.download(ticker, progress=False)
if stock.empty:
raise Exception("Stock ticker is invalid")
if start == "":
start = datetime.now() - timedelta(days=365)
else:
start = datetime.strptime(start, cfg.DATE_FORMAT)
if end == "":
end = datetime.now()
else:
end = datetime.strptime(end, cfg.DATE_FORMAT)
# Retrieve data
ftds_data = sec_model.get_fails_to_deliver(ticker, start, end, 0)
# Debug user output
if cfg.DEBUG:
print(ftds_data.to_string())
# Output data
plt.bar(
ftds_data["SETTLEMENT DATE"],
ftds_data["QUANTITY (FAILS)"] / 1000,
)
plt.ylabel("Shares [K]")
plt.title(f"Fails-to-deliver Data for {ticker}")
plt.grid(b=True, which="major", color="#666666", linestyle="-", alpha=0.2)
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%Y/%m/%d"))
plt.gca().xaxis.set_major_locator(mdates.DayLocator(interval=7))
plt.gcf().autofmt_xdate()
plt.xlabel("Days")
_ = plt.gca().twinx()
stock = helpers.load(ticker, start)
stock_ftd = stock[stock.index > start]
stock_ftd = stock_ftd[stock_ftd.index < end]
plt.plot(stock_ftd.index, stock_ftd["Adj Close"], color="tab:orange")
plt.ylabel("Share Price [$]")
plt.savefig("dps_ftd.png")
plt.close("all")
uploaded_image = gst_imgur.upload_image("dps_ftd.png", title="something")
image_link = uploaded_image.link
title = "Stocks: [SEC] Failure-to-deliver " + ticker
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_image(url=image_link)
os.remove("dps_ftd.png")
await ctx.send(embed=embed)
except Exception as e:
embed = discord.Embed(
title=f"ERROR Stocks: [SEC] Failure-to-deliver {ticker}",
colour=cfg.COLOR,
description=e,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)

View File

@@ -1,119 +1,79 @@
import discord
import config_discordbot as cfg
from helpers import pagination
from gamestonk_terminal.stocks.dark_pool_shorts import shortinterest_model
async def hsi_command(ctx, arg="10"):
"""Gets high shorted interest data from GST and sends it
Parameters
-----------
arg: str
number, -h or help
Returns
-------
discord message
Sends a message containing an embed of the stocks with the top high
shorted interest to the user
"""
try:
# Debug
if cfg.DEBUG:
print(f"!stocks.dps.hsi {arg}")
# Help
if arg == "-h" or arg == "help":
help_txt = "Display top high shorted interest stocks [Source: highshortinterest.com]\n"
help_txt += "\nPossible arguments:\n"
help_txt += "<NUM> Number of stocks to display. Default: 10"
embed = discord.Embed(
title="Stocks: [highshortinterest.com] Top High Short Interest HELP",
description=help_txt,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
else:
try:
# Parse argument
num = int(arg)
if num < 0:
raise ValueError("Number has to be above 0")
except ValueError:
title = "ERROR Stocks: [SEC] Failure-to-deliver"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"No number (int) entered."
"\nEnter a valid (positive) number, example: 10"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print("ERROR: No (positive) int entered")
return
df = shortinterest_model.get_high_short_interest()
df = df.iloc[1:].head(n=num)
future_column_name = df["Ticker"]
df = df.transpose()
df.columns = future_column_name
df.drop("Ticker")
columns = []
initial_str = "Page 0: Overview"
i = 1
for column in df.columns.values:
initial_str = initial_str + "\nPage " + str(i) + ": " + column
i += 1
columns.append(
discord.Embed(
title="Stocks: [highshortinterest.com] Top High Short Interest",
description=initial_str,
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
for column in df.columns.values:
columns.append(
discord.Embed(
title="Stocks: [highshortinterest.com] Top High Short Interest",
description="```" + df[column].fillna("").to_string() + "```",
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
await pagination(columns, ctx)
except Exception as e:
title = "INTERNAL ERROR"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"Try updating the bot, make sure DEBUG is True in the config "
"and restart it.\nIf the error still occurs open a issue at: "
"https://github.com/GamestonkTerminal/GamestonkTerminal/issues"
f"\n{e}"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(e)
import discord
import config_discordbot as cfg
from helpers import pagination
from gamestonk_terminal.stocks.dark_pool_shorts import shortinterest_model
async def hsi_command(ctx, num="10"):
"""Show top high short interest stocks of over 20% ratio [shortinterest.com]"""
try:
# Debug user input
if cfg.DEBUG:
print(f"\n!stocks.dps.hsi {num}")
# Check for argument
if not num.lstrip("-").isnumeric():
raise Exception("Number has to be an integer")
num = int(num)
if num < 0:
raise Exception("Number has to be above 0")
# Retrieve data
df = shortinterest_model.get_high_short_interest()
df = df.iloc[1:].head(n=num)
# Debug user output
if cfg.DEBUG:
print(df.to_string())
# Output data
future_column_name = df["Ticker"]
df = df.transpose()
df.columns = future_column_name
df.drop("Ticker")
columns = []
initial_str = "Page 0: Overview"
i = 1
for column in df.columns.values:
initial_str = initial_str + "\nPage " + str(i) + ": " + column
i += 1
columns.append(
discord.Embed(
title="Stocks: [highshortinterest.com] Top High Short Interest",
description=initial_str,
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
for column in df.columns.values:
columns.append(
discord.Embed(
title="Stocks: [highshortinterest.com] Top High Short Interest",
description="```" + df[column].fillna("").to_string() + "```",
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
await pagination(columns, ctx)
except Exception as e:
embed = discord.Embed(
title="ERROR Stocks: [highshortinterest.com] Top High Short Interest",
colour=cfg.COLOR,
description=e,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)

View File

@@ -1,177 +1,105 @@
import discord
import config_discordbot as cfg
from helpers import pagination
from gamestonk_terminal.stocks.dark_pool_shorts import stockgrid_model
async def pos_command(ctx, arg="dpp_dollar", arg2="10"):
"""Gets the dark pool shorts data sorted by arg from GST and sends it
Parameters
-----------
arg: str
sort (str in dark_pool_short), -h or help
arg2: str
number
Returns
-------
discord message
Sends a message containing an embed of dark pool shorts data given
the sorting arg to the user
"""
try:
# Debug
if cfg.DEBUG:
print(f"!stocks.dps.pos {arg} {arg2}")
# Help
if arg == "-h" or arg == "help":
dark_pool_sort = {
"sv": "Short Vol. (1M)",
"sv_pct": "Short Vol. %",
"nsv": "Net Short Vol. (1M)",
"nsv_dollar": "Net Short Vol. ($100M)",
"dpp": "DP Position (1M)",
"dpp_dollar": "DP Position ($1B)",
}
help_txt = "Get dark pool short positions. [Source: Stockgrid]\n"
possible_args = ""
for k, v in dark_pool_sort.items():
possible_args += f"\n{k}: {v}"
help_txt += "\nPossible arguments:\n"
help_txt += "<SORT> Field for which to sort by. Default: dpp_dollar\n"
help_txt += f"The choices are:{possible_args}\n"
help_txt += "<NUM> Number of top tickers to show. Default: 10"
embed = discord.Embed(
title="Stocks: [Stockgrid] Dark Pool Short Position HELP",
description=help_txt,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
else:
# Parse argument
sort = arg
try:
num = int(arg2)
if num < 0:
raise ValueError("Number has to be above 0")
except ValueError:
title = "ERROR Stocks: [Stockgrid] Dark Pool Short Position"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"No number (int) entered in the second argument."
"\nEnter a valid (positive) number, example: 10"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print("ERROR: No (positive) int for second argument entered")
return
try:
df = stockgrid_model.get_dark_pool_short_positions(sort, False)
except Exception as e:
title = "ERROR Stocks: [Stockgrid] Dark Pool Short Position"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
f"Sorting parameter given: {arg}"
"\nEnter a valid ticker, example: dpp_value"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(f"POSSIBLE ERROR: Wrong sort parameter entered\n{e}")
return
df = df.iloc[:num]
dp_date = df["Date"].values[0]
df = df.drop(columns=["Date"])
df["Net Short Volume $"] = df["Net Short Volume $"] / 100_000_000
df["Short Volume"] = df["Short Volume"] / 1_000_000
df["Net Short Volume"] = df["Net Short Volume"] / 1_000_000
df["Short Volume %"] = df["Short Volume %"] * 100
df["Dark Pools Position $"] = df["Dark Pools Position $"] / (1_000_000_000)
df["Dark Pools Position"] = df["Dark Pools Position"] / 1_000_000
df.columns = [
"Ticker",
"Short Vol. (1M)",
"Short Vol. %",
"Net Short Vol. (1M)",
"Net Short Vol. ($100M)",
"DP Position (1M)",
"DP Position ($1B)",
]
future_column_name = df["Ticker"]
df = df.transpose()
df.columns = future_column_name
df.drop("Ticker")
columns = []
initial_str = "Page 0: Overview"
i = 1
for column in df.columns.values:
initial_str = initial_str + "\nPage " + str(i) + ": " + column
i += 1
columns.append(
discord.Embed(
title="Stocks: [Stockgrid] Dark Pool Short Position",
description=initial_str,
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
for column in df.columns.values:
columns.append(
discord.Embed(
title="High Short Interest",
description="```The following data corresponds to the date: "
+ dp_date
+ "\n\n"
+ df[column].fillna("").to_string()
+ "```",
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
await pagination(columns, ctx)
except Exception as e:
title = "INTERNAL ERROR"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"Try updating the bot, make sure DEBUG is True in the config "
"and restart it.\nIf the error still occurs open a issue at: "
"https://github.com/GamestonkTerminal/GamestonkTerminal/issues"
f"\n{e}"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(e)
import discord
import config_discordbot as cfg
from helpers import pagination
from gamestonk_terminal.stocks.dark_pool_shorts import stockgrid_model
async def pos_command(ctx, sort="dpp_dollar", num="10"):
"""Dark pool short position [Stockgrid]"""
try:
# Debug user input
if cfg.DEBUG:
print(f"\n!stocks.dps.pos {sort} {num}")
# Check for argument
possible_sorts = ("sv", "sv_pct", "nsv", "nsv_dollar", "dpp", "dpp_dollar")
if sort not in possible_sorts:
raise Exception(f"The possible sorts are: {', '.join(possible_sorts)}")
if not num.lstrip("-").isnumeric():
raise Exception("Number has to be an integer")
num = int(num)
if num < 0:
raise Exception("Number has to be above 0")
# Retrieve data
df = stockgrid_model.get_dark_pool_short_positions(sort, False)
df = df.iloc[:num]
# Debug user output
if cfg.DEBUG:
print(df.to_string())
# Output data
dp_date = df["Date"].values[0]
df = df.drop(columns=["Date"])
df["Net Short Volume $"] = df["Net Short Volume $"] / 100_000_000
df["Short Volume"] = df["Short Volume"] / 1_000_000
df["Net Short Volume"] = df["Net Short Volume"] / 1_000_000
df["Short Volume %"] = df["Short Volume %"] * 100
df["Dark Pools Position $"] = df["Dark Pools Position $"] / (1_000_000_000)
df["Dark Pools Position"] = df["Dark Pools Position"] / 1_000_000
df.columns = [
"Ticker",
"Short Vol. (1M)",
"Short Vol. %",
"Net Short Vol. (1M)",
"Net Short Vol. ($100M)",
"DP Position (1M)",
"DP Position ($1B)",
]
future_column_name = df["Ticker"]
df = df.transpose()
df.columns = future_column_name
df.drop("Ticker")
columns = []
initial_str = "Page 0: Overview"
i = 1
for column in df.columns.values:
initial_str = initial_str + "\nPage " + str(i) + ": " + column
i += 1
columns.append(
discord.Embed(
title="Stocks: [Stockgrid] Dark Pool Short Position",
description=initial_str,
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
for column in df.columns.values:
columns.append(
discord.Embed(
title="High Short Interest",
description="```The following data corresponds to the date: "
+ dp_date
+ "\n\n"
+ df[column].fillna("").to_string()
+ "```",
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
await pagination(columns, ctx)
except Exception as e:
embed = discord.Embed(
title="ERROR Stocks: [Stockgrid] Dark Pool Short Position",
colour=cfg.COLOR,
description=e,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)

View File

@@ -1,171 +1,120 @@
import discord
import os
import config_discordbot as cfg
from discordbot import gst_imgur
from datetime import timedelta
from matplotlib import pyplot as plt
from gamestonk_terminal.config_plot import PLOT_DPI
from gamestonk_terminal.stocks.dark_pool_shorts import stockgrid_model
async def psi_command(ctx, arg=""):
"""Gets price vs short interest volume plot from GST and sends it
Parameters
-----------
arg: str
ticker, -h or help
Returns
-------
discord message
Sends a message containing an image of price vs short interest volume of
a given ticker to the user
"""
try:
# Debug
if cfg.DEBUG:
print(f"!stocks.dps.psi {arg}")
# Help
if arg == "-h" or arg == "help":
help_txt = "Plot price vs short interest volume. [Source: Stockgrid]\n"
help_txt += "\nPossible arguments:\n"
help_txt += "<TICKER> Stock ticker. REQUIRED!\n"
embed = discord.Embed(
title="Stocks: [Stockgrid] Price vs Short Interest Volume HELP",
description=help_txt,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
else:
if arg == "":
title = "ERROR Stocks: [SEC] Failure-to-deliver"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"No ticker entered." "\nEnter a valid ticker, example: GME"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print("ERROR: No ticker entered")
return
# Parse argument
ticker = arg.upper()
plt.ion()
title = "Stocks: [Stockgrid] Price vs Short Interest Volume " + ticker
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
try:
df, prices = stockgrid_model.get_short_interest_volume(ticker)
except Exception as e:
title = (
f"ERROR Stocks: [Stockgrid] Price vs Short Interest Volume {arg}"
)
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
f"Ticker given: {arg}" "\nEnter a valid ticker, example: GME"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(f"POSSIBLE ERROR: Wrong ticker parameter entered\n{e}")
return
_, axes = plt.subplots(
2,
1,
dpi=PLOT_DPI,
gridspec_kw={"height_ratios": [2, 1]},
)
axes[0].bar(
df["date"],
df["total_volume"] / 1_000_000,
width=timedelta(days=1),
color="b",
alpha=0.4,
label="Total Volume",
)
axes[0].bar(
df["date"],
df["short_volume"] / 1_000_000,
width=timedelta(days=1),
color="r",
alpha=0.4,
label="Short Volume",
)
axes[0].set_ylabel("Volume (1M)")
ax2 = axes[0].twinx()
ax2.plot(
df["date"].values, prices[len(prices) - len(df) :], c="k", label="Price"
)
ax2.set_ylabel("Price ($)")
lines, labels = axes[0].get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax2.legend(lines + lines2, labels + labels2, loc="upper left")
axes[0].grid()
axes[0].ticklabel_format(style="plain", axis="y")
plt.title(f"Price vs Short Volume Interest for {ticker}")
plt.gcf().autofmt_xdate()
axes[1].plot(
df["date"].values,
100 * df["short_volume%"],
c="green",
label="Short Vol. %",
)
axes[1].set_ylabel("Short Vol. %")
axes[1].grid(axis="y")
lines, labels = axes[1].get_legend_handles_labels()
axes[1].legend(lines, labels, loc="upper left")
axes[1].set_ylim([0, 100])
file_name = ticker + "_psi.png"
plt.savefig(file_name)
plt.close("all")
uploaded_image = gst_imgur.upload_image(file_name, title="something")
image_link = uploaded_image.link
embed.set_image(url=image_link)
os.remove(file_name)
await ctx.send(embed=embed)
except Exception as e:
title = "INTERNAL ERROR"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"Try updating the bot, make sure DEBUG is True in the config "
"and restart it.\nIf the error still occurs open a issue at: "
"https://github.com/GamestonkTerminal/GamestonkTerminal/issues"
f"\n{e}"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(e)
import os
from datetime import timedelta
from matplotlib import pyplot as plt
import yfinance as yf
import discord
import config_discordbot as cfg
from discordbot import gst_imgur
from gamestonk_terminal.config_plot import PLOT_DPI
from gamestonk_terminal.stocks.dark_pool_shorts import stockgrid_model
async def psi_command(ctx, ticker=""):
"""Price vs short interest volume [Stockgrid]"""
try:
# Debug user input
if cfg.DEBUG:
print(f"\n!stocks.dps.psi {ticker}")
# Check for argument
if ticker == "":
raise Exception("Stock ticker is required")
ticker = ticker.upper()
stock = yf.download(ticker, progress=False)
if stock.empty:
raise Exception("Stock ticker is invalid")
# Retrieve data
df, prices = stockgrid_model.get_short_interest_volume(ticker)
# Debug user output
if cfg.DEBUG:
print(df.to_string())
# Output data
title = f"Stocks: [Stockgrid] Price vs Short Interest Volume {ticker}"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
_, axes = plt.subplots(
2,
1,
dpi=PLOT_DPI,
gridspec_kw={"height_ratios": [2, 1]},
)
axes[0].bar(
df["date"],
df["total_volume"] / 1_000_000,
width=timedelta(days=1),
color="b",
alpha=0.4,
label="Total Volume",
)
axes[0].bar(
df["date"],
df["short_volume"] / 1_000_000,
width=timedelta(days=1),
color="r",
alpha=0.4,
label="Short Volume",
)
axes[0].set_ylabel("Volume (1M)")
ax2 = axes[0].twinx()
ax2.plot(
df["date"].values, prices[len(prices) - len(df) :], c="k", label="Price"
)
ax2.set_ylabel("Price ($)")
lines, labels = axes[0].get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax2.legend(lines + lines2, labels + labels2, loc="upper left")
axes[0].grid()
axes[0].ticklabel_format(style="plain", axis="y")
plt.title(f"Price vs Short Volume Interest for {ticker}")
plt.gcf().autofmt_xdate()
axes[1].plot(
df["date"].values,
100 * df["short_volume%"],
c="green",
label="Short Vol. %",
)
axes[1].set_ylabel("Short Vol. %")
axes[1].grid(axis="y")
lines, labels = axes[1].get_legend_handles_labels()
axes[1].legend(lines, labels, loc="upper left")
axes[1].set_ylim([0, 100])
file_name = ticker + "_psi.png"
plt.savefig(file_name)
plt.close("all")
uploaded_image = gst_imgur.upload_image(file_name, title="something")
image_link = uploaded_image.link
embed.set_image(url=image_link)
os.remove(file_name)
await ctx.send(embed=embed)
except Exception as e:
embed = discord.Embed(
title=f"ERROR Stocks: [Stockgrid] Price vs Short Interest Volume {ticker}",
colour=cfg.COLOR,
description=e,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)

View File

@@ -1,122 +1,82 @@
import discord
import config_discordbot as cfg
from helpers import pagination
from gamestonk_terminal.stocks.dark_pool_shorts import yahoofinance_model
async def shorted_command(ctx, arg="5"):
"""Gets the most shorted stocks data from GST and sends it
Parameters
-----------
arg: str
number, -h or help
Returns
-------
discord message
Sends a message containing an embed containing of the most shorted
stocks to the user
"""
try:
# Debug
if cfg.DEBUG:
print(f"!stocks.dps.shorted {arg}")
# Help
if arg == "-h" or arg == "help":
help_txt = "Display most shorted stocks screener. [Source: Yahoo Finance]\n"
help_txt += "\nPossible arguments:\n"
help_txt += "<NUM> Number of stocks to display. Default: 5"
embed = discord.Embed(
title="Stocks: [Yahoo Finance] Most Shorted HELP",
description=help_txt,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
else:
try:
# Parse argument
num = int(arg)
if num < 0:
raise ValueError("Number has to be above 0")
except ValueError:
title = "ERROR Stocks: [Yahoo Finance] Most Shorted"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"No number (int) entered."
"\nEnter a valid (positive) number, example: 10"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print("ERROR: No (positive) int entered")
return
df = yahoofinance_model.get_most_shorted().head(num)
df.dropna(how="all", axis=1, inplace=True)
df = df.replace(float("NaN"), "")
future_column_name = df["Symbol"]
df = df.transpose()
df.columns = future_column_name
df.drop("Symbol")
columns = []
initial_str = "Page 0: Overview"
i = 1
for col_name in df.columns.values:
initial_str += f"\nPage {i}: {col_name}"
i += 1
columns.append(
discord.Embed(
title="Stocks: [Yahoo Finance] Most Shorted",
description=initial_str,
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
for column in df.columns.values:
columns.append(
discord.Embed(
description="```" + df[column].fillna("").to_string() + "```",
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
await pagination(columns, ctx)
except Exception as e:
title = "INTERNAL ERROR"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"Try updating the bot, make sure DEBUG is True in the config "
"and restart it.\nIf the error still occurs open a issue at: "
"https://github.com/GamestonkTerminal/GamestonkTerminal/issues"
f"\n{e}"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(e)
import discord
import config_discordbot as cfg
from helpers import pagination
from gamestonk_terminal.stocks.dark_pool_shorts import yahoofinance_model
async def shorted_command(ctx, num="10"):
"""Show most shorted stocks [Yahoo Finance]"""
try:
# Debug user input
if cfg.DEBUG:
print(f"\n!stocks.dps.shorted {num}")
# Check for argument
if not num.lstrip("-").isnumeric():
raise Exception("Number has to be an integer")
num = int(num)
if num < 0:
raise Exception("Number has to be above 0")
# Retrieve data
df = yahoofinance_model.get_most_shorted().head(num)
# Debug user output
if cfg.DEBUG:
print(df.to_string())
# Output data
df.dropna(how="all", axis=1, inplace=True)
df = df.replace(float("NaN"), "")
future_column_name = df["Symbol"]
df = df.transpose()
df.columns = future_column_name
df.drop("Symbol")
columns = []
initial_str = "Page 0: Overview"
i = 1
for col_name in df.columns.values:
initial_str += f"\nPage {i}: {col_name}"
i += 1
columns.append(
discord.Embed(
title="Stocks: [Yahoo Finance] Most Shorted",
description=initial_str,
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
for column in df.columns.values:
columns.append(
discord.Embed(
description="```" + df[column].fillna("").to_string() + "```",
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
await pagination(columns, ctx)
except Exception as e:
embed = discord.Embed(
title="ERROR Stocks: [Yahoo Finance] Most Shorted",
colour=cfg.COLOR,
description=e,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)

View File

@@ -1,164 +1,96 @@
import discord
import config_discordbot as cfg
from helpers import pagination
from gamestonk_terminal.stocks.dark_pool_shorts import stockgrid_model
async def sidtc_command(ctx, arg="float", arg2="10"):
"""Gets short interest and days to cover data from GST and sends it
Parameters
-----------
arg: str
sort (dark_pool_shorts), -h or help
arg2: str
number
Returns
-------
discord message
Sends a message containing an embed with short interest and days to cover
data to the user
"""
try:
# Debug
if cfg.DEBUG:
print(f"!stocks.dps.sidtc {arg} {arg2}")
# Help
if arg == "-h" or arg == "help":
dark_pool_sort = {
"float": "Float Short %",
"dtc": "Days to Cover",
"si": "Short Interest",
}
help_txt = "Get short interest and days to cover. [Source: Stockgrid]\n"
possible_args = ""
for k, v in dark_pool_sort.items():
possible_args += f"\n{k}: {v}"
help_txt += "\nPossible arguments:\n"
help_txt += "<SORT> Field for which to sort by. Default: float\n"
help_txt += f"The choices are:{possible_args}\n"
help_txt += "<NUM> Number of top tickers to show. Default: 10"
embed = discord.Embed(
title="Stocks: [Stockgrid] Short Interest and Days to Cover HELP",
description=help_txt,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)
else:
# Parse argument
if arg == "float" or arg == "dtc" or arg == "si":
sort = arg
else:
title = "ERROR Stocks: [Stockgrid] Short Interest and Days to Cover"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
f"Entered sort argument: {arg}"
"\nEnter a valid sort argument, example: float"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print("ERROR: Bad sort argument entered")
return
try:
num = int(arg2)
if num < 0:
raise ValueError("Number has to be above 0")
except ValueError:
title = "ERROR Stocks: [Stockgrid] Short Interest and Days to Cover"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"No number (int) entered in the second argument."
"\nEnter a valid (positive) number, example: 10"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print("ERROR: No (positive) int for second argument entered")
return
df = stockgrid_model.get_short_interest_days_to_cover(sort)
df = df.iloc[:num]
dp_date = df["Date"].values[0]
df = df.drop(columns=["Date"])
df["Short Interest"] = df["Short Interest"] / 1_000_000
df.head()
df.columns = [
"Ticker",
"Float Short %",
"Days to Cover",
"Short Interest (1M)",
]
future_column_name = df["Ticker"]
df = df.transpose()
df.columns = future_column_name
df.drop("Ticker")
columns = []
initial_str = "Page 0: Overview"
i = 1
for column in df.columns.values:
initial_str = initial_str + "\nPage " + str(i) + ": " + column
i += 1
columns.append(
discord.Embed(
title="Dark Pool Shorts", description=initial_str, colour=cfg.COLOR
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
for column in df.columns.values:
columns.append(
discord.Embed(
title="Stocks: [Stockgrid] Short Interest and Days to Cover",
description="```The following data corresponds to the date: "
+ dp_date
+ "\n\n"
+ df[column].fillna("").to_string()
+ "```",
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
await pagination(columns, ctx)
except Exception as e:
title = "INTERNAL ERROR"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"Try updating the bot, make sure DEBUG is True in the config "
"and restart it.\nIf the error still occurs open a issue at: "
"https://github.com/GamestonkTerminal/GamestonkTerminal/issues"
f"\n{e}"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(e)
import discord
import config_discordbot as cfg
from helpers import pagination
from gamestonk_terminal.stocks.dark_pool_shorts import stockgrid_model
async def sidtc_command(ctx, sort="float", num="10"):
"""Short interest and days to cover [Stockgrid]"""
try:
# Debug
if cfg.DEBUG:
print(f"\n!stocks.dps.sidtc {sort} {num}")
# Check for argument
possible_sorts = ("float", "dtc", "si")
if sort not in possible_sorts:
raise Exception(f"The possible sorts are: {', '.join(possible_sorts)}")
if not num.lstrip("-").isnumeric():
raise Exception("Number has to be an integer")
num = int(num)
if num < 0:
raise Exception("Number has to be above 0")
# Retrieve data
df = stockgrid_model.get_short_interest_days_to_cover(sort)
df = df.iloc[:num]
# Debug user output
if cfg.DEBUG:
print(df.to_string())
# Output data
dp_date = df["Date"].values[0]
df = df.drop(columns=["Date"])
df["Short Interest"] = df["Short Interest"] / 1_000_000
df.head()
df.columns = [
"Ticker",
"Float Short %",
"Days to Cover",
"Short Interest (1M)",
]
future_column_name = df["Ticker"]
df = df.transpose()
df.columns = future_column_name
df.drop("Ticker")
columns = []
initial_str = "Page 0: Overview"
i = 1
for column in df.columns.values:
initial_str = initial_str + "\nPage " + str(i) + ": " + column
i += 1
columns.append(
discord.Embed(
title="Dark Pool Shorts", description=initial_str, colour=cfg.COLOR
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
for column in df.columns.values:
columns.append(
discord.Embed(
title="Stocks: [Stockgrid] Short Interest and Days to Cover",
description="```The following data corresponds to the date: "
+ dp_date
+ "\n\n"
+ df[column].fillna("").to_string()
+ "```",
colour=cfg.COLOR,
).set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
)
await pagination(columns, ctx)
except Exception as e:
embed = discord.Embed(
title="ERROR Stocks: [Stockgrid] Short Interest and Days to Cover",
colour=cfg.COLOR,
description=e,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)

View File

@@ -1,143 +1,94 @@
import discord
import os
import config_discordbot as cfg
from discordbot import gst_imgur
from matplotlib import pyplot as plt
from gamestonk_terminal.config_plot import PLOT_DPI
from gamestonk_terminal.stocks.dark_pool_shorts import stockgrid_model
async def spos_command(ctx, arg=""):
"""Gets price vs short interest volume plot from GST and sends it
Parameters
-----------
arg: str
ticker, -h or help
Returns
-------
discord message
Sends a message containing an image of net short position of a given
ticker to the user
"""
try:
# Debug
if cfg.DEBUG:
print(f"!stocks.dps.spos {arg}")
# Help
if arg == "-h" or arg == "help":
help_txt = "Plot net short position. [Source: Stockgrid]\n"
help_txt += "\nPossible arguments:\n"
help_txt += "<TICKER> Stock ticker. REQUIRED!\n"
embed = discord.Embed(
title="Stocks: [Stockgrid] Net Short vs Position HELP",
description=help_txt,
colour=cfg.COLOR,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
else:
if arg == "":
title = "ERROR Stocks: [Stockgrid] Net Short vs Position"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"No ticker entered." "\nEnter a valid ticker, example: GME"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print("ERROR: No ticker entered")
return
# Parse argument
ticker = arg.upper()
plt.ion()
title = f"Stocks: [Stockgrid] Net Short vs Position {arg}"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
try:
df = stockgrid_model.get_net_short_position(ticker)
except Exception as e:
title = "ERROR Stocks: [Stockgrid] Price vs Short Interest Volume"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
f"Ticker given: {arg}" "\nEnter a valid ticker, example: GME"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(f"POSSIBLE ERROR: Wrong ticker parameter entered\n{e}")
return
fig = plt.figure(dpi=PLOT_DPI)
ax = fig.add_subplot(111)
ax.bar(
df["dates"],
df["dollar_net_volume"] / 1_000,
color="r",
alpha=0.4,
label="Net Short Vol. (1k $)",
)
ax.set_ylabel("Net Short Vol. (1k $)")
ax2 = ax.twinx()
ax2.plot(
df["dates"].values,
df["dollar_dp_position"],
c="tab:blue",
label="Position (1M $)",
)
ax2.set_ylabel("Position (1M $)")
lines, labels = ax.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax2.legend(lines + lines2, labels + labels2, loc="upper left")
ax.grid()
plt.title(f"Net Short Vol. vs Position for {ticker}")
plt.gcf().autofmt_xdate()
file_name = ticker + "_spos.png"
plt.savefig(file_name)
plt.close("all")
uploaded_image = gst_imgur.upload_image(file_name, title="something")
image_link = uploaded_image.link
embed.set_image(url=image_link)
os.remove(file_name)
await ctx.send(embed=embed)
except Exception as e:
title = "INTERNAL ERROR"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
embed.set_description(
"Try updating the bot, make sure DEBUG is True in the config "
"and restart it.\nIf the error still occurs open a issue at: "
"https://github.com/GamestonkTerminal/GamestonkTerminal/issues"
f"\n{e}"
)
await ctx.send(embed=embed)
if cfg.DEBUG:
print(e)
import os
import config_discordbot as cfg
import discord
from matplotlib import pyplot as plt
import yfinance as yf
from discordbot import gst_imgur
from gamestonk_terminal.config_plot import PLOT_DPI
from gamestonk_terminal.stocks.dark_pool_shorts import stockgrid_model
async def spos_command(ctx, ticker=""):
"""Net short vs position [Stockgrid]"""
try:
# Debug user input
if cfg.DEBUG:
print(f"\n!stocks.dps.spos {ticker}")
# Check for argument
if ticker == "":
raise Exception("Stock ticker is required")
ticker = ticker.upper()
stock = yf.download(ticker, progress=False)
if stock.empty:
raise Exception("Stock ticker is invalid")
# Retrieve data
df = stockgrid_model.get_net_short_position(ticker)
# Debug user output
if cfg.DEBUG:
print(df.to_string())
# Output data
title = f"Stocks: [Stockgrid] Net Short vs Position {ticker}"
embed = discord.Embed(title=title, colour=cfg.COLOR)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
fig = plt.figure(dpi=PLOT_DPI)
ax = fig.add_subplot(111)
ax.bar(
df["dates"],
df["dollar_net_volume"] / 1_000,
color="r",
alpha=0.4,
label="Net Short Vol. (1k $)",
)
ax.set_ylabel("Net Short Vol. (1k $)")
ax2 = ax.twinx()
ax2.plot(
df["dates"].values,
df["dollar_dp_position"],
c="tab:blue",
label="Position (1M $)",
)
ax2.set_ylabel("Position (1M $)")
lines, labels = ax.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax2.legend(lines + lines2, labels + labels2, loc="upper left")
ax.grid()
plt.title(f"Net Short Vol. vs Position for {ticker}")
plt.gcf().autofmt_xdate()
file_name = ticker + "_spos.png"
plt.savefig(file_name)
plt.close("all")
uploaded_image = gst_imgur.upload_image(file_name, title="something")
image_link = uploaded_image.link
embed.set_image(url=image_link)
os.remove(file_name)
await ctx.send(embed=embed)
except Exception as e:
embed = discord.Embed(
title=f"ERROR Stocks: [Stockgrid] Net Short vs Position {ticker}",
colour=cfg.COLOR,
description=e,
)
embed.set_author(
name=cfg.AUTHOR_NAME,
icon_url=cfg.AUTHOR_ICON_URL,
)
await ctx.send(embed=embed)