/// <summary> /// Gets the historic prices for a stock /// </summary> /// <param name="stock">The stock to collect prices for</param> /// <param name="lastRetrieveDate">The date last retrieved</param> private void GetPricesForStock(Stock stock, DateTime lastRetrieveDate) { List <DailyPrice> historicPrices = this.yahooHistoricWebStockEngine.Fetch(stock, lastRetrieveDate); using (StockBanditDataContext dataContext = new StockBanditDataContext()) { // If different add to queue. foreach (DailyPrice dailyPrice in historicPrices) { // Find price for today DailyPrice existingPrice = dataContext.DailyPrices.FirstOrDefault( p => p.Date == dailyPrice.Date && p.StockCode == stock.StockCode); if (existingPrice != null) { existingPrice.High = dailyPrice.High; existingPrice.Low = dailyPrice.Low; existingPrice.Open = dailyPrice.Open; existingPrice.Close = dailyPrice.Close; existingPrice.Volume = dailyPrice.Volume; existingPrice.AdjustedClose = dailyPrice.AdjustedClose; } else { dataContext.DailyPrices.InsertOnSubmit(dailyPrice); } dataContext.SubmitChanges(); } } }
/// <summary> /// Reset the stock silence flags so it is checked again /// </summary> /// <param name="stock">The stock to reset</param> private void ResetStockSilenceFlags(Stock stock) { using (StockBanditDataContext dataContext = new StockBanditDataContext()) { Stock dalStock = dataContext.Stocks.Single(s => s.StockCode == stock.StockCode); dalStock.Silenced = false; dalStock.LastAlertTime = null; dataContext.SubmitChanges(); stock.Silenced = false; stock.LastAlertTime = null; } }
/// <summary> /// Silence a stock when it have alerted /// </summary> /// <param name="stock">The stock to silence</param> private void SilenceStock(Stock stock) { using (StockBanditDataContext dataContext = new StockBanditDataContext()) { Stock dalStock = dataContext.Stocks.Single(s => s.StockCode == stock.StockCode); dalStock.Silenced = true; dalStock.LastAlertTime = DateTime.Now; dataContext.SubmitChanges(); stock.Silenced = true; stock.LastAlertTime = DateTime.Now; } }
/// <summary> /// Populate the historic prices for all stocks /// </summary> private void PopulateHistoricPrices() { try { List <Task> updateTasks = new List <Task>(); // Get the latest prices foreach (Stock stock in this.StockCodesList) { this.logQueue.QueueLogEntry(new LogEntry(DateTime.Now, LogType.Info, string.Format("Collecting Historic Prices for {0}", stock.StockCode))); DateTime lastRetrieveDate; using (StockBanditDataContext dataContext = new StockBanditDataContext()) { // Get the historic prices lastRetrieveDate = dataContext.DailyPrices.Where(p => p.StockCode == stock.StockCode && p.Date <= DateTime.Today) .OrderByDescending(p => p.Date) .Select(p => p.Date) .FirstOrDefault(); } if (lastRetrieveDate == default(DateTime)) { lastRetrieveDate = DateTime.Now.AddDays(-150); } Task updateTask = Task.Factory.StartNew(() => { this.GetPricesForStock(stock, lastRetrieveDate); }, TaskCreationOptions.LongRunning); updateTasks.Add(updateTask); this.logQueue.QueueLogEntry(new LogEntry(DateTime.Now, LogType.Info, string.Format("Collected Historic Prices for {0}", stock.StockCode))); } Task.WaitAll(updateTasks.ToArray()); } catch (System.Net.WebException) { this.logQueue.QueueLogEntry(new LogEntry(DateTime.Now, LogType.Error, "No internet access - unable to get prices.")); } catch (Exception e) { this.logQueue.QueueLogEntry(new LogEntry(DateTime.Now, LogType.Error, string.Format("Error in PopulateHistoricPrices: {0}", e))); this.QueueEmail(this.EmailRecipient, "System Error", e.ToString()); } this.logQueue.QueueLogEntry(new LogEntry(DateTime.Now, LogType.Info, "Finished Collecting Historic Prices")); }
/// <summary> /// Starts the server and all classes required. /// </summary> /// <returns>The result if it could be started,</returns> public bool StartServer() { try { // Set up the email and log queues if ((this.EmailServer.Trim().Length > 0) && (this.EmailFromAddress.Trim().Length > 0)) { this.emailQueue = new EmailQueue(this.EmailServer, this.EmailPort, this.EmailUsername, this.EmailPassword, this.EmailFromAddress, this.EmailSSL, 1000, this.logQueue); } else { this.logQueue.QueueLogEntry(new LogEntry(DateTime.Now, LogType.Info, "Email not configured.")); } // Convert the stocks to a list this.StockCodesList = new ObservableCollection <Stock>(); // Setup Yahoo for querying this.yahooHistoricWebStockEngine = new YahooHistoricWebStockEngine(this.logQueue); using (StockBanditDataContext dataContext = new StockBanditDataContext()) { foreach (var stock in dataContext.Stocks.Where(s => s.Active)) { if (stock.MarketCap > this.MarketCapMin && stock.MarketCap < this.MarketCapMax) { this.StockCodesList.Add(stock); } } } // Get all the historical data and populate this.RegisterModels(); this.StartPriceFetchTimer(); } catch (Exception ex) { this.logQueue.QueueLogEntry(new LogEntry(DateTime.Now, LogType.Fatal, string.Format("Error starting server - {0}", ex))); return(false); } return(true); }
/// <summary> /// Collect the historical prices for a stock and evaluate against the registered models /// </summary> /// <param name="stock">The stock to check</param> /// <param name="resultString">The output string of the evaluation</param> private void GetPricesAndEvaluate(Stock stock, out string resultString) { resultString = null; using (StockBanditDataContext dataContext = new StockBanditDataContext()) { List <DailyPrice> historicPrices = dataContext.DailyPrices.Where( p => p.StockCode == stock.StockCode && p.Date > DateTime.Now.Date.Subtract(new TimeSpan(1825, 0, 0, 0, 0)) && p.Date <= DateTime.Now.Date).OrderByDescending(p => p.Date).ToList(); if (historicPrices.Count > 0 && historicPrices.First().Close > this.PriceMin && historicPrices.First().Close < this.PriceMax) { foreach (IModel model in this.registeredModels) { model.Evaluate(stock, historicPrices, out resultString); } } } }