def get_early_closes(start, end):
    # TSX closed at 1:00 PM on december 24th.

    start = canonicalize_datetime(start)
    end = canonicalize_datetime(end)

    start = max(start, datetime(1993, 1, 1, tzinfo=pytz.utc))
    end = max(end, datetime(1993, 1, 1, tzinfo=pytz.utc))

    # Not included here are early closes prior to 1993
    # or unplanned early closes

    early_close_rules = []

    christmas_eve = rrule.rrule(
        rrule.MONTHLY,
        bymonth=12,
        bymonthday=24,
        byweekday=(rrule.MO, rrule.TU, rrule.WE, rrule.TH, rrule.FR),
        cache=True,
        dtstart=start,
        until=end
    )
    early_close_rules.append(christmas_eve)

    early_close_ruleset = rrule.rruleset()

    for rule in early_close_rules:
        early_close_ruleset.rrule(rule)
    early_closes = early_close_ruleset.between(start, end, inc=True)

    early_closes.sort()
    return pd.DatetimeIndex(early_closes)
def get_early_closes(start, end):
    # TSX closed at 1:00 PM on december 24th.

    start = canonicalize_datetime(start)
    end = canonicalize_datetime(end)

    start = max(start, datetime(1993, 1, 1, tzinfo=pytz.utc))
    end = max(end, datetime(1993, 1, 1, tzinfo=pytz.utc))

    # Not included here are early closes prior to 1993
    # or unplanned early closes

    early_close_rules = []

    christmas_eve = rrule.rrule(rrule.MONTHLY,
                                bymonth=12,
                                bymonthday=24,
                                byweekday=(rrule.MO, rrule.TU, rrule.WE,
                                           rrule.TH, rrule.FR),
                                cache=True,
                                dtstart=start,
                                until=end)
    early_close_rules.append(christmas_eve)

    early_close_ruleset = rrule.rruleset()

    for rule in early_close_rules:
        early_close_ruleset.rrule(rule)
    early_closes = early_close_ruleset.between(start, end, inc=True)

    early_closes.sort()
    return pd.DatetimeIndex(early_closes)
