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