//This class now stores the information need for the stance and is called every turn to check it vs its conditions for success and failure
            public MarketStance(Stance s, int Quanity, int ClientID, string TargetStock, AlgoTrader owner, ThreadDataBaseHandler threadDataBaseHandler)
            {
                this.threadDataBaseHandler = threadDataBaseHandler;
                stance           = s;
                Owner            = owner;
                client           = ClientID;
                this.TargetStock = TargetStock;
                StartTime        = DateTime.Now;
                double CurrentPrice = threadDataBaseHandler.GetCountDouble("SELECT SUM(CurrentPrice) FROM Stock WHERE StockName = '" + this.TargetStock + "'");

                CurrentPrice = Math.Round(CurrentPrice, 2);
                switch (stance)
                {
                case Stance.ShortTermLong:
                    //For a long the trader believes the market will go up so success price if above current price
                    this.Quanity = Quanity;
                    SuccessPrice = CurrentPrice + 0.02f;
                    FailurePrice = CurrentPrice - 0.01f;
                    RequiredTime = 5;
                    ShortTermLong(Quanity, CurrentPrice);
                    break;

                case Stance.ShortTermShort:
                    //For a short the trader believes the market will go doen so success price if below current price
                    this.Quanity = Quanity;
                    SuccessPrice = CurrentPrice - 0.02f;
                    FailurePrice = CurrentPrice + 0.01f;
                    RequiredTime = 5;
                    ShortTermShort(Quanity, CurrentPrice);
                    break;
                }
                //Close DB thread for other parts of the program to be free to connect to DB
                threadDataBaseHandler.CloseCon();
            }
        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();
        }
        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();
        }
Exemple #4
0
        private static void BasicTraders()
        {
            List <Trader> Traders = new List <Trader>();
            //Grab the basic traders from the DB
            MySqlDataReader reader = threadDataBaseHandler.GetData("SELECT * FROM UserAlgoTraders");

            //Load them into instance of the local class so that we can evaluate them
            while (reader.Read())
            {
                Trader trader = new Trader();
                trader.TraderID         = (int)reader["ID"];
                trader.OwnerId          = (int)reader["OwnerID"];
                trader.Trigger          = new Trigger();
                trader.Trigger.Target   = (string)reader["TTarget"];
                trader.Trigger.Operator = (MathOperator)((int)reader["TOperator"]);
                trader.Trigger.Value    = (double)reader["TValue"];
                trader.action           = new Action();
                trader.action.Target    = (string)reader["ATarget"];
                trader.action.BuyOrSell = (BuySell)((int)reader["ABuyOrSell"]);
                trader.action.Quantity  = (int)reader["AQuantity"];
                Traders.Add(trader);
            }
            List <Trader> TradersToDelete = new List <Trader>();

            //Now for all of the basic traders stored locally we now evaulute against it condition
            foreach (Trader trader in Traders)
            {
                string          TargetName      = "";
                MySqlDataReader mySqlDataReader = threadDataBaseHandler.GetData("SELECT StockName From stock WHERE FullName = '" + trader.action.Target + "'");
                while (mySqlDataReader.Read())
                {
                    TargetName = (string)mySqlDataReader["StockName"];
                }
                string TriggerName = "";
                mySqlDataReader = threadDataBaseHandler.GetData("SELECT StockName From stock WHERE FullName = '" + trader.Trigger.Target + "'");
                while (mySqlDataReader.Read())
                {
                    TriggerName = (string)mySqlDataReader["StockName"];
                }
                bool   TriggersSuccesful = true;
                double CurrentPrice      = threadDataBaseHandler.GetCountDouble("SELECT SUM(CurrentPrice) FROM Stock WHERE StockName = '" + TriggerName + "'");
                if (trader.Trigger.Operator == MathOperator.Greater)
                {
                    if (!(trader.Trigger.Value < CurrentPrice))
                    {
                        TriggersSuccesful = false;
                    }
                }
                else
                {
                    if (!(trader.Trigger.Value > CurrentPrice))
                    {
                        TriggersSuccesful = false;
                    }
                }
                //If the condition is met we now excute position set by the user
                if (TriggersSuccesful)
                {
                    CurrentPrice = threadDataBaseHandler.GetCountDouble("SELECT SUM(CurrentPrice) FROM Stock WHERE StockName = '" + TargetName + "'");
                    threadDataBaseHandler.SetData(string.Format("INSERT INTO Pool(Type, Price, User, StockName, Quantity) VALUES({0}, {1}, {2}, '{3}', {4})", (int)trader.action.BuyOrSell, CurrentPrice, trader.OwnerId, TargetName, trader.action.Quantity));
                    threadDataBaseHandler.SetData("DELETE FROM AlgoTrader WHERE ID = " + trader.TraderID);
                    //Add to traders to be delete as the basic trader is now complete
                    TradersToDelete.Add(trader);
                }
            }
            foreach (Trader t in TradersToDelete)
            {
                Traders.Remove(t);
            }
            TradersToDelete.Clear();
            //Close the DB thread to free it up for other parts of the program to use
            threadDataBaseHandler.CloseCon();
        }
        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();
        }