/// <summary> /// Retrieves stock history data from Google for the specified stock. /// </summary> /// <param name="stock">The stock for which data will be retrieved.</param> /// <param name="startDate">The start date of the data set.</param> /// <param name="endDate">The end date of the data set.</param> /// <returns> /// The stock history read from Google. /// </returns> public List<StockDaily> GetDataFromGoogle(Stock stock, DateTime startDate, DateTime endDate) { var history = new List<StockDaily>(); // Read all of the lines from the CSV file. var csvLines = GetCsvData(stock, startDate, endDate).Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); // Iterate through each line to populate the price history... // ...skip the first line which contains the column headers. for (var index = 1; index < csvLines.Length; index++) { var fields = csvLines[index].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); // Construct the interval data from the fields of the CSV line. var priceData = new StockDaily { Exchange = stock.Exchange, Ticker = stock.Ticker, Date = DateTime.Parse(fields[GoogleCsvDateColumnIndex]), OpenPrice = Convert.ToSingle(fields[GoogleCsvOpenPriceColumnIndex]), HighPrice = Convert.ToSingle(fields[GoogleCsvHighPriceColumnIndex]), LowPrice = Convert.ToSingle(fields[GoogleCsvLowPriceColumnIndex]), ClosePrice = Convert.ToSingle(fields[GoogleCsvClosePriceColumnIndex]), Volume = Convert.ToInt64(fields[GoogleCsvVolumeColumnIndex]) <= int.MaxValue ? Convert.ToInt32(fields[GoogleCsvVolumeColumnIndex]) : int.MaxValue }; // Google sometimes provides data for non-trading days. Weed these out based on volume. if (priceData.Volume > 0) { // Google also sometimes has missing data points...we'll filter those out too. const float Epsilon = 0.000001f; if (Math.Abs(priceData.OpenPrice - 0.0f) < Epsilon || Math.Abs(priceData.ClosePrice - 0.0f) < Epsilon || Math.Abs(priceData.HighPrice - 0.0f) < Epsilon || Math.Abs(priceData.LowPrice - 0.0f) < Epsilon) { Console.WriteLine("WARNING: Filtering out data from " + priceData.Date + " due to missing price values!"); Console.WriteLine(); } else { history.Add(priceData); } } } // Sort the history into chronological order (Google CSV's are in reverse-chronological order). history.Sort(CompareDailyStockIntervals); return history; }
/// <summary> /// Create a new StockDaily object. /// </summary> /// <param name="exchange">Initial value of the Exchange property.</param> /// <param name="ticker">Initial value of the Ticker property.</param> /// <param name="date">Initial value of the Date property.</param> /// <param name="openPrice">Initial value of the OpenPrice property.</param> /// <param name="closePrice">Initial value of the ClosePrice property.</param> /// <param name="highPrice">Initial value of the HighPrice property.</param> /// <param name="lowPrice">Initial value of the LowPrice property.</param> /// <param name="volume">Initial value of the Volume property.</param> public static StockDaily CreateStockDaily(global::System.String exchange, global::System.String ticker, global::System.DateTime date, global::System.Double openPrice, global::System.Double closePrice, global::System.Double highPrice, global::System.Double lowPrice, global::System.Int32 volume) { StockDaily stockDaily = new StockDaily(); stockDaily.Exchange = exchange; stockDaily.Ticker = ticker; stockDaily.Date = date; stockDaily.OpenPrice = openPrice; stockDaily.ClosePrice = closePrice; stockDaily.HighPrice = highPrice; stockDaily.LowPrice = lowPrice; stockDaily.Volume = volume; return stockDaily; }
/// <summary> /// Compare two stock days by date. /// </summary> /// <param name="day1">Day 1</param> /// <param name="day2">Day 2</param> /// <returns> /// 0 when days are equal; 1 when day 2 is greater; -1 when Day 1 is greater. /// </returns> /// <remarks> /// This method is intended to be used as a Comparison method for sorting lists. /// </remarks> private static int CompareDailyStockIntervals(StockDaily day1, StockDaily day2) { return day1.Date.CompareTo(day2.Date); }
/// <summary> /// Deprecated Method for adding a new object to the StockDailies EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. /// </summary> public void AddToStockDailies(StockDaily stockDaily) { base.AddObject("StockDailies", stockDaily); }