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();
    }