//This method is called from TimingManager and manages the excutions of Algorythemic Traders public static async void RunTrader() { //Get the trader ids from the database MySqlDataReader reader = threadDataBaseHandler.GetData("SELECT ID FROM AlgoTrader"); List <int> TradersInDB = new List <int>(); List <int> TradersToDelete = new List <int>(); //Checks which traders we have stored locally //if the id exists in the DB but not in this program them grab from the DB and create local version //else if if it exists in this local version but not in the DB then delete the local instance while (reader.Read()) { TradersInDB.Add((int)reader["ID"]); } for (int i = 0; i < Traders.Count; i++) { if (!TradersInDB.Contains(Traders[i].ID)) { TradersToDelete.Add(i); } } for (int i = 0; i < TradersInDB.Count; i++) { if (!Traders.Exists((t) => t.ID == TradersInDB[i])) { reader = threadDataBaseHandler.GetData("SELECT * FROM AlgoTrader WHERE ID = " + TradersInDB[i]); while (reader.Read()) { Traders.Add(new AlgorithmsTrader1(TradersInDB[i], (string)reader["Target"], (int)reader["UserId"], (double)reader["ShortRequirement"], (double)reader["LongRequirement"], (int)reader["MinAmount"], (int)reader["MaxAmount"], (double)reader["Aggresion"])); } } } while (TradersToDelete.Count > 0) { threadDataBaseHandler.SetData("DELETE FROM Users WHERE ID = " + Traders[TradersToDelete[0]].UserID); threadDataBaseHandler.SetData("UPDATE Inventories SET UserID = 1 WHERE UserID = " + Traders[TradersToDelete[0]].UserID); threadDataBaseHandler.SetData("DELETE FROM AlgoTrader WHERE ID = " + Traders[TradersToDelete[0]].ID); Traders.Remove(Traders[TradersToDelete[0]]); TradersToDelete.RemoveAt(0); } //Now we have all the correct traders stored locally we can run a turn on them foreach (AlgoTrader t in Traders) { try { t.RunTurn(); } catch { Console.WriteLine("Error with DB Connectiom, Will retry next turn"); } } //Basic traders are the ones create by the user which just excute traders if certain criteria is met BasicTraders(); TimingManager.TraderTimer.Start(); Console.WriteLine("Traders Completed"); }
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; } } } } }
/// <summary> /// Reduces the frequency of data for a stock the older the data is in order to keep the DB at a reasonable size /// </summary> static void PricingThinner(string StockName, ThreadDataBaseHandler threadDataBaseHandler) { MySqlDataReader reader = threadDataBaseHandler.GetData(string.Format("SELECT Time From PricingHistory WHERE StockName = '{0}' AND Time < '{1}' ORDER BY Time ASC", StockName, DateTime.Now.AddSeconds(-10).ToString("yyyy-MM-dd HH:mm:ss"))); List <DateTime> LastHour = new List <DateTime>(); List <DateTime> Last12Hours = new List <DateTime>(); List <DateTime> LastDay = new List <DateTime>(); List <DateTime> LastWeek = new List <DateTime>(); List <DateTime> LastMonth = new List <DateTime>(); List <DateTime> Longer = new List <DateTime>(); while (reader.Read()) { DateTime time = (DateTime)reader["Time"]; if (time > DateTime.Now.AddHours(-1)) { LastHour.Add(time); } else if (time > DateTime.Now.AddHours(-12)) { Last12Hours.Add(time); } else if (time > DateTime.Now.AddDays(-1)) { LastDay.Add(time); } else if (time > DateTime.Now.AddDays(-7)) { LastWeek.Add(time); } else if (time > DateTime.Now.AddMonths(-1)) { LastMonth.Add(time); } else { Longer.Add(time); } } //For each time period there is a set gap which entries need to be apart by. //If the gap is not the right size then the entry is removed from the DB List <DateTime> ToBeDeleted = new List <DateTime>(); DateTime last = DateTime.MinValue; for (int i = 0; i < LastHour.Count; i++) { if (i == 0) { last = LastHour[i]; continue; } if ((LastHour[i] - last).Seconds < 10) { ToBeDeleted.Add(LastHour[i]); } else { last = LastHour[i]; } } last = DateTime.MinValue; for (int i = 0; i < Last12Hours.Count; i++) { if (i == 0) { last = Last12Hours[i]; continue; } if ((Last12Hours[i] - last).Minutes < 2) { ToBeDeleted.Add(Last12Hours[i]); } else { last = Last12Hours[i]; } } last = DateTime.MinValue; for (int i = 0; i < LastDay.Count; i++) { if (i == 0) { last = LastDay[i]; continue; } if ((LastDay[i] - last).Minutes < 10) { ToBeDeleted.Add(LastDay[i]); } else { last = LastDay[i]; } } last = DateTime.MinValue; for (int i = 0; i < LastWeek.Count; i++) { if (i == 0) { last = LastWeek[i]; continue; } if ((LastWeek[i] - last).Hours < 1) { ToBeDeleted.Add(LastWeek[i]); } else { last = LastWeek[i]; } } last = DateTime.MinValue; for (int i = 0; i < LastMonth.Count; i++) { if (i == 0) { last = LastMonth[i]; continue; } if ((LastMonth[i] - last).Hours < 6) { ToBeDeleted.Add(LastMonth[i]); } else { last = LastMonth[i]; } } last = DateTime.MinValue; for (int i = 0; i < Longer.Count; i++) { if (i == 0) { last = Longer[i]; continue; } if ((Longer[i] - last).Days < 7) { ToBeDeleted.Add(Longer[i]); } else { last = Longer[i]; } } for (int i = 0; i < ToBeDeleted.Count; i++) { threadDataBaseHandler.SetData("DELETE FROM PricingHistory WHERE StockName = '" + StockName + "' AND Time = '" + ToBeDeleted[i].ToString("yyyy-MM-dd HH:mm:ss") + "'"); } }
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(); }