diff --git a/bots/__init__.py b/bots/__init__.py
old mode 100644
new mode 100755
index 7e0e5b9649c..b4e0c8847df
--- a/bots/__init__.py
+++ b/bots/__init__.py
@@ -1,2 +1,13 @@
# flake8: noqa
-from . import common, economy, etf, groupme, menus, slack, stocks, telegram
+from . import (
+ common,
+ config_discordbot,
+ economy,
+ etf,
+ groupme,
+ imps,
+ menus,
+ slack,
+ stocks,
+ telegram,
+)
diff --git a/bots/cmds/cmds.py b/bots/cmds/cmds.py
index 873474289ff..227c8ddeba8 100644
--- a/bots/cmds/cmds.py
+++ b/bots/cmds/cmds.py
@@ -2,7 +2,7 @@
import disnake
from disnake.ext import commands
-import bots.config_discordbot as cfg
+from bots import config_discordbot as cfg
from bots.menus.menu import Menu
diff --git a/bots/cmds/dd_cmds.py b/bots/cmds/dd_cmds.py
old mode 100644
new mode 100755
index fd8eaba3982..8ceb53dbd0a
--- a/bots/cmds/dd_cmds.py
+++ b/bots/cmds/dd_cmds.py
@@ -6,6 +6,7 @@ from disnake.ext import commands
from bots.helpers import ShowView, ticker_autocomp
from bots.stocks.due_diligence.analyst import analyst_command
from bots.stocks.due_diligence.arktrades import arktrades_command
+from bots.stocks.due_diligence.borrowed import borrowed_command
from bots.stocks.due_diligence.customer import customer_command
from bots.stocks.due_diligence.est import est_command
from bots.stocks.due_diligence.pt import pt_command
@@ -36,6 +37,19 @@ class DueDiligenceCommands(commands.Cog):
"""
await ShowView().discord(analyst_command, inter, "dd analyst", ticker)
+ @dd.sub_command()
+ async def borrowed(
+ inter: disnake.AppCmdInter,
+ ticker: str = commands.Param(autocomplete=ticker_autocomp),
+ ):
+ """Displays borrowed shares available and fee [Stocksera]
+
+ Parameters
+ -----------
+ ticker: Stock Ticker
+ """
+ await ShowView().discord(borrowed_command, inter, "dd borrowed", ticker)
+
@dd.sub_command()
async def pt(
inter: disnake.AppCmdInter,
diff --git a/bots/cmds/economy_cmds.py b/bots/cmds/economy_cmds.py
old mode 100644
new mode 100755
index 28feddc569b..1bfef52f4b8
--- a/bots/cmds/economy_cmds.py
+++ b/bots/cmds/economy_cmds.py
@@ -17,6 +17,7 @@ from bots.economy.meats import meats_command
from bots.economy.metals import metals_command
from bots.economy.overview import overview_command
from bots.economy.performance import performance_command
+from bots.economy.reverse_repo import reverse_repo_command
from bots.economy.softs import softs_command
from bots.economy.usbonds import usbonds_command
from bots.economy.valuation import valuation_command
@@ -132,6 +133,20 @@ class EconomyCommands(commands.Cog):
valuation_command, inter, "econ valuation", economy_group
)
+ @econ.sub_command()
+ async def repo(
+ self,
+ inter: disnake.AppCmdInter,
+ days: int = 100,
+ ):
+ """Displays Reverse Repo [Stocksera]
+
+ Parameters
+ -----------
+ days: Number of days to display. Default: 100
+ """
+ await ShowView().discord(reverse_repo_command, inter, "econ repo", days)
+
@econ.sub_command()
async def performance(
self,
diff --git a/bots/cmds/etf_cmds.py b/bots/cmds/etf_cmds.py
old mode 100644
new mode 100755
index c2cc61e83da..e7fa4abc9af
--- a/bots/cmds/etf_cmds.py
+++ b/bots/cmds/etf_cmds.py
@@ -6,7 +6,7 @@ from disnake.ext import commands
from bots.etf.holdings import holdings_command
from bots.etf.tops import etfs_disc_command
from bots.etf.whatetf import by_ticker_command
-from bots.helpers import ShowView
+from bots.helpers import ShowView, ticker_autocomp
class EtfCommands(commands.Cog):
@@ -66,18 +66,30 @@ class EtfCommands(commands.Cog):
@holdings.sub_command(name="by-ticker")
async def by_ticker(
inter: disnake.AppCmdInter,
- ticker: str,
+ ticker: str = commands.Param(autocomplete=ticker_autocomp),
num: int = 15,
+ sort: str = commands.Param(
+ choices={
+ "Percentage of Fund": "fund_percent",
+ "Market Value": "mkt_value",
+ },
+ ),
):
"""Displays ETF Holdings By Ticker [ETF DataBase]
Parameters
-----------
ticker: Ticker to Search
+ sort: Sort by Percentage of Fund or Market Value
num: Amount of ETFs to display Default 15
"""
await ShowView().discord(
- by_ticker_command, inter, "etf holdings by-ticker", ticker, num
+ by_ticker_command,
+ inter,
+ "etf holdings by-ticker",
+ ticker,
+ sort,
+ num,
)
diff --git a/bots/cmds/ta_cmds.py b/bots/cmds/ta_cmds.py
old mode 100644
new mode 100755
index 825701bc16a..c335dcd68b3
--- a/bots/cmds/ta_cmds.py
+++ b/bots/cmds/ta_cmds.py
@@ -60,10 +60,10 @@ class TechnicalAnalysisCommands(commands.Cog):
interval: int = commands.Param(choices=[1, 5, 15, 30, 60, 1440]),
past_days: int = 0,
ma_mode: str = commands.Param(choices=["ema", "sma", "wma", "hma", "zlma"]),
- window="",
+ window: str = "",
offset: int = 0,
- start="",
- end="",
+ start: str = "",
+ end: str = "",
extended_hours: bool = False,
heikin_candles: bool = False,
):
@@ -107,8 +107,8 @@ class TechnicalAnalysisCommands(commands.Cog):
past_days: int = 0,
length="14",
scalar="0.015",
- start="",
- end="",
+ start: str = "",
+ end: str = "",
extended_hours: bool = False,
heikin_candles: bool = False,
):
@@ -151,8 +151,8 @@ class TechnicalAnalysisCommands(commands.Cog):
fast="12",
slow="26",
signal="9",
- start="",
- end="",
+ start: str = "",
+ end: str = "",
extended_hours: bool = False,
heikin_candles: bool = False,
):
@@ -197,8 +197,8 @@ class TechnicalAnalysisCommands(commands.Cog):
length="14",
scalar="100",
drift="1",
- start="",
- end="",
+ start: str = "",
+ end: str = "",
extended_hours: bool = False,
heikin_candles: bool = False,
):
@@ -243,8 +243,8 @@ class TechnicalAnalysisCommands(commands.Cog):
fast_k="14",
slow_d="3",
slow_k="3",
- start="",
- end="",
+ start: str = "",
+ end: str = "",
extended_hours: bool = False,
heikin_candles: bool = False,
):
@@ -287,8 +287,8 @@ class TechnicalAnalysisCommands(commands.Cog):
interval: int = commands.Param(choices=[1, 5, 15, 30, 60, 1440]),
past_days: int = 0,
length="14",
- start="",
- end="",
+ start: str = "",
+ end: str = "",
extended_hours: bool = False,
heikin_candles: bool = False,
):
@@ -352,8 +352,8 @@ class TechnicalAnalysisCommands(commands.Cog):
length="14",
scalar="100",
drift="1",
- start="",
- end="",
+ start: str = "",
+ end: str = "",
extended_hours: bool = False,
heikin_candles: bool = False,
):
@@ -397,8 +397,8 @@ class TechnicalAnalysisCommands(commands.Cog):
past_days: int = 0,
length="25",
scalar="100",
- start="",
- end="",
+ start: str = "",
+ end: str = "",
extended_hours: bool = False,
heikin_candles: bool = False,
):
@@ -441,8 +441,8 @@ class TechnicalAnalysisCommands(commands.Cog):
length="20",
std: float = 2.0,
ma_mode: str = commands.Param(choices=["ema", "sma", "wma", "hma", "zlma"]),
- start="",
- end="",
+ start: str = "",
+ end: str = "",
extended_hours: bool = False,
heikin_candles: bool = False,
):
@@ -484,8 +484,8 @@ class TechnicalAnalysisCommands(commands.Cog):
ticker: str = commands.Param(autocomplete=ticker_autocomp),
upper_length="25",
lower_length="100",
- start="",
- end="",
+ start: str = "",
+ end: str = "",
):
"""Displays chart with donchian channel [Yahoo Finance]
@@ -520,8 +520,8 @@ class TechnicalAnalysisCommands(commands.Cog):
scalar="2",
ma_mode: str = commands.Param(choices=["ema", "sma", "wma", "hma", "zlma"]),
offset="0",
- start="",
- end="",
+ start: str = "",
+ end: str = "",
extended_hours: bool = False,
heikin_candles: bool = False,
):
@@ -567,8 +567,8 @@ class TechnicalAnalysisCommands(commands.Cog):
interval: int = commands.Param(choices=[1, 5, 15, 30, 60, 1440]),
past_days: int = 0,
is_open="False",
- start="",
- end="",
+ start: str = "",
+ end: str = "",
extended_hours: bool = False,
heikin_candles: bool = False,
):
@@ -609,8 +609,8 @@ class TechnicalAnalysisCommands(commands.Cog):
is_open: bool = False,
fast="3",
slow="10",
- start="",
- end="",
+ start: str = "",
+ end: str = "",
extended_hours: bool = False,
heikin_candles: bool = False,
):
@@ -652,8 +652,8 @@ class TechnicalAnalysisCommands(commands.Cog):
ticker: str = commands.Param(autocomplete=ticker_autocomp),
interval: int = commands.Param(choices=[1, 5, 15, 30, 60, 1440]),
past_days: int = 0,
- start="",
- end="",
+ start: str = "",
+ end: str = "",
extended_hours: bool = False,
heikin_candles: bool = False,
):
@@ -687,18 +687,37 @@ class TechnicalAnalysisCommands(commands.Cog):
self,
inter: disnake.AppCmdInter,
ticker: str = commands.Param(autocomplete=ticker_autocomp),
- start="",
- end="",
+ interval: int = commands.Param(choices=[1, 5, 15, 30, 60, 1440]),
+ past_days: int = 0,
+ start: str = "",
+ end: str = "",
+ extended_hours: bool = False,
+ heikin_candles: bool = False,
):
"""Displays chart with fibonacci retracement [Yahoo Finance]
Parameters
-----------
ticker: Stock Ticker
+ interval : Chart Minute Interval, 1440 for Daily
+ past_days: Past Days to Display. Default: 0(Not for Daily)
start: YYYY-MM-DD format
end: YYYY-MM-DD format
+ extended_hours: Display Pre/After Market Hours. Default: False
+ heikin_candles: Heikin Ashi candles. Default: False
"""
- await ShowView().discord(fib_command, inter, "ta fib", ticker, start, end)
+ await ShowView().discord(
+ fib_command,
+ inter,
+ "ta fib",
+ ticker,
+ interval,
+ past_days,
+ start,
+ end,
+ extended_hours,
+ heikin_candles,
+ )
@ta.sub_command()
async def view(
diff --git a/bots/common/helpers.py b/bots/common/helpers.py
index 62d68d614ed..2de4f3d7adf 100644
--- a/bots/common/helpers.py
+++ b/bots/common/helpers.py
@@ -89,7 +89,7 @@ def non_slash(text: str, sender: Any, showview: Any):
full_cmd = cmd.split("/")
group = full_cmd[0].split("_")[0]
parents = {x.split("_")[0] for x in available_commands}
- if text[0] == "!" or text[0] == "/":
+ if text and text[0] in ["!", "/"]:
if group in parents:
if full_cmd[0] in available_commands:
selected = commands[full_cmd[0]]
diff --git a/bots/common/plot_tbls.py b/bots/common/plot_tbls.py
new file mode 100644
index 00000000000..840b6f15e9c
--- /dev/null
+++ b/bots/common/plot_tbls.py
@@ -0,0 +1,166 @@
+from math import floor
+from typing import List, Optional, Tuple, Union
+
+import pandas as pd
+import plotly
+
+
+# pylint: disable=R0913
+def plot_df(
+ df: Union[pd.Series, pd.DataFrame],
+ print_index: bool = True,
+ title: Optional[dict] = None,
+ tbl_header_visible: bool = True,
+ tbl_header: Optional[dict] = None,
+ tbl_cells: Optional[dict] = None,
+ row_fill_color: Optional[Tuple[str, str]] = None,
+ col_width: Optional[Union[int, float, List[Union[int, float]]]] = None,
+ fig_size: Optional[Tuple[int, int]] = None,
+ **layout_kwargs,
+) -> plotly.graph_objects.Figure:
+ """Plots a pd.Series or pd.DataFrame.
+
+ Parameters
+ ----------
+ df : Union[pd.Series, pd.DataFrame]
+ Series or dataframe to be plotted.
+ print_index : bool, default True
+ If `True`, prints the dataframe's index. `df.index.name` will become the index
+ column header.
+ title : dict, default None
+ A dict possibly containing `plotly` key/value pairs:
+ https://plotly.com/python/reference/layout/#layout-title
+
+ More relevant key/value pairs:
+
+ - font_color : color
+ - font_family : str
+ - font_size : number greater than or equal to 1
+ - text : str
+ - x : number between or equal to 0 and 1, default 0.5
+
+ Sets the x position with respect to `xref` in normalized coordinates
+ from "0" (left) to "1" (right).
+ - xanchor : enumerated, one of ("auto", "left", "center", "right"),
+ default "auto"
+
+ Sets the title's horizontal alignment with respect to its x position.
+ "left" means that the title starts at x, "right" means that the title ends
+ at x and "center" means that the title's center is at x. "auto" divides
+ `xref` by three and calculates the `xanchor` value automatically based on
+ the value of `x`.
+ tbl_header_visible : bool, default True,
+ If `False`, table header will be invisible. Takes precedence over `tbl_header`
+ argument.
+ tbl_header, tbl_cells : dict, default None
+ A dict possibly containing `plotly` key/value pairs:
+ https://plotly.com/python/reference/table/#table-header
+ https://plotly.com/python/reference/table/#table-cells
+
+ More relevant key/value pairs:
+
+ - align : enumerated or array of enumerateds,
+ one of ("left", "center", "right"), default "center"
+ - fill_color : color, default "white"
+ - font_color : color or array of colors
+ - font_family : str or array of str
+ - font_size : number or array of numbers greater than or equal to 1
+ - height : number, default 28
+ - line_width : number or array of numbers, default 1
+ row_fill_color : Tuple[str, str], default None
+ Tuple of colors that will be used to alternate row colors. Takes precedence
+ over `tbl_cells["fill_color"]`.
+ col_width : number or array of numbers, default None
+ The width of columns expressed as a ratio. Columns fill the available width
+ in proportion of their specified column widths.
+ fig_size : Tuple[int, int], default None
+ Tuple specifying the `width` and `height` of the figure.
+ **layout_kwargs
+ Plotly accepts a large number of layout-related keyword arguments.
+ A detailed descriptions is available at
+ https://plotly.com/python-api-reference/generated/plotly.graph_objects.Layout.html.
+
+ Returns
+ -------
+ plotly.graph_objects.Figure
+ Returns a figure object.
+
+ """
+
+ def _alternate_row_colors() -> Optional[List[str]]:
+ color_list = None
+ # alternate row colors
+ row_count = len(df)
+ if row_fill_color is not None:
+ # determine how many rows in `df` and then create a list with alternating
+ # row colors
+ row_odd_count = floor(row_count / 2) + row_count % 2
+ row_even_count = floor(row_count / 2)
+ odd_list = [row_fill_color[0]] * row_odd_count
+ even_list = [row_fill_color[1]] * row_even_count
+ color_list = [x for y in zip(odd_list, even_list) for x in y]
+ if row_odd_count > row_even_count:
+ color_list.append(row_fill_color[0])
+
+ return color_list
+
+ def _tbl_values():
+ if print_index:
+ header_values = [
+ "" + x + ""
+ for x in [
+ df.index.name if df.index.name is not None else "",
+ *df.columns,
+ ]
+ ]
+ cell_values = [df.index, *[df[col] for col in df]]
+ else:
+ header_values = ["" + x + "" for x in df.columns.to_list()]
+ cell_values = [df[col] for col in df]
+
+ return header_values, cell_values
+
+ row_color_list = _alternate_row_colors()
+ header_vals, cell_vals = _tbl_values()
+
+ if not tbl_header:
+ tbl_header = dict()
+ tbl_header.update(values=header_vals)
+
+ if not tbl_header_visible:
+ tbl_header.update(
+ fill_color="white", font_color="white", line_color="white", height=1
+ )
+
+ if not tbl_cells:
+ tbl_cells = dict()
+ tbl_cells.update(
+ values=cell_vals,
+ fill_color=[row_color_list] * len(df)
+ if row_color_list
+ else tbl_cells.get("fill_color"),
+ )
+
+ fig = plotly.graph_objs.Figure(
+ data=[plotly.graph_objs.Table(header=tbl_header, cells=tbl_cells)]
+ )
+
+ fig.data[0]["columnwidth"] = col_width if col_width else None
+
+ if not title:
+ title = dict()
+ title.update(
+ x=0.01 if title.get("x") is None else title.get("x"),
+ xanchor="left" if title.get("xanchor") is None else title.get("xanchor"),
+ )
+
+ fig.update_layout(
+ title=title,
+ margin=dict(autoexpand=False, b=5, l=5, r=5, t=40 if title.get("text") else 5),
+ width=fig_size[0] if fig_size else None,
+ height=fig_size[1] if fig_size else None,
+ autosize=False if col_width else None,
+ **layout_kwargs,
+ )
+
+ return fig
diff --git a/bots/config_discordbot.py b/bots/config_discordbot.py
old mode 100644
new mode 100755
index 22982c45296..73ecae748e4
--- a/bots/config_discordbot.py
+++ b/bots/config_discordbot.py
@@ -7,16 +7,17 @@ import disnake
import pyimgur
from dotenv import load_dotenv
-env_files = [f for f in os.listdir() if f.endswith(".env")]
+# Path to bots
+bots_path = Path(__file__).parent.absolute()
+
+env_files = [f for f in bots_path.iterdir() if f.as_posix().endswith(".env")]
+
if env_files:
load_dotenv(env_files[0])
# Relative path to the terminal
sys.path.append("..")
-# Path to bots
-bots_path = Path(__file__).parent.absolute()
-
# https://discord.com/developers/applications/
DISCORD_BOT_TOKEN = os.getenv("GT_DISCORD_BOT_TOKEN") or "REPLACE_ME"
@@ -41,86 +42,14 @@ COMMAND_PREFIX = "!"
DATE_FORMAT = "%Y-%m-%d"
COLOR = disnake.Color.from_rgb(255, 0, 0)
INTERACTIVE = False
-INTERACTIVE_DIR = bots_path / "in/"
+INTERACTIVE_DIR = bots_path / "interactive/"
INTERACTIVE_URL = ""
-IMG_DIR = bots_path / "in/images/"
+IMG_DIR = bots_path / "interactive/images/"
IMAGES_URL = "" # Ex. "http://your-site.com/images/"
# IMG_BG = bots_path.joinpath("files/bg.png") # Light BG
-IMG_BG = bots_path / "files/bg-dark.png" # Dark BG
-PLT_3DMESH_COLORSCALE = "Jet"
-PLT_3DMESH_SCENE = dict(
- xaxis=dict(
- backgroundcolor="rgb(94, 94, 94)",
- gridcolor="white",
- showbackground=True,
- zerolinecolor="white",
- ),
- yaxis=dict(
- backgroundcolor="rgb(94, 94, 94)",
- gridcolor="white",
- showbackground=True,
- zerolinecolor="white",
- ),
- zaxis=dict(
- backgroundcolor="rgb(94, 94, 94)",
- gridcolor="white",
- showbackground=True,
- zerolinecolor="white",
- ),
- aspectratio=dict(x=1.2, y=1.2, z=0.8),
-)
-PLT_3DMESH_HOVERLABEL = dict(bgcolor="gold")
-PLT_3DMESH_STYLE_TEMPLATE = "plotly_dark"
-PLT_CANDLE_STYLE_TEMPLATE = "plotly_dark"
-PLT_SCAT_STYLE_TEMPLATE = "plotly_dark"
-PLT_TA_STYLE_TEMPLATE = "plotly_dark"
-PLT_TA_COLORWAY = [
- "#fdc708",
- "#d81aea",
- "#00e6c3",
- "#9467bd",
- "#e250c3",
- "#d1fa3d",
-]
-PLT_TBL_HEADER = dict(
- height=30,
- fill_color="rgb(30, 30, 30)",
- font_color="white",
- font_size=14,
- line_color="rgb(63, 63, 63)",
- line_width=2,
-)
-PLT_TBL_CELLS = dict(
- height=25,
- font_size=12,
- fill_color="rgb(50, 50, 50)",
- font_color="white",
- line_color="rgb(63, 63, 63)",
- line_width=2,
-)
-PLT_TBL_FONT = dict(family="Fira Code")
-PLT_TBL_ROW_COLORS = ["rgb(55, 55, 55)", "rgb(50, 50, 50)"]
-PLT_FONT = dict(
- family="Fira Code",
- size=12,
-)
-PLT_WATERMARK = dict(
- source=(
- "https://raw.githubusercontent.com/GamestonkTerminal/GamestonkTerminal/main/images"
- "/gst_logo_lockup_rGreen_with_letters_only.png"
- ),
- xref="paper",
- yref="paper",
- x=0.88,
- y=0.28,
- sizex=0.8,
- sizey=0.9,
- opacity=0.04,
- xanchor="right",
- yanchor="bottom",
- layer="below",
-)
+IMG_BG = bots_path.joinpath("files/bg-dark.png") # Dark BG
+
MENU_TIMEOUT = 30
DEBUG = False
diff --git a/bots/config_plots.py b/bots/config_plots.py
new file mode 100644
index 00000000000..e56a0dbe0fa
--- /dev/null
+++ b/bots/config_plots.py
@@ -0,0 +1,97 @@
+from typing import Any, List, Optional, Tuple
+
+# Vsurf Plot Settings
+PLT_3DMESH_COLORSCALE = "Jet"
+PLT_3DMESH_SCENE = dict(
+ xaxis=dict(
+ backgroundcolor="rgb(94, 94, 94)",
+ gridcolor="white",
+ showbackground=True,
+ zerolinecolor="white",
+ ),
+ yaxis=dict(
+ backgroundcolor="rgb(94, 94, 94)",
+ gridcolor="white",
+ showbackground=True,
+ zerolinecolor="white",
+ ),
+ zaxis=dict(
+ backgroundcolor="rgb(94, 94, 94)",
+ gridcolor="white",
+ showbackground=True,
+ zerolinecolor="white",
+ ),
+ aspectratio=dict(x=1.2, y=1.2, z=0.8),
+)
+PLT_3DMESH_HOVERLABEL = dict(bgcolor="gold")
+PLT_3DMESH_STYLE_TEMPLATE = "plotly_dark"
+
+# Chart Plots Settings
+PLT_CANDLE_STYLE_TEMPLATE = "plotly_dark"
+PLT_SCAT_STYLE_TEMPLATE = "plotly_dark"
+PLT_TA_STYLE_TEMPLATE = "plotly_dark"
+PLT_FONT = dict(
+ family="Fira Code",
+ size=12,
+)
+PLT_TA_COLORWAY = [
+ "#fdc708",
+ "#d81aea",
+ "#00e6c3",
+ "#9467bd",
+ "#e250c3",
+ "#d1fa3d",
+]
+PLT_FIB_COLORWAY: List[Any] = [
+ "rgba(195, 50, 69, 1)", # 0
+ "rgba(130, 38, 96, 1)", # 0.235
+ "rgba(72, 39, 124, 1)", # 0.382
+ "rgba(0, 93, 168, 1)", # 0.5
+ "rgba(173, 0, 95, 1)", # 0.618
+ "rgba(253, 199, 8, 1)", # 0.65 Golden Pocket
+ "rgba(147, 103, 188, 1)", # 1
+ dict(
+ family="Fire Code",
+ size=16,
+ ), # Fib's Text
+ dict(color="rgba(0, 230, 195, 1)", width=2, dash="dash"), # Fib Trendline
+]
+PLT_WATERMARK = dict(
+ source=(
+ "https://raw.githubusercontent.com/GamestonkTerminal/GamestonkTerminal/main/images"
+ "/gst_logo_lockup_rGreen_with_letters_only.png"
+ ),
+ xref="paper",
+ yref="paper",
+ x=0.88,
+ y=0.28,
+ sizex=0.8,
+ sizey=0.9,
+ opacity=0.04,
+ xanchor="right",
+ yanchor="bottom",
+ layer="below",
+)
+
+# Table Plots Settings
+PLT_TBL_HEADER = dict(
+ height=30,
+ fill_color="rgb(30, 30, 30)",
+ font_color="white",
+ font_size=14,
+ line_color="rgb(63, 63, 63)",
+ line_width=2,
+)
+PLT_TBL_CELLS = dict(
+ height=25,
+ font_size=12,
+ fill_color="rgb(50, 50, 50)",
+ font_color="white",
+ line_color="rgb(63, 63, 63)",
+ line_width=2,
+)
+PLT_TBL_FONT = dict(family="Fira Code")
+PLT_TBL_ROW_COLORS: Optional[Tuple[str, str]] = (
+ "rgb(55, 55, 55)",
+ "rgb(50, 50, 50)",
+)
diff --git a/bots/economy/cpi.py b/bots/economy/cpi.py
old mode 100644
new mode 100755
index e809225e91e..612d6054546
--- a/bots/economy/cpi.py
+++ b/bots/economy/cpi.py
@@ -4,10 +4,9 @@ from datetime import datetime, timedelta
import pandas as pd
import plotly.graph_objects as go
-import bots.config_discordbot as cfg
-from bots import helpers
+from bots import imps
from gamestonk_terminal.decorators import log_start_end
-from gamestonk_terminal.economy.fred import fred_model
+from gamestonk_terminal.economy import fred_model
logger = logging.getLogger(__name__)
@@ -17,7 +16,7 @@ def cpi_command(start=""):
"""Displays Consumer Prices Index (CPI)"""
# Debug
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug(
"econ cpi %s",
start,
@@ -26,7 +25,7 @@ def cpi_command(start=""):
if start == "":
start = datetime.now() - timedelta(days=900)
else:
- start = datetime.strptime(start, cfg.DATE_FORMAT)
+ start = datetime.strptime(start, imps.DATE_FORMAT)
# Retrieve data
df_d = ("date", "CPI")
@@ -56,7 +55,7 @@ def cpi_command(start=""):
end = datetime.now() + timedelta(days=30)
# Debug user output
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug(df.to_string())
fig = go.Figure()
@@ -67,21 +66,21 @@ def cpi_command(start=""):
y=df["CPI"],
)
)
- if cfg.PLT_WATERMARK:
- fig.add_layout_image(cfg.PLT_WATERMARK)
- fig.update_layout(
- xaxis_range=[df.index[0], end],
- )
+
+ if imps.PLT_WATERMARK:
+ fig.add_layout_image(imps.PLT_WATERMARK)
+
fig.update_xaxes(dtick="M2", tickformat="%b\n%Y")
fig.update_layout(
+ xaxis_range=[df.index[0], end],
margin=dict(l=0, r=0, t=40, b=50),
- template=cfg.PLT_SCAT_STYLE_TEMPLATE,
- colorway=cfg.PLT_TA_COLORWAY,
+ template=imps.PLT_SCAT_STYLE_TEMPLATE,
+ colorway=imps.PLT_TA_COLORWAY,
title="CPI Monthly",
title_x=0.5,
yaxis_title="Consumer Prices",
legend_title="",
- font=cfg.PLT_FONT,
+ font=imps.PLT_FONT,
yaxis=dict(
fixedrange=False,
nticks=20,
@@ -98,15 +97,15 @@ def cpi_command(start=""):
# Check if interactive settings are enabled
plt_link = ""
- if cfg.INTERACTIVE:
- plt_link = helpers.inter_chart(fig, imagefile, callback=False)
+ if imps.INTERACTIVE:
+ plt_link = imps.inter_chart(fig, imagefile, callback=False)
fig.update_layout(
width=800,
height=500,
)
- imagefile = helpers.image_border(imagefile, fig=fig)
+ imagefile = imps.image_border(imagefile, fig=fig)
return {
"title": "Consumer Prices Index",
diff --git a/bots/economy/currencies.py b/bots/economy/currencies.py
old mode 100644
new mode 100755
index c276cafa258..61d6d106ec4
--- a/bots/economy/currencies.py
+++ b/bots/economy/currencies.py
@@ -1,27 +1,26 @@
import logging
-import df2img
import pandas as pd
-import bots.config_discordbot as cfg
-from bots.helpers import save_image
+from bots import imps
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.economy import wsj_model
logger = logging.getLogger(__name__)
+# pylint: disable=E1137
@log_start_end(log=logger)
def currencies_command():
"""Currencies overview [Wall St. Journal]"""
# Debug user input
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("econ-currencies")
# Retrieve data
df = wsj_model.global_currencies()
- df = pd.DataFrame.from_dict(df)
+ df = df.fillna("")
# Check for argument
if df.empty:
@@ -29,42 +28,36 @@ def currencies_command():
df["Last Price"] = pd.to_numeric(df["Last"].astype(float))
df["Change"] = pd.to_numeric(df["Chng"].astype(float))
- df["% Change"] = pd.to_numeric(df["%Chng"].astype(float))
- df = df.drop(columns=["Last", "Chng", "%Chng"])
+ df["%Chng"] = pd.to_numeric(df["%Chng"].astype(float))
# Debug user output
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug(df.to_string())
- formats = {"Last Price": "${:.2f}", "Change": "${:.2f}", "% Change": "{:.2f}%"}
+ formats = {
+ "Last Price": "${:.2f}",
+ "Change": "${:.2f}",
+ "%Chng": "{:.2f}%",
+ }
for col, value in formats.items():
df[col] = df[col].map(lambda x: value.format(x)) # pylint: disable=W0640
- df = df.fillna("")
+ df["Change"] = df.apply(lambda x: f"{x['Change']} ({x['%Chng']})", axis=1)
+
df.set_index(" ", inplace=True)
- font_color = (
- ["white"] * 2
- + [
- [
- "#e4003a" if boolv else "#00ACFF"
- for boolv in df["Change"].str.contains("-")
- ]
- ]
- + [
- [
- "#e4003a" if boolv else "#00ACFF"
- for boolv in df["% Change"].str.contains("-")
- ]
- ]
- )
- fig = df2img.plot_dataframe(
+
+ font_color = ["white"] * 2 + [
+ ["#e4003a" if boolv else "#00ACFF" for boolv in df["%Chng"].str.contains("-")]
+ ]
+ df = df.drop(columns=["Last", "Chng", "%Chng"])
+ fig = imps.plot_df(
df,
- fig_size=(720, (40 + (40 * len(df.index)))),
- col_width=[8, 3, 3],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ fig_size=(620, (40 + (40 * len(df.index)))),
+ col_width=[4.2, 2.4, 3],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
fig.update_traces(
@@ -75,7 +68,7 @@ def currencies_command():
)
)
)
- imagefile = save_image("econ-currencies.png", fig)
+ imagefile = imps.save_image("econ-currencies.png", fig)
return {
"title": "Economy: [WSJ] Currencies",
"imagefile": imagefile,
diff --git a/bots/economy/energy.py b/bots/economy/energy.py
old mode 100644
new mode 100755
index 35db4367be7..5c9d03f2a80
--- a/bots/economy/energy.py
+++ b/bots/economy/energy.py
@@ -1,10 +1,8 @@
import logging
-import df2img
import pandas as pd
-import bots.config_discordbot as cfg
-from bots.helpers import save_image
+from bots import imps
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.economy import finviz_model
@@ -16,7 +14,7 @@ def energy_command():
"""Displays energy futures data [Finviz]"""
# Debug user input
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("econ-energy")
# Retrieve data
@@ -27,14 +25,14 @@ def energy_command():
if df.empty:
raise Exception("No available data found")
- formats = {"last": "${:.2f}", "prevClose": "${:.2f}"}
+ formats = {"last": "${:.2f}", "prevClose": "${:.2f}", "change": "{:.2f}%"}
for col, value in formats.items():
df[col] = df[col].map(lambda x: value.format(x)) # pylint: disable=W0640
df = df.sort_values(by="ticker", ascending=False)
# Debug user output
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug(df.to_string())
df = df.fillna("")
@@ -47,23 +45,36 @@ def energy_command():
"change",
]
]
+
df.index.names = [""]
df = df.rename(
columns={"prevClose": "PrevClose", "last": "Last", "change": "Change"}
)
- fig = df2img.plot_dataframe(
+
+ font_color = ["white"] * 3 + [
+ ["#e4003a" if boolv else "#00ACFF" for boolv in df["Yld Chg"].str.contains("-")]
+ ]
+
+ fig = imps.plot_df(
df,
- fig_size=(800, (40 + (40 * len(df.index)))),
- col_width=[8, 3, 2],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ fig_size=(550, (40 + (40 * len(df.index)))),
+ col_width=[4, 2.1, 1.5],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
- fig.update_traces(cells=(dict(align="left")))
+ fig.update_traces(
+ cells=(
+ dict(
+ align=["center", "right"],
+ font=dict(color=font_color),
+ )
+ )
+ )
+ imagefile = imps.save_image("econ-energy.png", fig)
- imagefile = save_image("econ-energy.png", fig)
return {
"title": "[Finviz] Energy Futures",
"imagefile": imagefile,
diff --git a/bots/economy/feargreed.py b/bots/economy/feargreed.py
index 2313b6cbc5e..ce026a4f076 100644
--- a/bots/economy/feargreed.py
+++ b/bots/economy/feargreed.py
@@ -4,7 +4,7 @@ import os
import matplotlib.pyplot as plt
-import bots.config_discordbot as cfg
+from bots import config_discordbot as cfg
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.economy import cnn_model, cnn_view
diff --git a/bots/economy/futures.py b/bots/economy/futures.py
old mode 100644
new mode 100755
index 651f0f101eb..a4385d2eff3
--- a/bots/economy/futures.py
+++ b/bots/economy/futures.py
@@ -1,16 +1,13 @@
import logging
import os
-import df2img
import disnake
import pandas as pd
-import yahoo_fin.stock_info as si
+import requests
-import bots.config_discordbot as cfg
-from bots import helpers
-from bots.config_discordbot import gst_imgur
-from bots.menus.menu import Menu
+from bots import imps
from gamestonk_terminal.decorators import log_start_end
+from gamestonk_terminal.helper_funcs import get_user_agent
logger = logging.getLogger(__name__)
@@ -20,11 +17,17 @@ def futures_command():
"""Futures [Yahoo Finance]"""
# Debug user input
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("futures")
# Retrieve data
- df = si.get_futures()
+ req = pd.read_html(
+ requests.get(
+ "https://finance.yahoo.com/commodities",
+ headers={"User-Agent": get_user_agent()},
+ ).text
+ )
+ df = req[0]
# Check for argument
if df.empty:
@@ -34,34 +37,29 @@ def futures_command():
df["Last Price"] = pd.to_numeric(df["Last Price"].astype(float))
df["Change"] = pd.to_numeric(df["Change"].astype(float))
- formats = {"Last Price": "${:.2f}", "Change": "${:.2f}"}
+ formats = {
+ "Last Price": "${:.2f}",
+ "Change": "${:.2f}",
+ }
for col, value in formats.items():
df[col] = df[col].map(lambda x: value.format(x)) # pylint: disable=W0640
- df = df.applymap(str)
df = df.fillna("")
+ df["Change"] = df.apply(
+ lambda x: f"{x['Change']} ({x['% Change']})", axis=1
+ )
+
df.drop(columns="Symbol")
df = df.rename(columns={"Name": " "})
df.set_index(" ", inplace=True)
- df = df[["Last Price", "Change", "% Change"]]
+ df = df[["Last Price", "Change"]]
+
+ font_color = ["white"] * 2 + [
+ ["#e4003a" if boolv else "#00ACFF" for boolv in df["Change"].str.contains("-")]
+ ]
- font_color = (
- ["white"] * 2
- + [
- [
- "#e4003a" if boolv else "#00ACFF"
- for boolv in df["Change"].str.contains("-")
- ]
- ]
- + [
- [
- "#e4003a" if boolv else "#00ACFF"
- for boolv in df["% Change"].str.contains("-")
- ]
- ]
- )
dindex = len(df.index)
if dindex > 15:
embeds: list = []
@@ -69,31 +67,22 @@ def futures_command():
i, i2, end = 0, 0, 15
df_pg, embeds_img, images_list = pd.DataFrame(), [], []
while i < dindex:
- df_pg = df.iloc[i:end]
+ df_pg = df[["Last Price", "Change"]].iloc[i:end]
df_pg.append(df_pg)
- font_color = (
- ["white"] * 2
- + [
- [
- "#e4003a" if boolv else "#00ACFF"
- for boolv in df_pg["Change"].str.contains("-")
- ]
+ font_color = ["white"] * 2 + [
+ [
+ "#e4003a" if boolv else "#00ACFF"
+ for boolv in df_pg["Change"].str.contains("-")
]
- + [
- [
- "#e4003a" if boolv else "#00ACFF"
- for boolv in df_pg["% Change"].str.contains("-")
- ]
- ]
- )
- fig = df2img.plot_dataframe(
+ ]
+ fig = imps.plot_df(
df_pg,
- fig_size=(720, (40 + (45 * len(df.index)))),
- col_width=[4, 2, 2, 2],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ fig_size=(620, (40 + (45 * len(df.index)))),
+ col_width=[4.2, 1.8, 2.5],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
fig.update_traces(
@@ -105,14 +94,14 @@ def futures_command():
)
)
imagefile = "econ-futures.png"
- imagefile = helpers.save_image(imagefile, fig)
+ imagefile = imps.save_image(imagefile, fig)
- if cfg.IMAGES_URL or cfg.IMGUR_CLIENT_ID != "REPLACE_ME":
- image_link = cfg.IMAGES_URL + imagefile
+ if imps.IMAGES_URL or imps.IMGUR_CLIENT_ID != "REPLACE_ME":
+ image_link = imps.IMAGES_URL + imagefile
images_list.append(imagefile)
else:
- imagefile_save = cfg.IMG_DIR / imagefile
- uploaded_image = gst_imgur.upload_image(
+ imagefile_save = imps.IMG_DIR / imagefile
+ uploaded_image = imps.gst_imgur.upload_image(
imagefile_save, title="something"
)
image_link = uploaded_image.link
@@ -124,7 +113,7 @@ def futures_command():
embeds.append(
disnake.Embed(
title=title,
- colour=cfg.COLOR,
+ colour=imps.COLOR,
),
)
i2 += 1
@@ -134,13 +123,13 @@ def futures_command():
# Author/Footer
for i in range(0, i2):
embeds[i].set_author(
- name=cfg.AUTHOR_NAME,
- url=cfg.AUTHOR_URL,
- icon_url=cfg.AUTHOR_ICON_URL,
+ name=imps.AUTHOR_NAME,
+ url=imps.AUTHOR_URL,
+ icon_url=imps.AUTHOR_ICON_URL,
)
embeds[i].set_footer(
- text=cfg.AUTHOR_NAME,
- icon_url=cfg.AUTHOR_ICON_URL,
+ text=imps.AUTHOR_NAME,
+ icon_url=imps.AUTHOR_ICON_URL,
)
i = 0
@@ -154,7 +143,7 @@ def futures_command():
]
output = {
- "view": Menu,
+ "view": imps.Menu,
"title": title,
"embed": embeds,
"choices": choices,
@@ -162,14 +151,14 @@ def futures_command():
"images_list": images_list,
}
else:
- fig = df2img.plot_dataframe(
+ fig = imps.plot_df(
df,
- fig_size=(720, (40 + (45 * len(df.index)))),
- col_width=[4, 2, 2, 2],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ fig_size=(620, (40 + (45 * len(df.index)))),
+ col_width=[4.2, 1.8, 2.5],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
fig.update_traces(
@@ -181,7 +170,7 @@ def futures_command():
)
)
imagefile = "econ-futures.png"
- imagefile = helpers.save_image(imagefile, fig)
+ imagefile = imps.save_image(imagefile, fig)
output = {
"title": title,
diff --git a/bots/economy/futures_coms.py b/bots/economy/futures_coms.py
old mode 100644
new mode 100755
index 57f9002c9fd..becc0a1127c
--- a/bots/economy/futures_coms.py
+++ b/bots/economy/futures_coms.py
@@ -1,10 +1,8 @@
import logging
-import df2img
import pandas as pd
-import bots.config_discordbot as cfg
-from bots.helpers import save_image
+from bots import imps
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.economy import wsj_model
@@ -16,7 +14,7 @@ def futures_coms_command():
"""Futures and commodities overview [Wall St. Journal]"""
# Debug user input
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("econ-futures")
# Retrieve data
@@ -28,42 +26,38 @@ def futures_coms_command():
df["Last Price"] = pd.to_numeric(df["Price"].astype(float))
df["Change"] = pd.to_numeric(df["Chg"].astype(float))
- df["% Change"] = pd.to_numeric(df["%Chg"].astype(float))
- df = df.drop(columns=["Price", "Chg", "%Chg"])
+ df["%Chg"] = pd.to_numeric(df["%Chg"].astype(float))
# Debug user output
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug(df.to_string())
- formats = {"Last Price": "${:.2f}", "Change": "${:.2f}", "% Change": "{:.2f}%"}
+ formats = {
+ "Last Price": "${:.2f}",
+ "Change": "${:.2f}",
+ "%Chg": "{:.2f}%",
+ }
for col, value in formats.items():
df[col] = df[col].map(lambda x: value.format(x)) # pylint: disable=W0640
+ df["Change"] = df.apply(lambda x: f"{x['Change']} ({x['%Chg']})", axis=1)
+
df = df.fillna("")
df.set_index(" ", inplace=True)
- font_color = (
- ["white"] * 2
- + [
- [
- "#e4003a" if boolv else "#00ACFF"
- for boolv in df["Change"].str.contains("-")
- ]
- ]
- + [
- [
- "#e4003a" if boolv else "#00ACFF"
- for boolv in df["% Change"].str.contains("-")
- ]
- ]
- )
- fig = df2img.plot_dataframe(
+
+ font_color = ["white"] * 2 + [
+ ["#e4003a" if boolv else "#00ACFF" for boolv in df["%Chg"].str.contains("-")]
+ ]
+
+ df = df.drop(columns=["Price", "Chg", "%Chg"])
+ fig = imps.plot_df(
df,
- fig_size=(720, (40 + (40 * len(df.index)))),
- col_width=[8, 3, 3],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ fig_size=(620, (40 + (40 * len(df.index)))),
+ col_width=[4, 2.4, 3],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
fig.update_traces(
@@ -74,5 +68,5 @@ def futures_coms_command():
)
)
)
- imagefile = save_image("econ-futures.png", fig)
+ imagefile = imps.save_image("econ-futures.png", fig)
return {"title": "Economy: [WSJ] Futures/Commodities", "imagefile": imagefile}
diff --git a/bots/economy/glbonds.py b/bots/economy/glbonds.py
old mode 100644
new mode 100755
index e5e02f1dacd..70adc973135
--- a/bots/economy/glbonds.py
+++ b/bots/economy/glbonds.py
@@ -1,10 +1,8 @@
import logging
-import df2img
import pandas as pd
-import bots.config_discordbot as cfg
-from bots.helpers import save_image
+from bots import imps
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.economy import wsj_model
@@ -16,7 +14,7 @@ def glbonds_command():
"""Global bonds overview [Wall St. Journal]"""
# Debug user input
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("econ-glbonds")
# Retrieve data
@@ -33,13 +31,13 @@ def glbonds_command():
formats = {
"Rate (%)": "{:.2f}%",
"Yld (%)": "{:.2f}%",
- "Yld Chg (%)": "{:.2f}%",
+ "Yld Chg (%)": "{:.2f}%",
}
for col, value in formats.items():
df[col] = df[col].map(lambda x: value.format(x)) # pylint: disable=W0640
# Debug user output
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug(df.to_string())
df = df.fillna("")
@@ -53,17 +51,29 @@ def glbonds_command():
],
axis="columns",
)
- fig = df2img.plot_dataframe(
+
+ font_color = ["white"] * 3 + [
+ ["#e4003a" if boolv else "#00ACFF" for boolv in df["Yld Chg"].str.contains("-")]
+ ]
+
+ fig = imps.plot_df(
df,
- fig_size=(800, (40 + (40 * len(df.index)))),
+ fig_size=(500, (40 + (40 * len(df.index)))),
col_width=[8, 3, 3],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
- fig.update_traces(cells=(dict(align="left")))
- imagefile = save_image("econ-glbonds.png", fig)
+ fig.update_traces(
+ cells=(
+ dict(
+ align=["center", "right"],
+ font=dict(color=font_color),
+ )
+ )
+ )
+ imagefile = imps.save_image("econ-glbonds.png", fig)
return {"title": "Economy: [WSJ] Global Bonds", "imagefile": imagefile}
diff --git a/bots/economy/grains.py b/bots/economy/grains.py
old mode 100644
new mode 100755
index f1a17c2e1a8..6de145d4fe5
--- a/bots/economy/grains.py
+++ b/bots/economy/grains.py
@@ -1,10 +1,8 @@
import logging
-import df2img
import pandas as pd
-import bots.config_discordbot as cfg
-from bots.helpers import save_image
+from bots import imps
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.economy import finviz_model
@@ -16,7 +14,7 @@ def grains_command():
"""Displays grains futures data [Finviz]"""
# Debug user input
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("econ-grains")
# Retrieve data
@@ -27,7 +25,7 @@ def grains_command():
if df.empty:
raise Exception("No available data found")
- formats = {"last": "${:.2f}", "prevClose": "${:.2f}"}
+ formats = {"last": "${:.2f}", "prevClose": "${:.2f}", "change": "{:.2f}%"}
for col, value in formats.items():
df[col] = df[col].map(lambda x: value.format(x)) # pylint: disable=W0640
@@ -36,7 +34,7 @@ def grains_command():
df = df.sort_values(by="ticker", ascending=False)
# Debug user output
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug(df)
df = df[
@@ -46,23 +44,35 @@ def grains_command():
"change",
]
]
+
df.index.names = [""]
df = df.rename(
columns={"prevClose": "PrevClose", "last": "Last", "change": "Change"}
)
- fig = df2img.plot_dataframe(
+
+ font_color = ["white"] * 3 + [
+ ["#e4003a" if boolv else "#00ACFF" for boolv in df["Change"].str.contains("-")]
+ ]
+
+ fig = imps.plot_df(
df,
- fig_size=(800, (40 + (40 * len(df.index)))),
- col_width=[6, 3, 3],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ fig_size=(500, (40 + (40 * len(df.index)))),
+ col_width=[5, 3.2, 2.8, 2.8],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
- fig.update_traces(cells=(dict(align="left")))
-
- imagefile = save_image("econ-grains.png", fig)
+ fig.update_traces(
+ cells=(
+ dict(
+ align=["center", "right"],
+ font=dict(color=font_color),
+ )
+ )
+ )
+ imagefile = imps.save_image("econ-grains.png", fig)
return {
"title": "Economy: [Finviz] Grains Futures",
diff --git a/bots/economy/indices.py b/bots/economy/indices.py
old mode 100644
new mode 100755
index a0368569f32..1da9bb79c65
--- a/bots/economy/indices.py
+++ b/bots/economy/indices.py
@@ -1,10 +1,8 @@
import logging
-import df2img
import pandas as pd
-import bots.config_discordbot as cfg
-from bots.helpers import save_image
+from bots import imps
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.economy import wsj_model
@@ -15,7 +13,7 @@ logger = logging.getLogger(__name__)
def indices_command():
"""US indices overview [Wall St. Journal]"""
# Debug user input
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("econ-indices")
# Retrieve data
@@ -27,42 +25,38 @@ def indices_command():
df["Last Price"] = pd.to_numeric(df["Price"].astype(float))
df["Change"] = pd.to_numeric(df["Chg"].astype(float))
- df["% Change"] = pd.to_numeric(df["%Chg"].astype(float))
- df = df.drop(columns=["Price", "Chg", "%Chg"])
+ df["%Chg"] = pd.to_numeric(df["%Chg"].astype(float))
# Debug user output
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug(df.to_string())
- formats = {"Last Price": "${:.2f}", "Change": "${:.2f}", "% Change": "{:.2f}%"}
+ formats = {
+ "Last Price": "${:.2f}",
+ "Change": "${:.2f}",
+ "%Chg": "{:.2f}%",
+ }
for col, value in formats.items():
df[col] = df[col].map(lambda x: value.format(x)) # pylint: disable=W0640
+ df["Change"] = df.apply(lambda x: f"{x['Change']} ({x['%Chg']})", axis=1)
+
df = df.fillna("")
df.set_index(" ", inplace=True)
- font_color = (
- ["white"] * 2
- + [
- [
- "#e4003a" if boolv else "#00ACFF"
- for boolv in df["Change"].str.contains("-")
- ]
- ]
- + [
- [
- "#e4003a" if boolv else "#00ACFF"
- for boolv in df["% Change"].str.contains("-")
- ]
- ]
- )
- fig = df2img.plot_dataframe(
+
+ font_color = ["white"] * 2 + [
+ ["#e4003a" if boolv else "#00ACFF" for boolv in df["%Chg"].str.contains("-")]
+ ]
+
+ df = df.drop(columns=["Price", "Chg", "%Chg"])
+ fig = imps.plot_df(
df,
- fig_size=(720, (40 + (40 * len(df.index)))),
- col_width=[8, 3, 3],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ fig_size=(620, (40 + (40 * len(df.index)))),
+ col_width=[4, 2.4, 3],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
fig.update_traces(
@@ -73,7 +67,7 @@ def indices_command():
)
)
)
- imagefile = save_image("econ-indices.png", fig)
+ imagefile = imps.save_image("econ-indices.png", fig)
return {
"title": "Economy: [WSJ] US Indices",
"imagefile": imagefile,
diff --git a/bots/economy/meats.py b/bots/economy/meats.py
old mode 100644
new mode 100755
index ddf364472e0..3e141cbf174
--- a/bots/economy/meats.py
+++ b/bots/economy/meats.py
@@ -1,10 +1,8 @@
import logging
-import df2img
import pandas as pd
-import bots.config_discordbot as cfg
-from bots.helpers import save_image
+from bots import imps
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.economy import finviz_model
@@ -16,7 +14,7 @@ def meats_command():
"""Displays meats futures data [Finviz]"""
# Debug user input
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("econ-meats")
# Retrieve data
@@ -31,12 +29,12 @@ def meats_command():
df = df.set_index("label")
df = df.sort_values(by="ticker", ascending=False)
- formats = {"last": "${:.2f}", "prevClose": "${:.2f}"}
+ formats = {"last": "${:.2f}", "prevClose": "${:.2f}", "change": "{:.2f}%"}
for col, value in formats.items():
df[col] = df[col].map(lambda x: value.format(x)) # pylint: disable=W0640
# Debug user output
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug(df)
df = df[
@@ -46,23 +44,35 @@ def meats_command():
"change",
]
]
+
df.index.names = [""]
df = df.rename(
columns={"prevClose": "PrevClose", "last": "Last", "change": "Change"}
)
- fig = df2img.plot_dataframe(
+
+ font_color = ["white"] * 3 + [
+ ["#e4003a" if boolv else "#00ACFF" for boolv in df["Change"].str.contains("-")]
+ ]
+
+ fig = imps.plot_df(
df,
- fig_size=(800, (40 + (40 * len(df.index)))),
- col_width=[6, 3, 3],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ fig_size=(500, (40 + (40 * len(df.index)))),
+ col_width=[5, 3, 3],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
- fig.update_traces(cells=(dict(align="left")))
-
- imagefile = save_image("econ-meats.png", fig)
+ fig.update_traces(
+ cells=(
+ dict(
+ align=["center", "right"],
+ font=dict(color=font_color),
+ )
+ )
+ )
+ imagefile = imps.save_image("econ-meats.png", fig)
return {
"title": "Economy: [Finviz] Meats Futures",
"imagefile": imagefile,
diff --git a/bots/economy/metals.py b/bots/economy/metals.py
old mode 100644
new mode 100755
index 7591f6322c1..ba0e6cce632
--- a/bots/economy/metals.py
+++ b/bots/economy/metals.py
@@ -1,10 +1,8 @@
import logging
-import df2img
import pandas as pd
-import bots.config_discordbot as cfg
-from bots.helpers import save_image
+from bots import imps
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.economy import finviz_model
@@ -15,7 +13,7 @@ logger = logging.getLogger(__name__)
def metals_command():
"""Displays metals futures data [Finviz]"""
# Debug user input
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("econ-metals")
# Retrieve data
@@ -26,12 +24,12 @@ def metals_command():
if df.empty:
raise Exception("No available data found")
- formats = {"last": "${:.2f}", "prevClose": "${:.2f}"}
+ formats = {"last": "${:.2f}", "prevClose": "${:.2f}", "change": "{:.2f}%"}
for col, value in formats.items():
df[col] = df[col].map(lambda x: value.format(x)) # pylint: disable=W0640
# Debug user output
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug(df)
df = df.sort_values(by="ticker", ascending=False)
@@ -51,18 +49,29 @@ def metals_command():
columns={"prevClose": "PrevClose", "last": "Last", "change": "Change"}
)
- fig = df2img.plot_dataframe(
+ font_color = ["white"] * 3 + [
+ ["#e4003a" if boolv else "#00ACFF" for boolv in df["Change"].str.contains("-")]
+ ]
+
+ fig = imps.plot_df(
df,
- fig_size=(800, (40 + (40 * len(df.index)))),
- col_width=[6, 3, 3],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ fig_size=(570, (40 + (40 * len(df.index)))),
+ col_width=[5, 3, 3],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
- fig.update_traces(cells=(dict(align="left")))
- imagefile = save_image("econ-metals.png", fig)
+ fig.update_traces(
+ cells=(
+ dict(
+ align=["center", "right"],
+ font=dict(color=font_color),
+ )
+ )
+ )
+ imagefile = imps.save_image("econ-metals.png", fig)
return {
"title": "Economy: [WSJ] Metals Futures",
"imagefile": imagefile,
diff --git a/bots/economy/overview.py b/bots/economy/overview.py
old mode 100644
new mode 100755
index b92cf5529dd..c954ee00eb6
--- a/bots/economy/overview.py
+++ b/bots/economy/overview.py
@@ -1,10 +1,8 @@
import logging
-import df2img
import pandas as pd
-import bots.config_discordbot as cfg
-from bots.helpers import save_image
+from bots import imps
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.economy import wsj_model
@@ -15,7 +13,7 @@ logger = logging.getLogger(__name__)
def overview_command():
"""Market data overview [Wall St. Journal]"""
# Debug user input
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("econ-overview")
# Retrieve data
@@ -27,42 +25,38 @@ def overview_command():
df["Last Price"] = pd.to_numeric(df["Price"].astype(float))
df["Change"] = pd.to_numeric(df["Chg"].astype(float))
- df["% Change"] = pd.to_numeric(df["%Chg"].astype(float))
- df = df.drop(columns=["Price", "Chg", "%Chg"])
+ df["%Chg"] = pd.to_numeric(df["%Chg"].astype(float))
# Debug user output
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug(df.to_string())
- formats = {"Last Price": "${:.2f}", "Change": "${:.2f}", "% Change": "{:.2f}%"}
+ formats = {
+ "Last Price": "${:.2f}",
+ "Change": "${:.2f}",
+ "%Chg": "{:.2f}%",
+ }
for col, value in formats.items():
df[col] = df[col].map(lambda x: value.format(x)) # pylint: disable=W0640
+ df["Change"] = df.apply(lambda x: f"{x['Change']} ({x['%Chg']})", axis=1)
+
df = df.fillna("")
df.set_index(" ", inplace=True)
- font_color = (
- ["white"] * 2
- + [
- [
- "#e4003a" if boolv else "#00ACFF"
- for boolv in df["Change"].str.contains("-")
- ]
- ]
- + [
- [
- "#e4003a" if boolv else "#00ACFF"
- for boolv in df["% Change"].str.contains("-")
- ]
- ]
- )
- fig = df2img.plot_dataframe(
+
+ font_color = ["white"] * 2 + [
+ ["#e4003a" if boolv else "#00ACFF" for boolv in df["Change"].str.contains("-")]
+ ]
+
+ df = df.drop(columns=["Price", "Chg", "%Chg"])
+ fig = imps.plot_df(
df,
- fig_size=(720, (40 + (40 * len(df.index)))),
- col_width=[8, 3, 3],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ fig_size=(620, (40 + (40 * len(df.index)))),
+ col_width=[4, 2.4, 3],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
fig.update_traces(
@@ -74,7 +68,7 @@ def overview_command():
)
)
- imagefile = save_image("econ-indices.png", fig)
+ imagefile = imps.save_image("econ-overview.png", fig)
return {
"title": "Economy: [WSJ] Market Overview",
"imagefile": imagefile,
diff --git a/bots/economy/performance.py b/bots/economy/performance.py
old mode 100644
new mode 100755
index 2e5abd3ddbe..67024b0ff8d
--- a/bots/economy/performance.py
+++ b/bots/economy/performance.py
@@ -1,13 +1,13 @@
import logging
+import os
-import df2img
-import numpy as np
+import disnake
import pandas as pd
-import bots.config_discordbot as cfg
-from bots.helpers import save_image
+from bots import imps
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.economy import finviz_model
+from gamestonk_terminal.helper_funcs import lambda_long_number_format
logger = logging.getLogger(__name__)
@@ -35,12 +35,12 @@ def performance_command(economy_group="sector"):
}
# Debug user input
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("econ-performance %s", economy_group)
# Select default group
if not economy_group:
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("Use default economy_group: 'sector'")
economy_group = "sector"
@@ -62,19 +62,18 @@ def performance_command(economy_group="sector"):
# Output data
df = pd.DataFrame(df_group)
- df = df.replace(np.nan, 0)
df["Volume"] = df["Volume"] / 1_000_000
df["Avg Volume"] = df["Avg Volume"] / 1_000_000
formats = {
"Perf Month": "{:.2f}",
- "Perf Quart": "{:.2f}",
- "Perf Half": "{:.2f}",
- "Perf Year": "{:.2f}",
- "Perf YTD": "{:.2f}",
+ "Perf Quart": "{:.2f}%",
+ "Perf Half": "{:.2f}%",
+ "Perf Year": "{:.2f}%",
+ "Perf YTD": "{:.2f}%",
"Avg Volume": "{:.0f}M",
- "Change": "{:.2f}",
+ "Change": "{:.2f}%",
"Volume": "{:.0f}M",
}
for col, value in formats.items():
@@ -85,36 +84,118 @@ def performance_command(economy_group="sector"):
"Name",
"Week",
"Month",
- "3Month",
- "6Month",
- "1Year",
+ "3 Mouth",
+ "6 Mouth",
+ "1 Year",
"YTD",
"Recom",
- "Avg Vol.",
- "RelVolume",
+ "Avg Volume",
+ "Rel Volume",
"Change",
"Volume",
],
axis="columns",
)
-
- df = df.fillna("")
df.set_index("Name", inplace=True)
+ df = df.fillna("-")
+ df = df.applymap(lambda x: lambda_long_number_format(x, 2))
- fig = df2img.plot_dataframe(
- df,
- fig_size=(1500, (40 + (50 * len(df.index)))),
- col_width=[10, 3, 3, 3, 3, 3, 3, 3, 4, 4, 3, 3.5],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
- paper_bgcolor="rgba(0, 0, 0, 0)",
- )
- fig.update_traces(cells=(dict(align=["left", "center"])))
+ title = f"Economy: [WSJ] Performance {group}"
- imagefile = save_image("econ-performance.png", fig)
- return {
- "title": f"Economy: [WSJ] Performance {group}",
- "imagefile": imagefile,
- }
+ dindex = len(df.index)
+ if dindex > 2:
+ embeds: list = []
+ # Output
+ i, i2, end = 0, 0, 2
+ df_pg, embeds_img, images_list = pd.DataFrame(), [], []
+ while i < dindex:
+ df_pg = df.iloc[i:end]
+ df_pg.append(df_pg)
+ fig = imps.plot_df(
+ df_pg.transpose(),
+ fig_size=(800, 720),
+ col_width=[6, 10],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
+ paper_bgcolor="rgba(0, 0, 0, 0)",
+ )
+ fig.update_traces(cells=(dict(align=["center", "right"])))
+ imagefile = "econ_performance.png"
+ imagefile = imps.save_image(imagefile, fig)
+
+ if imps.IMAGES_URL or imps.IMGUR_CLIENT_ID != "REPLACE_ME":
+ image_link = imps.IMAGES_URL + imagefile
+ images_list.append(imagefile)
+ else:
+ imagefile_save = imps.IMG_DIR / imagefile
+ uploaded_image = imps.gst_imgur.upload_image(
+ imagefile_save, title="something"
+ )
+ image_link = uploaded_image.link
+ os.remove(imagefile_save)
+
+ embeds_img.append(
+ f"{image_link}",
+ )
+ embeds.append(
+ disnake.Embed(
+ title=title,
+ colour=imps.COLOR,
+ ),
+ )
+ i2 += 1
+ i += 2
+ end += 2
+
+ # Author/Footer
+ for i in range(0, i2):
+ embeds[i].set_author(
+ name=imps.AUTHOR_NAME,
+ url=imps.AUTHOR_URL,
+ icon_url=imps.AUTHOR_ICON_URL,
+ )
+ embeds[i].set_footer(
+ text=imps.AUTHOR_NAME,
+ icon_url=imps.AUTHOR_ICON_URL,
+ )
+
+ i = 0
+ for i in range(0, i2):
+ embeds[i].set_image(url=embeds_img[i])
+
+ i += 1
+ embeds[0].set_footer(text=f"Page 1 of {len(embeds)}")
+ choices = [
+ disnake.SelectOption(label="Home", value="0", emoji="🟢"),
+ ]
+
+ output = {
+ "view": imps.Menu,
+ "title": title,
+ "embed": embeds,
+ "choices": choices,
+ "embeds_img": embeds_img,
+ "images_list": images_list,
+ }
+ else:
+ fig = imps.plot_df(
+ df.transpose(),
+ fig_size=(800, 720),
+ col_width=[6, 10],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
+ paper_bgcolor="rgba(0, 0, 0, 0)",
+ )
+ fig.update_traces(cells=(dict(align=["center", "right"])))
+ imagefile = imps.save_image("econ_performance.png", fig)
+
+ output = {
+ "title": title,
+ "imagefile": imagefile,
+ }
+
+ return output
diff --git a/bots/economy/reverse_repo.py b/bots/economy/reverse_repo.py
new file mode 100755
index 00000000000..4d95df4ca1e
--- /dev/null
+++ b/bots/economy/reverse_repo.py
@@ -0,0 +1,171 @@
+import logging
+import os
+
+import disnake
+import pandas as pd
+import requests
+
+from bots import imps
+from gamestonk_terminal.decorators import log_start_end
+
+logger = logging.getLogger(__name__)
+
+
+@log_start_end(log=logger)
+def reverse_repo_command(days: int = 100):
+ """Displays Reverse Repo [Stocksera.com]"""
+
+ # Debug user input
+ if imps.DEBUG:
+ logger.debug("dd repo %s", days)
+
+ df = pd.DataFrame(
+ requests.get(
+ f"https://stocksera.pythonanywhere.com/api/reverse_repo/?days={str(days)}"
+ ).json()
+ )
+
+ if df.empty:
+ raise Exception("No Data Found")
+
+ title = "Reverse Repo [Stocksera]"
+
+ df["Difference"] = df["Amount"].diff().fillna(0)
+
+ formats = {
+ "Amount": "${:.2f}B",
+ "Average": "${:.2f}B",
+ "Difference": "${:.2f}B",
+ }
+ for col, value in formats.items():
+ df[col] = df[col].map(lambda x: value.format(x)) # pylint: disable=W0640
+
+ font_color = ["white"] * 4 + [
+ [
+ "#e4003a" if boolv else "#00ACFF"
+ for boolv in df["Difference"].str.contains("-")
+ ] # type: ignore
+ ]
+
+ df = df.drop(columns="Moving Avg")
+ df = df.sort_values(by="Date", ascending=False)
+ df.set_index("Date", inplace=True)
+ df.columns = df.columns.str.capitalize()
+
+ dindex = len(df.index)
+ if dindex > 15:
+ embeds: list = []
+ # Output
+ i, i2, end = 0, 0, 15
+ df_pg, embeds_img, images_list = pd.DataFrame(), [], []
+ while i < dindex:
+ df_pg = df.iloc[i:end]
+ font_color = ["white"] * 4 + [
+ [
+ "#e4003a" if boolv else "#00ACFF"
+ for boolv in df_pg["Difference"].str.contains("-")
+ ] # type: ignore
+ ]
+ df_pg.append(df_pg)
+ fig = imps.plot_df(
+ df_pg,
+ fig_size=(650, (40 + (40 * len(df.index)))),
+ col_width=[1.8, 1.5, 1.7, 1.3, 1.8],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
+ paper_bgcolor="rgba(0, 0, 0, 0)",
+ )
+ fig.update_traces(
+ cells=(
+ dict(
+ align=["center", "right", "center", "right"],
+ font=dict(color=font_color),
+ )
+ )
+ )
+ imagefile = "dd_r_repo.png"
+ imagefile = imps.save_image(imagefile, fig)
+
+ if imps.IMAGES_URL or imps.IMGUR_CLIENT_ID != "REPLACE_ME":
+ image_link = imps.IMAGES_URL + imagefile
+ images_list.append(imagefile)
+ else:
+ imagefile_save = imps.IMG_DIR / imagefile
+ uploaded_image = imps.gst_imgur.upload_image(
+ imagefile_save, title="something"
+ )
+ image_link = uploaded_image.link
+ os.remove(imagefile_save)
+
+ embeds_img.append(
+ f"{image_link}",
+ )
+ embeds.append(
+ disnake.Embed(
+ title=title,
+ colour=imps.COLOR,
+ ),
+ )
+ i2 += 1
+ i += 15
+ end += 15
+
+ # Author/Footer
+ for i in range(0, i2):
+ embeds[i].set_author(
+ name=imps.AUTHOR_NAME,
+ url=imps.AUTHOR_URL,
+ icon_url=imps.AUTHOR_ICON_URL,
+ )
+ embeds[i].set_footer(
+ text=imps.AUTHOR_NAME,
+ icon_url=imps.AUTHOR_ICON_URL,
+ )
+
+ i = 0
+ for i in range(0, i2):
+ embeds[i].set_image(url=embeds_img[i])
+
+ i += 1
+ embeds[0].set_footer(text=f"Page 1 of {len(embeds)}")
+ choices = [
+ disnake.SelectOption(label="Home", value="0", emoji="🟢"),
+ ]
+
+ output = {
+ "view": imps.Menu,
+ "title": title,
+ "embed": embeds,
+ "choices": choices,
+ "embeds_img": embeds_img,
+ "images_list": images_list,
+ }
+ else:
+ fig = imps.plot_df(
+ df,
+ fig_size=(650, (40 + (40 * len(df.index)))),
+ col_width=[1.8, 1.5, 1.7, 1.3, 1.8],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
+ paper_bgcolor="rgba(0, 0, 0, 0)",
+ )
+ fig.update_traces(
+ cells=(
+ dict(
+ align=["center", "right", "center", "right"],
+ font=dict(color=font_color),
+ )
+ )
+ )
+ imagefile = "dd_r_repo.png"
+ imagefile = imps.save_image(imagefile, fig)
+
+ output = {
+ "title": title,
+ "imagefile": imagefile,
+ }
+ return output
diff --git a/bots/economy/softs.py b/bots/economy/softs.py
old mode 100644
new mode 100755
index 0e268ade5b4..c8e3b294563
--- a/bots/economy/softs.py
+++ b/bots/economy/softs.py
@@ -1,10 +1,8 @@
import logging
-import df2img
import pandas as pd
-import bots.config_discordbot as cfg
-from bots.helpers import save_image
+from bots import imps
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.economy import finviz_model
@@ -16,7 +14,7 @@ def softs_command():
"""Displays softs futures data [Finviz]"""
# Debug user input
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("econ-softs")
# Retrieve data
@@ -27,12 +25,12 @@ def softs_command():
if df.empty:
raise Exception("No available data found")
- formats = {"last": "${:.2f}", "prevClose": "${:.2f}"}
+ formats = {"last": "${:.2f}", "prevClose": "${:.2f}", "change": "{:.2f}%"}
for col, value in formats.items():
df[col] = df[col].map(lambda x: value.format(x)) # pylint: disable=W0640
# Debug user output
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug(df)
df = df.sort_values(by="ticker", ascending=False)
@@ -52,19 +50,30 @@ def softs_command():
columns={"prevClose": "PrevClose", "last": "Last", "change": "Change"}
)
- fig = df2img.plot_dataframe(
+ font_color = ["white"] * 3 + [
+ ["#e4003a" if boolv else "#00ACFF" for boolv in df["Change"].str.contains("-")]
+ ]
+
+ fig = imps.plot_df(
df,
- fig_size=(800, (40 + (40 * len(df.index)))),
- col_width=[6, 3, 3],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ fig_size=(550, (40 + (40 * len(df.index)))),
+ col_width=[5, 3, 3],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
- fig.update_traces(cells=(dict(align="left")))
+ fig.update_traces(
+ cells=(
+ dict(
+ align=["center", "right"],
+ font=dict(color=font_color),
+ )
+ )
+ )
+ imagefile = imps.save_image("econ-softs.png", fig)
- imagefile = save_image("econ-softs.png", fig)
return {
"title": "Economy: [Finviz] Softs Futures",
"imagefile": imagefile,
diff --git a/bots/economy/usbonds.py b/bots/economy/usbonds.py
old mode 100644
new mode 100755
index cb91540b323..df12715d6d0
--- a/bots/economy/usbonds.py
+++ b/bots/economy/usbonds.py
@@ -1,10 +1,8 @@
import logging
-import df2img
import pandas as pd
-import bots.config_discordbot as cfg
-from bots.helpers import save_image
+from bots import imps
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.economy import wsj_model
@@ -16,7 +14,7 @@ def usbonds_command():
"""US bonds overview [Wall St. Journal]"""
# Debug user input
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("econ-usbonds")
# Retrieve data
@@ -33,7 +31,7 @@ def usbonds_command():
formats = {
"Rate (%)": "{:.2f}%",
"Yld (%)": "{:.2f}%",
- "Yld Chg (%)": "{:.2f}%",
+ "Yld Chg (%)": "{:.2f}%",
}
for col, value in formats.items():
df[col] = df[col].map(lambda x: value.format(x)) # pylint: disable=W0640
@@ -50,19 +48,31 @@ def usbonds_command():
axis="columns",
)
- fig = df2img.plot_dataframe(
+ font_color = ["white"] * 3 + [
+ ["#e4003a" if boolv else "#00ACFF" for boolv in df["Yld Chg"].str.contains("-")]
+ ]
+
+ fig = imps.plot_df(
df,
- fig_size=(800, (40 + (40 * len(df.index)))),
- col_width=[8, 3, 3],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ fig_size=(550, (40 + (40 * len(df.index)))),
+ col_width=[4, 2, 2, 2.1],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
- fig.update_traces(cells=(dict(align="left")))
+ fig.update_traces(
+ cells=(
+ dict(
+ align=["center", "right"],
+ font=dict(color=font_color),
+ )
+ )
+ )
+ fig.update_traces(cells=(dict(align=["center", "right"])))
- imagefile = save_image("econ-usbonds.png", fig)
+ imagefile = imps.save_image("econ-usbonds.png", fig)
return {
"title": "Economy: [WSJ] US Bonds",
"imagefile": imagefile,
diff --git a/bots/economy/valuation.py b/bots/economy/valuation.py
old mode 100644
new mode 100755
index 0203e0b0320..6e3e8bfe3a4
--- a/bots/economy/valuation.py
+++ b/bots/economy/valuation.py
@@ -1,13 +1,13 @@
import logging
+import os
-import df2img
-import numpy as np
+import disnake
import pandas as pd
-import bots.config_discordbot as cfg
-from bots.helpers import save_image
+from bots import imps
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.economy import finviz_model
+from gamestonk_terminal.helper_funcs import lambda_long_number_format
logger = logging.getLogger(__name__)
@@ -35,12 +35,12 @@ def valuation_command(economy_group="sector"):
}
# Debug user input
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("econ-valuation %s", economy_group)
# Select default group
if economy_group == "":
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("Use default economy_group: 'sector'")
economy_group = "sector"
@@ -63,64 +63,106 @@ def valuation_command(economy_group="sector"):
# Output data
df = pd.DataFrame(df_group)
- df = df.replace(np.nan, 0)
-
- df = df.set_axis(
- [
- "Name",
- "MarketCap",
- "P/E",
- "FwdP/E",
- "PEG",
- "P/S",
- "P/B",
- "P/C",
- "P/FCF",
- "EPSpast5Y",
- "EPSnext5Y",
- "Salespast5Y",
- "Change",
- "Volume",
- ],
- axis="columns",
- )
-
- df["P/E"] = pd.to_numeric(df["P/E"].astype(float))
- df["FwdP/E"] = pd.to_numeric(df["FwdP/E"].astype(float))
- df["EPSpast5Y"] = pd.to_numeric(df["EPSpast5Y"].astype(float))
- df["EPSnext5Y"] = pd.to_numeric(df["EPSnext5Y"].astype(float))
- df["Salespast5Y"] = pd.to_numeric(df["Salespast5Y"].astype(float))
- df["Volume"] = pd.to_numeric(df["Volume"].astype(float))
- df["Volume"] = df["Volume"] / 1_000_000
-
- formats = {
- "P/E": "{:.2f}",
- "FwdP/E": "{:.2f}",
- "EPSpast5Y": "{:.2f}",
- "EPSnext5Y": "{:.2f}",
- "Salespast5Y": "{:.2f}",
- "Change": "{:.2f}",
- "Volume": "{:.0f}M",
- }
- for col, value in formats.items():
- df[col] = df[col].map(lambda x: value.format(x)) # pylint: disable=W0640
-
- df = df.fillna("")
df.set_index("Name", inplace=True)
+ df = df.fillna("-")
+ df = df.applymap(lambda x: lambda_long_number_format(x, 2))
- fig = df2img.plot_dataframe(
- df,
- fig_size=(1600, (40 + (50 * len(df.index)))),
- col_width=[12, 5, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 4, 4],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
- paper_bgcolor="rgba(0, 0, 0, 0)",
- )
- fig.update_traces(cells=(dict(align=["left", "center"])))
- imagefile = save_image("econ-valuation.png", fig)
- return {
- "title": "Economy: [Finviz] Valuation",
- "imagefile": imagefile,
- }
+ title = f"Economy: [Finviz] Valuation {group}"
+
+ dindex = len(df.index)
+ if dindex > 2:
+ embeds: list = []
+ # Output
+ i, i2, end = 0, 0, 2
+ df_pg, embeds_img, images_list = pd.DataFrame(), [], []
+ while i < dindex:
+ df_pg = df.iloc[i:end]
+ df_pg.append(df_pg)
+ fig = imps.plot_df(
+ df_pg.transpose(),
+ fig_size=(800, 720),
+ col_width=[6, 10],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
+ paper_bgcolor="rgba(0, 0, 0, 0)",
+ )
+ fig.update_traces(cells=(dict(align=["center", "right"])))
+ imagefile = "econ_valuation.png"
+ imagefile = imps.save_image(imagefile, fig)
+
+ if imps.IMAGES_URL or imps.IMGUR_CLIENT_ID != "REPLACE_ME":
+ image_link = imps.IMAGES_URL + imagefile
+ images_list.append(imagefile)
+ else:
+ imagefile_save = imps.IMG_DIR / imagefile
+ uploaded_image = imps.gst_imgur.upload_image(
+ imagefile_save, title="something"
+ )
+ image_link = uploaded_image.link
+ os.remove(imagefile_save)
+
+ embeds_img.append(
+ f"{image_link}",
+ )
+ embeds.append(
+ disnake.Embed(
+ title=title,
+ colour=imps.COLOR,
+ ),
+ )
+ i2 += 1
+ i += 2
+ end += 2
+
+ # Author/Footer
+ for i in range(0, i2):
+ embeds[i].set_author(
+ name=imps.AUTHOR_NAME,
+ url=imps.AUTHOR_URL,
+ icon_url=imps.AUTHOR_ICON_URL,
+ )
+ embeds[i].set_footer(
+ text=imps.AUTHOR_NAME,
+ icon_url=imps.AUTHOR_ICON_URL,
+ )
+
+ i = 0
+ for i in range(0, i2):
+ embeds[i].set_image(url=embeds_img[i])
+
+ i += 1
+ embeds[0].set_footer(text=f"Page 1 of {len(embeds)}")
+ choices = [
+ disnake.SelectOption(label="Home", value="0", emoji="🟢"),
+ ]
+
+ output = {
+ "view": imps.Menu,
+ "title": title,
+ "embed": embeds,
+ "choices": choices,
+ "embeds_img": embeds_img,
+ "images_list": images_list,
+ }
+ else:
+ fig = imps.plot_df(
+ df.transpose(),
+ fig_size=(800, 720),
+ col_width=[6, 10],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
+ paper_bgcolor="rgba(0, 0, 0, 0)",
+ )
+ fig.update_traces(cells=(dict(align=["center", "right"])))
+ imagefile = imps.save_image("econ_valuation.png", fig)
+
+ output = {
+ "title": title,
+ "imagefile": imagefile,
+ }
+
+ return output
diff --git a/bots/etf/holdings.py b/bots/etf/holdings.py
index a23c85c3a74..d1224b21651 100755
--- a/bots/etf/holdings.py
+++ b/bots/etf/holdings.py
@@ -1,13 +1,9 @@
import logging
import os
-import df2img
import disnake
-import bots.config_discordbot as cfg
-from bots import helpers
-from bots.config_discordbot import gst_imgur
-from bots.menus.menu import Menu
+from bots import imps
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.etf import stockanalysis_model
@@ -18,7 +14,7 @@ logger = logging.getLogger(__name__)
def holdings_command(etf="", num: int = 15):
"""Display ETF Holdings. [Source: StockAnalysis]"""
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("etfs")
holdings = stockanalysis_model.get_etf_holdings(etf.upper())
@@ -38,26 +34,26 @@ def holdings_command(etf="", num: int = 15):
while i < dindex:
df_pg = holdings.iloc[i:end]
df_pg.append(df_pg)
- fig = df2img.plot_dataframe(
+ fig = imps.plot_df(
df_pg,
- fig_size=(800, (40 + (40 * dindex))),
- col_width=[3, 4, 4],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ fig_size=(500, (40 + (40 * dindex))),
+ col_width=[1, 2, 2],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
- fig.update_traces(cells=(dict(align=["left", "center"])))
+ fig.update_traces(cells=(dict(align=["center", "right"])))
imagefile = "etf-holdings.png"
- imagefile = helpers.save_image(imagefile, fig)
+ imagefile = imps.save_image(imagefile, fig)
- if cfg.IMAGES_URL or cfg.IMGUR_CLIENT_ID != "REPLACE_ME":
- image_link = cfg.IMAGES_URL + imagefile
+ if imps.IMAGES_URL or imps.IMGUR_CLIENT_ID != "REPLACE_ME":
+ image_link = imps.IMAGES_URL + imagefile
images_list.append(imagefile)
else:
- imagefile_save = cfg.IMG_DIR / imagefile
- uploaded_image = gst_imgur.upload_image(
+ imagefile_save = imps.IMG_DIR / imagefile
+ uploaded_image = imps.gst_imgur.upload_image(
imagefile_save, title="something"
)
image_link = uploaded_image.link
@@ -69,7 +65,7 @@ def holdings_command(etf="", num: int = 15):
embeds.append(
disnake.Embed(
title=title,
- colour=cfg.COLOR,
+ colour=imps.COLOR,
),
)
i2 += 1
@@ -79,13 +75,13 @@ def holdings_command(etf="", num: int = 15):
# Author/Footer
for i in range(0, i2):
embeds[i].set_author(
- name=cfg.AUTHOR_NAME,
- url=cfg.AUTHOR_URL,
- icon_url=cfg.AUTHOR_ICON_URL,
+ name=imps.AUTHOR_NAME,
+ url=imps.AUTHOR_URL,
+ icon_url=imps.AUTHOR_ICON_URL,
)
embeds[i].set_footer(
- text=cfg.AUTHOR_NAME,
- icon_url=cfg.AUTHOR_ICON_URL,
+ text=imps.AUTHOR_NAME,
+ icon_url=imps.AUTHOR_ICON_URL,
)
i = 0
@@ -99,7 +95,7 @@ def holdings_command(etf="", num: int = 15):
]
output = {
- "view": Menu,
+ "view": imps.Menu,
"title": title,
"embed": embeds,
"choices": choices,
@@ -107,18 +103,18 @@ def holdings_command(etf="", num: int = 15):
"images_list": images_list,
}
else:
- fig = df2img.plot_dataframe(
+ fig = imps.plot_df(
holdings,
- fig_size=(800, (40 + (40 * dindex))),
- col_width=[3, 4, 4],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ fig_size=(500, (40 + (40 * dindex))),
+ col_width=[1, 2, 2],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
- fig.update_traces(cells=(dict(align=["left", "center"])))
- imagefile = helpers.save_image("etf-holdings.png", fig)
+ fig.update_traces(cells=(dict(align=["center", "right"])))
+ imagefile = imps.save_image("etf-holdings.png", fig)
output = {
"title": title,
diff --git a/bots/etf/tops.py b/bots/etf/tops.py
old mode 100644
new mode 100755
index 29f5ec6b9c9..da085399049
--- a/bots/etf/tops.py
+++ b/bots/etf/tops.py
@@ -1,13 +1,10 @@
import logging
import os
-import df2img
import disnake
+import pandas as pd
-import bots.config_discordbot as cfg
-from bots import helpers
-from bots.config_discordbot import gst_imgur
-from bots.menus.menu import Menu
+from bots import imps
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.etf.discovery import wsj_model
@@ -19,7 +16,7 @@ def etfs_disc_command(sort=""):
"""Displays ETF's Top Gainers/Decliners, Most Active [Wall Street Journal]"""
# Debug
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("etfs")
df_etfs = wsj_model.etf_movers(sort, export=True)
@@ -27,12 +24,28 @@ def etfs_disc_command(sort=""):
if df_etfs.empty:
raise Exception("No available data found")
- df_etfs.set_index(" ", inplace=True)
- prfx = "Top"
- if sort == "active":
- prfx = "Most"
+ prfx = "Most" if sort == "active" else "Top"
title = f"ETF Movers ({prfx} {sort.capitalize()})"
+ df_etfs["Price"] = pd.to_numeric(df_etfs["Price"].astype(float))
+
+ df_etfs["Price"] = df_etfs.apply(lambda x: f"${x['Price']:.2f}", axis=1)
+ df_etfs["Change"] = df_etfs.apply(
+ lambda x: f"${x['Chg']:.2f} ({x['%Chg']:.2f}%)", axis=1
+ )
+
+ df_etfs.set_index(" ", inplace=True)
+ df_etfs = df_etfs.drop(columns=["Chg", "%Chg"])
+
+ df_etfs = df_etfs[
+ [
+ "Name",
+ "Price",
+ "Change",
+ "Vol",
+ ]
+ ]
+
dindex = len(df_etfs.index)
if dindex > 15:
embeds: list = []
@@ -42,26 +55,26 @@ def etfs_disc_command(sort=""):
while i < dindex:
df_pg = df_etfs.iloc[i:end]
df_pg.append(df_pg)
- fig = df2img.plot_dataframe(
+ fig = imps.plot_df(
df_pg,
- fig_size=(1200, (40 + (40 * dindex))),
- col_width=[1, 9, 1.5, 1.5, 1.5, 1.5],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ fig_size=(820, (40 + (40 * dindex))),
+ col_width=[1.1, 9, 1.5, 3, 1.5],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
- fig.update_traces(cells=(dict(align=["left"])))
+ fig.update_traces(cells=(dict(align=["center", "center", "right"])))
imagefile = "disc-etfs.png"
- imagefile = helpers.save_image(imagefile, fig)
+ imagefile = imps.save_image(imagefile, fig)
- if cfg.IMAGES_URL or cfg.IMGUR_CLIENT_ID != "REPLACE_ME":
- image_link = cfg.IMAGES_URL + imagefile
+ if imps.IMAGES_URL or imps.IMGUR_CLIENT_ID != "REPLACE_ME":
+ image_link = imps.IMAGES_URL + imagefile
images_list.append(imagefile)
else:
- imagefile_save = cfg.IMG_DIR / imagefile
- uploaded_image = gst_imgur.upload_image(
+ imagefile_save = imps.IMG_DIR / imagefile
+ uploaded_image = imps.gst_imgur.upload_image(
imagefile_save, title="something"
)
image_link = uploaded_image.link
@@ -73,7 +86,7 @@ def etfs_disc_command(sort=""):
embeds.append(
disnake.Embed(
title=title,
- colour=cfg.COLOR,
+ colour=imps.COLOR,
),
)
i2 += 1
@@ -83,13 +96,13 @@ def etfs_disc_command(sort=""):
# Author/Footer
for i in range(0, i2):
embeds[i].set_author(
- name=cfg.AUTHOR_NAME,
- url=cfg.AUTHOR_URL,
- icon_url=cfg.AUTHOR_ICON_URL,
+ name=imps.AUTHOR_NAME,
+ url=imps.AUTHOR_URL,
+ icon_url=imps.AUTHOR_ICON_URL,
)
embeds[i].set_footer(
- text=cfg.AUTHOR_NAME,
- icon_url=cfg.AUTHOR_ICON_URL,
+ text=imps.AUTHOR_NAME,
+ icon_url=imps.AUTHOR_ICON_URL,
)
i = 0
@@ -103,7 +116,7 @@ def etfs_disc_command(sort=""):
]
output = {
- "view": Menu,
+ "view": imps.Menu,
"title": title,
"embed": embeds,
"choices": choices,
@@ -111,18 +124,18 @@ def etfs_disc_command(sort=""):
"images_list": images_list,
}
else:
- fig = df2img.plot_dataframe(
+ fig = imps.plot_df(
df_etfs,
- fig_size=(1200, (40 + (40 * dindex))),
- col_width=[1, 9, 1.5, 1.5, 1.5, 1.5],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ fig_size=(820, (40 + (40 * dindex))),
+ col_width=[1, 9, 1.5, 3, 1.5],
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
- fig.update_traces(cells=(dict(align=["left"])))
- imagefile = helpers.save_image("disc-etfs.png", fig)
+ fig.update_traces(cells=(dict(align=["center", "center", "right"])))
+ imagefile = imps.save_image("disc-etfs.png", fig)
output = {
"title": title,
diff --git a/bots/etf/whatetf.py b/bots/etf/whatetf.py
index 52300cc3f8a..704da0e1b68 100755
--- a/bots/etf/whatetf.py
+++ b/bots/etf/whatetf.py
@@ -1,50 +1,27 @@
import logging
import os
-import re
import time
import bs4
-import df2img
import disnake
-import natsort
import pandas as pd
import undetected_chromedriver.v2 as uc
from selenium.webdriver.common.by import By
-import bots.config_discordbot as cfg
-from bots import helpers
-from bots.config_discordbot import gst_imgur
-from bots.menus.menu import Menu
+from bots import imps
from gamestonk_terminal.decorators import log_start_end
+# pylint:disable=no-member
+
logger = logging.getLogger(__name__)
-conversion_mapping = {
- "K": 1_000,
- "M": 1_000_000,
-}
-
-all_units = "|".join(conversion_mapping.keys())
-float_re = natsort.numeric_regex_chooser(natsort.ns.FLOAT | natsort.ns.SIGNED)
-unit_finder = re.compile(rf"({float_re})\s*({all_units})", re.IGNORECASE)
-
-
-def unit_replacer(matchobj):
- """
- Given a regex match object, return a replacement string where units are modified
- """
- number = matchobj.group(1)
- unit = matchobj.group(2)
- new_number = float(number) * conversion_mapping[unit]
- return f"{new_number} in"
-
@log_start_end(log=logger)
def by_ticker_command(ticker="", sort="fund_percent", num: int = 15):
"""Display ETF Holdings. [Source: StockAnalysis]"""
# Debug
- if cfg.DEBUG:
+ if imps.DEBUG:
logger.debug("etfs")
options = uc.ChromeOptions()
@@ -91,10 +68,9 @@ def by_ticker_command(ticker="", sort="fund_percent", num: int = 15):
raise Exception("No company holdings found!\n")
if sort == "mkt_value":
- # [unit_finder.sub(unit_replacer, x) for x in df["Market Value"]]
- key = natsort.index_natsorted(
+ key = imps.natsort.index_natsorted(
df["Market Value"],
- key=lambda x: unit_finder.sub(unit_replacer, x),
+ key=lambda x: imps.unit_finder.sub(imps.unit_replacer, x),
reverse=True,
)
df = df.reindex(key)
@@ -112,28 +88,28 @@ def by_ticker_command(ticker="", sort="fund_percent", num: int = 15):
while i < dindex:
df_pg = df.iloc[i:end]
df_pg.append(df_pg)
- fig = df2img.plot_dataframe(
+ fig = imps.plot_df(
df_pg,
fig_size=(800, (40 * dindex)),
col_width=[0.6, 3.5, 0.65, 1.1],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
fig.update_traces(
cells=(dict(align=["center", "center", "center", "right"]))
)
imagefile = "etf-byticker.png"
- imagefile = helpers.save_image(imagefile, fig)
+ imagefile = imps.save_image(imagefile, fig)
- if cfg.IMAGES_URL or cfg.IMGUR_CLIENT_ID != "REPLACE_ME":
- image_link = cfg.IMAGES_URL + imagefile
+ if imps.IMAGES_URL or imps.IMGUR_CLIENT_ID != "REPLACE_ME":
+ image_link = imps.IMAGES_URL + imagefile
images_list.append(imagefile)
else:
- imagefile_save = cfg.IMG_DIR / imagefile
- uploaded_image = gst_imgur.upload_image(
+ imagefile_save = imps.IMG_DIR / imagefile
+ uploaded_image = imps.gst_imgur.upload_image(
imagefile_save, title="something"
)
image_link = uploaded_image.link
@@ -145,7 +121,7 @@ def by_ticker_command(ticker="", sort="fund_percent", num: int = 15):
embeds.append(
disnake.Embed(
title=title,
- colour=cfg.COLOR,
+ colour=imps.COLOR,
),
)
i2 += 1
@@ -155,13 +131,13 @@ def by_ticker_command(ticker="", sort="fund_percent", num: int = 15):
# Author/Footer
for i in range(0, i2):
embeds[i].set_author(
- name=cfg.AUTHOR_NAME,
- url=cfg.AUTHOR_URL,
- icon_url=cfg.AUTHOR_ICON_URL,
+ name=imps.AUTHOR_NAME,
+ url=imps.AUTHOR_URL,
+ icon_url=imps.AUTHOR_ICON_URL,
)
embeds[i].set_footer(
- text=cfg.AUTHOR_NAME,
- icon_url=cfg.AUTHOR_ICON_URL,
+ text=imps.AUTHOR_NAME,
+ icon_url=imps.AUTHOR_ICON_URL,
)
i = 0
@@ -175,7 +151,7 @@ def by_ticker_command(ticker="", sort="fund_percent", num: int = 15):
]
output = {
- "view": Menu,
+ "view": imps.Menu,
"title": title,
"embed": embeds,
"choices": choices,
@@ -183,18 +159,18 @@ def by_ticker_command(ticker="", sort="fund_percent", num: int = 15):
"images_list": images_list,
}
else:
- fig = df2img.plot_dataframe(
+ fig = imps.plot_df(
df,
fig_size=(800, (40 * dindex)),
col_width=[0.6, 3.5, 0.65, 1.1],
- tbl_header=cfg.PLT_TBL_HEADER,
- tbl_cells=cfg.PLT_TBL_CELLS,
- font=cfg.PLT_TBL_FONT,
- row_fill_color=cfg.PLT_TBL_ROW_COLORS,
+ tbl_header=imps.PLT_TBL_HEADER,
+ tbl_cells=imps.PLT_TBL_CELLS,
+ font=imps.PLT_TBL_FONT,
+ row_fill_color=imps.PLT_TBL_ROW_COLORS,
paper_bgcolor="rgba(0, 0, 0, 0)",
)
fig.update_traces(cells=(dict(align=["center", "center", "center", "right"])))
- imagefile = helpers.save_image("etf-holdings.png", fig)
+ imagefile = imps.save_image("etf-holdings.png", fig)
output = {
"title": title,
diff --git a/bots/groupme/run_groupme.py b/bots/groupme/run_groupme.py
index 5ad21810b53..554df197a42 100644
--- a/bots/groupme/run_groupme.py
+++ b/bots/groupme/run_groupme.py
@@ -1,8 +1,8 @@
import json
+from bots.common.helpers import non_slash
from bots.groupme.groupme_helpers import send_message
from bots.helpers import ShowView
-from bots.common.helpers import non_slash
def handle_groupme(request) -> bool:
diff --git a/bots/helpers.py b/bots/helpers.py
old mode 100644
new mode 100755
index 04113a38340..6be0d5067f8
--- a/bots/helpers.py
+++ b/bots/helpers.py
@@ -4,18 +4,20 @@ import re
import uuid
from typing import List
-import df2img
import disnake
import financedatabase as fd
+import natsort
import pandas as pd
+import plotly.graph_objects
import yfinance as yf
from numpy.core.fromnumeric import transpose
from PIL import Image
from plotly.offline import plot
-import bots.config_discordbot as cfg
+from bots import imps
from bots.groupme.groupme_helpers import send_image, send_message
+# pylint: disable=W0613
logger = logging.getLogger(__name__)
presets_custom = [
@@ -182,7 +184,21 @@ def quote(ticker):
return quote_data
-def autocrop_image(image, border=0):
+def autocrop_image(image: Image, border=0) -> Image:
+ """Crop empty space from PIL image
+
+ Parameters
+ ----------
+ image : Image
+ PIL image to crop
+ border : int, optional
+ scale border outwards, by default 0
+
+ Returns
+ -------
+ Image
+ Cropped image
+ """
bbox = image.getbbox()
image = image.crop(bbox)
(width, height) = image.size
@@ -193,18 +209,45 @@ def autocrop_image(image, border=0):
return cropped_image
-def uuid_get():
+conversion_mapping = {
+ "K": 1_000,
+ "M": 1_000_000,
+}
+
+all_units = "|".join(conversion_mapping.keys())
+float_re = natsort.numeric_regex_chooser(natsort.ns.FLOAT | natsort.ns.SIGNED)
+unit_finder = re.compile(rf"({float_re})\s*({all_units})", re.IGNORECASE)
+
+
+def unit_replacer(matchobj):
+ """
+ Given a regex match object, return a replacement string where units are modified
+ """
+ number = matchobj.group(1)
+ unit = matchobj.group(2)
+ new_number = float(number) * conversion_mapping[unit]
+ return f"{new_number}"
+
+
+def uuid_get() -> str:
+ """Returns a UUID
+
+ Returns
+ -------
+ str
+ UUID Ex. e48c4851a42711ec8e11fb53fa4c20e5
+ """
rand = str(uuid.uuid1()).replace("-", "")
return rand
-def country_autocomp(inter, country: str): # pylint: disable=W0613
+def country_autocomp(inter, country: str):
data = fd.show_options("equities", "countries")
clow = country.lower()
return [country for country in data if country.lower().startswith(clow)][:24]
-def industry_autocomp(inter, industry: str): # pylint: disable=W0613
+def industry_autocomp(inter, industry: str):
data = fd.show_options("equities", "industries")
if not industry:
industry = "a"
@@ -212,7 +255,7 @@ def industry_autocomp(inter, industry: str): # pylint: disable=W0613
return [industry for industry in data if industry.lower().startswith(ilow)][:24]
-def metric_autocomp(inter, metric: str): # pylint: disable=W0613
+def metric_autocomp(inter, metric: str):
data: dict = metric_yf_keys
if not metric:
data = list(data.keys()) # type: ignore
@@ -223,7 +266,7 @@ def metric_autocomp(inter, metric: str): # pylint: disable=W0613
]
-def ticker_autocomp(inter, ticker: str): # pylint: disable=W0613
+def ticker_autocomp(inter, ticker: str):
if not ticker:
return ["Start Typing", "for a", "stock ticker"]
print(f"ticker_autocomp [ticker]: {ticker}")
@@ -234,14 +277,14 @@ def ticker_autocomp(inter, ticker: str): # pylint: disable=W0613
return [ticker for ticker in df if ticker.lower().startswith(tlow)][:24]
-def expiry_autocomp(inter, ticker: str): # pylint: disable=W0613
+def expiry_autocomp(inter, ticker: str):
data = inter.filled_options["ticker"]
yf_ticker = yf.Ticker(data)
dates = list(yf_ticker.options)
return dates[:24]
-def presets_custom_autocomp(inter, preset: str): # pylint: disable=W0613
+def presets_custom_autocomp(inter, preset: str):
df = presets_custom
if not preset:
return df[:24]
@@ -250,7 +293,7 @@ def presets_custom_autocomp(inter, preset: str): # pylint: disable=W0613
return [preset for preset in df if preset.lower().startswith(plow)][:24]
-def signals_autocomp(inter, signal: str): # pylint: disable=W0613
+def signals_autocomp(inter, signal: str):
df = signals
if not signal:
return df[:24]
@@ -259,8 +302,24 @@ def signals_autocomp(inter, signal: str): # pylint: disable=W0613
return [signal for signal in df if signal.lower().startswith(slow)][:24]
-def inter_chart(fig, file, **data):
- filename = f"{file.replace('.png', '')}_{uuid_get()}.html"
+def inter_chart(fig: plotly.graph_objects, filename: str, **data) -> str:
+ """Takes plotly chart object and saves as a html file for interactive charts
+
+ Parameters
+ ----------
+ fig : plotly.graph_objects
+ Table object to autocrop and save
+ filename : str
+ Name to save html as
+ **kawrgs:
+ config: dict = plotly config Ex. dict(scrollZoom=True, displayModeBar=False)
+ callback: bool = enable js_callback for clickable news
+ Returns
+ -------
+ str
+ Link for interactive charts Ex. f"[Interactive]({imps.INTERACTIVE_URL}/{filename})"
+ """
+ filename = f"{filename.replace('.png', '')}_{uuid_get()}.html"
if "config" not in data:
config = dict(scrollZoom=True, displayModeBar=False)
plot_div = plot(fig, output_type="div", include_plotlyjs=True, config=config)
@@ -306,25 +365,54 @@ def inter_chart(fig, file, **data):
"""
# Write out HTML file
- with open(f"{cfg.INTERACTIVE_DIR / filename}", "w") as f:
+ with open(f"{imps.INTERACTIVE_DIR / filename}", "w") as f:
f.write(html_str)
- plt_link = f"[Interactive]({cfg.INTERACTIVE_URL}/{filename})"
+ plt_link = f"[Interactive]({imps.INTERACTIVE_URL}/{filename})"
return plt_link
-def save_image(file, fig):
- imagefile = f"{file.replace('.png', '')}_{uuid_get()}.png"
- filesave = cfg.IMG_DIR / imagefile
- df2img.save_dataframe(fig=fig, filename=filesave)
+def save_image(filename: str, fig: plotly.graph_objects) -> str:
+ """Takes plotly table object, adds uuid to filename, and autocrops
+
+ Parameters
+ ----------
+ filename : str
+ Name to save image as
+ fig : plotly.graph_objects
+ Table object to autocrop and save
+
+ Returns
+ -------
+ str
+ filename with UUID added to use for bot processing
+ """
+ imagefile = f"{filename.replace('.png', '')}_{uuid_get()}.png"
+ filesave = imps.IMG_DIR / imagefile
+ fig.write_image(filesave)
image = Image.open(filesave)
image = autocrop_image(image, 0)
image.save(filesave, "PNG", quality=100)
return imagefile
-def image_border(file, **kwargs):
- imagefile = f"{file.replace('.png', '')}_{uuid_get()}.png"
- filesave = cfg.IMG_DIR / imagefile
+def image_border(filename: str, **kwargs) -> str:
+ """Takes fig, base64, or already saved image and adds border to it
+
+ Parameters
+ ----------
+ filename : str
+ Name to save image as. If no fig or base64, will try to find
+ an image with this name to open.
+ **kawrgs:
+ fig=plotly.graph_objects
+ base64=BytesIo object
+ Returns
+ -------
+ str
+ filename with UUID added to use for bot processing
+ """
+ imagefile = f"{filename.replace('.png', '')}_{uuid_get()}.png"
+ filesave = imps.IMG_DIR / imagefile
if "fig" in kwargs:
fig = kwargs["fig"]
fig.write_image(filesave)
@@ -333,7 +421,7 @@ def image_border(file, **kwargs):
img = Image.open(kwargs["base64"])
else:
img = Image.open(filesave)
- im_bg = Image.open(cfg.IMG_BG)
+ im_bg = Image.open(imps.IMG_BG)
w = img.width + 520
h = img.height + 240
@@ -366,15 +454,15 @@ class ShowView:
else:
title = data.get("title", "")
embed = disnake.Embed(
- title=title, colour=cfg.COLOR, description=data.get("description", "")
+ title=title, colour=imps.COLOR, description=data.get("description", "")
)
embed.set_author(
- name=cfg.AUTHOR_NAME,
- icon_url=cfg.AUTHOR_ICON_URL,
+ name=imps.AUTHOR_NAME,
+ icon_url=imps.AUTHOR_ICON_URL,
)
if "imagefile" in data:
filename = data["imagefile"]
- imagefile = cfg.IMG_DIR / filename
+ imagefile = (imps.IMG_DIR / filename).as_posix()
image = disnake.File(imagefile, filename=filename)
embed.set_image(url=f"attachment://{filename}")
os.remove(imagefile)
@@ -393,25 +481,25 @@ class ShowView:
except Exception as e:
embed = disnake.Embed(
title=name,
- colour=cfg.COLOR,
+ colour=imps.COLOR,
description=e,
)
embed.set_author(
- name=cfg.AUTHOR_NAME,
- icon_url=cfg.AUTHOR_ICON_URL,
+ name=imps.AUTHOR_NAME,
+ icon_url=imps.AUTHOR_ICON_URL,
)
await inter.send(embed=embed, delete_after=30.0)
- def groupme(self, func, group_id, name, *args, **kwargs): # pylint: disable=W0613
+ def groupme(self, func, group_id, name, *args, **kwargs):
data = func(*args, **kwargs)
if "imagefile" in data:
- imagefile = cfg.IMG_DIR / data["imagefile"]
+ imagefile = (imps.IMG_DIR / data["imagefile"]).as_posix()
send_image(imagefile, group_id, data.get("description", ""))
elif "embeds_img" in data:
imagefiles = data["images_list"]
for img in imagefiles:
- imagefile = cfg.IMG_DIR / img
+ imagefile = (imps.IMG_DIR / img).as_posix()
send_image(imagefile, group_id, data.get("description", ""))
elif "description" in data:
title = data.get("title", "")
@@ -435,7 +523,7 @@ class ShowView:
.replace(".html)", ".html\n\n")
)
message = f"{title}\n{description}"
- imagefile = cfg.IMG_DIR / data["imagefile"]
+ imagefile = (imps.IMG_DIR / data["imagefile"]).as_posix()
client.files_upload(
file=imagefile,
initial_comment=message,
@@ -452,7 +540,7 @@ class ShowView:
title = data["title"] if "titles" not in data else data["titles"][0]
N = 0
for img in data["images_list"]:
- imagefile = cfg.IMG_DIR / img
+ imagefile = (imps.IMG_DIR / img).as_posix()
if N == 0:
message = f"{title}\n{description}"
payload = {
@@ -483,12 +571,10 @@ class ShowView:
payload = {"channel": channel_id, "username": user_id, "text": message}
client.chat_postMessage(**payload)
- def telegram(
- self, func, message, bot, cmd, *args, **kwargs
- ): # pylint: disable=W0613
+ def telegram(self, func, message, bot, cmd, *args, **kwargs):
data = func(*args, **kwargs)
if "imagefile" in data:
- imagefile = cfg.IMG_DIR / data["imagefile"]
+ imagefile = (imps.IMG_DIR / data["imagefile"]).as_posix()
title = data["title"]
description = (
data.get("description", "")
@@ -502,23 +588,21 @@ class ShowView:
bot.send_photo(message.chat.id, image)
os.remove(imagefile)
elif "embeds_img" in data:
- title = data["title"] if "titles" not in data else data["titles"][0]
+ res_title = data["title"] if "titles" not in data else data["titles"][0]
N = 0
for img in data["images_list"]:
- imagefile = cfg.IMG_DIR / img
+ imagefile = (imps.IMG_DIR / img).as_posix()
if N == 0:
description = (
data.get("description", "")
.replace("[Interactive](", "")
.replace(".html)", ".html\n\n")
)
- res = f"{title}\n{description}"
- bot.reply_to(message, res)
- title = ""
+ res_title = f"{res_title}\n{description}"
if N < len(data["titles"]) and N != 0:
- title = data["titles"][N]
+ res_title = data["titles"][N]
with open(imagefile, "rb") as image:
- bot.reply_to(message, title)
+ bot.reply_to(message, res_title)
bot.send_photo(message.chat.id, image)
N += 1
os.remove(imagefile)
diff --git a/bots/imps.py b/bots/imps.py
new file mode 100644
index 00000000000..3201bcb969e
--- /dev/null
+++ b/bots/imps.py
@@ -0,0 +1,8 @@
+"""Bot Imports"""
+# flake8: noqa
+# pylint: disable=unused-import,W0401,W0614
+from .common.plot_tbls import *
+from .config_discordbot import *
+from .config_plots import *
+from .helpers import *
+from .menus.menu import Menu
diff --git a/tests/gamestonk_terminal/stocks/txt/test_stocks_helper/test_load_custom[custom_imports/stocks/test.csv].txt b/bots/interactive/__init__.py
similarity index 100%
rename from tests/gamestonk_terminal/stocks/txt/test_stocks_helper/test_load_custom[custom_imports/stocks/test.csv].txt
rename to bots/interactive/__init__.py
diff --git a/tests/gamestonk_terminal/stocks/txt/test_stocks_helper/test_load_custom[none].txt b/bots/interactive/images/__init__.py
similarity index 100%
rename from tests/gamestonk_terminal/stocks/txt/test_stocks_helper/test_load_custom[none].txt
rename to bots/interactive/images/__init__.py
diff --git a/bots/load_candle.py b/bots/load_candle.py
old mode 100644
new mode 100755
index 4b7c519f656..4acca9abd10
--- a/bots/load_candle.py
+++ b/bots/load_candle.py
@@ -12,7 +12,7 @@ from binance.client import Client
from plotly.subplots import make_subplots
from scipy import stats
-import bots.config_discordbot as cfg
+from bots import imps
futures = "=F" or "^"
crypto = "-"
@@ -143,7 +143,7 @@ def stock_data(
max_days = day_list[interval]
if dt_utcnow_local_tz().weekday() not in range(2, 5):
- past_days += 2
+ past_days += 3
p_days = (
((past_days + 1) if (past_days < max_days) else max_days)
if (interval != 1440 and past_days < 365)
@@ -157,12 +157,12 @@ def stock_data(
bar_start if (bar_start < start) else start
) # Check if past days requested further back than start
else:
- start = datetime.strptime(start, cfg.DATE_FORMAT)
- bar_start = datetime.strptime(start, cfg.DATE_FORMAT) - timedelta(days=p_days)
+ start = datetime.strptime(start, imps.DATE_FORMAT).astimezone(est_tz)
+ bar_start = start - timedelta(days=p_days)
if end == "":
end = dt_utcnow_local_tz()
else:
- end = datetime.strptime(end, cfg.DATE_FORMAT)
+ end = datetime.strptime(end, imps.DATE_FORMAT).astimezone(est_tz)
if interval == 1440 and crypto not in ticker.upper():
df_stock = yf.download(
@@ -192,8 +192,8 @@ def stock_data(
(past_days + 10) if (((10 + past_days) + max_days) < max_days) else max_days
)
s_int = str(interval) + "m"
- if crypto in ticker.upper() and (cfg.API_BINANCE_KEY != "REPLACE_ME"):
- client = Client(cfg.API_BINANCE_KEY, cfg.API_BINANCE_SECRET)
+ if crypto in ticker.upper() and (imps.API_BINANCE_KEY != "REPLACE_ME"):
+ client = Client(imps.API_BINANCE_KEY, imps.API_BINANCE_SECRET)
interval_map = {
"1440m": client.KLINE_INTERVAL_1DAY,
"60m": client.KLINE_INTERVAL_1HOUR,
@@ -322,7 +322,7 @@ def candle_fig(
data["bar"]
> (dt_utcnow_local_tz() - timedelta(days=(dt[data["int_bar"]] * 3)))
)
- else 0.4
+ else 0.33
)
bar_opacity = (
bar_opacity
@@ -330,7 +330,7 @@ def candle_fig(
data["bar"]
> (dt_utcnow_local_tz() - timedelta(days=(dt[data["int_bar"]] * 4)))
)
- else 0.6
+ else 0.35
)
bar_opacity = (
bar_opacity
@@ -338,7 +338,7 @@ def candle_fig(
data["bar"]
> (dt_utcnow_local_tz() - timedelta(days=(dt[data["int_bar"]] * 10)))
)
- else 0.7
+ else 0.4
)
else:
bar_opacity = 0.2
@@ -405,7 +405,7 @@ def candle_fig(
df_date, df_title, df_current, df_content, df_url = [], [], [], [], []
- if (cfg.API_NEWS_TOKEN != "REPLACE_ME") and crypto in ticker.upper():
+ if (imps.API_NEWS_TOKEN != "REPLACE_ME") and crypto in ticker.upper():
d_stock = yf.Ticker(ticker).info
s_from = (dt_utcnow_local_tz() - timedelta(days=28)).strftime("%Y-%m-%d")
term = (
@@ -416,7 +416,7 @@ def candle_fig(
link = (
f"https://newsapi.org/v2/everything?q={term}&from={s_from}&sortBy=publishedAt&language=en"
- f"&apiKey={cfg.API_NEWS_TOKEN}"
+ f"&apiKey={imps.API_NEWS_TOKEN}"
)
response = requests.get(link)
articles = response.json()["articles"]
@@ -433,12 +433,12 @@ def candle_fig(
df_content.append(textwrap.indent(text=content, prefix="{text}
" + + +def row(elements: List) -> str: + with open( + os.path.join(os.path.dirname(os.path.abspath(__file__)), "widgets", "row.j2") + ) as f: + template = Template(f.read()) + return template.render(elements=elements) diff --git a/gamestonk_terminal/jupyter/widgets/card.j2 b/gamestonk_terminal/jupyter/widgets/card.j2 new file mode 100644 index 00000000000..09e630ad46b --- /dev/null +++ b/gamestonk_terminal/jupyter/widgets/card.j2 @@ -0,0 +1,8 @@ +