def get_non_trading_days(start, end):
    non_trading_rules = []

    start = canonicalize_datetime(start)
    end = canonicalize_datetime(end)

    weekends = rrule.rrule(
        rrule.YEARLY,
        byweekday=(rrule.SA, rrule.SU),
        cache=True,
        dtstart=start,
        until=end
    )
    non_trading_rules.append(weekends)

    new_years = rrule.rrule(
        rrule.MONTHLY,
        byyearday=1,
        cache=True,
        dtstart=start,
        until=end
    )
    non_trading_rules.append(new_years)

    new_years_sunday = rrule.rrule(
        rrule.MONTHLY,
        byyearday=2,
        byweekday=rrule.MO,
        cache=True,
        dtstart=start,
        until=end
    )
    non_trading_rules.append(new_years_sunday)

    new_years_saturday = rrule.rrule(
        rrule.MONTHLY,
        byyearday=3,
        byweekday=rrule.MO,
        cache=True,
        dtstart=start,
        until=end
    )
    non_trading_rules.append(new_years_saturday)

    # Family day in Ontario, starting in 2008, third monday of February
    family_day = rrule.rrule(
        rrule.MONTHLY,
        bymonth=2,
        byweekday=(rrule.MO(3)),
        cache=True,
        dtstart=datetime(2008, 1, 1, tzinfo=pytz.utc),
        until=end
    )
    non_trading_rules.append(family_day)

    good_friday = rrule.rrule(
        rrule.DAILY,
        byeaster=-2,
        cache=True,
        dtstart=start,
        until=end
    )
    non_trading_rules.append(good_friday)

    #Monday prior to May 25th.
    victoria_day = rrule.rrule(
        rrule.MONTHLY,
        bymonth=5,
        byweekday=rrule.MO,
        bymonthday=[24, 23, 22, 21, 20, 19, 18],
        cache=True,
        dtstart=start,
        until=end
    )
    non_trading_rules.append(victoria_day)

    july_1st = rrule.rrule(
        rrule.MONTHLY,
        bymonth=7,
        bymonthday=1,
        cache=True,
        dtstart=start,
        until=end
    )
    non_trading_rules.append(july_1st)

    july_1st_sunday = rrule.rrule(
        rrule.MONTHLY,
        bymonth=7,
        bymonthday=2,
        byweekday=rrule.MO,
        cache=True,
        dtstart=start,
        until=end
    )
    non_trading_rules.append(july_1st_sunday)

    july_1st_saturday = rrule.rrule(
        rrule.MONTHLY,
        bymonth=7,
        bymonthday=3,
        byweekday=rrule.MO,
        cache=True,
        dtstart=start,
        until=end
    )
    non_trading_rules.append(july_1st_saturday)

    civic_holiday = rrule.rrule(
        rrule.MONTHLY,
        bymonth=8,
        byweekday=rrule.MO(1),
        cache=True,
        dtstart=start,
        until=end
    )
    non_trading_rules.append(civic_holiday)

    labor_day = rrule.rrule(
        rrule.MONTHLY,
        bymonth=9,
        byweekday=(rrule.MO(1)),
        cache=True,
        dtstart=start,
        until=end
    )
    non_trading_rules.append(labor_day)

    thanksgiving = rrule.rrule(
        rrule.MONTHLY,
        bymonth=10,
        byweekday=(rrule.MO(2)),
        cache=True,
        dtstart=start,
        until=end
    )
    non_trading_rules.append(thanksgiving)

    christmas = rrule.rrule(
        rrule.MONTHLY,
        bymonth=12,
        bymonthday=25,
        cache=True,
        dtstart=start,
        until=end
    )
    non_trading_rules.append(christmas)

    # If Christmas is a Sunday then the 26th, a Monday is observed.
    # (but that would be boxing day), so the 27th is also observed.
    christmas_sunday = rrule.rrule(
        rrule.MONTHLY,
        bymonth=12,
        bymonthday=27,
        byweekday=rrule.TU,
        cache=True,
        dtstart=start,
        until=end
    )
    non_trading_rules.append(christmas_sunday)

    # If Christmas is a Saturday then the 27th, a monday is observed.
    christmas_saturday = rrule.rrule(
        rrule.MONTHLY,
        bymonth=12,
        bymonthday=27,
        byweekday=rrule.MO,
        cache=True,
        dtstart=start,
        until=end
    )
    non_trading_rules.append(christmas_saturday)

    boxing_day = rrule.rrule(
        rrule.MONTHLY,
        bymonth=12,
        bymonthday=26,
        cache=True,
        dtstart=start,
        until=end
    )
    non_trading_rules.append(boxing_day)

    #if boxing day is a sunday, the Christmas was saturday.
    # Christmas is observed on the 27th, a month and boxing day is observed
    # on the 28th, a tuesday.
    boxing_day_sunday = rrule.rrule(
        rrule.MONTHLY,
        bymonth=12,
        bymonthday=28,
        byweekday=rrule.TU,
        cache=True,
        dtstart=start,
        until=end
    )
    non_trading_rules.append(boxing_day_sunday)

    # If boxing day is a Saturday then the 28th, a monday is observed.
    boxing_day_saturday = rrule.rrule(
        rrule.MONTHLY,
        bymonth=12,
        bymonthday=28,
        byweekday=rrule.MO,
        cache=True,
        dtstart=start,
        until=end
    )
    non_trading_rules.append(boxing_day_saturday)

    non_trading_ruleset = rrule.rruleset()

    for rule in non_trading_rules:
        non_trading_ruleset.rrule(rule)

    non_trading_days = non_trading_ruleset.between(start, end, inc=True)

    # Add September 11th closings
    # The TSX was open for 71 minutes on September 11, 2011.
    # It was closed on the 12th and reopened on the 13th.
    # http://www.cbc.ca/news2/interactives/map-tsx/
    #
    #    September 2001
    # Su Mo Tu We Th Fr Sa
    #                    1
    #  2  3  4  5  6  7  8
    #  9 10 11 12 13 14 15
    # 16 17 18 19 20 21 22
    # 23 24 25 26 27 28 29
    # 30

    non_trading_days.append(
        datetime(2001, 9, 12, tzinfo=pytz.utc))

    non_trading_days.sort()
    return pd.DatetimeIndex(non_trading_days)
