using System; using System.Collections.Generic; // Filename: DateGenerator.cs // Author:Sean Kessler namespace MarketData.Utils { /// DateGenerator - Generate Historical Dates /// "BusinessDay" is analagous to "MarketDay". To qualify as a business day the date must not be a weekend or a market holiday [Serializable] public class DateGenerator { private static readonly TimeSpan TIMESPAN_INCREASE_ONE_DAY=new TimeSpan(1,0,0,0); private static readonly TimeSpan TIMESPAN_DECREASE_ONE_DAY=new TimeSpan(-1,0,0,0); public DateGenerator() { } /// GetCurrMonthStart - Finds the first business day of the previous month /// DateTime public DateTime GetPrevMonthStart(DateTime dateTime) { DateTime startDate = new DateTime(dateTime.Year, dateTime.Month, 1); startDate = startDate.AddMonths(-1); startDate = GetNextBusinessDay(startDate); return startDate; } /// GetCurrMonthStart - Finds the first business day of the current month /// DateTime public DateTime GetCurrMonthStart(DateTime dateTime) { DateTime startDate = new DateTime(dateTime.Year, dateTime.Month, 1); startDate = GetNextBusinessDay(startDate); return startDate; } public static int GetPrevMonth(int month) { if(1==month)return 12; return month-1; } /// FindPrevBusinessDay - Finds previous business day /// DateTime public DateTime FindPrevBusinessDay(DateTime asOf) { TimeSpan oneDay=new TimeSpan(1,0,0,0); asOf=asOf.Subtract(oneDay); while(IsWeekend(asOf)||IsHoliday(asOf))asOf=asOf.Subtract(oneDay); return asOf.Date; } /// FindForwardBusinessDay - Finds following business day going daysForward days /// DateTime public DateTime FindForwardBusinessDay(DateTime asOf,int daysForward) { for (int index = 0; index < daysForward; index++) { asOf = FindNextBusinessDay(asOf); } return asOf.Date; } /// FindPastBusinessDay - Finds previous business day going daysPast days /// DateTime public DateTime FindPastBusinessDay(DateTime asOf,int daysPast) { for (int index = 0; index < daysPast; index++) { asOf = FindPrevBusinessDay(asOf); } return asOf.Date; } /// FindNextBusinessDay - Finds following nth business day /// DateTime public DateTime FindNextBusinessDay(DateTime asOf,int days) { DateTime nextDate=asOf; for(int index=0;indexFindNextBusinessDay - Finds following business day /// DateTime public DateTime FindNextBusinessDay(DateTime asOf) { TimeSpan oneDay=new TimeSpan(1,0,0,0); asOf=asOf.Add(oneDay); while(IsWeekend(asOf)||IsHoliday(asOf))asOf=asOf.Add(oneDay); return asOf.Date; } /// GetPrevBusinessDay - Gets previous business day /// If the given date is a business day then this method will return the given date /// None public DateTime GetPrevBusinessDay(DateTime asOf) { TimeSpan oneDay=new TimeSpan(1,0,0,0); while(IsWeekend(asOf)||IsHoliday(asOf))asOf=asOf.Subtract(oneDay); return asOf.Date; } /// GetNextBusinessDay - Gets next business day /// If the given date is a business day then this method will return the given date /// None public DateTime GetNextBusinessDay(DateTime asOf) { TimeSpan oneDay=new TimeSpan(1,0,0,0); while(IsWeekend(asOf)||IsHoliday(asOf))asOf=asOf.Add(oneDay); return asOf.Date; } /// GetNextDay - Gets next business day /// If the given date is a business day then this method will return the given date /// None public DateTime GetNextDay(DateTime asOf) { return (asOf.Add(Utility.OneDay)).Date; } /// GetPrevFriday - Gets date of prior friday /// Get the date of the previous friday - if previous Friday is holiday will seek previous business day /// None public DateTime GetPrevFriday(DateTime asOf) { TimeSpan oneDay=new TimeSpan(1,0,0,0); List historicalDates=null; int daysToFetch=7; if(DayOfWeek.Friday==asOf.DayOfWeek) { asOf=asOf.Subtract(oneDay); daysToFetch--; } historicalDates=GenerateHistoricalDates(asOf,daysToFetch); for(int index=0;index=1 && asOf.Month<=3)month=1; else if(asOf.Month>=4 && asOf.Month<=6)month=4; else if(asOf.Month>=7 && asOf.Month<=9)month=7; else month=10; DateTime quarterStartDate=new DateTime(asOf.Year,month,1); quarterStartDate=GetNextBusinessDay(quarterStartDate); return quarterStartDate; } public DateTime GetNextQuarterStartDate(DateTime asOf) { DateTime prevQuarterStartDate=GetPrevQuarterStartDate(asOf); int month=prevQuarterStartDate.Month; int year=prevQuarterStartDate.Year; if(prevQuarterStartDate.Month.Equals(10)){year++;} month+=3; if(month>12)month=1; DateTime nextQuarterStartDate=new DateTime(year,month,1); nextQuarterStartDate=GetNextBusinessDay(nextQuarterStartDate); return nextQuarterStartDate; } public DateTime GetCurrentMonthEnd(DateTime asOf) { TimeSpan oneDay=new TimeSpan(-1,0,0,0); DateTime date=new DateTime(asOf.Year,asOf.Month,asOf.Day); date=new DateTime(date.Year,date.Month,DateTime.DaysInMonth(asOf.Year,asOf.Month)); while(IsWeekend(date)||IsHoliday(date))date=date.Add(oneDay); return date; } public DateTime GetNextMonthEnd(DateTime asOf) { TimeSpan oneDay=new TimeSpan(-1,0,0,0); DateTime date=new DateTime(asOf.Year,asOf.Month,asOf.Day); date=date.AddMonths(1); date=new DateTime(date.Year,date.Month,DateTime.DaysInMonth(date.Year,date.Month)); while(IsWeekend(date)||IsHoliday(date))date=date.Add(oneDay); return date; } public DateTime GetPrevMonthEnd(DateTime asOf) { TimeSpan oneDay=new TimeSpan(-1,0,0,0); DateTime date=new DateTime(asOf.Year,asOf.Month,asOf.Day); date=date.AddMonths(-1); date=new DateTime(date.Year,date.Month,DateTime.DaysInMonth(date.Year,date.Month)); while(IsWeekend(date)||IsHoliday(date))date=date.Add(oneDay); return date; } public DateTime GetPrevMonthEnd(DateTime asOf,int count) { for(int index=0;index endDate) { TimeSpan timeSpan = startDate.Date - endDate.Date; return (int)timeSpan.TotalDays; } else { TimeSpan timeSpan = endDate.Date - startDate.Date; return (int)timeSpan.TotalDays; } } public int MonthsBetween(DateTime startDate,DateTime endDate) { return DaysBetween(startDate,endDate)/30; } public static List GenerateHistoricalYear(int startYear,int years) { List yearsList = new List(); for (int index = 0; index < years; index++) { yearsList.Add(startYear); startYear--; } return yearsList; } public List GenerateHistoricalDates(DateTime startDate, int dayCount) { List histDates=new List(); DateTime histDate; TimeSpan singleDay; startDate = startDate.Date; histDate=startDate; if(dayCount<0)singleDay=new TimeSpan(-1,0,0,0); else singleDay=new TimeSpan(1,0,0,0); dayCount=dayCount<0?-dayCount:dayCount; while(histDates.Count /// Generates dates into the future respecting weekens and market holidays /// /// /// /// public List GenerateFutureDates(DateTime startDate, int dayCount) { List futureDates=new List(); DateTime futureDate; TimeSpan singleDay; startDate = startDate.Date; futureDate=startDate; if(dayCount<0)singleDay=new TimeSpan(1,0,0,0); else singleDay=new TimeSpan(1,0,0,0); dayCount=dayCount<0?-dayCount:dayCount; while(futureDates.Count historicalDates=GenerateHistoricalDates(startDate,endDate); return historicalDates.Count; } // The function will figure out which date is the most recent and which one is the historical date. // Generally, make startDate the most recent and endDate the historical date. // The returned series will contain an ascending date series with the earliest (most distant) date in the lowest numbered index. public List GenerateHistoricalDates(DateTime startDate,DateTime endDate) { if (Utility.Epoch.Equals(startDate)||Utility.Epoch.Equals(endDate)) return null; startDate = startDate.Date; endDate = endDate.Date; List histDates = new List(); DateTime histDate; TimeSpan singleDay; bool reverse = false; if (endDate > startDate) { reverse = true; DateTime swap = endDate; endDate = startDate; startDate = swap; } histDate=startDate; singleDay=new TimeSpan(1,0,0,0); while(histDate>=endDate) { if(IsMarketOpen(histDate))histDates.Add(histDate); histDate=histDate.Subtract(singleDay); } if (reverse) histDates.Reverse(); return histDates; } // The function will figure out which date is the most recent and which one is the historical date. // Generally, make startDate the most recent and endDate the historical date. public List GenerateHistoricalDatesActual(DateTime startDate, DateTime endDate) { if (Utility.Epoch.Equals(startDate) || Utility.Epoch.Equals(endDate)) return null; startDate = startDate.Date; endDate = endDate.Date; List histDates = new List(); DateTime histDate; TimeSpan singleDay; bool reverse = false; if (endDate > startDate) { reverse = true; DateTime swap = endDate; endDate = startDate; startDate = swap; } histDate = startDate; singleDay = new TimeSpan(1, 0, 0, 0); while (histDate >= endDate) { histDates.Add(histDate); histDate = histDate.Subtract(singleDay); } if (reverse) histDates.Reverse(); return histDates; } public bool IsMarketOpen(DateTime dateTime) { if(IsWeekend(dateTime)||IsHoliday(dateTime))return false; return true; } public bool IsWeekend(DateTime dateTime) { if(DayOfWeek.Sunday==dateTime.DayOfWeek || DayOfWeek.Saturday==dateTime.DayOfWeek)return true; return false; } // This uses a singleton cache of holidays. public bool IsHoliday(DateTime dateTime) { return HolidayCache.GetInstance().IsHoliday(dateTime); } } }