From 883f84f569d180fea51271980ab8c7a6660eff9f Mon Sep 17 00:00:00 2001 From: NikolajDanger Date: Sun, 18 Apr 2021 14:06:39 +0200 Subject: [PATCH] :moneybag: Invest --- funcs/games/invest.py | 297 +++++++++++++++++++++++++++---------- resources/longStrings.json | 4 +- 2 files changed, 220 insertions(+), 81 deletions(-) diff --git a/funcs/games/invest.py b/funcs/games/invest.py index 75bb33a..2501353 100644 --- a/funcs/games/invest.py +++ b/funcs/games/invest.py @@ -1,111 +1,243 @@ -import discord +""" +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): + 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.finnhubClient.quote(symbol.upper()) if res == {}: return 0 else: return int(res["c"] * 100) - def getPortfolio(self, user : str): - userInvestments = self.bot.database["investments"].find_one({"_id":user}) + def getPortfolio(self, user: str): + """ + Get the stock portfolio of a user. - if userInvestments in [None,{}]: - return f"{self.bot.databaseFuncs.getName(user)} does not have a stock portfolio." + *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}) + + userName = self.bot.databaseFuncs.getName(user) + + if userInvestments in [None, {}]: + return f"{userName} does not have a stock portfolio." else: - portfolio = f"**Stock portfolio for {self.bot.databaseFuncs.getName(user)}**" + portfolio = f"**Stock portfolio for {userName}**" for key, value in list(userInvestments["investments"].items()): purchaseValue = value["purchased for"] - currentValue = int((self.getPrice(key) / value["value at purchase"]) * value["purchased"]) - if purchaseValue == "?": - portfolio += f"\n**{key}**: ___{str(currentValue)} GwendoBucks___" - else: - portfolio += f"\n**{key}**: ___{str(currentValue)} GwendoBucks___ (purchased for {str(purchaseValue)})" + 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): - if buyAmount >= 100: - if self.bot.money.checkBalance(user) >= buyAmount: - stockPrice = self.getPrice(stock) - if stockPrice > 0: - userInvestments = self.bot.database["investments"].find_one({"_id":user}) + def buyStock(self, user: str, stock: str, buyAmount: int): + """ + Buy an amount of a specific stock. - self.bot.money.addMoney(user,-1*buyAmount) - stock = stock.upper() + *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. - if userInvestments != None: - userInvestments = userInvestments["investments"] - if stock in userInvestments: - value = userInvestments[stock] - newAmount = int((stockPrice / value["value at purchase"]) * value["purchased"]) + buyAmount - - self.bot.database["investments"].update_one({"_id":user}, - {"$set":{"investments."+stock+".value at purchase" : stockPrice}}) - - self.bot.database["investments"].update_one({"_id":user}, - {"$set":{"investments."+stock+".purchased" : newAmount}}) - - if value["purchased for"] != "?": - self.bot.database["investments"].update_one({"_id":user}, - {"$set":{"investments."+stock+".purchased for" : buyAmount}}) - else: - self.bot.database["investments"].update_one({"_id":user}, - {"$set":{"investments."+stock : {"purchased" : buyAmount, "value at purchase" : stockPrice, - "purchased for" : buyAmount}}}) - else: - newUser = {"_id":user,"investments":{stock : {"purchased" : buyAmount, "value at purchase" : stockPrice, "purchased for" : buyAmount}}} - self.bot.database["investments"].insert_one(newUser) - - return f"{self.bot.databaseFuncs.getName(user)} bought {buyAmount} GwendoBucks worth of {stock} stock" - else: - return f"{stock} is not traded on the american market." - else: - return "You don't have enough money for that" - else: + *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}) - def sellStock(self, user : str, stock : str, sellAmount : int): - if sellAmount > 0: + self.bot.money.addMoney(user, -1*buyAmount) + stock = stock.upper() - userInvestments = self.bot.database["investments"].find_one({"_id":user})["investments"] + 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) + + userName = self.bot.databaseFuncs.getName(user) + sendMessage = "{} bought {} GwendoBucks worth of {} stock" + sendMessage = sendMessage.format(userName, 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 != None and stock in userInvestments: + if userInvestments is not None and stock in userInvestments: value = userInvestments[stock] stockPrice = self.getPrice(stock) - self.bot.database["investments"].update_one({"_id":user}, - {"$set":{"investments."+stock+".purchased" : - int((stockPrice / value["value at purchase"]) * value["purchased"])}}) - self.bot.database["investments"].update_one({"_id":user}, - {"$set":{"investments."+stock+".value at purchase" : stockPrice}}) + 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) + self.bot.money.addMoney(user, sellAmount) if sellAmount < value["purchased"]: - self.bot.database["investments"].update_one({"_id":user}, - {"$inc":{"investments."+stock+".purchased" : -sellAmount}}) + purchasedPath = f"investments.{stock}.purchased" + updater = {"$inc": {purchasedPath: -sellAmount}} + investmentsDatabase.update_one({"_id": user}, updater) - self.bot.database["investments"].update_one({"_id":user}, - {"$set":{"investments."+stock+".purchased for" : "?"}}) + purchasedForPath = f"investments.{stock}.purchased for" + updater = {"$set": {purchasedForPath: "?"}} + investmentsDatabase.update_one({"_id": user}, updater) else: - self.bot.database["investments"].update_one({"_id":user}, - {"$unset":{"investments."+stock:""}}) + updater = {"$unset": {f"investments.{stock}": ""}} + investmentsDatabase.update_one({"_id": user}, updater) - return f"{self.bot.databaseFuncs.getName(user)} sold {sellAmount} GwendoBucks worth of {stock} stock" + userName = self.bot.databaseFuncs.getName(user) + sendMessage = "{} sold {} GwendoBucks worth of {} stock" + return sendMessage.format(userName, 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" - else: - return "no" - async def parseInvest(self, ctx, parameters): + 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}" @@ -116,34 +248,39 @@ class Invest(): else: price = self.getPrice(commands[1]) if price == 0: - response = f"{commands[1].upper()} is not traded on the american market." + response = "{} is not traded on the american market." + response = response.format(commands[0].upper()) else: - price = f"{price:,}".replace(",",".") - response = f"The current {commands[1].upper()} stock is valued at **{price}** GwendoBucks" + price = f"{price:,}".replace(",", ".") + response = self.bot.longStrings["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])) + response = self.buyStock(user, commands[1], int(commands[2])) else: - response = "You must give both a stock name and an amount of gwendobucks you wish to spend." + response = self.bot.longStrings["Stock parameters"] elif parameters.startswith("sell"): commands = parameters.split(" ") if len(commands) == 3: - try: - response = self.sellStock(user,commands[1],int(commands[2])) - except: - response = "The command must be given as \"/invest sell [stock] [amount of GwendoBucks to sell stocks for]\"" + response = self.sellStock(user, commands[1], int(commands[2])) else: - response = "You must give both a stock name and an amount of GwendoBucks you wish to sell stocks for." + response = self.bot.longStrings["Stock parameters"] else: response = "Incorrect parameters" if response.startswith("**"): responses = response.split("\n") - em = discord.Embed(title=responses[0],description="\n".join(responses[1:]),colour=0x00FF00) + 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) diff --git a/resources/longStrings.json b/resources/longStrings.json index 1458e3d..d1e1a0e 100644 --- a/resources/longStrings.json +++ b/resources/longStrings.json @@ -8,5 +8,7 @@ "Blackjack different cards": "You can only split if your cards have the same value", "Blackjack split": "Splitting {}'s hand into 2. Adding their original bet to the second hand. You can use \"/blackjack hit/stand/double 1\" and \"/blackjack hit/stand/double 2\" to play the different hands.", "Blackjack started": "Blackjack game started. Use \"/blackjack bet [amount]\" to enter the game within the next 30 seconds.", - "Blackjack going on": "There's already a blackjack game going on. Try again in a few minutes." + "Blackjack going on": "There's already a blackjack game going on. Try again in a few minutes.", + "Stock value": "The current {} stock is valued at **{}** GwendoBucks", + "Stock parameters": "You must give both a stock name and an amount of GwendoBucks you wish to spend." } \ No newline at end of file