<jupyter_start><jupyter_text>Calendar properties This tutorial offers a walk through of ExchangeCalendar properties (for methods see the [calendar methods](./calendar_methods.ipynb) tutorial).NB properties that _define_ a calendar (`open_times`, `special_closes_adhoc` etc) are not covered by this tutorial (see the [How can I create a new calendar](https://github.com/gerrymanoim/exchange_calendars/tree/masterhow-can-i-create-a-new-calendar) section of the [README](https://github.com/gerrymanoim/exchange_calendars/tree/master)).<jupyter_code># set up
import exchange_calendars as xcals
import pandas as pd

hkg = xcals.get_calendar("XHKG", side="left")  # Hong Kong Stock Exchange
nys = xcals.get_calendar("XNYS", side="left")  # New York Stock Exchange<jupyter_output><empty_output><jupyter_text>Calendar construction The **`bound_*`** properties return the earliest/latest date from/to which a calendar class can be constructed, or None if there is no limit:<jupyter_code>hkg.bound_start, hkg.bound_end
nys.bound_start == nys.bound_end == None<jupyter_output><empty_output><jupyter_text>**`default_start`**/**`default_end`** return the dates from/to which a calendar will be created if the `start`/`end` parameters are not passed to the constructor (unless limited by the bounds, the defaults are '20 years ago' / '1 year from now'):<jupyter_code>nys.default_start, nys.default_end<jupyter_output><empty_output><jupyter_text>**`default_side`** is a class method that returns the calendar's default side in the event `side` is not otherwise passed to the constructor. By default 24-hour calendars are side "right" and all others side "both".<jupyter_code>open24 = xcals.get_calendar("24/7")
open24.default_side(), nys.default_side()<jupyter_output><empty_output><jupyter_text>NB the actual calendar side is returned by the **`side`** property.<jupyter_code>nys.default_side(), nys.side<jupyter_output><empty_output><jupyter_text>**`valid_sides`** is a class method that returns all side values that can be passed to the constructor's `side` parameter:<jupyter_code>nys.valid_sides()
open24.valid_sides()<jupyter_output><empty_output><jupyter_text>See the [minutes](./minutes.ipynb) tutorial for an explanation of how a calendar's side determines which minutes are treated as trading minutes.  General Calendar Properties<jupyter_code>nys.name
nys.tz  # timezone
nys.side<jupyter_output><empty_output><jupyter_text>**`day`** returns a `CustomBusinessDay` for the calendar:<jupyter_code># for reference
nys.sessions_in_range("2020-12-29", "2021-01-06")
pd.Timestamp("2020-12-31") + (nys.day * 2)<jupyter_output><empty_output><jupyter_text>**`has_break`** queries if _any_ calendar session has a break<jupyter_code>nys.has_break<jupyter_output><empty_output><jupyter_text>Sessions and Minutes **NOTE:** This section does little more than catalogue the calendar properties concerned with sessions or minutes. See the [sessions](./sessions.ipynb) and [minutes](./minutes.ipynb) tutorials for notes on 'working with sessions/minutes'.  All of them<jupyter_code>nys.sessions  # DatetimeIndex representing all calendar sessions
nys.minutes  # DatetimeIndex representing every calendar trading minute<jupyter_output><empty_output><jupyter_text>Calendar Bounds<jupyter_code>nys.first_session, nys.last_session
nys.first_minute, nys.last_minute
nys.first_session_open, nys.last_session_close<jupyter_output><empty_output><jupyter_text>Schedule (open, close and break times)<jupyter_code>hkg.schedule<jupyter_output><empty_output><jupyter_text>The schedule is a pandas DataFrame. It shows the days the exchange is open and describes the bounds when the exchange is open for regular trading on each of those days.The index represents the calendar's sessions as a pandas DatetimeIndex with timezone as UTC. For each session, the columns offer the open, close and, if applicable, break-start and break-end time. **The times are defined in UTC terms although the actual columns' DatetimeIndex are tz-naive**.**NB It's proposed that from version 4.0 the timezone of the columns' DatetimeIndex will be set to "UTC" whilst the index will become tz-naive.** Have your say [here](https://github.com/gerrymanoim/exchange_calendars/issues/42).The break_start/break_end columns take pd.NaT in the event that a session does not have a break.<jupyter_code>hkg.schedule.loc["2020-12-23":"2020-12-28"]<jupyter_output><empty_output><jupyter_text>The properties **`opens`**, **`closes`**, **`break_starts`** and **`break_ends`** return the corresponding column of the schedule as a pd.Series.<jupyter_code>hkg.opens<jupyter_output><empty_output><jupyter_text>As for the schedule, **although these times are defined in terms of UTC, the properties are tz-naive** (again, it's anticipated that from version 4.0 the timezone of these properties will be set to "UTC", see [42](https://github.com/gerrymanoim/exchange_calendars/issues/42)). The **`late_opens`** and **`early_closes`** properties return a DatetimeIndex of those sessions that have a later open/earlier close than the prevailing regular open/close time.<jupyter_code>nys.early_closes[-10:]<jupyter_output><empty_output><jupyter_text>Bound Trading Minutes by-sessions The **`first_*`** and **`last_*`** methods return pd.Series with index as `sessions` and value as the corresponding trading minute (UTC) for the session. NB As explained in the [minutes tutorial](./minutes.ipynb), these minutes are not necessarily the same as the session open/close/break times.<jupyter_code>nys.first_minutes
nys.last_minutes
# in terms of local times...
nys.last_minutes.dt.tz_convert(nys.tz)
# last pre-break minute of am subsession
hkg.last_am_minutes["2020-12-23":"2020-12-28"]
# first post-break minute of pm subsession
hkg.first_pm_minutes.loc["2020-12-23":"2020-12-28"]
# in local time...
hkg.first_pm_minutes.loc["2020-12-23":"2020-12-28"].dt.tz_convert(hkg.tz)<jupyter_output><empty_output><jupyter_text>Nanos Many sessions/minutes properties that return a `DatetimeIndex` have a 'nanos' equivalent that returns a numpy ndarray of integers.Why? Internally `ExchangeCalendar` uses these nano arrays because they are faster to operate on than `DatetimeIndex`. Indeed, for some operations, working with nanos can be **much** faster.<jupyter_code>hkg.sessions_nanos, hkg.minutes_nanos
hkg.opens_nanos, hkg.closes_nanos
hkg.break_starts_nanos, hkg.break_ends_nanos, 
hkg.first_minutes_nanos, hkg.last_minutes_nanos
hkg.last_am_minutes_nanos, hkg.first_pm_minutes_nanos<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10426249616682, 'fraction_numerical': 0.017632628028212204, 'mean_word_length': 6.897094430992736, 'pattern_counts': {'":': 4, '<': 69, '<?xml version=': 0, '>': 69, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '17', 'dir': 'jupyter-structured-clean-dedup', 'id': '297657', 'license': 'Apache-2.0', 'n_tokens_mistral': 2178, 'n_tokens_neox': 2046, 'n_words': 611, 'path': 'docs/tutorials/calendar_properties.ipynb', 'repo_name': 'philiptromans/exchange_calendars', 'size': '6522'}