""" Contains functions relating to invest commands. *Classes* --------- Invest Contains all the code for the invest commands. """ import discord # Used for embeds from discord_slash.context import SlashContext # Used for type hints class Invest(): """ Contains all the invest functions. *Methods* --------- getPrice(symbol: str) -> int getPortfolio(user: str) -> str buyStock(user: str, stock: str: buyAmount: int) -> str sellStock(user: str, stock: str, buyAmount: int) -> str parseInvest(ctx: discord_slash.context.SlashContext, parameters: str) """ def __init__(self, bot): """Initialize the class.""" self.bot = bot def getPrice(self, symbol: str): """ Get the price of a stock. *Parameters* ------------ symbol: str The symbol of the stock to get the price of. *Returns* --------- price: int The price of the stock. """ res = self.bot.finnhub_client.quote(symbol.upper()) if res == {}: return 0 else: return int(res["c"] * 100) def getPortfolio(self, user: str): """ Get the stock portfolio of a user. *Parameters* ------------ user: str The id of the user to get the portfolio of. *Returns* --------- portfolio: str The portfolio. """ investmentsDatabase = self.bot.database["investments"] userInvestments = investmentsDatabase.find_one({"_id": user}) user_name = self.bot.database_funcs.get_name(user) if userInvestments in [None, {}]: return f"{user_name} does not have a stock portfolio." else: portfolio = f"**Stock portfolio for {user_name}**" for key, value in list(userInvestments["investments"].items()): purchaseValue = value["purchased for"] stockPrice = self.getPrice(key) valueAtPurchase = value["value at purchase"] purchasedStock = value["purchased"] valueChange = (stockPrice / valueAtPurchase) currentValue = int(valueChange * purchasedStock) portfolio += f"\n**{key}**: ___{currentValue} GwendoBucks___" if purchaseValue != "?": portfolio += f" (purchased for {purchaseValue})" return portfolio def buyStock(self, user: str, stock: str, buyAmount: int): """ Buy an amount of a specific stock. *Paramaters* ------------ user: str The id of the user buying. stock: str The symbol of the stock to buy. buyAmount: int The amount of GwendoBucks to use to buy the stock. *Returns* --------- sendMessage: str The message to return to the user. """ if buyAmount < 100: return "You cannot buy stocks for less than 100 GwendoBucks" elif self.bot.money.checkBalance(user) < buyAmount: return "You don't have enough money for that" elif self.getPrice(stock) <= 0: return f"{stock} is not traded on the american market." else: investmentsDatabase = self.bot.database["investments"] stockPrice = self.getPrice(stock) userInvestments = investmentsDatabase.find_one({"_id": user}) self.bot.money.addMoney(user, -1*buyAmount) stock = stock.upper() if userInvestments is not None: userInvestments = userInvestments["investments"] if stock in userInvestments: value = userInvestments[stock] valueChange = (stockPrice / value["value at purchase"]) currentValue = int(valueChange * value["purchased"]) newAmount = currentValue + buyAmount valuePath = f"investments.{stock}.value at purchase" updater = {"$set": {valuePath: stockPrice}} investmentsDatabase.update_one({"_id": user}, updater) purchasedPath = f"investments.{stock}.purchased" updater = {"$set": {purchasedPath: newAmount}} investmentsDatabase.update_one({"_id": user}, updater) if value["purchased for"] != "?": purchasedForPath = f"investments.{stock}.purchased for" updater = {"$set": {purchasedForPath: buyAmount}} investmentsDatabase.update_one({"_id": user}, updater) else: updater = { "$set": { "investments.{stock}": { "purchased": buyAmount, "value at purchase": stockPrice, "purchased for": buyAmount } } } investmentsDatabase.update_one({"_id": user}, updater) else: newUser = { "_id": user, "investments": { stock: { "purchased": buyAmount, "value at purchase": stockPrice, "purchased for": buyAmount } } } investmentsDatabase.insert_one(newUser) user_name = self.bot.database_funcs.get_name(user) sendMessage = "{} bought {} GwendoBucks worth of {} stock" sendMessage = sendMessage.format(user_name, buyAmount, stock) return sendMessage def sellStock(self, user: str, stock: str, sellAmount: int): """ Sell an amount of a specific stock. *Paramaters* ------------ user: str The id of the user selling. stock: str The symbol of the stock to sell. buyAmount: int The amount of GwendoBucks to sell for. *Returns* --------- sendMessage: str The message to return to the user. """ if sellAmount <= 0: return "no" else: investmentsDatabase = self.bot.database["investments"] userData = investmentsDatabase.find_one({"_id": user}) userInvestments = userData["investments"] stock = stock.upper() if userInvestments is not None and stock in userInvestments: value = userInvestments[stock] stockPrice = self.getPrice(stock) priceChange = (stockPrice / value["value at purchase"]) purchasedAmount = int(priceChange * value["purchased"]) purchasedPath = f"investments.{stock}.purchased" updater = {"$set": {purchasedPath: purchasedAmount}} investmentsDatabase.update_one({"_id": user}, updater) valueAtPurchasePath = f"investments.{stock}.value at purchase" updater = {"$set": {valueAtPurchasePath: stockPrice}} investmentsDatabase.update_one({"_id": user}, updater) if value["purchased"] >= sellAmount: self.bot.money.addMoney(user, sellAmount) if sellAmount < value["purchased"]: purchasedPath = f"investments.{stock}.purchased" updater = {"$inc": {purchasedPath: -sellAmount}} investmentsDatabase.update_one({"_id": user}, updater) purchasedForPath = f"investments.{stock}.purchased for" updater = {"$set": {purchasedForPath: "?"}} investmentsDatabase.update_one({"_id": user}, updater) else: updater = {"$unset": {f"investments.{stock}": ""}} investmentsDatabase.update_one({"_id": user}, updater) user_name = self.bot.database_funcs.get_name(user) sendMessage = "{} sold {} GwendoBucks worth of {} stock" return sendMessage.format(user_name, sellAmount, stock) else: return f"You don't have enough {stock} stocks to do that" else: return f"You don't have any {stock} stock" async def parseInvest(self, ctx: SlashContext, parameters: str): """ Parse an invest command. TO BE DELETED. *Parameters* ------------ ctx: discord_slash.context.SlashContext The context of the slash command. parameters: str The parameters of the command. """ await self.bot.defer(ctx) user = f"#{ctx.author.id}" if parameters.startswith("check"): commands = parameters.split(" ") if len(commands) == 1: response = self.getPortfolio(user) else: price = self.getPrice(commands[1]) if price == 0: response = "{} is not traded on the american market." response = response.format(commands[0].upper()) else: price = f"{price:,}".replace(",", ".") response = self.bot.long_strings["Stock value"] response = response.format(commands[1].upper(), price) elif parameters.startswith("buy"): commands = parameters.split(" ") if len(commands) == 3: response = self.buyStock(user, commands[1], int(commands[2])) else: response = self.bot.long_strings["Stock parameters"] elif parameters.startswith("sell"): commands = parameters.split(" ") if len(commands) == 3: response = self.sellStock(user, commands[1], int(commands[2])) else: response = self.bot.long_strings["Stock parameters"] else: response = "Incorrect parameters" if response.startswith("**"): responses = response.split("\n") text = "\n".join(responses[1:]) embedParams = { "title": responses[0], "description": text, "colour": 0x00FF00 } em = discord.Embed(**embedParams) await ctx.send(embed=em) else: await ctx.send(response)