public void HoldAuctions() { BidLedger.Clear(); AskLedger.Clear(); MarketHistoryRecord record = new MarketHistoryRecord(); List <float> clearingPrices = new List <float>(); //clearing prices in the current round foreach (AgentEntity agent in Agents) { agent.NumberOfAuctions++; if (agent.Inventory[Resource.Type].MakeOffer == true && agent.Inventory[Resource.Type].Offer != null) { if (agent.Inventory[Resource.Type].Action == InventoryItem.ActionType.buy) { if (agent.Inventory[Resource.Type].Offer.Amount > 0 && agent.Inventory[Resource.Type].Offer.TotalPrice < agent.Currency) { BidLedger.Add(agent); } } else if (agent.Inventory[Resource.Type].Action == InventoryItem.ActionType.sell) { if (agent.Inventory[Resource.Type].Offer.Amount > 0) { AskLedger.Add(agent); } } } else { agent.RoundsWithoutTrading++; } } if (Town.Inventory[Resource.Type].MakeOffer == true) { BidLedger.Add(Town); } BidLedger.Shuffle(); AskLedger.Shuffle(); BidLedger = BidLedger.OrderByDescending(agent => agent.Inventory[Resource.Type].Offer.Price).ToList(); AskLedger = AskLedger.OrderBy(agent => agent.Inventory[Resource.Type].Offer.Price).ToList(); record.NumberOfAsks = AskLedger.Count(); record.NumberOfBids = BidLedger.Count(); record.Demand = (int)BidLedger.Sum(x => x.Inventory[Resource.Type].Offer.Amount); record.Supply = (int)AskLedger.Sum(x => x.Inventory[Resource.Type].Offer.Amount); if (BidLedger.Count > 0 && AskLedger.Count > 0) { LastRoundTraded = TimeUtil.Rounds; } while (BidLedger.Count > 0 && AskLedger.Count > 0) { float quantityTraded = Math.Min(BidLedger[0].Inventory[Resource.Type].Offer.Amount, AskLedger[0].Inventory[Resource.Type].Offer.Amount); float clearingPrice = (float)Math.Ceiling((BidLedger[0].Inventory[Resource.Type].Offer.Price + AskLedger[0].Inventory[Resource.Type].Offer.Price) / 2); if (quantityTraded > 0) { BidLedger[0].Inventory[Resource.Type].Offer.Amount -= quantityTraded; AskLedger[0].Inventory[Resource.Type].Offer.Amount -= quantityTraded; BidLedger[0].Inventory[Resource.Type].Amount += quantityTraded; AskLedger[0].Inventory[Resource.Type].Amount -= quantityTraded; BidLedger[0].Currency -= quantityTraded * clearingPrice; AskLedger[0].Currency += quantityTraded * clearingPrice; UpdatePriceHistory(clearingPrice); clearingPrices.Add(clearingPrice); AddTransactionRecord(new TransactionRecord(BidLedger[0], AskLedger[0], clearingPrice, quantityTraded, Resource)); BidLedger[0].UpdateBidPriceBelief(this, BidLedger[0].Inventory[Resource.Type], true); //Buyer updates price belief AskLedger[0].UpdateAskPriceBelief(this, AskLedger[0].Inventory[Resource.Type], true); //Seller updates price belief if (BidLedger[0].Inventory[Resource.Type].Offer.Amount == 0) { BidLedger.RemoveAt(0); } if (AskLedger[0].Inventory[Resource.Type].Offer.Amount == 0) { AskLedger.RemoveAt(0); } } else { Console.WriteLine("Sumtin' f****d up"); } } record.MeanClearingPrice = clearingPrices.Count() > 0 ? (float)Math.Round(clearingPrices.Sum() / clearingPrices.Count()) : 0; AddMarketHistoryRecord(record); // Go through offers left over and update their price beliefs, having been rejected foreach (Entity agent in BidLedger) { agent.UpdateBidPriceBelief(this, agent.Inventory[Resource.Type], false); } foreach (Entity agent in AskLedger) { agent.UpdateAskPriceBelief(this, agent.Inventory[Resource.Type], false); } // Deal with supply/demand getting out of control if (TimeUtil.Rounds - LastRoundTraded > 5 || TimeUtil.Rounds == 1) { if (DemandThisRound() > 0) { if ((DemandThisRound() - SupplyThisRound()) / DemandThisRound() * 100 >= 75) // check to see how much more demand there is than supply { Town.SpawnAgent(Resource.ProducedBy); Console.WriteLine(String.Format("Round: {0}, Town: {1}; Market: {2}; Supply: {3}, Demand: {4}", TimeUtil.Rounds, Town.Name, Resource.DisplayName, Supply, Demand)); } } } }
public void HoldTownAuctions() { if (Town.Inventory[Resource.Type].MakeOffer == true) { BidLedger.Add(Town); } foreach (AgentEntity agent in Agents.Where(x => x.Inventory[Resource.Type].Action == InventoryItem.ActionType.sell)) { agent.NumberOfAuctions++; if (agent.Inventory[Resource.Type].MakeOffer == true && agent.Inventory[Resource.Type].Offer.Amount > 0) { AskLedger.Add(agent); } else { agent.RoundsWithoutTrading++; } } AskLedger.Shuffle(); AskLedger = AskLedger.OrderBy(agent => agent.Inventory[Resource.Type].Offer.Price).ToList(); while (BidLedger.Count > 0 && AskLedger.Count > 0) { float quantityTraded = Math.Min(BidLedger[0].Inventory[Resource.Type].Offer.Amount, AskLedger[0].Inventory[Resource.Type].Offer.Amount); float clearingPrice = (float)Math.Ceiling((BidLedger[0].Inventory[Resource.Type].Offer.Price + AskLedger[0].Inventory[Resource.Type].Offer.Price) / 2); if (quantityTraded > 0) { BidLedger[0].Inventory[Resource.Type].Offer.Amount -= quantityTraded; AskLedger[0].Inventory[Resource.Type].Offer.Amount -= quantityTraded; BidLedger[0].Inventory[Resource.Type].Amount += quantityTraded; AskLedger[0].Inventory[Resource.Type].Amount -= quantityTraded; BidLedger[0].Currency -= quantityTraded * clearingPrice; AskLedger[0].Currency += quantityTraded * clearingPrice; UpdatePriceHistory(clearingPrice); BidLedger[0].UpdateBidPriceBelief(this, BidLedger[0].Inventory[Resource.Type], true); //Buyer updates price belief if (BidLedger[0].Inventory[Resource.Type].Offer.Amount == 0) { BidLedger.RemoveAt(0); } if (AskLedger[0].Inventory[Resource.Type].Offer.Amount == 0) { AskLedger.RemoveAt(0); } } else { Console.WriteLine("Sumtin' f****d up"); } } // Go through offers left over and update their price beliefs, having been rejected BidLedger.Clear(); AskLedger.Clear(); }