async def history( self, inter: disnake.AppCmdInter, ticker: str = commands.Param(autocomplete=ticker_autocomp), expiry: str = commands.Param(autocomplete=expiry_autocomp), strike: float = commands.Param(), opt_type: str = commands.Param(choices=["Calls", "Puts"]), greek: str = commands.Param( default="", choices=[ "iv", "gamma", "delta", "theta", "rho", "vega", ], ), ): """Options Price History with Greeks [Yahoo Finance] Parameters ---------- ticker: Stock Ticker expiry: Expiration Date strike: Options Strike Price opt_type: Calls or Puts greek: Greek variable to plot """ await ShowView().discord(hist_command, inter, "opt grhist", ticker, expiry, strike, opt_type, greek)
async def kc( self, ctx: disnake.AppCmdInter, ticker: str = commands.Param(autocomplete=ticker_autocomp), length="20", scalar="2", ma_mode: str = commands.Param( choices=["ema", "sma", "wma", "hma", "zlma"]), offset="0", start="", end="", ): """Displays chart with keltner channel [Yahoo Finance] Parameters ----------- ticker: Stock Ticker length: length. Default: 20 scalar: scalar. Default: 2 ma_mode: mode of moving average. offset: offset value. Default: 0 start: YYYY-MM-DD format end: YYYY-MM-DD format """ await ctx.response.defer() logger.info("ta-kc") ma_mode = str(ma_mode) await kc_command(ctx, ticker, length, scalar, ma_mode, offset, start, end)
async def by_ticker( inter: disnake.AppCmdInter, 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, sort, num, )
async def warden_limit_settings( self, ctx: discord.CommandInteraction, dismiss_limit: int = commands.Param( default=None, description=Strings.warden_settings_dismiss_limit_description), delete_limit: int = commands.Param( default=None, description=Strings.warden_settings_delete_limit_description), delete_enable: bool = commands.Param( default=None, description=Strings.warden_settings_delete_enable_description)): guild_warden_settings = self.warden_repo.get_warden_settings(ctx.guild) if dismiss_limit is not None: guild_warden_settings.dismiss_threshold = dismiss_limit if delete_limit is not None: guild_warden_settings.delete_threshold = delete_limit if delete_enable is not None: guild_warden_settings.enable_deleting_duplicates = delete_enable if dismiss_limit is not None or delete_limit is not None or delete_enable is not None: self.warden_repo.update() await ctx.send(embed=general_util.generate_success_message( "Settings updated"), delete_after=Config.base_success_duration) else: await ctx.send(embed=general_util.generate_success_message( "*Nothing changed*"), delete_after=Config.base_success_duration)
async def gtrades( self, inter: disnake.AppCmdInter, ticker: str = commands.Param(autocomplete=ticker_autocomp), gov_type: str = commands.Param( choices=["congress", "senate", "house"]), past_transactions_months: int = 10, raw: bool = False, ): """Displays government trades [quiverquant.com] Parameters ----------- ticker: Stock Ticker gov_type: Government Type past_transactions_months: Positive number of past transaction months raw: If raw data should be outputted """ await ShowView().discord( gtrades_command, inter, "gov gtrades", ticker, gov_type, past_transactions_months, raw, )
async def fib( self, inter: disnake.AppCmdInter, ticker: str = commands.Param(autocomplete=ticker_autocomp), 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, interval, past_days, start, end, extended_hours, heikin_candles, )
async def vsurf( self, inter: disnake.AppCmdInter, ticker: str = commands.Param(autocomplete=ticker_autocomp), z: str = commands.Param( choices=["Volatility", "Open Interest", "Last Price"]), ): """Display Volatility Surface Parameters ---------- ticker: Stock Ticker z: The variable for the Z axis """ await inter.response.defer() logger.info("opt-vsurf") if z == "Volatility": z = "IV" if z == "Open Interest": z = "OI" if z == "Last Price": z = "LP" await vsurf_command(inter, ticker, z)
async def history( self, inter: disnake.AppCmdInter, ticker: str = commands.Param(autocomplete=ticker_autocomp), expiry: str = commands.Param(autocomplete=expiry_autocomp), strike: float = commands.Param(), opt_type: str = commands.Param(choices=["Calls", "Puts"]), greek: str = commands.Param( default="", choices=[ "iv", "gamma", "delta", "theta", "rho", "vega", ], ), ): """Options Price History Parameters ---------- ticker: Stock Ticker expiry: Expiration Date strike: Options Strike Price type: Calls or Puts greek: Greek variable to plot """ await inter.response.defer() logger.info("opt-hist") await hist_command(inter, ticker, expiry, strike, opt_type, greek)
async def bbands( self, ctx: disnake.AppCmdInter, ticker: str = commands.Param(autocomplete=ticker_autocomp), length="5", std="2", ma_mode: str = commands.Param( choices=["ema", "sma", "wma", "hma", "zlma"]), start="", end="", ): """Displays chart with bollinger bands [Yahoo Finance] Parameters ----------- ticker: Stock Ticker length: length. Default: 5 std: standard deviation. Default: 2 ma_mode: mode of moving average. start: YYYY-MM-DD format end: YYYY-MM-DD format """ await ctx.response.defer() logger.info("ta-bbands") ma_mode = str(ma_mode) await bbands_command(ctx, ticker, length, std, ma_mode, start, end)
async def add( self, inter: disnake.GuildCommandInteraction, duration: str = commands.Param(description="Format: XdXhXmXs"), msg: str = commands.Param(description="Content of the reminder")): """Remind you of something at the specified time (±30 seconds precision)""" id = str(inter.author.id) if id not in self.bot.data.save['reminders']: self.bot.data.save['reminders'][id] = [] if len(self.bot.data.save['reminders'] [id]) >= 5 and inter.author.id != self.bot.owner.id: await inter.response.send_message(embed=self.bot.util.embed( title="Reminder Error", description="Sorry, I'm limited to 5 reminders per user 🙇", color=self.color), ephemeral=True) return try: d = self.bot.util.str2delta(duration) if d is None: raise Exception() except: await inter.response.send_message(embed=self.bot.util.embed( title="Reminder Error", description="Invalid duration string `{}`, format is `NdNhNm`". format(duration), color=self.color), ephemeral=True) return if msg == "": await inter.response.send_message(embed=self.bot.util.embed( title="Reminder Error", description="Tell me what I'm supposed to remind you 🤔", color=self.color), ephemeral=True) return if len(msg) > 200: await inter.response.send_message(embed=self.bot.util.embed( title="Reminder Error", description="Reminders are limited to 200 characters", color=self.color), ephemeral=True) return try: with self.bot.data.lock: self.bot.data.save['reminders'][id].append([ datetime.utcnow().replace(microsecond=0) + timedelta(seconds=32400) + d, msg ]) # keep JST self.bot.data.pending = True await inter.response.send_message(embed=self.bot.util.embed( title="The command ran with success", color=self.color), ephemeral=True) except: await inter.response.send_message(embed=self.bot.util.embed( title="Reminder Error", footer="I have no clues about what went wrong", color=self.color), ephemeral=True)
async def warden_scan( self, ctx: discord.CommandInteraction, limit: str = commands.Param( description=Strings.warden_scan_limit_description, default="all"), channel: str = commands.Param( description=Strings.warden_scan_channel_description, default=None, autocomplete=text_channels_autocomplete)): if channel is None: channel = ctx.channel else: channel = discord.utils.get(ctx.guild.channels, name=channel) if channel is None: return await ctx.send( embed=general_util.generate_error_message( Strings.populate_string("warden_channel_doesnt_exist", name=channel)), delete_after=Config.base_error_duration) guild_warden_settings = self.warden_repo.get_warden_settings(ctx.guild) if str(channel.id) not in guild_warden_settings.whitelist_channel_ids: return await ctx.send(embed=general_util.generate_error_message( Strings.populate_string("warden_channel_is_not_in_whitelist", name=channel.name)), delete_after=Config.base_error_duration) if limit.isnumeric(): limit = int(limit) elif limit == "all": limit = None else: return await ctx.send(embed=general_util.generate_error_message( Strings.warden_scan_bad_limit_format), delete_after=Config.base_error_duration) messages = await channel.history(limit=limit).flatten() ctr_hashes = 0 now = time.time() for i, message in enumerate(messages): if len(message.attachments) == 0: continue hashes = [x async for x in self.generate_message_hash(message)] ctr_hashes += len(hashes) await ctx.send( content="**SCAN COMPLETE**\n\n" f"Processed **{len(messages)}** messages.\n" f"Computed **{ctr_hashes}** hashes in {(time.time() - now):.1f} seconds.", delete_after=Config.base_long_success_duration)
async def volume( self, inter: disnake.AppCmdInter, ticker: str = commands.Param(autocomplete=ticker_autocomp), expiry: str = commands.Param(autocomplete=expiry_autocomp), ): """Options Volume [Yahoo Finance] Parameters ---------- ticker: Stock Ticker expiry: Expiration Date """ await ShowView().discord(vol_command, inter, "opt vol", ticker, expiry)
async def kc( self, inter: disnake.AppCmdInter, ticker: str = commands.Param(autocomplete=ticker_autocomp), interval: int = commands.Param(choices=[1, 5, 15, 30, 60, 1440]), past_days: int = 0, length="20", scalar="2", ma_mode: str = commands.Param( choices=["ema", "sma", "wma", "hma", "zlma"]), offset="0", start: str = "", end: str = "", extended_hours: bool = False, heikin_candles: bool = False, ): """Displays chart with keltner channel [Yahoo Finance] Parameters ----------- ticker: Stock Ticker interval : Chart Minute Interval, 1440 for Daily past_days: Past Days to Display. Default: 0(Not for Daily) length: length. Default: 20 scalar: scalar. Default: 2 ma_mode: mode of moving average. offset: offset value. Default: 0 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 """ ma_mode = str(ma_mode) await ShowView().discord( kc_command, inter, "ta-vlt kc", ticker, interval, past_days, length, scalar, ma_mode, offset, start, end, extended_hours, heikin_candles, )
async def remove_channel_from_whitelist( self, ctx: discord.CommandInteraction, channel_name: str = commands.Param( description=Strings.warden_channel_remove_channel_description, autocomplete=text_channels_autocomplete)): channel = discord.utils.get(ctx.guild.channels, name=channel_name) if channel is None: return await ctx.send(embed=general_util.generate_error_message( Strings.populate_string("warden_channel_doesnt_exist", name=channel_name)), delete_after=Config.base_error_duration) settings = self.warden_repo.get_warden_settings(ctx.guild) if str(channel.id) not in settings.whitelist_channel_ids: return await ctx.send(embed=general_util.generate_error_message( Strings.populate_string("warden_channel_is_not_in_whitelist", name=channel_name)), delete_after=Config.base_error_duration) channel_ids = settings.whitelist_channel_ids.split(";") channel_ids.remove(str(channel.id)) channels_string = ";".join(channel_ids) settings.whitelist_channel_ids = channels_string self.warden_repo.update() await ctx.send( embed=general_util.generate_success_message("Settings updated"), delete_after=Config.base_success_duration)
async def verify( inter: disnake.AppCommandInteraction, decklist_file: disnake.Attachment = commands.Param( description= "A .txt file containing the decklist. Use /decklist for more info on the format to use." )): await inter.response.defer(with_message=True) f = await decklist_file.read() try: f = f.decode() except UnicodeError: await inter.send( "Oops, I can't read that. Please send me a .txt file, with utf-8 encoding. Try copying your decklist into Notepad and saving it from there." ) return set_codes = bot.get_legal_set_codes(inter.guild) try: decklist = decklist_verification.decklist_parser(f, string=True) except decklist_verification.DecklistError as err: await inter.send(err.args) return verification = decklist_verification.verify_decklist(*decklist, legal_sets=set_codes) if verification is True: await inter.send("Verified!") else: await inter.send("There were some problems with your list:\n" + '\n'.join(verification))
async def zero(self, inter: disnake.GuildCommandInteraction, day_difference: int = commands.Param( description="Add a number of days to today date", ge=0, default=0)): """Post a spark estimation based on today date""" try: t_min, t_max, expected, now = self._estimate(day_difference, None) # roll count text await inter.response.send_message(embed=self.bot.util.embed( title='{} Spark estimation from {} rolls at {}'.format( self.bot.emote.get("crystal"), day_difference, now.strftime("%y/%m/%d")), description= "Next spark between {} and {}\n*Expecting {} to {} rolls in {}*" .format(t_min.strftime("%y/%m/%d"), t_max.strftime("%y/%m/%d"), expected[0], expected[1], now.strftime("%B")), color=self.color), ephemeral=True) except Exception as e: await inter.response.send_message(embed=self.bot.util.embed( title="Critical Error", description="I warned my owner", color=self.color, footer=str(e)), ephemeral=True) await self.bot.sendError('zeroRoll', e)
async def sol( self, inter: disnake.AppCmdInter, interval: int = commands.Param(choices=[1, 5, 15, 30, 60, 1440]), past_days: int = 0, start="", end="", news: bool = False, heikin_candles: bool = False, ): """Display Solana Chart [Yahoo Finance or Binance API] Parameters ---------- 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 news: Display clickable news markers on interactive chart. Default: False heikin_candles: Heikin Ashi candles. Default: False """ await ShowView().discord( candle_command, inter, "sol", "sol-usd", interval, past_days, False, start, end, news, heikin_candles, )
async def pos( self, ctx: disnake.AppCmdInter, sort: str = commands.Param(choices=pos_choices), num: int = 10, ): """Dark pool short position [Stockgrid] Parameters ----------- sort: Field for which to sort. num: Number of top tickers to show """ await ctx.response.defer() logger.info("dps-pos") if str(sort) == "Short Vol (1M)": sort = "sv" if str(sort) == "Short Vol %": sort = "sv_pct" if str(sort) == "Net Short Vol (1M)": sort = "nsv" if str(sort) == "Net Short Vol ($100M)": sort = "nsv_dollar" if str(sort) == "DP Position (1M)": sort = "dpp" if str(sort) == "DP Position ($1B)": sort = "dpp_dollar" await pos_command(ctx, sort, num)
async def feargreed(self, ctx: disnake.AppCmdInter, indicator: str = commands.Param(choices=fgind)): """CNN Fear and Greed Index [CNN] Parameters ---------- indicator: Select an Indicator """ await ctx.response.defer() logger.info("econ-feargreed") if indicator == "Junk Bond Demand": indicator = "jbd" if indicator == "Market Volatility": indicator = "mv" if indicator == "Put and Call Options": indicator = "pco" if indicator == "Market Momentum": indicator = "mm" if indicator == "Stock Price Strength": indicator = "sps" if indicator == "Stock Price Breadth": indicator = "spb" if indicator == "Safe Heaven Demand": indicator = "shd" await feargreed_command(ctx, indicator)
async def donchian( self, inter: disnake.AppCmdInter, ticker: str = commands.Param(autocomplete=ticker_autocomp), upper_length="25", lower_length="100", start="", end="", ): """Displays chart with donchian channel [Yahoo Finance] Parameters ----------- ticker: Stock Ticker upper_length: length. Default: 25 lower_length: standard deviation. Default: 100 start: YYYY-MM-DD format end: YYYY-MM-DD format """ await ShowView().discord( donchian_command, inter, "ta-donchian", ticker, upper_length, lower_length, start, end, )
async def sidtc( self, ctx: disnake.AppCmdInter, sort: str = commands.Param( choices=["Float Short %", "Days to Cover", "Short Interest"]), num: int = 10, ): """Short interest and days to cover [Stockgrid] Parameters ----------- sort: Field for which to sort. Possible are: `float`, `dtc`, `si`. num: Number of top tickers to show """ await ctx.response.defer() logger.info("dps-sidtc") if str(sort) == "Float Short %": sort = "float" if str(sort) == "Days to Cover": sort = "dtc" if str(sort) == "Short Interest": sort = "si" await sidtc_command(ctx, sort, num)
async def reminddel(self, inter: disnake.GuildCommandInteraction, rid: int = commands.Param( description="Number of the reminder to delete")): """Delete one of your reminders""" id = str(inter.author.id) if id not in self.bot.data.save['reminders'] or len( self.bot.data.save['reminders'][id]) == 0: await inter.response.send_message(embed=self.bot.util.embed( title="Reminder Error", description="You don't have any reminders", color=self.color), ephemeral=True) else: if rid < 0 or rid >= len(self.bot.data.save['reminders'][id]): await inter.response.send_message(embed=self.bot.util.embed( title="Reminder Error", description="Invalid id `{}`".format(rid), color=self.color), ephemeral=True) else: with self.bot.data.lock: self.bot.data.save['reminders'][id].pop(rid) if len(self.bot.data.save['reminders'][id]) == 0: self.bot.data.save['reminders'].pop(id) self.bot.data.pending = True await inter.response.send_message(embed=self.bot.util.embed( title="The command ran with success", color=self.color), ephemeral=True)
async def topsells( self, inter: disnake.AppCmdInter, gov_type: str = commands.Param( choices=["congress", "senate", "house"]), past_transactions_months: int = 5, num: int = 10, raw: bool = False, ): """Displays most sold stocks by the congress/senate/house [quiverquant.com] Parameters ----------- gov_type: Government Type past_transactions_months: Positive number of past transaction months num: Number of most sold stocks to retrieve raw: If raw data should be outputted """ await ShowView().discord( topsells_command, inter, "gov topsells", gov_type, past_transactions_months, num, raw, )
async def sia_mertics( self, inter: disnake.AppCmdInter, ticker: str = commands.Param(autocomplete=helpers.ticker_autocomp), metric: str = commands.Param(autocomplete=helpers.metric_autocomp), ): """Visualise financial metric across filters selected [Source: Finance Database] Parameters ---------- metric: Select financial metric ticker: Company to use for Industry, Sector, and Market Cap """ met_arg = helpers.metric_yf_keys[metric] await helpers.ShowView().discord(metric_command, inter, "sia metrics", met_arg[0], met_arg[1], ticker)
async def volume( self, inter: disnake.AppCmdInter, ticker: str = commands.Param(autocomplete=ticker_autocomp), expiry: str = commands.Param(autocomplete=expiry_autocomp), ): """Options Volume Parameters ---------- ticker: Stock Ticker expiry: Expiration Date """ await inter.response.defer() logger.info("opt-vol") await vol_command(inter, ticker, expiry)
async def bonk_slash(self, inter: discord.CommandInteraction, user: Optional[str] = commands.Param( autocomplete=user_autocomplete, description="User to bonk", default=None)): user = discord.utils.get(inter.guild.members, display_name=user) await self.bonk(inter, user=user)
async def box( self, inter: disnake.GuildCommandInteraction, box: int = commands.Param(description="Number of box to clear", ge=1, le=1000), box_done: int = commands.Param( description= "Your current box progress, default 0 (Will be ignored if equal or higher than target)", ge=0, default=0)): """Convert Dread Barrage box values""" try: t = 0 if box_done >= box: raise Exception( "Your current box count `{}` is higher or equal to your target `{}`" .format(box_done, box)) for b in range(box_done + 1, box + 1): if b == 1: t += 1600 elif b <= 4: t += 2400 elif b <= 20: t += 2000 elif b <= 40: t += 10000 else: t += 15000 s1 = math.ceil(t / 52.0) s2 = math.ceil(t / 70.0) s3 = math.ceil(t / 97.0) s4 = math.ceil(t / 146.0) s5 = math.ceil(t / 243.0) await inter.response.send_message(embed=self.bot.util.embed( title="{} Dread Barrage Token Calculator ▫️ Box {}".format( self.bot.emote.get('crew'), box), description= "**{:,}** tokens needed{}\n\n**{:,}** \⭐ (**{:,}** pots)\n**{:,}** \⭐\⭐ (**{:,}** pots)\n**{:,}** \⭐\⭐\⭐ (**{:,}** pots)\n**{:,}** \⭐\⭐\⭐\⭐ (**{:,}** pots)\n**{:,}** \⭐\⭐\⭐\⭐\⭐ (**{:,}** pots)" .format(t, ("" if box_done == 0 else " from box **{}**".format(box_done)), s1, math.ceil(s1 * 30 / 75), s2, math.ceil(s2 * 30 / 75), s3, math.ceil(s3 * 40 / 75), s4, math.ceil(s4 * 50 / 75), s5, math.ceil(s5 * 50 / 75)), color=self.color), ephemeral=True) except Exception as e: await inter.response.send_message(embed=self.bot.util.embed( title="Error", description=str(e), color=self.color), ephemeral=True)
async def bbands( self, inter: disnake.AppCmdInter, ticker: str = commands.Param(autocomplete=ticker_autocomp), interval: int = commands.Param(choices=[1, 5, 15, 30, 60, 1440]), past_days: int = 0, length="20", std: float = 2.0, ma_mode: str = commands.Param( choices=["ema", "sma", "wma", "hma", "zlma"]), start: str = "", end: str = "", extended_hours: bool = False, heikin_candles: bool = False, ): """Displays chart with bollinger bands [Yahoo Finance] Parameters ----------- ticker: Stock Ticker interval : Chart Minute Interval, 1440 for Daily past_days: Past Days to Display. Default: 0(Not for Daily) length: length. Default: 5 std: standard deviation. Default: 2.0 ma_mode: mode of moving average. 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( bbands_command, inter, "ta-vlt bbands", ticker, interval, past_days, length, std, ma_mode, start, end, extended_hours, heikin_candles, )
async def ma( self, inter: disnake.AppCmdInter, ticker: str = commands.Param(autocomplete=ticker_autocomp), 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: str = "", offset: int = 0, start: str = "", end: str = "", extended_hours: bool = False, heikin_candles: bool = False, ): """Displays chart with selected moving average [Yahoo Finance] Parameters ----------- ticker: Stock Ticker interval : Chart Minute Interval, 1440 for Daily past_days: Past Days to Display. Default: 0(Not for Daily) ma_mode: mode of moving average. window: window length. Default: 20, 50 offset: offset. Default: 0 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( ma_command, inter, "ta-ma", ticker, interval, past_days, ma_mode, window, offset, start, end, extended_hours, heikin_candles, )
async def vsurf( self, inter: disnake.AppCmdInter, ticker: str = commands.Param(autocomplete=ticker_autocomp), z: str = commands.Param(choices={ "Volatility": "IV", "Open Interest": "OI", "Last Price": "LP", }), ): """Display Volatility Surface [Yahoo Finance] Parameters ---------- ticker: Stock Ticker z: The variable for the Z axis """ await ShowView().discord(vsurf_command, inter, "opt vsurf", ticker, z)