Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#4.0

NYC Exchange Holidays

5.00/5 (3 votes)
6 Dec 2012GPL3 15.4K  
Code to produce holidays for NYC Stock Exchange.

Introduction

This article is intended to show how to produce Holidays for NYC Stock Exchange.

Background

User must be familiar with NYC Stock Exchange holidays rules

Using the code

Self documented coding style, read the code and you'll be able to understand how to produce the holidays. 

C#
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace Interview
{
    public enum Holidays
    {
        [Description("New Year's Day")]
        NewYear,
        [Description("Martin Luther King, Jr. Day")]
        MLK,
        [Description("Presidents' Day")]
        Presidents,
        [Description("Good Friday")]
        GoodFriday,
        [Description("Memorial Day")]
        Memorial,
        [Description("Independence Day")]
        Independence,
        [Description("Labor Day")]
        Labor,
        [Description("Thanksgiving Day")]
        Thanksgiving,
        [Description("Christmas Day")]
        Christmas,
    }
       
    public class ExchangeCalendar
    {
        /* Rule 1: When any stock market holiday falls on a Saturday, the market will be closed on the previous day (Friday) 
         *         unless the Friday is the end of a monthly or yearly accounting period.
         * 
         * Rule 2: When any stock market holiday falls on a Sunday, the market will be closed the next day (Monday).
         * 
         * Rule 3: Special Holidays
         *         Martin Luther King, Jr. Day is always observed on the third Monday in January.
         *         President’s Day is always observed on the third Monday in February.
         *         Memorial Day is always observed on the last Monday in May
         *         Good Friday, the Friday before easter sunday
         *         Labor Day, the first Monday of September
         *         Thanksgiving Day, the fourth Thursday of November
         */

        public static bool IsHoliday(DateTime date)
        {
            var holidays = GetHolidaysByYear(date.Year);
            return holidays.Any(x => x.Value.Year == date.Year && 
               x.Value.Month == date.Month && x.Value.Day == date.Day);
        }

        public static Dictionary<Holidays, DateTime> GetHolidaysByYear(int year)
        {
            var holidays = new Dictionary<Holidays, DateTime>();

            #region New Year''s Day

            var date = new DateTime(year, 1, 1);
            //If date falled on Saturday, no holiday is set since Friday is last day of accounting year.
            if(date.DayOfWeek != DayOfWeek.Saturday)
            {
                if (date.DayOfWeek == DayOfWeek.Sunday)
                    date = date.AddDays(1);
                holidays.Add(Holidays.NewYear, date);
            }

            #endregion

            holidays.Add(Holidays.MLK, GetMartinLutherKingDay(year));
            holidays.Add(Holidays.Presidents, GetPresidentsDay(year));
            holidays.Add(Holidays.GoodFriday, GetGoodFirday(year));
            holidays.Add(Holidays.Memorial, GetMemorialDay(year));
            holidays.Add(Holidays.Independence, AdjustDate(new DateTime(year, 7, 4)));
            holidays.Add(Holidays.Labor, GetLaborDay(year));
            holidays.Add(Holidays.Thanksgiving, GetThanksgivingDay(year));
            holidays.Add(Holidays.Christmas, AdjustDate(new DateTime(year, 12, 25)));
            return holidays;
        }

        public static DateTime GetMartinLutherKingDay(int year)
        {
            var date = new DateTime(year, 1, 1);
            date = GetMonday(date);
            return date.AddDays(14);
        }

        public static DateTime GetPresidentsDay(int year)
        {
            var date = new DateTime(year, 2, 1);
            date = GetMonday(date);
            return date.AddDays(14);
        }

        public static DateTime GetGoodFirday(int year)
        {
            return GetEasterSunday(year).AddDays(-2);
        }

        public static DateTime GetEasterSunday(int year)
        {
            int y = year;
            int a = y % 19;
            int b = y / 100;
            int c = y % 100;
            int d = b / 4;
            int e = b % 4;
            int f = (b + 8) / 25;
            int g = (b - f + 1) / 3;
            int h = (19 * a + b - d - g + 15) % 30;
            int i = c / 4;
            int k = c % 4;
            int l = (32 + 2 * e + 2 * i - h - k) % 7;
            int m = (a + 11 * h + 22 * l) / 451;
            int month = (h + l - 7 * m + 114) / 31;
            int day = ((h + l - 7 * m + 114) % 31) + 1;
            return new DateTime(year, month, day);
        }

        public static DateTime GetMemorialDay(int year)
        {
            var date = new DateTime(year, 5, 1);
            date = GetMonday(date);
            var assumedLast = date.AddDays(28);
            return assumedLast.Month == date.Month ? assumedLast : date.AddDays(21);
        }

        public static DateTime GetLaborDay(int year)
        {
            var date = new DateTime(year, 9, 1);
            return GetMonday(date);
        }

        public static DateTime GetThanksgivingDay(int year)
        {
            var date = new DateTime(year, 11, 1);
            date = GetThursday(date);
            return date.AddDays(21);
        }

        private static DateTime GetMonday(DateTime date)
        {
            if (date.DayOfWeek == DayOfWeek.Monday)
                return date;

            if (date.DayOfWeek == DayOfWeek.Sunday)
                return date.AddDays(1);

            var offset = 8 - (int) date.DayOfWeek;
            return date.AddDays(offset);
        }

        private static DateTime GetThursday(DateTime date)
        {
            if (date.DayOfWeek == DayOfWeek.Friday)
                return date.AddDays(6);

            if (date.DayOfWeek == DayOfWeek.Saturday)
                return date.AddDays(5);

            var offset = 4 - (int)date.DayOfWeek;
            return date.AddDays(offset);
        }

        private static DateTime AdjustDate(DateTime date)
        {
            if (date.DayOfWeek == DayOfWeek.Saturday)
                return date.AddDays(-1);
            if (date.DayOfWeek == DayOfWeek.Sunday)
                return date.AddDays(1);
            return date;
        }

        public class Program
        {
            public static void Main(string[] args)
            {
                var year = 2013;
                while (year > 2005)
                {
                    var holidays = GetHolidaysByYear(year);
                    foreach (var holiday in holidays)
                    {
                        Debug.WriteLine("{0:MM/dd/yyyy} {1}", holiday.Value, holiday.Key);
                    }

                    Debug.WriteLine("");
                    year--;
                }
            }
        }

    }
}

Points of Interest

This will help and speed up financial software programmers to eliminate time

History

Version 1.3.   

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)