def get_non_trading_days(start, end):
    non_trading_rules = []

    start = canonicalize_datetime(start)
    end = canonicalize_datetime(end)

    weekends = rrule.rrule(rrule.YEARLY,
                           byweekday=(rrule.SA, rrule.SU),
                           cache=True,
                           dtstart=start,
                           until=end)
    non_trading_rules.append(weekends)

    new_years = rrule.rrule(rrule.MONTHLY,
                            byyearday=1,
                            cache=True,
                            dtstart=start,
                            until=end)
    non_trading_rules.append(new_years)

    new_years_sunday = rrule.rrule(rrule.MONTHLY,
                                   byyearday=2,
                                   byweekday=rrule.MO,
                                   cache=True,
                                   dtstart=start,
                                   until=end)
    non_trading_rules.append(new_years_sunday)

    new_years_saturday = rrule.rrule(rrule.MONTHLY,
                                     byyearday=3,
                                     byweekday=rrule.MO,
                                     cache=True,
                                     dtstart=start,
                                     until=end)
    non_trading_rules.append(new_years_saturday)

    # Family day in Ontario, starting in 2008, third monday of February
    family_day = rrule.rrule(rrule.MONTHLY,
                             bymonth=2,
                             byweekday=(rrule.MO(3)),
                             cache=True,
                             dtstart=datetime(2008, 1, 1, tzinfo=pytz.utc),
                             until=end)
    non_trading_rules.append(family_day)

    good_friday = rrule.rrule(rrule.DAILY,
                              byeaster=-2,
                              cache=True,
                              dtstart=start,
                              until=end)
    non_trading_rules.append(good_friday)

    #Monday prior to May 25th.
    victoria_day = rrule.rrule(rrule.MONTHLY,
                               bymonth=5,
                               byweekday=rrule.MO,
                               bymonthday=[24, 23, 22, 21, 20, 19, 18],
                               cache=True,
                               dtstart=start,
                               until=end)
    non_trading_rules.append(victoria_day)

    july_1st = rrule.rrule(rrule.MONTHLY,
                           bymonth=7,
                           bymonthday=1,
                           cache=True,
                           dtstart=start,
                           until=end)
    non_trading_rules.append(july_1st)

    july_1st_sunday = rrule.rrule(rrule.MONTHLY,
                                  bymonth=7,
                                  bymonthday=2,
                                  byweekday=rrule.MO,
                                  cache=True,
                                  dtstart=start,
                                  until=end)
    non_trading_rules.append(july_1st_sunday)

    july_1st_saturday = rrule.rrule(rrule.MONTHLY,
                                    bymonth=7,
                                    bymonthday=3,
                                    byweekday=rrule.MO,
                                    cache=True,
                                    dtstart=start,
                                    until=end)
    non_trading_rules.append(july_1st_saturday)

    civic_holiday = rrule.rrule(rrule.MONTHLY,
                                bymonth=8,
                                byweekday=rrule.MO(1),
                                cache=True,
                                dtstart=start,
                                until=end)
    non_trading_rules.append(civic_holiday)

    labor_day = rrule.rrule(rrule.MONTHLY,
                            bymonth=9,
                            byweekday=(rrule.MO(1)),
                            cache=True,
                            dtstart=start,
                            until=end)
    non_trading_rules.append(labor_day)

    thanksgiving = rrule.rrule(rrule.MONTHLY,
                               bymonth=10,
                               byweekday=(rrule.MO(2)),
                               cache=True,
                               dtstart=start,
                               until=end)
    non_trading_rules.append(thanksgiving)

    christmas = rrule.rrule(rrule.MONTHLY,
                            bymonth=12,
                            bymonthday=25,
                            cache=True,
                            dtstart=start,
                            until=end)
    non_trading_rules.append(christmas)

    # If Christmas is a Sunday then the 26th, a Monday is observed.
    # (but that would be boxing day), so the 27th is also observed.
    christmas_sunday = rrule.rrule(rrule.MONTHLY,
                                   bymonth=12,
                                   bymonthday=27,
                                   byweekday=rrule.TU,
                                   cache=True,
                                   dtstart=start,
                                   until=end)
    non_trading_rules.append(christmas_sunday)

    # If Christmas is a Saturday then the 27th, a monday is observed.
    christmas_saturday = rrule.rrule(rrule.MONTHLY,
                                     bymonth=12,
                                     bymonthday=27,
                                     byweekday=rrule.MO,
                                     cache=True,
                                     dtstart=start,
                                     until=end)
    non_trading_rules.append(christmas_saturday)

    boxing_day = rrule.rrule(rrule.MONTHLY,
                             bymonth=12,
                             bymonthday=26,
                             cache=True,
                             dtstart=start,
                             until=end)
    non_trading_rules.append(boxing_day)

    #if boxing day is a sunday, the Christmas was saturday.
    # Christmas is observed on the 27th, a month and boxing day is observed
    # on the 28th, a tuesday.
    boxing_day_sunday = rrule.rrule(rrule.MONTHLY,
                                    bymonth=12,
                                    bymonthday=28,
                                    byweekday=rrule.TU,
                                    cache=True,
                                    dtstart=start,
                                    until=end)
    non_trading_rules.append(boxing_day_sunday)

    # If boxing day is a Saturday then the 28th, a monday is observed.
    boxing_day_saturday = rrule.rrule(rrule.MONTHLY,
                                      bymonth=12,
                                      bymonthday=28,
                                      byweekday=rrule.MO,
                                      cache=True,
                                      dtstart=start,
                                      until=end)
    non_trading_rules.append(boxing_day_saturday)

    non_trading_ruleset = rrule.rruleset()

    for rule in non_trading_rules:
        non_trading_ruleset.rrule(rule)

    non_trading_days = non_trading_ruleset.between(start, end, inc=True)

    # Add September 11th closings
    # The TSX was open for 71 minutes on September 11, 2011.
    # It was closed on the 12th and reopened on the 13th.
    # http://www.cbc.ca/news2/interactives/map-tsx/
    #
    #    September 2001
    # Su Mo Tu We Th Fr Sa
    #                    1
    #  2  3  4  5  6  7  8
    #  9 10 11 12 13 14 15
    # 16 17 18 19 20 21 22
    # 23 24 25 26 27 28 29
    # 30

    non_trading_days.append(datetime(2001, 9, 12, tzinfo=pytz.utc))

    non_trading_days.sort()
    return pd.DatetimeIndex(non_trading_days)