Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Irregular English bank holidays missing from the LSE calender #84

Closed
matthew-tomlinson opened this issue Feb 7, 2020 · 4 comments
Closed

Comments

@matthew-tomlinson
Copy link

matthew-tomlinson commented Feb 7, 2020

Could you please account for the following occasions in which the LSE was either closed due to a one-off English bank holiday or open due to the removal of a regular bank holiday in compensation [1, 2].

This code includes all the dates on which ad-hoc holiday addition or removal is required:

import pandas as pd
import pandas_market_calendars as mcal

England_unique_hols_names = [
                                "VE_50", "VE_75", 
                                "QEII_Jubilee_25", "QEII_Jubilee_50", "QEII_Jubilee_60",
                                "Royal_Wedding_Anne_1973", "Royal_Wedding_Charles_1981", "Royal_Wedding_William_2011",
                                "3rd_Millenium_Eve",
                            ]
England_unique_hols = {i: {"closed": None, "open": None} for i in England_unique_hols_names}

#=====================================================
# One-off holiday additions and removals in England
#=====================================================

## VE-Day Anniversary
# 50th Anniversary
England_unique_hols["VE_50"]["closed"] = [pd.Timestamp("1995-05-08")]      
England_unique_hols["VE_50"]["open"] = [pd.Timestamp("1995-05-01")]     # Early May bank holiday removed
# 75th Anniversary
England_unique_hols["VE_75"]["closed"] = [pd.Timestamp("2020-05-08")]      
England_unique_hols["VE_75"]["open"] = [pd.Timestamp("2020-05-04")]     # Early May bank holiday removed

## Queen Elizabeth II Jubilees
# Silver Jubilee
England_unique_hols["QEII_Jubilee_25"]["closed"] = [pd.Timestamp("1977-06-07")]
# Golden Jubilee
England_unique_hols["QEII_Jubilee_50"]["closed"] = [pd.Timestamp("2002-06-03"), pd.Timestamp("2002-06-04")]    
England_unique_hols["QEII_Jubilee_50"]["open"] = [pd.Timestamp("2002-05-27")]                                   # Spring bank holiday removed
# Diamond Jubilee
England_unique_hols["QEII_Jubilee_60" ]["closed"] = [pd.Timestamp("2012-06-04"), pd.Timestamp("2012-06-05")]    # Already added in ecd8ec4
England_unique_hols["QEII_Jubilee_60" ]["open"] = [pd.Timestamp("2012-05-28")]                                  # Spring bank holiday removed (Not removed as of release 1.2)

## Royal Weddings
# Wedding Day of Princess Anne and Mark Phillips
England_unique_hols["Royal_Wedding_Anne_1973"]["closed"] = [pd.Timestamp("1973-11-14")]      
# Wedding Day of Prince Charles and Diana Spencer
England_unique_hols["Royal_Wedding_Charles_1981"]["closed"] = [pd.Timestamp("1981-07-29")]     
# Wedding Day of Prince William and Catherine Middleton
England_unique_hols["Royal_Wedding_William_2011"]["closed"] = [pd.Timestamp("2011-04-29")]  

## Miscellaneous
# Eve of 3rd Millenium A.D.
England_unique_hols["3rd_Millenium_Eve"]["closed"] = [pd.Timestamp("1999-12-31")] 


#=====================================================
# Test of current LSE calender
#=====================================================

LSE_sch = mcal.get_calendar("LSE").schedule(start_date="1900-01-01", end_date="2099-12-31")

for i in England_unique_hols:

    print(i)

    min_closed = np.min(England_unique_hols[i]["closed"])
    max_closed = np.max(England_unique_hols[i]["closed"])
    print("should be closed:")
    print(LSE_sch.iloc[np.logical_and(min_closed <= LSE_sch.index, LSE_sch.index <= max_closed)]) 
    if England_unique_hols[i]["open"] is not None:
        min_open = np.min(England_unique_hols[i]["open"])
        max_open = np.max(England_unique_hols[i]["open"])
        print("should be open:")
        print(LSE_sch.iloc[np.logical_and(min_open <= LSE_sch.index, LSE_sch.index <= max_open)]) 
        
    print("")

Running the above gives the following output:

VE_50
should be closed:
                         market_open              market_close
1995-05-08 1995-05-08 07:00:00+00:00 1995-05-08 15:30:00+00:00
should be open:
Empty DataFrame
Columns: [market_open, market_close]
Index: []

VE_75
should be closed:
                         market_open              market_close
2020-05-08 2020-05-08 07:00:00+00:00 2020-05-08 15:30:00+00:00
should be open:
Empty DataFrame
Columns: [market_open, market_close]
Index: []

QEII_Jubilee_25
should be closed:
                         market_open              market_close
1977-06-07 1977-06-07 07:00:00+00:00 1977-06-07 15:30:00+00:00

QEII_Jubilee_50
should be closed:
                         market_open              market_close
2002-06-03 2002-06-03 07:00:00+00:00 2002-06-03 15:30:00+00:00
2002-06-04 2002-06-04 07:00:00+00:00 2002-06-04 15:30:00+00:00
should be open:
Empty DataFrame
Columns: [market_open, market_close]
Index: []

QEII_Jubilee_60
should be closed:
Empty DataFrame
Columns: [market_open, market_close]
Index: []
should be open:
Empty DataFrame
Columns: [market_open, market_close]
Index: []

Royal_Wedding_Anne_1973
should be closed:
                         market_open              market_close
1973-11-14 1973-11-14 08:00:00+00:00 1973-11-14 16:30:00+00:00

Royal_Wedding_Charles_1981
should be closed:
                         market_open              market_close
1981-07-29 1981-07-29 07:00:00+00:00 1981-07-29 15:30:00+00:00

Royal_Wedding_William_2011
should be closed:
                         market_open              market_close
2011-04-29 2011-04-29 07:00:00+00:00 2011-04-29 15:30:00+00:00

3rd_Millenium_Eve
should be closed:
                         market_open              market_close
1999-12-31 1999-12-31 08:00:00+00:00 1999-12-31 12:30:00+00:00

I note that you have already added the additional holidays on 2012-06-04 and 2012-06-05 for the Diamond Jubilee, but did not remove the corresonding spring bank holiday on 2012-05-28.

Thank you in advance.

@rsheftel
Copy link
Owner

First, than you very much for this. I pushed a new commit that includes all the closed dates you identified with unit tests. For the holidays that are skipped and open, I am not able yet to figure out how the Pandas library (which drives this package) can work for that. If you know how that would be great, otherwise at some point I may need to hard code the holidays so can force the skip.

@rbubley
Copy link

rbubley commented May 5, 2020

As one of these extra holidays is this coming Friday, it would be good to cut a release before then if possible.

rsheftel added a commit that referenced this issue May 5, 2020
@rsheftel
Copy link
Owner

rsheftel commented May 5, 2020

@rbubley v.1.3.4 has been published to PyPi with the fixes above. Note that the removal of holidays has not been implemented yet.

@rsheftel
Copy link
Owner

rsheftel commented May 7, 2020

@matthew-tomlinson I figured out how to make the skipped holidays show as open. So now everything you highlighted has been fixed and there is a test in the code to make sure it works. This is in the commit 04e94a1 and pushed to PyPi as v1.3.5

Thank you very much for all your work on this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants