Пример #1
0
        static void RunBid(Job job)
        {
            //Grab the total stocks the market maker owns of this stock
            int NumberOfStocksOwned = DataBaseHandler.GetCount("SELECT SUM(Quantity) FROM Inventories WHERE UserID = " + clientID + " AND StockName = '" + job.bidAndOffer.StockName + "'");
            //Count how many of these the market maker is already selling
            int AlreadySelling = DataBaseHandler.GetCount("SELECT COUNT(Quantity) FROM Pool WHERE Type = 1 AND User = "******" AND StockName = '" + job.bidAndOffer.StockName + "'");
            //Calculate the total stock available for the market maker to sell
            int StocksAvailable = NumberOfStocksOwned - AlreadySelling;

            //If it has more stock available than needed to complete the job
            if (job.Quanity <= StocksAvailable)
            {
                BidsAndOffers offer = new BidsAndOffers(true, DateTime.Now, job.bidAndOffer.Price, clientID, job.bidAndOffer.StockName, job.Quanity, 0);
                //Complete the trade by selling the market makers stock to this user
                TradeManager.CreateTrade(ref offer, ref job.bidAndOffer, job.Quanity, threadDataBaseHandler);
                //Remove job as it now complete
                Queue.Remove(job);
            }
            else
            {
                //Market maker does not have enough stock to currently complete this trade so it sells to job as much as it can and puts in a bid into the market to buy more
                //of the stock so that it can fully complete the job
                double Price = DataBaseHandler.GetCountDouble("SELECT SUM(CurrentPrice) FROM Stock WHERE StockName = '" + job.bidAndOffer.StockName + "'");
                DataBaseHandler.SetData(string.Format("INSERT INTO Pool (Type, Price, User, StockName, Quantity) VALUES ({0}, {1}, {2}, '{3}', {4})", (int)BidOffer.bid, Math.Round(Price, 2) + 1.5, clientID, job.bidAndOffer.StockName, job.Quanity - StocksAvailable));
                //Console.WriteLine(job.Quanity - StocksAvailable);
                BidsAndOffers offer = new BidsAndOffers(true, DateTime.Now, job.bidAndOffer.Price, clientID, job.bidAndOffer.StockName, StocksAvailable, 0);
                TradeManager.CreateTrade(ref offer, ref job.bidAndOffer, job.Quanity - StocksAvailable, threadDataBaseHandler);
            }
        }
Пример #2
0
 void FIFO(ref BidsAndOffers Bid, ref List <BidsAndOffers> Offers)
 {
     //FIFO round simple assigns all remain bids and offers in a First in First Out approach
     Offers.OrderBy((o) => o.TimePlaced);
     for (int i = 0; i < Offers.Count; i++)
     {
         if (Bid.Quantity == 0)
         {
             break;
         }
         if (Offers[i].Quantity == 0)
         {
             continue;
         }
         if (Offers[i].Quantity > Bid.Quantity)
         {
             BidsAndOffers Offer = Offers[i];
             TradeManager.CreateTrade(ref Bid, ref Offer, Bid.Quantity, threadDataBaseHandler);
             Offers[i] = Offer;
         }
         else
         {
             BidsAndOffers Offer = Offers[i];
             TradeManager.CreateTrade(ref Bid, ref Offer, Offer.Quantity, threadDataBaseHandler);
             Offers[i] = Offer;
         }
     }
 }
Пример #3
0
 private void LMMRound(ref BidsAndOffers Bid, ref List <BidsAndOffers> Offers)
 {
     //In the LLM round we assign a selection of all bids at the price level to lead market makers, this help market makers complete orders faster
     for (int i = 0; i < Offers.Count; i++)
     {
         //Select their LMM percentage from DB
         MySqlDataReader r             = threadDataBaseHandler.GetData("SELECT LMM FROM Users WHERE ID = " + Offers[i].User);
         double          LMMPercentage = 0;
         while (r.Read())
         {
             LMMPercentage = (double)r["LMM"];
         }
         //Check if they have a percentage
         if (LMMPercentage > 0f)
         {
             int LMMAmount = (int)(Bid.Quantity * LMMPercentage);
             if (LMMAmount > 0)
             {
                 //If there percentage is more than avilable we clamp it to max
                 if (LMMAmount > Offers[i].Quantity)
                 {
                     BidsAndOffers Offer = Offers[i];
                     TradeManager.CreateTrade(ref Bid, ref Offer, Offer.Quantity, threadDataBaseHandler);
                     Offers[i] = Offer;
                 }
                 else
                 {
                     BidsAndOffers Offer = Offers[i];
                     TradeManager.CreateTrade(ref Bid, ref Offer, LMMAmount, threadDataBaseHandler);
                     Offers[i] = Offer;
                 }
             }
         }
     }
 }
Пример #4
0
        public static void RemoveFromPool(BidsAndOffers Trade, ThreadDataBaseHandler threadDataBaseHandler)
        {
            //When a bid or offer is ready to be removed it passed to this method which removes it from DB
            string command = string.Format("DELETE FROM Pool WHERE Type = {0} AND TimePlaced = '{1}' AND Price = {2} AND User = {3} AND StockName = '{4}'", Trade.Type, Trade.TimePlaced.ToString("yyyy-MM-dd HH:mm:ss"), Trade.Price, Trade.User, Trade.StockName);

            threadDataBaseHandler.SetData(command);
            threadDataBaseHandler.CloseCon();
        }
Пример #5
0
        static void RunOfffer(Job job)
        {
            //Purchase the stocks that this job is selling to complete the job
            BidsAndOffers bid = new BidsAndOffers(false, DateTime.Now, job.bidAndOffer.Price, clientID, job.bidAndOffer.StockName, job.Quanity, 0);

            TradeManager.CreateTrade(ref job.bidAndOffer, ref bid, job.Quanity, threadDataBaseHandler);
            //Remove job from queue as it is now complete
            Queue.Remove(job);
        }
Пример #6
0
        public static void CreateTrade(ref BidsAndOffers Bid, ref BidsAndOffers Offer, int Quantity, ThreadDataBaseHandler threadDataBaseHandler)
        {
            //Get the total quantity that the user can sell
            int StockAvailable = threadDataBaseHandler.GetCount(string.Format("SELECT COUNT(Quantity) FROM Inventories WHERE StockName = '{0}' AND UserID = {1}", Offer.StockName, Offer.User));

            if (Quantity > StockAvailable)
            {
                //If the quantity if the sale is greater than that the user can offer limit to the max amount the user could sell
                Quantity = StockAvailable;
            }
            //If the Quantity is not greater than one we can skip trade creation
            if (Quantity > 0)
            {
                //Checking to see if the bid user has an entry in the iventory table
                if (threadDataBaseHandler.GetCount("SELECT COUNT(UserID) FROM Inventories WHERE UserID = " + Bid.User + " AND StockName = '" + Bid.StockName + "'") == 0)
                {
                    //If not then an entry for the bid user for this stock is inserted into inventories
                    threadDataBaseHandler.SetData(string.Format("INSERT INTO Inventories(UserID, StockName, Quantity, LastTradedPrice) VALUES({0}, '{1}', {2}, {3})", Bid.User, Bid.StockName, 0, 0));
                }
                //Update the database reflect the new trade
                threadDataBaseHandler.SetData(string.Format("INSERT INTO Trades(StockName, BuyerID, SellerID, Price, Quantity) VALUES('{0}', {1}, {2}, {3}, {4})", Bid.StockName, Bid.User, Offer.User, Offer.Price, Quantity));
                threadDataBaseHandler.SetData(string.Format("UPDATE Inventories set LastTradedPrice = {0}, Quantity = Quantity - {1} WHERE StockName = '{2}' AND UserID = {3}", Offer.Price, Quantity, Offer.StockName, Offer.User));
                threadDataBaseHandler.SetData(string.Format("UPDATE Inventories set LastTradedPrice = {0}, Quantity = Quantity + {1} WHERE StockName = '{2}' AND UserID = {3}", Offer.Price, Quantity, Offer.StockName, Bid.User));
                threadDataBaseHandler.SetData(string.Format("UPDATE Stock SET VolumeTraded = VolumeTraded + {0} WHERE StockName = '{1}'", Quantity, Offer.StockName));
                threadDataBaseHandler.SetData(string.Format("UPDATE Users SET Balance = Balance + {0} WHERE ID = {1}", Offer.Price * Quantity, Offer.User));
                threadDataBaseHandler.SetData(string.Format("UPDATE Users SET Balance = Balance - {0} WHERE ID = {1}", Offer.Price * Quantity, Bid.User));
            }
            else if (Quantity < 0)
            {
                throw new Exception("Error with trade, quantity is less than 0");
            }
            //Checking if trade went ahead
            if (Quantity != 0)
            {
                //If it did then we are updating are local version of the bids and offfers in the server pool
                //This allows the matchmaking algorythim to continue without having to grab the new trade data
                //from the database
                Bid.Quantity   -= Quantity;
                Offer.Quantity -= Quantity;
                //Update database to reflect new trade
                threadDataBaseHandler.SetData(string.Format("Update Pool set Quantity = {0} WHERE Type = {1} AND TimePlaced = '{2}' AND Price = {3} AND User = {4} AND StockName = '{5}'", Bid.Quantity, Bid.Type, Bid.TimePlaced.ToString("yyyy-MM-dd HH:mm:ss"), Bid.Price, Bid.User, Bid.StockName));
                threadDataBaseHandler.SetData(string.Format("Update Pool set Quantity = {0} WHERE Type = {1} AND TimePlaced = '{2}' AND Price = {3} AND User = {4} AND StockName = '{5}'", Offer.Quantity, Offer.Type, Offer.TimePlaced.ToString("yyyy-MM-dd HH:mm:ss"), Offer.Price, Offer.User, Offer.StockName));
            }
            else
            {
                //If they couldn't supply any stock to sell then set the offer quantity to be zero
                Offer.Quantity = 0;
            }
            //Close the connection to the DB so that DB connection thread can be open for the next thread
            threadDataBaseHandler.CloseCon();
        }
Пример #7
0
        void ProRataWithLMM(ref BidsAndOffers Bid, ref List <BidsAndOffers> Offers, int ProRataMinimumAllocation)
        {
            //This round assigns offer quantities in relation to the size of the pool
            int TotalQuanityOfOffers = 0;
            int BidQuanity           = Bid.Quantity;

            foreach (BidsAndOffers o in Offers)
            {
                TotalQuanityOfOffers += o.Quantity;
            }
            for (int i = 0; i < Offers.Count; i++)
            {
                double ProRata = 0;
                if (Offers[i].Quantity != 0)
                {
                    //This equation gives us the percentage of the total quantity of offer this offer is
                    ProRata = (double)Offers[i].Quantity / (double)TotalQuanityOfOffers;
                }
                int ProRataAmount = (int)(ProRata * BidQuanity);
                //This stop there being a lower amount of stock moved if small value
                //Could increase this value to stop small trades of only 1 stock ect being assigned
                if (ProRataAmount >= ProRataMinimumAllocation)
                {
                    if (ProRataAmount > Offers[i].Quantity)
                    {
                        BidsAndOffers Offer = Offers[i];
                        TradeManager.CreateTrade(ref Bid, ref Offer, Offer.Quantity, threadDataBaseHandler);
                        Offers[i] = Offer;
                    }
                    else
                    {
                        BidsAndOffers Offer = Offers[i];
                        TradeManager.CreateTrade(ref Bid, ref Offer, ProRataAmount, threadDataBaseHandler);
                        Offers[i] = Offer;
                    }
                }
            }
        }
Пример #8
0
 //This is called by pool and it simply creates a new instance of Job class
 //which takes the bid / offer which has been taken from the DB to be completed
 //by the market maker as it had been in the pool too long.
 //This instance of Job is then added to Queue
 public static void AddJob(BidsAndOffers bidAndOffer)
 {
     Queue.Add(new Job((JobType)Convert.ToInt32(bidAndOffer.Type), bidAndOffer));
 }
Пример #9
0
 public Job(JobType jobType, BidsAndOffers bidAndOffer)
 {
     this.jobType     = jobType;
     this.bidAndOffer = bidAndOffer;
 }
