mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-27 04:31:13 +00:00
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:
11
discordbot/README.md
vendored
11
discordbot/README.md
vendored
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user