using MarketData.MarketDataModel; using MarketData.DataAccess; using MarketData.Utils; namespace MarketData.Helper { public class PricingThreadHelper : ThreadHelper { private DateTime pricingDate=DateTime.Parse("12-31-9999"); private DateTime? startDate; public PricingThreadHelper(String symbol,ManualResetEvent resetEvent) { Symbol=symbol; ResetEvent=resetEvent; } public PricingThreadHelper(String symbol, DateTime pricingDate,ManualResetEvent resetEvent) { Symbol = symbol; this.pricingDate=pricingDate; ResetEvent = resetEvent; } public PricingThreadHelper(String symbol, ManualResetEvent resetEvent,DateTime? startDate=null) { Symbol = symbol; this.pricingDate=DateTime.Now; this.startDate=startDate; ResetEvent = resetEvent; } public DateTime PricingDate { get{return pricingDate;} } public DateTime? StartDate { get{return startDate;} } } public class PricingMarketDataHelper { private static int MaxThreads = (int)ThreadHelperEnum.MaxThreads; private static int WaitBetweenRequests = 125; private List symbols; private int currentIndex = 0; public PricingMarketDataHelper() { } public static Price RollPriceForward(String symbol) { try { DateGenerator dateGenerator = new DateGenerator(); DateTime latestDate = PremarketDA.GetLatestMarketDate(); if (Utility.IsEpoch(latestDate)) return null; Price latestPrice = PricingDA.GetPrice(symbol); if (null == latestPrice) return null; DateTime latestPriceDateSymbol = latestPrice.Date; latestPrice.Date = latestDate; PricingDA.InsertPrice(latestPrice); MDTrace.WriteLine(LogLevel.DEBUG, String.Format("{0} price rolled forward from {1} to {2}", symbol, latestPriceDateSymbol.ToShortDateString(), latestDate.ToShortDateString())); return latestPrice; } catch (Exception exception) { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Exception rolling price forward for {0}. Exception was {1}", symbol, exception.ToString())); return null; } } public bool UpdateLatestPriceAll() { Profiler profiler = new Profiler(); try { symbols = PricingDA.GetSymbols(); currentIndex = 0; while (true) { List queueSymbols = GetQueueSymbols(); if (null == queueSymbols || 0 == queueSymbols.Count) break; ManualResetEvent[] resetEvents = new ManualResetEvent[queueSymbols.Count]; for (int eventIndex = 0; eventIndex < resetEvents.Length; eventIndex++) { resetEvents[eventIndex] = new ManualResetEvent(false); } for (int index = 0; index < queueSymbols.Count; index++) { PricingThreadHelper pricingThreadHelper = new PricingThreadHelper(queueSymbols[index], resetEvents[index]); ThreadPool.QueueUserWorkItem(ThreadPoolCallbackUpdateLatestPriceAll, pricingThreadHelper); try { Thread.Sleep(WaitBetweenRequests); } catch (Exception) {; } } MDTrace.WriteLine(LogLevel.DEBUG, "UpdateLatestPriceAll, waiting for queued items to complete."); WaitHandle.WaitAll(resetEvents); } return true; } finally { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("[UpdateLatestPriceAll]End, total took {0}(ms)", profiler.End())); } } // ************************************************************************************************************************************** // ************************************************************* R O B I N H O O D ****************************************************** // ************************************************************************************************************************************** /// /// Robinhood will only give us latest price. The price will have a date associated with it.. todays date. so the date provided needs to match. /// This feed works the same way as the BarChartSweep in that we will only attempt to fetch prices that are missing today for which we had prices yesterday. /// /// /// public bool UpdatePricesRobinhoodSweep(DateTime startDate) { Profiler profiler = new Profiler(); try { int maxThreads = 20; // I am tweaking these to back into a total runtime of 40 minutes for all stocks. maxThreads=10 waitBetweenRequests=500 = 86 minutes int waitBetweenRequests = 200; MDTrace.WriteLine(LogLevel.DEBUG, "[UpdatePricesRobinhoodSweep]Enter"); DateGenerator dateGenerator = new DateGenerator(); startDate = dateGenerator.GetPrevBusinessDay(startDate); // make sure we are given a valid business date DateTime requiredDate = dateGenerator.FindPrevBusinessDay(startDate); // now go and fetch yesterday (prev business day) MDTrace.WriteLine(LogLevel.DEBUG, $"[UpdatePricesRobinhoodSweep] Determining what prices we need on {startDate.ToShortDateString()} by examing what prices we had on {requiredDate.ToShortDateString()}"); MDTrace.WriteLine(LogLevel.DEBUG, $"[UpdatePricesRobinhoodSweep] Retrieve universe of symbols..."); symbols = PricingDA.GetSymbols(); // get the list of symbols in the universe MDTrace.WriteLine(LogLevel.DEBUG, $"[UpdatePricesRobinhoodSweep] Retrieve latest dates..."); Dictionary latestDates = PricingDA.GetLatestDates(symbols); // get the latest pricing date for these symbols List symbolsToFetch = new List(); List keys = latestDates.Keys.ToList(); MDTrace.WriteLine(LogLevel.DEBUG, $"[UpdatePricesRobinhoodSweep] Filtering..."); foreach (String key in keys) // go through the latest dates and select those for which { // we have a price on previous business date if (latestDates[key].Date.Date.Equals(requiredDate.Date)) { symbolsToFetch.Add(key); } } symbols = symbolsToFetch; // These are the symbols that we know we need to fetch MDTrace.WriteLine(LogLevel.DEBUG, $"[UpdatePricesRobinhoodSweep] Preparing to supplement {symbolsToFetch.Count} prices for pricing date {startDate.ToShortDateString()} ."); currentIndex = 0; while (true) { List queueSymbols = GetQueueSymbols(maxThreads); if (null == queueSymbols || 0 == queueSymbols.Count) break; ManualResetEvent[] resetEvents = new ManualResetEvent[queueSymbols.Count]; for (int eventIndex = 0; eventIndex < resetEvents.Length; eventIndex++) { resetEvents[eventIndex] = new ManualResetEvent(false); } for (int index = 0; index < queueSymbols.Count; index++) { PricingThreadHelper pricingThreadHelper = new PricingThreadHelper(queueSymbols[index], startDate, resetEvents[index]); ThreadPool.QueueUserWorkItem(ThreadPoolCallbackUpdatePricesRobinhoodSweep, pricingThreadHelper); try { Thread.Sleep(waitBetweenRequests); } catch (Exception) {; } } MDTrace.WriteLine(LogLevel.DEBUG, "UpdatePricesRobinhoodSweep, waiting for queued items to complete."); WaitHandle.WaitAll(resetEvents); } return true; } finally { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("[UpdatePricesRobinhoodSweep] End, total took {0}(ms)", profiler.End())); } } // ************************************************************************************************************************************** // ************************************************************* E N D R O B I N H O O D *********************************************** // ************************************************************************************************************************************** // ************************************************************************************************************************************** // ******************************************************************* Y A H O O ******************************************************* // ************************************************************************************************************************************** public bool UpdatePricesYahoo(DateTime? startDate = null) // get prices from Yahoo { Profiler profiler = new Profiler(); try { symbols = PricingDA.GetSymbols(); currentIndex = 0; if (null == startDate) startDate = DateTime.Now; while (true) { List queueSymbols = GetQueueSymbols(); if (null == queueSymbols || 0 == queueSymbols.Count) break; ManualResetEvent[] resetEvents = new ManualResetEvent[queueSymbols.Count]; for (int eventIndex = 0; eventIndex < resetEvents.Length; eventIndex++) { resetEvents[eventIndex] = new ManualResetEvent(false); } for (int index = 0; index < queueSymbols.Count; index++) { PricingThreadHelper pricingThreadHelper = new PricingThreadHelper(queueSymbols[index], startDate.Value, resetEvents[index]); ThreadPool.QueueUserWorkItem(ThreadPoolCallbackUpdatePricesYahoo, pricingThreadHelper); try { Thread.Sleep(WaitBetweenRequests); } catch (Exception) {; } } MDTrace.WriteLine(LogLevel.DEBUG, "UpdatePricesYahoo, waiting for queued items to complete."); WaitHandle.WaitAll(resetEvents); } return true; } finally { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("[UpdatePricesBigCharts]End, total took {0}(ms)", profiler.End())); } } public bool UpdatePricesYahooSweep(DateTime? startDate = null) // get prices from Yahoo { Profiler profiler = new Profiler(); try { symbols = PricingDA.GetSymbols(); currentIndex = 0; if (null == startDate) startDate = DateTime.Now; while (true) { List queueSymbols = GetQueueSymbols(); if (null == queueSymbols || 0 == queueSymbols.Count) break; ManualResetEvent[] resetEvents = new ManualResetEvent[queueSymbols.Count]; for (int eventIndex = 0; eventIndex < resetEvents.Length; eventIndex++) { resetEvents[eventIndex] = new ManualResetEvent(false); } for (int index = 0; index < queueSymbols.Count; index++) { PricingThreadHelper pricingThreadHelper = new PricingThreadHelper(queueSymbols[index], startDate.Value, resetEvents[index]); ThreadPool.QueueUserWorkItem(ThreadPoolCallbackUpdatePricesYahooSweep, pricingThreadHelper); try { Thread.Sleep(WaitBetweenRequests); } catch (Exception) {; } } MDTrace.WriteLine(LogLevel.DEBUG, "UpdatePricesYahooSweep, waiting for queued items to complete."); WaitHandle.WaitAll(resetEvents); } return true; } finally { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("[UpdatePricesYahooSweep]End, total took {0}(ms)", profiler.End())); } } // ******************************************************************************************************************************************** // ******************************************************************* E N D Y A H O O ******************************************************* // ******************************************************************************************************************************************** // ******************************************************************************************************************************************** // ********************************************************************** B A R C H A R T *************************************************** // ******************************************************************************************************************************************** /// /// UpdatePricesBarChartSweep - This feed is intended to supplement BigCharts nightly price feed in UPDATEDAILY2 by filling any gaps that may occur /// in that feed. This feed will only pull a price for which we had a price yesterday (findprevbusinessday) and for which do not have /// a price tonight. If BigCharts was successful then we can expect this method to retrieve nothing. If BigCharts fails to give us a price /// tonight BUT did in fact give us a price yesterday then this method will attempt to rerieve that symbol from BarChart and insert that /// price into the database with the appropriate date (tonight) and with the appropriate Source (BarChart). /// /// /// public bool UpdatePricesBarChartSweep(DateTime? startDate = null) { Profiler profiler = new Profiler(); try { MDTrace.WriteLine(LogLevel.DEBUG, "[UpdatePricesBarChartSweep]Enter"); DateGenerator dateGenerator = new DateGenerator(); if (null == startDate) startDate = DateTime.Now; startDate = dateGenerator.GetPrevBusinessDay(startDate.Value); // make sure we are given a valid business date DateTime requiredDate = dateGenerator.FindPrevBusinessDay(startDate.Value); // now go and fetch yesterday (prev business day) MDTrace.WriteLine(LogLevel.DEBUG, $"[UpdatePricesBarChartSweep] Determining what prices we need on {startDate.Value.ToShortDateString()} by examing what prices we had on {requiredDate.ToShortDateString()}"); MDTrace.WriteLine(LogLevel.DEBUG, $"[UpdatePricesBarChartSweep] Retrieve universe of symbols..."); symbols = PricingDA.GetSymbols(); // get the list of symbols in the universe MDTrace.WriteLine(LogLevel.DEBUG, $"[UpdatePricesBarChartSweep] Retrieve latest dates..."); Dictionary latestDates = PricingDA.GetLatestDates(symbols); // get the latest pricing date for these symbols List symbolsToFetch = new List(); List keys = latestDates.Keys.ToList(); MDTrace.WriteLine(LogLevel.DEBUG, $"[UpdatePricesBarChartSweep] Filtering..."); foreach (String key in keys) // go through the latest dates and select those for which { // we have a price on previous business date if (latestDates[key].Date.Date.Equals(requiredDate.Date)) { symbolsToFetch.Add(key); } } symbols = symbolsToFetch; // These are the symbols that we know we need to fetch MDTrace.WriteLine(LogLevel.DEBUG, $"[UpdatePricesBarChartSweep] Preparing to supplement {symbolsToFetch.Count} prices for pricing date {startDate.Value.ToShortDateString()} ."); currentIndex = 0; while (true) { List queueSymbols = GetQueueSymbols(); if (null == queueSymbols || 0 == queueSymbols.Count) break; ManualResetEvent[] resetEvents = new ManualResetEvent[queueSymbols.Count]; for (int eventIndex = 0; eventIndex < resetEvents.Length; eventIndex++) { resetEvents[eventIndex] = new ManualResetEvent(false); } for (int index = 0; index < queueSymbols.Count; index++) { PricingThreadHelper pricingThreadHelper = new PricingThreadHelper(queueSymbols[index], startDate.Value, resetEvents[index]); ThreadPool.QueueUserWorkItem(ThreadPoolCallbackUpdatePricesBarChartSweep, pricingThreadHelper); try { Thread.Sleep(WaitBetweenRequests); } catch (Exception) {; } } MDTrace.WriteLine(LogLevel.DEBUG, "UpdatePricesBarChartSweep, waiting for queued items to complete."); WaitHandle.WaitAll(resetEvents); } return true; } finally { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("[UpdatePricesBarChartSweep]End, total took {0}(ms)", profiler.End())); } } // ******************************************************************************************************************************************** // ********************************************************************** E N D B A R C H A R T *************************************************** // ******************************************************************************************************************************************** public bool UpdatePriceAsOfSymbolYahoo(String symbol, DateTime asOf) // get prices from Yahoo { Profiler profiler = new Profiler(); try { symbols = new List(); symbols.Add(symbol); currentIndex = 0; while (true) { List queueSymbols = GetQueueSymbols(); if (null == queueSymbols || 0 == queueSymbols.Count) break; ManualResetEvent[] resetEvents = new ManualResetEvent[queueSymbols.Count]; for (int eventIndex = 0; eventIndex < resetEvents.Length; eventIndex++) { resetEvents[eventIndex] = new ManualResetEvent(false); } for (int index = 0; index < queueSymbols.Count; index++) { PricingThreadHelper pricingThreadHelper = new PricingThreadHelper(queueSymbols[index], asOf, resetEvents[index]); ThreadPool.QueueUserWorkItem(ThreadPoolCallbackUpdatePricesYahoo, pricingThreadHelper); try { Thread.Sleep(WaitBetweenRequests); } catch (Exception) {; } } MDTrace.WriteLine(LogLevel.DEBUG, "UpdatePricesAsOfSymbol, waiting for queued items to complete."); WaitHandle.WaitAll(resetEvents); } return true; } finally { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("[UpdatePricesAsOfSymbol]End, total took {0}(ms)", profiler.End())); } } public bool GetMissingPricesSymbol(String symbol, DateTime? startDate = null) { Profiler profiler = new Profiler(); try { List symbols = new List(); symbols.Add(symbol); this.symbols = symbols; currentIndex = 0; while (true) { List queueSymbols = GetQueueSymbols(); if (null == queueSymbols || 0 == queueSymbols.Count) break; ManualResetEvent[] resetEvents = new ManualResetEvent[queueSymbols.Count]; for (int eventIndex = 0; eventIndex < resetEvents.Length; eventIndex++) { resetEvents[eventIndex] = new ManualResetEvent(false); } for (int index = 0; index < queueSymbols.Count; index++) { PricingThreadHelper pricingThreadHelper = new PricingThreadHelper(queueSymbols[index], resetEvents[index], startDate); ThreadPool.QueueUserWorkItem(ThreadPoolCallbackGetMissingPrice, pricingThreadHelper); try { Thread.Sleep(WaitBetweenRequests); } catch (Exception) {; } } MDTrace.WriteLine(LogLevel.DEBUG, "Get missing prices, waiting for queued items to complete."); WaitHandle.WaitAll(resetEvents); } return true; } finally { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("[GetMissingPrices]End, total took {0}(ms)", profiler.End())); } } public bool GetMissingPrices(DateTime? startDate = null) { Profiler profiler = new Profiler(); try { this.symbols = PricingDA.GetSymbols(); currentIndex = 0; while (true) { List queueSymbols = GetQueueSymbols(); if (null == queueSymbols || 0 == queueSymbols.Count) break; ManualResetEvent[] resetEvents = new ManualResetEvent[queueSymbols.Count]; for (int eventIndex = 0; eventIndex < resetEvents.Length; eventIndex++) { resetEvents[eventIndex] = new ManualResetEvent(false); } for (int index = 0; index < queueSymbols.Count; index++) { PricingThreadHelper pricingThreadHelper = new PricingThreadHelper(queueSymbols[index], resetEvents[index], startDate); ThreadPool.QueueUserWorkItem(ThreadPoolCallbackGetMissingPrice, pricingThreadHelper); try { Thread.Sleep(WaitBetweenRequests); } catch (Exception) {; } } MDTrace.WriteLine(LogLevel.DEBUG, "Get missing prices, waiting for queued items to complete."); WaitHandle.WaitAll(resetEvents); } return true; } finally { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("[GetMissingPrices]End, total took {0}(ms)", profiler.End())); } } public bool UpdateLatestPriceSymbol(String symbol) { List symbols = new List(); symbols.Add(symbol); return UpdateLatestPrices(symbols); } public bool UpdateLatestPrices(List symbols) { Profiler profiler = new Profiler(); try { DateTime pricingDate = DateTime.Now; this.symbols = symbols; currentIndex = 0; while (true) { List queueSymbols = GetQueueSymbols(); if (null == queueSymbols || 0 == queueSymbols.Count) break; ManualResetEvent[] resetEvents = new ManualResetEvent[queueSymbols.Count]; for (int eventIndex = 0; eventIndex < resetEvents.Length; eventIndex++) { resetEvents[eventIndex] = new ManualResetEvent(false); } for (int index = 0; index < queueSymbols.Count; index++) { PricingThreadHelper pricingThreadHelper = new PricingThreadHelper(queueSymbols[index], pricingDate, resetEvents[index]); ThreadPool.QueueUserWorkItem(ThreadPoolCallbackUpdateLatestPrice, pricingThreadHelper); try { Thread.Sleep(WaitBetweenRequests); } catch (Exception) {; } } MDTrace.WriteLine(LogLevel.DEBUG, "Load prices, waiting for queued items to complete."); WaitHandle.WaitAll(resetEvents); } return true; } finally { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("[UpdateLatestPrices]End, total took {0}(ms)", profiler.End())); } } // ************************************************************************************************************************************ // *************************************************** T H R E A D P O O L C A L L B A C K ****************************************** // ************************************************************************************************************************************ public void ThreadPoolCallbackUpdateLatestPriceAll(Object pricingThreadHelperContext) { PricingThreadHelper pricingThreadHelper = (PricingThreadHelper)pricingThreadHelperContext; try { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("UpdateLatestPriceAll, Thread {0} started for {1}...", Thread.CurrentThread.ManagedThreadId, pricingThreadHelper.Symbol)); UpdateLatestPriceAllEx(pricingThreadHelper.Symbol); MDTrace.WriteLine(LogLevel.DEBUG, String.Format("UpdateLatestPriceAll, Thread {0} ended for {1}", Thread.CurrentThread.ManagedThreadId, pricingThreadHelper.Symbol)); } finally { pricingThreadHelper.ResetEvent.Set(); } } public void ThreadPoolCallbackUpdatePricesRobinhoodSweep(Object pricingThreadHelperContext) { PricingThreadHelper pricingThreadHelper = (PricingThreadHelper)pricingThreadHelperContext; try { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Load price (Robinhood), Thread {0} started for {1}...", Thread.CurrentThread.ManagedThreadId, pricingThreadHelper.Symbol)); UpdatePriceRobinhoodSweepEx(pricingThreadHelper.Symbol, pricingThreadHelper.PricingDate); MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Load price (Robinhood), Thread {0} ended for {1}", Thread.CurrentThread.ManagedThreadId, pricingThreadHelper.Symbol)); } finally { pricingThreadHelper.ResetEvent.Set(); } } public void ThreadPoolCallbackUpdatePricesYahoo(Object pricingThreadHelperContext) { PricingThreadHelper pricingThreadHelper = (PricingThreadHelper)pricingThreadHelperContext; try { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Load price (Yahoo), Thread {0} started for {1}...", Thread.CurrentThread.ManagedThreadId, pricingThreadHelper.Symbol)); UpdatePriceYahoo(pricingThreadHelper.Symbol, pricingThreadHelper.PricingDate); MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Load price (Yahoo), Thread {0} ended for {1}", Thread.CurrentThread.ManagedThreadId, pricingThreadHelper.Symbol)); } finally { pricingThreadHelper.ResetEvent.Set(); } } public void ThreadPoolCallbackUpdatePricesYahooSweep(Object pricingThreadHelperContext) { PricingThreadHelper pricingThreadHelper = (PricingThreadHelper)pricingThreadHelperContext; try { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Load price (Yahoo), Thread {0} started for {1}...", Thread.CurrentThread.ManagedThreadId, pricingThreadHelper.Symbol)); UpdatePriceYahooSweep(pricingThreadHelper.Symbol, pricingThreadHelper.PricingDate); MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Load price (Yahoo), Thread {0} ended for {1}", Thread.CurrentThread.ManagedThreadId, pricingThreadHelper.Symbol)); } finally { pricingThreadHelper.ResetEvent.Set(); } } public void ThreadPoolCallbackUpdatePricesBarChartSweep(Object pricingThreadHelperContext) { PricingThreadHelper pricingThreadHelper = (PricingThreadHelper)pricingThreadHelperContext; try { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Load price (BarChart), Thread {0} started for {1}...", Thread.CurrentThread.ManagedThreadId, pricingThreadHelper.Symbol)); UpdatePriceBarChartSweep(pricingThreadHelper.Symbol, pricingThreadHelper.PricingDate); MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Load price (BarChart), Thread {0} ended for {1}", Thread.CurrentThread.ManagedThreadId, pricingThreadHelper.Symbol)); } finally { pricingThreadHelper.ResetEvent.Set(); } } public void ThreadPoolCallbackGetMissingPrice(Object pricingThreadHelperContext) { PricingThreadHelper pricingThreadHelper = (PricingThreadHelper)pricingThreadHelperContext; try { GetMissingPricesEx(pricingThreadHelper.Symbol, pricingThreadHelper.StartDate == null ? new DateTime() : pricingThreadHelper.StartDate.Value); } finally { pricingThreadHelper.ResetEvent.Set(); } } public void ThreadPoolCallbackUpdateLatestPrice(Object pricingThreadHelperContext) { PricingThreadHelper pricingThreadHelper = (PricingThreadHelper)pricingThreadHelperContext; try { Price latestPrice = MarketDataHelper.GetLatestPrice(pricingThreadHelper.Symbol); if (null == latestPrice) { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("***** Error retrieving latest price for {0} *****", pricingThreadHelper.Symbol)); return; } MDTrace.WriteLine(LogLevel.DEBUG, Price.Header); MDTrace.WriteLine(LogLevel.DEBUG, latestPrice.ToString()); MDTrace.WriteLine(LogLevel.DEBUG, "Removing price for '" + pricingThreadHelper.Symbol + "' on " + Utility.DateTimeToStringMMSDDSYYYY(latestPrice.Date)); PricingDA.DeletePrice(pricingThreadHelper.Symbol, latestPrice.Date); MDTrace.WriteLine(LogLevel.DEBUG, "Adding price for '" + pricingThreadHelper.Symbol + "' on " + Utility.DateTimeToStringMMSDDSYYYY(latestPrice.Date)); PricingDA.InsertPrice(latestPrice); } finally { pricingThreadHelper.ResetEvent.Set(); } } // **************************************************************************************************************************************** // **************************************************************************************************************************************** // **************************************************************************************************************************************** private List GetQueueSymbols() { List queueSymbols = new List(); int index = currentIndex; for (; index < currentIndex + MaxThreads && index < symbols.Count; index++) { queueSymbols.Add(symbols[index]); } currentIndex = index; return queueSymbols; } private List GetQueueSymbols(int maxThreads) { List queueSymbols = new List(); int index = currentIndex; for (; index < currentIndex + maxThreads && index < symbols.Count; index++) { queueSymbols.Add(symbols[index]); } currentIndex = index; return queueSymbols; } // ******************************************************************************************************************************************** // ************************************************************ W O R K E R S ***************************************************************** // ******************************************************************************************************************************************** public static void GetMissingPricesEx(String symbol, DateTime startDate) { try { DateGenerator dateGenerator = new DateGenerator(); TimeSpan oneDay = new TimeSpan(1, 0, 0, 0); DateTime? historicalDate = null; DateTime minDate = Constants.MIN_PRICING_DATE; List pricingDatesList = PricingDA.GetPricingDatesForSymbol(symbol); if (null == pricingDatesList || 0 == pricingDatesList.Count) return; pricingDatesList = pricingDatesList.Where(x => x.Date >= minDate.Date).ToList(); if (null == pricingDatesList || 0 == pricingDatesList.Count) return; DateTime beginDate = pricingDatesList[0]; DateTime endDate = pricingDatesList[pricingDatesList.Count - 1]; Dictionary pricingDates = new Dictionary(); for (int listIndex = 0; listIndex < pricingDatesList.Count; listIndex++) { DateTime pricingDate = pricingDatesList[listIndex]; pricingDates.Add(pricingDate.Date, pricingDate.Date); } Dictionary marketPrices = new Dictionary(); if (Utility.IsEpoch(startDate)) historicalDate = beginDate; else historicalDate = startDate; MDTrace.WriteLine(LogLevel.DEBUG, "Working on '" + symbol + "' from " + Utility.DateTimeToStringMMHDDHYYYY(historicalDate.Value) + " to " + Utility.DateTimeToStringMMHDDHYYYY(endDate)); Prices prices = MarketDataHelper.GetDailyPrices(symbol, historicalDate.Value, endDate); // yahoo finance // if (null == prices || 0 == prices.Count) prices = MarketDataHelper.GetPricesAsOf(symbol, historicalDate.Value, endDate); // try big charts if (null == prices || 0 == prices.Count) return; for (int listIndex = 0; listIndex < prices.Count; listIndex++) { Price price = prices[listIndex]; if (!marketPrices.ContainsKey(price.Date.Date)) marketPrices.Add(price.Date, price); } MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Retrieved {0} prices from feed for {1}", prices.Count, symbol)); bool added = false; for (DateTime date = historicalDate.Value.Date; date < endDate.Date; date += oneDay) { if (pricingDates.ContainsKey(date.Date)) continue; if (dateGenerator.IsWeekend(date)) continue; Price price = null; if (!marketPrices.ContainsKey(date.Date)) continue; MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Inserting price {0}...", price.ToString())); price = marketPrices[date.Date]; MDTrace.WriteLine(LogLevel.DEBUG, price.ToString()); PricingDA.InsertPrice(price); added = true; } if (!added) { MDTrace.WriteLine(LogLevel.DEBUG, "There were no new prices to add for '" + symbol); } } catch (Exception exception) { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Exception {0}", exception.ToString())); } } public static void UpdateLatestPriceAllEx(String symbol) { try { symbol = symbol.ToUpper(); Price latestPrice = MarketDataHelper.GetLatestPrice(symbol); if (null == latestPrice) { MDTrace.WriteLine(LogLevel.DEBUG, "Error retrieving latest price."); return; } MDTrace.WriteLine(LogLevel.DEBUG, Price.Header); MDTrace.WriteLine(LogLevel.DEBUG, latestPrice.ToString()); MDTrace.WriteLine(LogLevel.DEBUG, "Removing price for '" + symbol + "' on " + Utility.DateTimeToStringMMSDDSYYYY(latestPrice.Date)); PricingDA.DeletePrice(symbol, latestPrice.Date); MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Inserting price {0}...", latestPrice.ToString())); PricingDA.InsertPrice(latestPrice); } catch (Exception exception) { MDTrace.WriteLine(LogLevel.DEBUG, exception.ToString()); } } public static void UpdatePriceRobinhoodSweepEx(String symbol, DateTime pricingDate) { try { Price price = PricingDA.GetPrice(symbol, pricingDate); if (null != price) { MDTrace.WriteLine(LogLevel.DEBUG, "Already have latest price for '" + symbol + "'"); return; } MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Requesting price for {0} for start date:{1}", symbol, pricingDate)); price = MarketDataHelper.GetPriceRobinHood(symbol, pricingDate); if (null == price) { MDTrace.WriteLine(LogLevel.DEBUG, "No price (GetPriceRobinHood) for '" + symbol + "'"); return; } else { MDTrace.WriteLine(LogLevel.DEBUG, price.ToString()); MDTrace.WriteLine(LogLevel.DEBUG, "Inserting...."); PricingDA.InsertPrice(price); MDTrace.WriteLine(LogLevel.DEBUG, "Done."); } } catch (Exception exception) { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Exception {0}", exception.ToString())); } } public static void UpdatePriceYahoo(String symbol, DateTime pricingDate) { try { Price price = PricingDA.GetPrice(symbol, pricingDate); if (null != price) { MDTrace.WriteLine(LogLevel.DEBUG, "Already have latest price for '" + symbol + "'"); return; } MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Requesting price for {0} for start date:{1} end date:{2}", symbol, pricingDate, pricingDate)); price = MarketDataHelper.GetDailyPrice(symbol, pricingDate); if (null == price) { MDTrace.WriteLine(LogLevel.DEBUG, "No price (UpdatePriceYahoo) for '" + symbol + "'"); return; } else { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Inserting price {0}...", price.ToString())); PricingDA.InsertPrice(price); } } catch (Exception exception) { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Exception {0}", exception.ToString())); } } public static void UpdatePriceYahooSweep(String symbol, DateTime pricingDate) { try { CompanyProfile companyProfile = CompanyProfileDA.GetCompanyProfile(symbol); Price price = PricingDA.GetPrice(symbol, pricingDate); if (null != price) { if (companyProfile == null || !companyProfile.PricingSourceEnum.Equals(CompanyProfile.EnumPricingSource.YAHOO)) { MDTrace.WriteLine(LogLevel.DEBUG, "Already have latest price for '" + symbol + "'"); return; } } MDTrace.WriteLine(LogLevel.DEBUG, String.Format("UpdatePriceYahooSweep: Requesting price for {0} for start date:{1} end date:{2}", symbol, pricingDate, pricingDate)); price = MarketDataHelper.GetDailyPrice(symbol, pricingDate); if (null == price) { MDTrace.WriteLine(LogLevel.DEBUG, "No price (UpdatePriceYahooSweep) for '" + symbol + "'"); return; } else if (!price.IsValid) { MDTrace.WriteLine(LogLevel.DEBUG, "Invalid price (UpdatePriceYahooSweep) for '" + symbol + "'"); return; } else { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Inserting price {0}...", price.ToString())); PricingDA.InsertPrice(price); } } catch (Exception exception) { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Exception {0}", exception.ToString())); } } /// /// This feed is intended to supplement BigCharts and Yahoo feed. /// It should run in the UPDATEDAILY2 chain after Yahoo during the nightly price capture. /// It will only retrieve price for the current date AND it expects us to have a price for the previous business date. /// In other words it will not fill pricing gaps, it will only add "tonights" price to an already established pricing history /// and only if we are missing a price. See the method UpdatePricesBarChartSweep to understand the context. /// /// /// public static void UpdatePriceBarChartSweep(String symbol, DateTime pricingDate) { try { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("UpdatePriceBarChartSweep: Requesting latest price for {0} ", symbol)); Price price = MarketDataHelper.GetLatestPriceBarChart(symbol); if (null == price) { MDTrace.WriteLine(LogLevel.DEBUG, "(UpdatePriceBarChartSweep) No price for '" + symbol + "'"); return; } else if (!price.IsValid) { MDTrace.WriteLine(LogLevel.DEBUG, "(UpdatePriceBarChartSweep) Invalid price for '" + symbol + "'"); return; } MDTrace.WriteLine(LogLevel.DEBUG, String.Format("(UpdatePriceBarChartSweep) Inserting price {0}...", price.ToString())); PricingDA.InsertPrice(price); } catch (Exception exception) { MDTrace.WriteLine(LogLevel.DEBUG, String.Format("(UpdatePriceBarChartSweep) Exception {0}", exception.ToString())); } } } }