Пример #10
0
        public async void RunMatchMaker(string s, int ThreadCounter)
        {
            //Store DB connection class from array in Pool in order to not overload the server with conncetions
            threadDataBaseHandler = Pool.DataBaseHandlers[ThreadCounter];
            //Get the Pricelevels of bids for the assigned stock from DB
            MySqlDataReader BidPoolReader  = threadDataBaseHandler.GetData("SELECT DISTINCT Price FROM Pool WHERE Type = 0 AND StockName = '" + s + "' ORDER BY Price ASC");
            List <double>   BidPriceLevels = new List <double>();

            while (BidPoolReader.Read())
            {
                //Read redsults from DB
                BidPriceLevels.Add((double)BidPoolReader["Price"]);
            }
            if (BidPriceLevels.Count == 0)
            {
                return;
            }
            //Get the Pricelevels of offers for the assigned stock from DB
            MySqlDataReader OfferPoolReader  = threadDataBaseHandler.GetData("SELECT DISTINCT Price FROM Pool WHERE Type = 1 AND StockName = '" + s + "' ORDER BY Price DESC");
            List <double>   OfferPriceLevels = new List <double>();

            while (OfferPoolReader.Read())
            {
                //Read redsults from DB
                OfferPriceLevels.Add((double)OfferPoolReader["Price"]);
            }
            if (OfferPriceLevels.Count == 0)
            {
                return;
            }
            //Close connection with DB
            threadDataBaseHandler.CloseCon();
            foreach (double BidPrice in BidPriceLevels)
            {
                for (int i = 0; i < OfferPriceLevels.Count; i++)
                {
                    //Cycle through the bid price levels with every offer price level to find offers which are lower than that of the bid price level
                    if (OfferPriceLevels[i] <= BidPrice)
                    {
                        //if this is the case then lets grab all the bids at this level to be able to assign with offers at this price level
                        MySqlDataReader      BidReader = threadDataBaseHandler.GetData("SELECT * FROM Pool WHERE Type = 0 AND StockName = '" + s + "' AND Price = " + BidPrice);
                        List <BidsAndOffers> bids      = new List <BidsAndOffers>();
                        while (BidReader.Read())
                        {
                            //These are commented out as they are used for debugging
                            //Console.WriteLine(BidReader["Type"].GetType());
                            //Console.WriteLine(BidReader["TimePlaced"].GetType());
                            //Console.WriteLine(BidReader["Price"].GetType());
                            //Console.WriteLine(BidReader["User"].GetType());
                            //Console.WriteLine(BidReader["StockName"].GetType());
                            //Console.WriteLine(BidReader["Quantity"].GetType());
                            //Console.WriteLine(BidReader["TurnsInPool"].GetType());
                            bids.Add(new BidsAndOffers((bool)BidReader["Type"], (DateTime)BidReader["TimePlaced"], (double)BidReader["Price"], (int)BidReader["User"], (string)BidReader["StockName"], (int)BidReader["Quantity"], (int)BidReader["TurnsInPool"]));
                        }
                        //Grab the offers at this price level for assignment
                        MySqlDataReader      OfferReader = threadDataBaseHandler.GetData("SELECT * FROM Pool WHERE Type = 1 AND StockName = '" + s + "' AND Price = " + OfferPriceLevels[i]);
                        List <BidsAndOffers> offers      = new List <BidsAndOffers>();
                        while (OfferReader.Read())
                        {
                            offers.Add(new BidsAndOffers((bool)OfferReader["Type"], (DateTime)OfferReader["TimePlaced"], (double)OfferReader["Price"], (int)OfferReader["User"], (string)OfferReader["StockName"], (int)OfferReader["Quantity"], (int)OfferReader["TurnsInPool"]));
                        }
                        //While there is atleast one offer and one bid available at this price range we allocate them
                        while (bids.Count != 0 && offers.Count != 0)
                        {
                            BidsAndOffers b = bids[0];
                            LMMRound(ref b, ref offers);
                            #region Cleaner
                            foreach (BidsAndOffers o in offers)
                            {
                                if (o.Quantity <= 0)
                                {
                                    TradeManager.RemoveFromPool(o, threadDataBaseHandler);
                                }
                            }
                            offers.RemoveAll((o) => o.Quantity <= 0);
                            bids[0] = b;
                            if (bids[0].Quantity <= 0)
                            {
                                TradeManager.RemoveFromPool(bids[0], threadDataBaseHandler);
                                bids.RemoveAt(0);
                                continue;
                            }
                            #endregion
                            ProRataWithLMM(ref b, ref offers, 5);
                            #region Cleaner
                            foreach (BidsAndOffers o in offers)
                            {
                                if (o.Quantity <= 0)
                                {
                                    TradeManager.RemoveFromPool(o, threadDataBaseHandler);
                                }
                            }
                            offers.RemoveAll((o) => o.Quantity <= 0);
                            bids[0] = b;
                            if (bids[0].Quantity <= 0)
                            {
                                TradeManager.RemoveFromPool(bids[0], threadDataBaseHandler);
                                bids.RemoveAt(0);
                                continue;
                            }
                            #endregion
                            FIFO(ref b, ref offers);
                            #region Cleaner
                            foreach (BidsAndOffers o in offers)
                            {
                                if (o.Quantity <= 0)
                                {
                                    TradeManager.RemoveFromPool(o, threadDataBaseHandler);
                                }
                            }
                            offers.RemoveAll((o) => o.Quantity <= 0);
                            bids[0] = b;
                            if (bids[0].Quantity <= 0)
                            {
                                TradeManager.RemoveFromPool(bids[0], threadDataBaseHandler);
                                bids.RemoveAt(0);
                                continue;
                            }
                            #endregion
                        }
                    }
                }
            }
            threadDataBaseHandler.CloseCon();
        }