public async Task ProcessPotentialFlipps(CancellationToken cancleToken) { try { await TryLoadFromCache(); using (var context = new HypixelContext()) { var batchSize = 5; if (PotetialFlipps.Count > 200) { batchSize = 10; } if (PotetialFlipps.Count > 400) { batchSize = 20; } for (int i = 0; i < batchSize; i++) { if (cancleToken.IsCancellationRequested) { return; } SaveAuction auction; if (GetAuctionToCheckFlipability(out auction)) { await NewAuction(auction, context); } } } } catch (Exception e) { dev.Logger.Instance.Error($"Flipper threw an exception {e.Message} {e.StackTrace}"); } }
private static IQueryable <SaveAuction> GetSelect( SaveAuction auction, HypixelContext context, string clearedName, int itemId, DateTime youngest, int matchingCount, Enchantment ulti, List <Enchantment.EnchantmentType> highLvlEnchantList, DateTime oldest, ItemReferences.Reforge reforge, int limit = 60) { var select = context.Auctions .Where(a => a.ItemId == itemId) .Where(a => a.HighestBidAmount > 0) .Where(a => a.Tier == auction.Tier); byte ultiLevel = 127; Enchantment.EnchantmentType ultiType = Enchantment.EnchantmentType.unknown; if (ulti != null) { ultiLevel = ulti.Level; ultiType = ulti.Type; } if (relevantReforges.Contains(reforge)) { select = select.Where(a => a.Reforge == reforge); } if (auction.ItemName != clearedName && clearedName != null) { select = select.Where(a => EF.Functions.Like(a.ItemName, "%" + clearedName)); } else if (auction.Tag.StartsWith("PET")) { select = AddPetLvlSelect(auction, select); } else { select = select.Where(a => a.ItemName == clearedName); } if (auction.Tag == "MIDAS_STAFF" || auction.Tag == "MIDAS_SWORD") { try { var val = (long)auction.NbtData.Data["winning_bid"]; var keyId = NBT.GetLookupKey(auction.Tag); select = select.Where(a => a.NBTLookup.Where(n => n.KeyId == keyId && n.Value > val - 2_000_000 && n.Value < val + 2_000_000).Any()); oldest -= TimeSpan.FromDays(10); } catch {} } select = AddEnchantmentSubselect(auction, matchingCount, highLvlEnchantList, select, ultiLevel, ultiType); if (limit == 0) { return(select); } return(select .Where(a => a.End > oldest && a.End < youngest) //.OrderByDescending(a=>a.Id) //.Include(a => a.NbtData) .Take(limit)); }
public async Task <(List <SaveAuction>, DateTime)> GetRelevantAuctions(SaveAuction auction, HypixelContext context) { var itemData = auction.NbtData.Data; var clearedName = auction.Reforge != ItemReferences.Reforge.None ? ItemReferences.RemoveReforge(auction.ItemName) : auction.ItemName; var itemId = ItemDetails.Instance.GetItemIdForName(auction.Tag, false); var youngest = DateTime.Now; var relevantEnchants = auction.Enchantments?.Where(e => UltimateEnchants.ContainsKey(e.Type) || e.Level >= 6).ToList(); var matchingCount = relevantEnchants.Count > 2 ? relevantEnchants.Count / 2 : relevantEnchants.Count; var ulti = relevantEnchants.Where(e => UltimateEnchants.ContainsKey(e.Type)).FirstOrDefault(); var highLvlEnchantList = relevantEnchants.Where(e => !UltimateEnchants.ContainsKey(e.Type)).Select(a => a.Type).ToList(); var oldest = DateTime.Now - TimeSpan.FromHours(1); IQueryable <SaveAuction> select = GetSelect(auction, context, clearedName, itemId, youngest, matchingCount, ulti, highLvlEnchantList, oldest, auction.Reforge, 10); var relevantAuctions = await select .ToListAsync(); if (relevantAuctions.Count < 9) { // to few auctions in last hour, try a whole day oldest = DateTime.Now - TimeSpan.FromDays(1.5); relevantAuctions = await GetSelect(auction, context, clearedName, itemId, youngest, matchingCount, ulti, highLvlEnchantList, oldest, auction.Reforge) .ToListAsync(); if (relevantAuctions.Count < 50 && PotetialFlipps.Count < 2000) { // to few auctions in a day, query a week oldest = DateTime.Now - TimeSpan.FromDays(8); relevantAuctions = await GetSelect(auction, context, clearedName, itemId, youngest, matchingCount, ulti, highLvlEnchantList, oldest, auction.Reforge, 120) .ToListAsync(); if (relevantAuctions.Count < 10 && clearedName.Contains("✪")) { clearedName = clearedName.Replace("✪", "").Trim(); relevantAuctions = await GetSelect(auction, context, clearedName, itemId, youngest, matchingCount, ulti, highLvlEnchantList, oldest, auction.Reforge, 120) .ToListAsync(); } } } /* got replaced with average overall lookup * if (relevantAuctions.Count < 3 && PotetialFlipps.Count < 100) * { * oldest = DateTime.Now - TimeSpan.FromDays(25); * relevantAuctions = await GetSelect(auction, context, null, itemId, youngest, matchingCount, ulti, ultiList, highLvlEnchantList, oldest) * .ToListAsync(); * } */ return(relevantAuctions, oldest); }
public async System.Threading.Tasks.Task NewAuction(SaveAuction auction, HypixelContext context) { if (!Program.Migrated) { if (auction.UId % 20 == 0) // don't spam the log { Console.WriteLine("not yet migrated skiping flip"); } return; } if (diabled && auction.UId % 5 != 0) { return; // don't run on full cap on my dev machine :D } var price = (auction.HighestBidAmount == 0 ? auction.StartingBid : (auction.HighestBidAmount * 1.1)) / auction.Count; // if(auction.Enchantments.Count == 0 && auction.Reforge == ItemReferences.Reforge.None) // Console.WriteLine("easy item"); var(relevantAuctions, oldest) = await GetRelevantAuctions(auction, context); long medianPrice = 0; if (relevantAuctions.Count < 2) { Console.WriteLine($"Could not find enough relevant auctions for {auction.ItemName} {auction.Uuid} ({auction.Enchantments.Count} {relevantAuctions.Count})"); var itemId = ItemDetails.Instance.GetItemIdForName(auction.Tag, false); medianPrice = (long)(await ItemPrices.GetLookupForToday(itemId)).Prices.Average(p => p.Avg * 0.8 + p.Min * 0.2); } else { medianPrice = relevantAuctions .OrderByDescending(a => a.HighestBidAmount) .Select(a => a.HighestBidAmount / a.Count) .Skip(relevantAuctions.Count / 2) .FirstOrDefault(); } var recomendedBuyUnder = medianPrice * 0.8; if (price > recomendedBuyUnder) // at least 20% profit { return; // not a good flip } relevantAuctionIds[auction.UId] = relevantAuctions.Select(a => a.UId == 0 ? AuctionService.Instance.GetId(a.Uuid) : a.UId).ToList(); if (relevantAuctionIds.Count > 10000) { relevantAuctionIds.Clear(); } var query = new ActiveItemSearchQuery() { Order = SortOrder.LOWEST_PRICE, Limit = 1, Filter = new Dictionary <string, string>() { { "Bin", "true" } }, name = auction.Tag }; var lowestBin = Server.ExecuteCommandWithCache <ActiveItemSearchQuery, List <ItemPrices.AuctionPreview> >("activeAuctions", query); var flip = new FlipInstance() { MedianPrice = (int)medianPrice, Name = auction.ItemName, Uuid = auction.Uuid, LastKnownCost = (int)price, Volume = (float)(relevantAuctions.Count / (DateTime.Now - oldest).TotalDays), Tag = auction.Tag, Bin = auction.Bin, UId = auction.UId, SellerName = await PlayerSearch.Instance.GetNameWithCacheAsync(auction.AuctioneerId), LowestBin = (await lowestBin).FirstOrDefault()?.Price }; FlippFound(flip); if (auction.Uuid[0] == 'a') // reduce saves { await CacheService.Instance.SaveInRedis(FoundFlippsKey, Flipps); } }