async def findOptionChain(self, ctx, stock=None, type=None, expir=None): """Takes in a stock ticker, an optional expiration date (defaulted to friday expiration [if applicable]), a type (defaulted to call) and prints the information (Strike, price, volume, OI) on 1 ITM strike and 3 OTM strikes to discord. :param ctx: :param stock: {1-5} character stock-ticker. :param type: Defaulted to 'call'. Can be either 'call' or 'put'. :param expir: Defaulted to 'None'. Represents the expiration date in the format YYYY-MM-DD :return: """ if stock and s.validateTicker(stock): price = s.tickerPrice(stock) if price >= 5: res = o.pcOptionChain(stock, type, expir, price) await ctx.send("```" + res + "```") else: await ctx.send("```" + stock.upper() + " is not a valid ticker for options.\n" + "```") elif stock: await ctx.send("```" + stock.upper() + " is not a valid ticker.\n" + "```") else: res = "Option chain: Displays stock option chain information based on ticker, type (call or put), " \ "and expiration.\n" + \ "Ex: .f [stock]\n" + \ "Ex: .f [stock], [type]\n" + \ "Ex: .f [stock], [type], [expiration]\n" await ctx.send("```" + res + "```")
async def readOptionChain(self, ctx, stock=None): """Takes a stock ticker as the parameter to parse multiple option chains for multiple dynamically generated expirations (currently set to next 3 monthly expirations) and prints out information regarding a stock option's volume * current price. The printout takes the 5 best results and showcases it, as well as the entire OCs tallied up to show a preferred side. :param ctx: :param stock: :return: """ if stock and s.validateTicker(stock): price = s.tickerPrice(stock) if price >= 10: junk = await ctx.send("```" + "Loading the option chain for " + str(stock).upper() + "..." + "```") try: res = flow.mostExpensive(stock) if res: await ctx.send("```" + res + "```") except: await ctx.send("```" + "Failed to load the option chain for " + str(stock).upper() + "\n" "This may be due to low activity in the option chain, Robinhood API, " "or other abnormal activity." + "```") finally: await junk.delete() else: await ctx.send("```" + stock.upper() + " is not a valid ticker for options.\n" + "```") elif stock: await ctx.send("```" + stock.upper() + " is not a valid ticker.\n" + "```") else: res = "Read Option Info: Displays closest valued options for a ticker with which side is dominating and " \ "top 5 most valued strikes.\n" + \ "Ex. .read [stock]\n" await ctx.send("```" + res + "```")
async def background_loop(self, bot): """Runs on startup and every minute that the bot is running. [Specified in EST, but made in UTC] Task 1: If the US market is open (9AM[pre-market] - 8PM[after-hours] and not holiday), print a SPY chart`` every 15 minutes. Task 2: Every 10 minutes (global time) write the stocks mentioned to 'stocks_mentioned.csv'. Task 3: If the US market is pre-market (9AM and weekday), but it's a holiday - make an announcement. :return: """ await self.bot.wait_until_ready() channel = self.bot.get_channel(int(os.getenv('DISCORD_CHANNEL'))) altchannel = self.bot.get_channel(int( os.getenv('DISCORD_CHANNEL_ALT'))) holidayDate = cal.getHolidays() if cal.getDay() < 5 and not self.bot.is_closed() and cal.getCurrentDay() not in holidayDate and \ (12 <= cal.getHour() <= 23): if cal.getMinute() % 15 == 0: res = s.autoPull() await channel.send("```" + res + "```") if cal.getMinute() % 5 == 0: if not s.validateTicker('SPY'): user = await bot.fetch_user( int(os.getenv('ROBINHOOD_USER_ACCOUNT'))) await channel.send(user.mention + " API key expired.") if r.login(username=os.getenv('RH_USER'), password=os.getenv('RH_PASS')): await channel.send( "```" + 'Restarted Robinhood instance successfully.' + "```") print("Restarted Robinhood instance successfully.") else: await channel.send( "```" + 'Failed to create Robinhood instance. Bot owner has been sent an SMS.' + "```") print("Failed to create Robinhood instance.") s.stocks_mentioned['SPY'] = s.stocks_mentioned.get('SPY', 0) - 1 if cal.getMinute() % 1 == 0: msg, found = sweepcast() if found: print('Option whales spotted') await channel.send("```" + msg + "```") await altchannel.send("```" + msg + "```") if cal.getMinute() % 10 == 0: s.writeStocksMentioned() if cal.getCurrentDay() in holidayDate and cal.getHour( ) == 14 and cal.getMinute() == 0: await channel.send("Today is " + holidayDate[cal.getCurrentDay()] + " the market is closed. Enjoy your holiday!")
def trending(): try: result = requests.get("https://api.stocktwits.com/api/2/trending/symbols.json") if result.status_code == 200: res = '' found = 0 for symbol in result.json()["symbols"]: stock = symbol["symbol"] if stock.find('.') == -1 and found <= 10 and s.validateTicker(stock): pc, _ = s.WLpc(stock) res += pc found += 1 return res else: print("Failure to pull Stocktwits trending.") except Exception as e: print(e)
async def createWL(self, ctx, *args): author = args[0] wlKeywords = ['refresh', 'reset', 'rm', 'remove'] if args and ctx.message.author.id == 247095523197190154: if not args[0].lower() in wlKeywords: stockWPrice = {} stockInArgs = False for stock in args: stock = stock[1:-2] print(stock) if s.validateTicker(stock) and stock not in stockWPrice: print(stock) stockInArgs = True stockWPrice[stock] = s.grabSimplePrice(stock) if stockInArgs: print(stockWPrice) self.wl_dict[author] = stockWPrice writeWatchlist(self.wl_dict) await ctx.send( "```" + "Watchlist instance successfully created\n" + "```")
async def priceCheck(self, ctx, *args): """Takes in any amount of arguments for a price check on each ticker. :param ctx: :param args: (arg1), (arg2), ... (argN) Takes one to multiple stock tickers. :return: """ res = "" stocksRequested = [] for stock in args: if s.validateTicker(stock) and stock not in stocksRequested: stocksRequested.append(stock) pcList, perc = s.pc( stock ) # currently not using perc return - maybe in future? res += pcList elif stock in stocksRequested: continue else: res += stock.upper() + " is not a valid ticker.\n" await ctx.send("```" + res + "```")
async def pullWL(self, ctx, *args): author = str(ctx.message.author.id) initiatedUser = True sudoUser = False wlKeywords = ['refresh', 'reset', 'rm', 'remove'] if not self.wl_dict: self.loadWatchlist() responseRet = "" if args and args[0][:3] == '<@!': sudoUser = True author = args[0][3:-1] elif args and args[0][:2] == '<@': sudoUser = True author = args[0][2:-1] if self.wl_dict.get(author) is None and not sudoUser: if args: if not args[0].lower() in wlKeywords: stockWPrice = {} stockInArgs = False for stock in args: if s.validateTicker( stock) and stock not in stockWPrice: stockInArgs = True stockWPrice[stock.upper()] = s.grabSimplePrice( stock) if stockInArgs: self.wl_dict[author] = stockWPrice writeWatchlist(self.wl_dict) responseRet += "Watchlist instance successfully created\n" else: initiatedUser = False await ctx.send( "```" + "To create a personal watchlist use the command \".wl\" followed by stock " "tickers.\n" "Example: .wl estc net\n" "To view other user's watchlists use the command \".wl @user\"\n" "To remove a stock use the command \".wl rm\"\n" "To remove watchlist use the command \".wl refresh\"\n" + "```") elif not sudoUser: if args: if args[0].lower() == 'refresh' or args[0].lower() == 'reset': self.wl_dict.pop(author, None) await ctx.send( "```" + "Watchlist instance successfully removed for " + str(ctx.message.author) + "```") else: stockWPrice = self.wl_dict.get(author) old_wl = [] updatedList = False for stock in self.wl_dict[author]: old_wl.append(stock.upper()) if args[0].lower() == 'rm' or args[0].lower() == 'remove': for stock in args: if s.validateTicker( stock) and stock.upper() in old_wl: updatedList = True stockWPrice.pop(stock.upper()) else: for stock in args: if s.validateTicker(stock) and stock not in old_wl: updatedList = True stockWPrice[stock.upper()] = s.grabSimplePrice( stock) if updatedList: self.wl_dict[author] = stockWPrice writeWatchlist(self.wl_dict) responseRet += "Watchlist instance successfully updated\n" else: responseRet += "Watchlist had no unique stock tickers to add\n" if initiatedUser and self.wl_dict.get(author) is not None: res = "" stockList = {} stockPercent = {} netPercentDAY = 0 countDay = 0 netPercentAH = 0 countAH = 0 stockWPrice = self.wl_dict.get(author) for stock in stockWPrice: pcList, perc = s.WLpc(stock) stockList[stock] = pcList netPercentDAY += perc[0] countDay += 1 if len(perc) == 1: stockPercent[stock] = perc[0] else: stockPercent[stock] = perc[1] netPercentAH += perc[1] countAH += 1 highestStock = s.checkMostMentioned(stockPercent, len(self.wl_dict[author])) for val in highestStock: res += stockList[val] if countAH > 1: totalPercent = '{:<6}{:>15}{:>2}{:>4}{:>15}'.format( 'NET: ', s.validateUporDown(round(netPercentDAY / countDay, 2)) + '%', '|', 'AH: ', s.validateUporDown(round(netPercentAH / countAH, 2)) + '%') else: totalPercent = '{:<6}{:>15}'.format( 'NET: ', s.validateUporDown(round(netPercentDAY / countDay, 2)) + '%') authorName = str(await self.bot.fetch_user(author)).split('#') await ctx.send("```" + responseRet + '------\n' + authorName[0] + "'s Watchlist\n" + '---------------------------------\n' + res + '---------------------------------\n' + totalPercent + "```")