public async void Thread_ContinuousChecker() { while (true) { var count = 0; using (var context = new FantasyPortfolio_DBEntities()) { if (context.Coins.Any()) { foreach (var coin in context.Coins) { if (coin.LastUpdated <= DateTime.Now.AddMinutes(-20)) { try { await Coin.UpdateCoinValue(coin.Id); } catch (Exception ex) { Console.WriteLine($"Failed to Update {coin.TickerName} - {ex.Message}"); } count++; } if (count == 25) { Console.WriteLine($"{DateTime.Now} - Limit reached: Sleeping for a minute"); count = 0; Thread.Sleep(60000); Console.WriteLine($"{DateTime.Now} - Continuing"); } } } Thread.Sleep(120000); } } }
public async Task Share() { var sb = new StringBuilder(); var embed = new EmbedBuilder(); using (var context = new FantasyPortfolio_DBEntities()) { var userId = Context.User.Id.ToString(); var ports = context.LeaderboardTickers.Where(d => d.RoundId == Round.CurrentRound && d.UserId == userId); if (!ports.Any()) { sb.AppendLine($"You are not signed up to this round. Please ensure you have the entry fee of {EntryFee} {Preferences.BaseCurrency} and type `-join`"); embed.WithTitle("Not Signed Up"); } else { string usdValue = ""; decimal totalAmount = 0; foreach (var p in ports) { totalAmount += p.DollarValue.GetValueOrDefault(0); if (p.TickerName == "USD") { if (!p.DollarValue.HasValue || p.DollarValue == 0) { usdValue = "0.00"; } else { usdValue = p.DollarValue?.ToString("N") ?? "0.00"; } } else { if (p.DollarValue == 0) { continue; } sb.AppendLine($"**{p.TickerName}** - ${Math.Round(p.DollarValue.GetValueOrDefault(0), 2):N} ({p.CoinCount} {p.TickerName})"); } } sb.AppendLine("**USD**: $" + usdValue); sb.AppendLine(Environment.NewLine + $"Total Value: ${totalAmount:N}"); embed.Title = "Your Portfolio"; } } embed.Description = sb.ToString(); await ReplyAsync("", false, embed); }
public static EmbedBuilder GetLeaderboardEmbed() { using (var context = new FantasyPortfolio_DBEntities()) { var leaderboards = context.Leaderboards.Where(d => d.RoundId == Round.CurrentRound).OrderByDescending(d => d.totalamount); var position = 1; var sb = new StringBuilder(); if (leaderboards.Any()) { foreach (var player in leaderboards) { sb.AppendLine($"{position} - {DiscordClientNew._client.GetUser(ulong.Parse(player.UserId))?.Username ?? player.UserId} - ${player.totalamount:N}"); position++; } } else { sb.AppendLine("No players currently participating in this round"); } sb.AppendLine(Environment.NewLine); var embed = new EmbedBuilder { Title = $"{Preferences.BaseCurrency} Discord Leaderboard - Round {Round.CurrentRound}", Description = sb.ToString() }; TimeSpan span = (Round.CurrentRoundEnd - DateTime.Now); var timeRemainingStr = ""; if (span.Days > 0) { timeRemainingStr += $"{span.Days} {(span.Days > 1 ? "Days" : "Day")} "; } if (span.Hours > 0) { timeRemainingStr += $"{span.Hours} {(span.Hours > 1 ? "Hours" : "Hour")} "; } if (span.Hours < 1 && span.Minutes > 0) { timeRemainingStr += $"{span.Minutes} {(span.Minutes > 1 ? "Minutes" : "Minute")}"; } var endStr = string.IsNullOrEmpty(timeRemainingStr) ? "soon" : $"in {timeRemainingStr}"; embed.WithFooter($"Round Ends {endStr} - Grand Prize: {PrizePool} {Preferences.BaseCurrency}"); return(embed); } }
public bool CheckBalance(string amount, string ticker, out string reason) { reason = ""; var userId = Context.User.Id.ToString(); if (decimal.TryParse(amount, out var amountDec)) { using (var context = new FantasyPortfolio_DBEntities()) { int tickerId; if (ticker.ToUpper() == "USD") { tickerId = -1; } else { var coins = Coin.GetTickers(ticker); if (coins.Result.Count > 1) { var nameStrings = new List <string>(); foreach (var coin in coins.Result) { nameStrings.Add($"`{coin.TickerName}`"); } reason = $"Multiple coins in database with this ticker exist, please use the coin name instead: {string.Join(", ", nameStrings)})"; return(false); } else if (coins.Result.Count == 0) { reason = "No coin found with this ticker or name"; return(false); } else { // ReSharper disable once PossibleNullReferenceException - Not null as above tickerId = coins.Result.FirstOrDefault().TickerId; } } var value = context.Portfolios.FirstOrDefault(d => d.UserId == userId && d.TickerId == tickerId && d.RoundId == Round.CurrentRound); if (value != null && value.CoinAmount >= amountDec) { return(true); } reason = "Not enough balance"; return(false); } } reason = "Invalid input"; return(false); }
private void FantasyTimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs) { var embed = FantasyPortfolioModule.GetLeaderboardEmbed(); var winner = FantasyPortfolioModule.GetWinner(); var additionalText = ""; TimeSpan span = (Round.CurrentRoundEnd - DateTime.Now); if (Round.CurrentRoundEnd <= DateTime.Now) { Console.WriteLine($"Round {Round.CurrentRoundEnd} Finished. Winner: {winner.UserId}"); using (var context = new FantasyPortfolio_DBEntities()) { if (context.Leaderboards.Any(d => d.RoundId == Round.CurrentRound)) { if (FantasyPortfolioModule.PrizePool > 0) { additionalText = $"Congratulations <@{winner.UserId}>! You have won the fantasy portfolio and won {FantasyPortfolioModule.PrizePool} {Preferences.BaseCurrency}"; QTCommands.SendTip(_client.CurrentUser.Id, ulong.Parse(winner.UserId), FantasyPortfolioModule.PrizePool); } else { additionalText = $"Congratulations <@{winner.UserId}>! You have won the fantasy portfolio! There was no prize."; } } else { embed.WithDescription("Round has finished! There were no participants in this round, so nobody wins!"); } Round round = new Round { RoundEnds = DateTime.Now.AddDays(Round.RoundDurationDays) }; context.Rounds.Add(round); context.SaveChanges(); } } else if (span.TotalMilliseconds < fantasyTickerTimer.Interval) { //Set next interval to 5000ms after the round ends fantasyTimer.Interval = span.TotalMilliseconds + 5000; Console.WriteLine("Next fantasy interval set to 5 seconds"); } else { // Set the next interval to 2 hours fantasyTickerTimer.Interval = 7200000; Console.WriteLine("Next fantasy interval set to 2 hours"); } _client.GetGuild(Settings.Default.GuildId).GetTextChannel(Settings.Default.FantasyChannel).SendMessageAsync(additionalText, false, embed); }
public async Task Flip(string side, string amount) { if (CanRunTipCommands) { if (Enum.TryParse(side.ToLower(), out CoinSide coinSide)) { if (decimal.TryParse(amount, out var betAmount)) { if (QTCommands.CheckBalance(Context.User.Id, betAmount)) { if (betAmount < MinBetAmount) { await ReplyAsync($"Minimum bet {MinBetAmount} {Preferences.BaseCurrency}"); return; } decimal balance = 0; var houseBalanceCall = QTCommands.GetBalance(Context.Client.CurrentUser.Id).Result; decimal.TryParse(houseBalanceCall, out balance); decimal maxBet = balance / 10; if (betAmount > maxBet) { await ReplyAsync($"Maximum bet exceeded. Max: {maxBet} {Preferences.BaseCurrency}"); return; } var rewardValue = betAmount * (decimal)BetWin; if (QTCommands.CheckBalance(Context.Client.CurrentUser.Id, rewardValue + FantasyPortfolioModule.PrizePool)) { QTCommands.SendTip(Context.User.Id, Context.Client.CurrentUser.Id, betAmount); try { var coin = (CoinSide)RandomInteger(0, 2); //var coin = (CoinSide)Generator.Next(0, 2); var embed = new EmbedBuilder(); string message; if (coin == coinSide) { QTCommands.SendTip(DiscordClientNew._client.CurrentUser.Id, Context.User.Id, rewardValue); embed.AddInlineField("Flipped", FirstCharToUpper(coin.ToString())); embed.AddInlineField("Prize", $"{rewardValue} {Preferences.BaseCurrency}"); embed.AddInlineField("Profit", $"{(rewardValue - betAmount)} {Preferences.BaseCurrency}"); embed.WithColor(Discord.Color.Green); message = $"You won! Congratulations {Context.User.Mention}!"; } else { embed.AddInlineField("Flipped", FirstCharToUpper(coin.ToString())); embed.AddInlineField("Lost", $"{betAmount} {Preferences.BaseCurrency}"); embed.WithColor(Discord.Color.Red); message = $"Unlucky {Context.User.Mention}, you lost :("; } embed.WithFooter(Preferences.FooterText); await ReplyAsync(message, false, embed); using (var context = new FantasyPortfolio_DBEntities()) { var result = new FlipResults(); result.DateTime = DateTime.Now; result.UserId = Context.User.Id.ToString(); result.FlipResult = (byte)coin; result.UserFlip = (byte)coinSide; result.FlipValue = betAmount; context.FlipResults.Add(result); context.SaveChanges(); } Console.WriteLine($"{Context.User.Id} ({Context.User.Username}) bet on {side} and flipped {coin}"); } catch (Exception e) { Console.WriteLine(e.Message); QTCommands.SendTip(DiscordClientNew._client.CurrentUser.Id, Context.User.Id, betAmount); await ReplyAsync("Sorry something went wrong. You have been refunded your bet."); } } else { await ReplyAsync("Sorry, the bot is too poor to reward you if you won :("); } } else { await ReplyAsync("You do not have enough balance to perform this action"); } } } } else { await ReplyAsync($"Please use the <#{Preferences.TipBotChannel}> channel"); } }
public static Leaderboard GetWinner() { using (var context = new FantasyPortfolio_DBEntities()) { return(context.Leaderboards.FirstOrDefault(d => d.RoundId == Round.CurrentRound)); } }
public async Task Buy(string amount, string ticker) { var userId = Context.User.Id.ToString(); if (amount != "all") { if (!CheckBalance(amount, "USD", out var reason)) { await ReplyAsync($"Error Buying {ticker.ToUpper()} - {reason}"); return; } } using (var context = new FantasyPortfolio_DBEntities()) { var coins = await Coin.GetTickers(ticker); var embed = new EmbedBuilder(); if (coins.Count > 1) { embed.WithTitle("Multiple Coins Found"); foreach (var coin in coins) { embed.AddInlineField(coin.TickerName, $"${decimal.Parse(Math.Round(coin.PriceUSD, 8).ToString(), NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint)}"); } embed.WithDescription("Multiple coins found with the same ticker, please use the name below."); await ReplyAsync("", false, embed); return; } else if (coins.Count == 0) { embed.WithTitle("No coin found with this ticker"); embed.WithDescription("No coin with this ticker has been found."); await ReplyAsync("", false, embed); return; } else { var coin = coins.FirstOrDefault(); if (coin.Volume24 != null && coin.Volume24 < 50000) { embed.WithTitle("Volume is too low for this ticker"); embed.WithDescription($"Volume is too low for this ticker. Minimum volume: $50,000 (Current: ${coin.Volume24:N})"); await ReplyAsync("", false, embed); return; } if (amount == "all") { amount = context.Portfolios.FirstOrDefault(d => d.UserId == userId && d.TickerId == -1 && Round.CurrentRound == d.RoundId)?.CoinAmount.ToString(); } if (decimal.TryParse(amount, out var amountDec)) { amountDec = Math.Round(amountDec, 8); var feeAmount = amountDec * (decimal)0.005; amountDec = amountDec * (decimal)0.995; var usdAmount = context.Portfolios.FirstOrDefault(d => d.RoundId == Round.CurrentRound && d.UserId == userId && d.TickerId == -1); var usdAmount2 = usdAmount.CoinAmount; var portCoin = context.Portfolios.FirstOrDefault(d => d.RoundId == Round.CurrentRound && d.UserId == userId && d.TickerId == coin.TickerId); var roundedAmount = Math.Round(amountDec / coin.PriceUSD, 8); if (roundedAmount == 0) { await ReplyAsync("Buy failed: Amount bought would be 0."); return; } if (portCoin == null) { portCoin = new Portfolio { UserId = Context.User.Id.ToString(), TickerId = coin.TickerId, RoundId = Round.CurrentRound, CoinAmount = 0 }; context.Portfolios.Add(portCoin); } else { context.Portfolios.Attach(portCoin); } portCoin.CoinAmount += roundedAmount; if (usdAmount != null) { usdAmount.CoinAmount = usdAmount.CoinAmount - amountDec - feeAmount; } try { context.SaveChanges(); } catch (Exception e) { await ReplyAsync(e.Message + Environment.NewLine + Environment.NewLine + e.InnerException?.Message); return; } await ReplyAsync($"Successfully bought {roundedAmount} {ticker.ToUpper()}"); return; } } } await ReplyAsync("Error... Please try again."); }
public async Task Sell(string amount, string ticker) { var userId = Context.User.Id.ToString(); if (amount != "all") { if (!CheckBalance(amount, ticker, out var reason)) { await ReplyAsync($"Error Selling {ticker.ToUpper()} - {reason}"); return; } } using (var context = new FantasyPortfolio_DBEntities()) { var coins = await Coin.GetTickers(ticker); var embed = new EmbedBuilder(); if (coins.Count > 1) { embed.WithTitle("Multiple Coins Found"); foreach (var coin in coins) { embed.AddInlineField(coin.TickerName, $"${decimal.Parse(Math.Round(coin.PriceUSD, 8).ToString(), NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint)}"); } embed.WithDescription("Multiple coins found with the same ticker, please use the name below."); await ReplyAsync("", false, embed); return; } else if (coins.Count == 0) { embed.WithTitle("No coin found with this ticker"); embed.WithDescription("No coin with this ticker has been found."); await ReplyAsync("", false, embed); return; } else { var coin = coins.FirstOrDefault(); var portCoin = context.Portfolios.FirstOrDefault(d => d.RoundId == Round.CurrentRound && d.UserId == userId && d.TickerId == coin.TickerId); if (amount == "all") { amount = portCoin?.CoinAmount.ToString(); } if (decimal.TryParse(amount, out var amountDec)) { amountDec = Math.Round(amountDec, 8); var usdAmount = context.Portfolios.FirstOrDefault(d => d.RoundId == Round.CurrentRound && d.UserId == userId && d.TickerId == -1); var roundedAmount = Math.Round(amountDec * coin.PriceUSD, 8) * (decimal)0.995; if (portCoin == null) { portCoin = new Portfolio { UserId = Context.User.Id.ToString(), TickerId = coin.TickerId, RoundId = Round.CurrentRound, CoinAmount = 0 }; context.Portfolios.Add(portCoin); } else { context.Portfolios.Attach(portCoin); } portCoin.CoinAmount -= amountDec; Debug.Assert(usdAmount != null, nameof(usdAmount) + " != null"); usdAmount.CoinAmount = usdAmount.CoinAmount + roundedAmount; try { context.SaveChanges(); } catch (Exception e) { await ReplyAsync(e.Message + Environment.NewLine + Environment.NewLine + e.InnerException?.Message); return; } await ReplyAsync($"Successfully sold {amountDec} {ticker.ToUpper()}"); return; } } } await ReplyAsync("Error connecting to database... Please try again"); }
public static async Task <Embed> GetPriceEmbed(string ticker) { var tickerFormatted = ticker.ToUpper().Trim(); long?tickerId; using (var context = new FantasyPortfolio_DBEntities()) { var coin = context.Coins.FirstOrDefault(d => d.TickerName.ToUpper().Trim() == tickerFormatted); if (coin == null) { var listings = await priceClientNew.GetListingsAsync(); var listingSingle = listings.Data.FirstOrDefault(d => d.Symbol == tickerFormatted); if (listingSingle != null) { coin = new Coin { TickerId = (int)listingSingle.Id, TickerName = listingSingle.Symbol, LastUpdated = new DateTime(2000, 1, 1) }; context.Coins.Add(coin); context.SaveChanges(); } } tickerId = coin?.TickerId; } if (tickerId != null) { var tickerResponse = await priceClientNew.GetTickerAsync((int)tickerId, "BTC"); var emb = new EmbedBuilder(); emb.WithTitle($"Price of {tickerResponse.Data.Name} [{tickerFormatted}]"); var sb = new StringBuilder(); sb.AppendLine($"**Rank:** {tickerResponse.Data.Rank}"); sb.Append(Environment.NewLine); foreach (var quote in tickerResponse.Data.Quotes) { if (quote.Key == "USD") { sb.AppendLine("**Price " + quote.Key + ":** " + "$" + decimal.Parse(Math.Round(quote.Value.Price.GetValueOrDefault(0), 5).ToString(), NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint)); } else { sb.AppendLine("**Price " + quote.Key + ":** " + decimal.Parse(Math.Round(quote.Value.Price.GetValueOrDefault(0), 8).ToString(), NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent) + " " + quote.Key); } } sb.Append(Environment.NewLine); sb.AppendLine($"**Market Cap: **${tickerResponse.Data.Quotes.FirstOrDefault(d => d.Key == "USD").Value.MarketCap:n}"); sb.AppendLine($"**24h volume: **${tickerResponse.Data.Quotes.FirstOrDefault(d => d.Key == "USD").Value.Volume24H:n}"); sb.AppendLine($"**Supply: **{tickerResponse.Data.TotalSupply:n}"); sb.Append(Environment.NewLine); sb.AppendLine($"**Change 1h: **{tickerResponse.Data.Quotes.FirstOrDefault(d => d.Key == "USD").Value.PercentChange1H:n}%"); sb.AppendLine($"**Change 24h: **{tickerResponse.Data.Quotes.FirstOrDefault(d => d.Key == "USD").Value.PercentChange24H:n}%"); sb.AppendLine($"**Change 7 days: **{tickerResponse.Data.Quotes.FirstOrDefault(d => d.Key == "USD").Value.PercentChange7D:n}%"); emb.WithDescription(sb.ToString()); try { emb.WithUrl($"https://coinmarketcap.com/currencies/{tickerResponse.Data.WebsiteSlug}/"); } catch { // ignored } emb.ThumbnailUrl = $"https://s2.coinmarketcap.com/static/img/coins/32x32/{tickerId}.png"; emb.WithFooter(Preferences.FooterText); return(emb); } return(null); }