Copy disabled (too large)
Download .txt
Showing preview only (34,354K chars total). Download the full file to get everything.
Repository: gerrymanoim/exchange_calendars
Branch: master
Commit: 3668a8961d0b
Files: 278
Total size: 32.7 MB
Directory structure:
gitextract_kugg5ghl/
├── .devcontainer/
│ ├── Dockerfile
│ ├── base.Dockerfile
│ ├── devcontainer.json
│ └── library-scripts/
│ ├── README.md
│ ├── common-debian.sh
│ ├── node-debian.sh
│ └── python-debian.sh
├── .gitattributes
├── .github/
│ ├── dependabot.yml
│ ├── pull_request_template.md
│ ├── release-drafter-config.yml
│ └── workflows/
│ ├── benchmark.yml
│ ├── labeler.yml
│ ├── main.yml
│ ├── master-merge.yml
│ └── release.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .python-version
├── LICENSE
├── MANIFEST.in
├── README.md
├── docs/
│ ├── changes_archive.md
│ ├── dev/
│ │ └── depenencies_update.md
│ └── tutorials/
│ ├── calendar_methods.ipynb
│ ├── calendar_properties.ipynb
│ ├── minutes.ipynb
│ ├── sessions.ipynb
│ └── trading_index.ipynb
├── etc/
│ ├── __init__.py
│ ├── bench.py
│ ├── check_holidays.py
│ ├── ecal
│ ├── factory_bounds.py
│ ├── lunisolar
│ ├── make_exchange_calendar_test_csv.py
│ └── update_xkrx_holidays.py
├── exchange_calendars/
│ ├── __init__.py
│ ├── always_open.py
│ ├── calendar_helpers.py
│ ├── calendar_utils.py
│ ├── common_holidays.py
│ ├── ecal.py
│ ├── errors.py
│ ├── exchange_calendar.py
│ ├── exchange_calendar_aixk.py
│ ├── exchange_calendar_asex.py
│ ├── exchange_calendar_bvmf.py
│ ├── exchange_calendar_cmes.py
│ ├── exchange_calendar_iepa.py
│ ├── exchange_calendar_xams.py
│ ├── exchange_calendar_xasx.py
│ ├── exchange_calendar_xbda.py
│ ├── exchange_calendar_xbel.py
│ ├── exchange_calendar_xbkk.py
│ ├── exchange_calendar_xbog.py
│ ├── exchange_calendar_xbom.py
│ ├── exchange_calendar_xbra.py
│ ├── exchange_calendar_xbru.py
│ ├── exchange_calendar_xbse.py
│ ├── exchange_calendar_xbud.py
│ ├── exchange_calendar_xbue.py
│ ├── exchange_calendar_xcbf.py
│ ├── exchange_calendar_xcse.py
│ ├── exchange_calendar_xcys.py
│ ├── exchange_calendar_xdub.py
│ ├── exchange_calendar_xdus.py
│ ├── exchange_calendar_xeee.py
│ ├── exchange_calendar_xetr.py
│ ├── exchange_calendar_xeur.py
│ ├── exchange_calendar_xfra.py
│ ├── exchange_calendar_xham.py
│ ├── exchange_calendar_xhel.py
│ ├── exchange_calendar_xhkg.py
│ ├── exchange_calendar_xice.py
│ ├── exchange_calendar_xidx.py
│ ├── exchange_calendar_xist.py
│ ├── exchange_calendar_xjse.py
│ ├── exchange_calendar_xkar.py
│ ├── exchange_calendar_xkls.py
│ ├── exchange_calendar_xkrx.py
│ ├── exchange_calendar_xlim.py
│ ├── exchange_calendar_xlis.py
│ ├── exchange_calendar_xlit.py
│ ├── exchange_calendar_xlju.py
│ ├── exchange_calendar_xlon.py
│ ├── exchange_calendar_xlux.py
│ ├── exchange_calendar_xmad.py
│ ├── exchange_calendar_xmex.py
│ ├── exchange_calendar_xmil.py
│ ├── exchange_calendar_xmos.py
│ ├── exchange_calendar_xnys.py
│ ├── exchange_calendar_xnze.py
│ ├── exchange_calendar_xosl.py
│ ├── exchange_calendar_xpar.py
│ ├── exchange_calendar_xphs.py
│ ├── exchange_calendar_xpra.py
│ ├── exchange_calendar_xris.py
│ ├── exchange_calendar_xsau.py
│ ├── exchange_calendar_xses.py
│ ├── exchange_calendar_xsgo.py
│ ├── exchange_calendar_xshg.py
│ ├── exchange_calendar_xsto.py
│ ├── exchange_calendar_xstu.py
│ ├── exchange_calendar_xswx.py
│ ├── exchange_calendar_xtae.py
│ ├── exchange_calendar_xtai.py
│ ├── exchange_calendar_xtal.py
│ ├── exchange_calendar_xtks.py
│ ├── exchange_calendar_xtse.py
│ ├── exchange_calendar_xwar.py
│ ├── exchange_calendar_xwbo.py
│ ├── exchange_calendar_xzag.py
│ ├── lunisolar_holidays.py
│ ├── pandas_extensions/
│ │ ├── __init__.py
│ │ ├── holiday.py
│ │ ├── korean_holiday.py
│ │ └── offsets.py
│ ├── precomputed_exchange_calendar.py
│ ├── tase_holidays.py
│ ├── us_futures_calendar.py
│ ├── us_holidays.py
│ ├── utils/
│ │ ├── __init__.py
│ │ └── pandas_utils.py
│ ├── weekday_calendar.py
│ ├── xbkk_holidays.py
│ ├── xkls_holidays.py
│ ├── xkrx_holidays.py
│ └── xtks_holidays.py
├── pyproject.toml
├── requirements.txt
├── ruff.toml
└── tests/
├── __init__.py
├── resources/
│ ├── 24-5.csv
│ ├── 24-7.csv
│ ├── aixk.csv
│ ├── asex.csv
│ ├── bvmf.csv
│ ├── cmes.csv
│ ├── iepa.csv
│ ├── test.csv
│ ├── xams.csv
│ ├── xasx.csv
│ ├── xbda.csv
│ ├── xbel.csv
│ ├── xbkk.csv
│ ├── xbog.csv
│ ├── xbom.csv
│ ├── xbra.csv
│ ├── xbru.csv
│ ├── xbse.csv
│ ├── xbud.csv
│ ├── xbue.csv
│ ├── xcbf.csv
│ ├── xcse.csv
│ ├── xcys.csv
│ ├── xdub.csv
│ ├── xdus.csv
│ ├── xeee.csv
│ ├── xetr.csv
│ ├── xeur.csv
│ ├── xfra.csv
│ ├── xham.csv
│ ├── xhel.csv
│ ├── xhkg.csv
│ ├── xice.csv
│ ├── xidx.csv
│ ├── xist.csv
│ ├── xjse.csv
│ ├── xkar.csv
│ ├── xkls.csv
│ ├── xkrx.csv
│ ├── xlim.csv
│ ├── xlis.csv
│ ├── xlit.csv
│ ├── xlju.csv
│ ├── xlon.csv
│ ├── xlux.csv
│ ├── xmad.csv
│ ├── xmex.csv
│ ├── xmil.csv
│ ├── xmos.csv
│ ├── xnys.csv
│ ├── xnze.csv
│ ├── xosl.csv
│ ├── xpar.csv
│ ├── xphs.csv
│ ├── xpra.csv
│ ├── xris.csv
│ ├── xsau.csv
│ ├── xses.csv
│ ├── xsgo.csv
│ ├── xshg.csv
│ ├── xsto.csv
│ ├── xstu.csv
│ ├── xswx.csv
│ ├── xtae.csv
│ ├── xtai.csv
│ ├── xtal.csv
│ ├── xtks.csv
│ ├── xtse.csv
│ ├── xwar.csv
│ ├── xwbo.csv
│ └── xzag.csv
├── test_aixk_calendar.py
├── test_always_open.py
├── test_asex_calendar.py
├── test_bvmf_calendar.py
├── test_calendar_dispatcher.py
├── test_calendar_helpers.py
├── test_cmes_calendar.py
├── test_exchange_calendar.py
├── test_iepa_calendar.py
├── test_utils.py
├── test_weekday_calendar.py
├── test_xams_calendar.py
├── test_xasx_calendar.py
├── test_xbda_calendar.py
├── test_xbel_calendar.py
├── test_xbkk_calendar.py
├── test_xbog_calendar.py
├── test_xbom_calendar.py
├── test_xbra_calendar.py
├── test_xbru_calendar.py
├── test_xbse_calendar.py
├── test_xbud_calendar.py
├── test_xbue_calendar.py
├── test_xcbf_calendar.py
├── test_xcse_calendar.py
├── test_xcys_calendar.py
├── test_xdub_calendar.py
├── test_xdus_calendar.py
├── test_xeee_calendar.py
├── test_xetr_calendar.py
├── test_xeur_calendar.py
├── test_xfra_calendar.py
├── test_xham_calendar.py
├── test_xhel_calendar.py
├── test_xhkg_calendar.py
├── test_xice_calendar.py
├── test_xidx_calendar.py
├── test_xist_calendar.py
├── test_xjse_calendar.py
├── test_xkar_calendar.py
├── test_xkls_calendar.py
├── test_xkrx_calendar.py
├── test_xlim_calendar.py
├── test_xlis_calendar.py
├── test_xlit_calendar.py
├── test_xlju_calendar.py
├── test_xlon_calendar.py
├── test_xlux_calendar.py
├── test_xmad_calendar.py
├── test_xmex_calendar.py
├── test_xmil_calendar.py
├── test_xmos_calendar.py
├── test_xnys_calendar.py
├── test_xnze_calendar.py
├── test_xosl_calendar.py
├── test_xpar_calendar.py
├── test_xphs_calendar.py
├── test_xpra_calendar.py
├── test_xris_calendar.py
├── test_xsau_calendar.py
├── test_xses_calendar.py
├── test_xsgo_calendar.py
├── test_xshg_calendar.py
├── test_xsto_calendar.py
├── test_xstu_calendar.py
├── test_xswx_calendar.py
├── test_xtae_calendar.py
├── test_xtai_calendar.py
├── test_xtal_calendar.py
├── test_xtks_calendar.py
├── test_xtse_calendar.py
├── test_xwar_calendar.py
├── test_xwbo_calendar.py
└── test_xzag_calendar.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .devcontainer/Dockerfile
================================================
# [Choice] Python version: 3, 3.11, 3.12, 3.13
ARG VARIANT=3
FROM mcr.microsoft.com/vscode/devcontainers/python:${VARIANT}
# [Option] Install Node.js
ARG INSTALL_NODE="true"
ARG NODE_VERSION="lts/*"
RUN if [ "${INSTALL_NODE}" = "true" ]; then su vscode -c "source /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
# [Optional] If your pip requirements rarely change, uncomment this section to add them to the image.
COPY requirements.txt /tmp/pip-tmp/
RUN pip3 --disable-pip-version-check --no-cache-dir install ipython \
&& pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \
&& rm -rf /tmp/pip-tmp
# Set the PYTHONTZPATH environment variable to use Python's tzdata package instead of the operating system's timezone data.
RUN python -c 'import os; print("export PYTHONTZPATH=\"" + os.path.dirname(os.__file__) + "\"")' >> /home/vscode/.profile
# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>
# [Optional] Uncomment this line to install global node packages.
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1
================================================
FILE: .devcontainer/base.Dockerfile
================================================
# [Choice] Python version: 3, 3.8, 3.7, 3.6
ARG VARIANT=3
FROM python:${VARIANT}
# [Option] Install zsh
ARG INSTALL_ZSH="true"
# [Option] Upgrade OS packages to their latest versions
ARG UPGRADE_PACKAGES="true"
# Install needed packages and setup non-root user. Use a separate RUN statement to add your own dependencies.
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID
COPY .devcontainer/library-scripts/common-debian.sh /tmp/library-scripts/
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# Remove imagemagick due to https://security-tracker.debian.org/tracker/CVE-2019-10131
&& apt-get purge -y imagemagick imagemagick-6-common \
# Install common packages, non-root user
&& bash /tmp/library-scripts/common-debian.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" \
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts
# Setup default python tools in a venv via pipx to avoid conflicts
ENV PIPX_HOME=/usr/local/py-utils \
PIPX_BIN_DIR=/usr/local/py-utils/bin
ENV PATH=${PATH}:${PIPX_BIN_DIR}
COPY .devcontainer/library-scripts/python-debian.sh /tmp/library-scripts/
RUN bash /tmp/library-scripts/python-debian.sh "none" "/usr/local" "${PIPX_HOME}" "${USERNAME}" "false" \
&& apt-get clean -y && rm -rf /tmp/library-scripts
# [Option] Install Node.js
ARG INSTALL_NODE="true"
ARG NODE_VERSION="none"
ENV NVM_DIR=/usr/local/share/nvm
ENV NVM_SYMLINK_CURRENT=true \
PATH=${NVM_DIR}/current/bin:${PATH}
COPY .devcontainer/library-scripts/node-debian.sh /tmp/library-scripts/
RUN if [ "$INSTALL_NODE" = "true" ]; then bash /tmp/library-scripts/node-debian.sh "${NVM_DIR}" "${NODE_VERSION}" "${USERNAME}"; fi \
&& apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts
# [Optional] If your pip requirements rarely change, uncomment this section to add them to the image.
# COPY requirements.txt /tmp/pip-tmp/
# RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \
# && rm -rf /tmp/pip-tmp
# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>
# [Optional] Uncomment this line to install global node packages.
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1
================================================
FILE: .devcontainer/devcontainer.json
================================================
{
"name": "Python 3",
"build": {
"dockerfile": "Dockerfile",
"context": "..",
"args": {
// Update 'VARIANT' to pick a Python version: 3, 3.11, 3.12, 3.13
"VARIANT": "3.13",
// Options
"INSTALL_NODE": "false",
"NODE_VERSION": "lts/*"
}
},
"features": {
"ghcr.io/va-h/devcontainers-features/uv:1": {},
"ghcr.io/devcontainers-extra/features/ruff:1": {}
},
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.shell.linux": "/bin/bash",
"python.pythonPath": "/usr/local/bin/python",
"python.linting.enabled": true,
"python.linting.pylintEnabled": true,
"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
"python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-python.python"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "pip3 install --user -e .[dev]",
// Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root.
// "remoteUser": "vscode"
}
================================================
FILE: .devcontainer/library-scripts/README.md
================================================
# Warning: Folder contents may be replaced
The contents of this folder will be automatically replaced with a file of the same name in the [vscode-dev-containers](https://github.com/microsoft/vscode-dev-containers) repository's [script-library folder](https://github.com/microsoft/vscode-dev-containers/tree/master/script-library) whenever the repository is packaged.
To retain your edits, move the file to a different location. You may also delete the files if they are not needed.
================================================
FILE: .devcontainer/library-scripts/common-debian.sh
================================================
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/master/script-library/docs/common.md
#
# Syntax: ./common-debian.sh [install zsh flag] [username] [user UID] [user GID] [upgrade packages flag] [install Oh My *! flag]
INSTALL_ZSH=${1:-"true"}
USERNAME=${2:-"automatic"}
USER_UID=${3:-"automatic"}
USER_GID=${4:-"automatic"}
UPGRADE_PACKAGES=${5:-"true"}
INSTALL_OH_MYS=${6:-"true"}
set -e
if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1
fi
# If in automatic mode, determine if a user already exists, if not use vscode
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
USERNAME=""
POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)")
for CURRENT_USER in ${POSSIBLE_USERS[@]}; do
if id -u ${CURRENT_USER} > /dev/null 2>&1; then
USERNAME=${CURRENT_USER}
break
fi
done
if [ "${USERNAME}" = "" ]; then
USERNAME=vscode
fi
elif [ "${USERNAME}" = "none" ]; then
USERNAME=root
USER_UID=0
USER_GID=0
fi
# Load markers to see which steps have already run
MARKER_FILE="/usr/local/etc/vscode-dev-containers/common"
if [ -f "${MARKER_FILE}" ]; then
echo "Marker file found:"
cat "${MARKER_FILE}"
source "${MARKER_FILE}"
fi
# Ensure apt is in non-interactive to avoid prompts
export DEBIAN_FRONTEND=noninteractive
# Function to call apt-get if needed
apt-get-update-if-needed()
{
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update
else
echo "Skipping apt-get update."
fi
}
# Run install apt-utils to avoid debconf warning then verify presence of other common developer tools and dependencies
if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then
apt-get-update-if-needed
PACKAGE_LIST="apt-utils \
git \
openssh-client \
gnupg2 \
iproute2 \
procps \
lsof \
htop \
net-tools \
psmisc \
curl \
wget \
rsync \
ca-certificates \
unzip \
zip \
nano \
vim-tiny \
less \
jq \
lsb-release \
apt-transport-https \
dialog \
libc6 \
libgcc1 \
libgssapi-krb5-2 \
libicu[0-9][0-9] \
liblttng-ust0 \
libstdc++6 \
zlib1g \
locales \
sudo \
ncdu \
man-db"
# Install libssl1.1 if available
if [[ ! -z $(apt-cache --names-only search ^libssl1.1$) ]]; then
PACKAGE_LIST="${PACKAGE_LIST} libssl1.1"
fi
# Install appropriate version of libssl1.0.x if available
LIBSSL=$(dpkg-query -f '${db:Status-Abbrev}\t${binary:Package}\n' -W 'libssl1\.0\.?' 2>&1 || echo '')
if [ "$(echo "$LIBSSL" | grep -o 'libssl1\.0\.[0-9]:' | uniq | sort | wc -l)" -eq 0 ]; then
if [[ ! -z $(apt-cache --names-only search ^libssl1.0.2$) ]]; then
# Debian 9
PACKAGE_LIST="${PACKAGE_LIST} libssl1.0.2"
elif [[ ! -z $(apt-cache --names-only search ^libssl1.0.0$) ]]; then
# Ubuntu 18.04, 16.04, earlier
PACKAGE_LIST="${PACKAGE_LIST} libssl1.0.0"
fi
fi
echo "Packages to verify are installed: ${PACKAGE_LIST}"
apt-get -y install --no-install-recommends ${PACKAGE_LIST} 2> >( grep -v 'debconf: delaying package configuration, since apt-utils is not installed' >&2 )
PACKAGES_ALREADY_INSTALLED="true"
fi
# Get to latest versions of all packages
if [ "${UPGRADE_PACKAGES}" = "true" ]; then
apt-get-update-if-needed
apt-get -y upgrade --no-install-recommends
apt-get autoremove -y
fi
# Ensure at least the en_US.UTF-8 UTF-8 locale is available.
# Common need for both applications and things like the agnoster ZSH theme.
if [ "${LOCALE_ALREADY_SET}" != "true" ] && ! grep -o -E '^\s*en_US.UTF-8\s+UTF-8' /etc/locale.gen > /dev/null; then
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
locale-gen
LOCALE_ALREADY_SET="true"
fi
# Create or update a non-root user to match UID/GID.
if id -u ${USERNAME} > /dev/null 2>&1; then
# User exists, update if needed
if [ "${USER_GID}" != "automatic" ] && [ "$USER_GID" != "$(id -G $USERNAME)" ]; then
groupmod --gid $USER_GID $USERNAME
usermod --gid $USER_GID $USERNAME
fi
if [ "${USER_UID}" != "automatic" ] && [ "$USER_UID" != "$(id -u $USERNAME)" ]; then
usermod --uid $USER_UID $USERNAME
fi
else
# Create user
if [ "${USER_GID}" = "automatic" ]; then
groupadd $USERNAME
else
groupadd --gid $USER_GID $USERNAME
fi
if [ "${USER_UID}" = "automatic" ]; then
useradd -s /bin/bash --gid $USERNAME -m $USERNAME
else
useradd -s /bin/bash --uid $USER_UID --gid $USERNAME -m $USERNAME
fi
fi
# Add add sudo support for non-root user
if [ "${USERNAME}" != "root" ] && [ "${EXISTING_NON_ROOT_USER}" != "${USERNAME}" ]; then
echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME
chmod 0440 /etc/sudoers.d/$USERNAME
EXISTING_NON_ROOT_USER="${USERNAME}"
fi
# ** Shell customization section **
if [ "${USERNAME}" = "root" ]; then
USER_RC_PATH="/root"
else
USER_RC_PATH="/home/${USERNAME}"
fi
# .bashrc/.zshrc snippet
RC_SNIPPET="$(cat << EOF
export USER=\$(whoami)
export PATH=\$PATH:\$HOME/.local/bin
EOF
)"
# code shim, it fallbacks to code-insiders if code is not available
cat << 'EOF' > /usr/local/bin/code
#!/bin/sh
get_in_path_except_current() {
which -a "$1" | grep -v "$0" | head -1
}
code="$(get_in_path_except_current code)"
if [ -n "$code" ]; then
exec "$code" "$@"
elif [ "$(command -v code-insiders)" ]; then
exec code-insiders "$@"
else
echo "code or code-insiders is not installed" >&2
exit 127
fi
EOF
chmod +x /usr/local/bin/code
# Codespaces themes - partly inspired by https://github.com/ohmyzsh/ohmyzsh/blob/master/themes/robbyrussell.zsh-theme
CODESPACES_BASH="$(cat \
<<EOF
#!/usr/bin/env bash
prompt() {
if [ "\$?" != "0" ]; then
local arrow_color=\${bold_red}
else
local arrow_color=\${reset_color}
fi
if [ ! -z "\${GITHUB_USER}" ]; then
local USERNAME="@\${GITHUB_USER}"
else
local USERNAME="\\u"
fi
local cwd="\$(pwd | sed "s|^\${HOME}|~|")"
PS1="\${green}\${USERNAME} \${arrow_color}➜\${reset_color} \${bold_blue}\${cwd}\${reset_color} \$(scm_prompt_info)\${white}$ \${reset_color}"
}
SCM_THEME_PROMPT_PREFIX="\${reset_color}\${cyan}(\${bold_red}"
SCM_THEME_PROMPT_SUFFIX="\${reset_color} "
SCM_THEME_PROMPT_DIRTY=" \${bold_yellow}✗\${reset_color}\${cyan})"
SCM_THEME_PROMPT_CLEAN="\${reset_color}\${cyan})"
SCM_GIT_SHOW_MINIMAL_INFO="true"
safe_append_prompt_command prompt
EOF
)"
CODESPACES_ZSH="$(cat \
<<EOF
prompt() {
if [ ! -z "\${GITHUB_USER}" ]; then
local USERNAME="@\${GITHUB_USER}"
else
local USERNAME="%n"
fi
PROMPT="%{\$fg[green]%}\${USERNAME} %(?:%{\$reset_color%}➜ :%{\$fg_bold[red]%}➜ )"
PROMPT+='%{\$fg_bold[blue]%}%~%{\$reset_color%} \$(git_prompt_info)%{\$fg[white]%}$ %{\$reset_color%}'
}
ZSH_THEME_GIT_PROMPT_PREFIX="%{\$fg_bold[cyan]%}(%{\$fg_bold[red]%}"
ZSH_THEME_GIT_PROMPT_SUFFIX="%{\$reset_color%} "
ZSH_THEME_GIT_PROMPT_DIRTY=" %{\$fg_bold[yellow]%}✗%{\$fg_bold[cyan]%})"
ZSH_THEME_GIT_PROMPT_CLEAN="%{\$fg_bold[cyan]%})"
prompt
EOF
)"
# Adapted Oh My Zsh! install step to work with both "Oh Mys" rather than relying on an installer script
# See https://github.com/ohmyzsh/ohmyzsh/blob/master/tools/install.sh for offical script.
install-oh-my()
{
local OH_MY=$1
local OH_MY_INSTALL_DIR="${USER_RC_PATH}/.oh-my-${OH_MY}"
local TEMPLATE="${OH_MY_INSTALL_DIR}/templates/$2"
local OH_MY_GIT_URL=$3
local USER_RC_FILE="${USER_RC_PATH}/.${OH_MY}rc"
if [ -d "${OH_MY_INSTALL_DIR}" ] || [ "${INSTALL_OH_MYS}" != "true" ]; then
return 0
fi
umask g-w,o-w
mkdir -p ${OH_MY_INSTALL_DIR}
git clone --depth=1 \
-c core.eol=lf \
-c core.autocrlf=false \
-c fsck.zeroPaddedFilemode=ignore \
-c fetch.fsck.zeroPaddedFilemode=ignore \
-c receive.fsck.zeroPaddedFilemode=ignore \
${OH_MY_GIT_URL} ${OH_MY_INSTALL_DIR} 2>&1
echo -e "$(cat "${TEMPLATE}")\nDISABLE_AUTO_UPDATE=true\nDISABLE_UPDATE_PROMPT=true" > ${USER_RC_FILE}
if [ "${OH_MY}" = "bash" ]; then
sed -i -e 's/OSH_THEME=.*/OSH_THEME="codespaces"/g' ${USER_RC_FILE}
mkdir -p ${OH_MY_INSTALL_DIR}/custom/themes/codespaces
echo "${CODESPACES_BASH}" > ${OH_MY_INSTALL_DIR}/custom/themes/codespaces/codespaces.theme.sh
else
sed -i -e 's/ZSH_THEME=.*/ZSH_THEME="codespaces"/g' ${USER_RC_FILE}
mkdir -p ${OH_MY_INSTALL_DIR}/custom/themes
echo "${CODESPACES_ZSH}" > ${OH_MY_INSTALL_DIR}/custom/themes/codespaces.zsh-theme
fi
# Shrink git while still enabling updates
cd ${OH_MY_INSTALL_DIR}
git repack -a -d -f --depth=1 --window=1
if [ "${USERNAME}" != "root" ]; then
cp -rf ${USER_RC_FILE} ${OH_MY_INSTALL_DIR} /root
chown -R ${USERNAME}:${USERNAME} ${USER_RC_PATH}
fi
}
if [ "${RC_SNIPPET_ALREADY_ADDED}" != "true" ]; then
echo "${RC_SNIPPET}" >> /etc/bash.bashrc
RC_SNIPPET_ALREADY_ADDED="true"
fi
install-oh-my bash bashrc.osh-template https://github.com/ohmybash/oh-my-bash
# Optionally install and configure zsh and Oh My Zsh!
if [ "${INSTALL_ZSH}" = "true" ]; then
if ! type zsh > /dev/null 2>&1; then
apt-get-update-if-needed
apt-get install -y zsh
fi
if [ "${ZSH_ALREADY_INSTALLED}" != "true" ]; then
echo "${RC_SNIPPET}" >> /etc/zsh/zshrc
ZSH_ALREADY_INSTALLED="true"
fi
install-oh-my zsh zshrc.zsh-template https://github.com/ohmyzsh/ohmyzsh
fi
# Write marker file
mkdir -p "$(dirname "${MARKER_FILE}")"
echo -e "\
PACKAGES_ALREADY_INSTALLED=${PACKAGES_ALREADY_INSTALLED}\n\
LOCALE_ALREADY_SET=${LOCALE_ALREADY_SET}\n\
EXISTING_NON_ROOT_USER=${EXISTING_NON_ROOT_USER}\n\
RC_SNIPPET_ALREADY_ADDED=${RC_SNIPPET_ALREADY_ADDED}\n\
ZSH_ALREADY_INSTALLED=${ZSH_ALREADY_INSTALLED}" > "${MARKER_FILE}"
echo "Done!"
================================================
FILE: .devcontainer/library-scripts/node-debian.sh
================================================
#!/bin/bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/master/script-library/docs/node.md
#
# Syntax: ./node-debian.sh [directory to install nvm] [node version to install (use "none" to skip)] [non-root user] [Update rc files flag]
export NVM_DIR=${1:-"/usr/local/share/nvm"}
export NODE_VERSION=${2:-"lts/*"}
USERNAME=${3:-"automatic"}
UPDATE_RC=${4:-"true"}
set -e
if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1
fi
# Determine the appropriate non-root user
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
USERNAME=""
POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)")
for CURRENT_USER in ${POSSIBLE_USERS[@]}; do
if id -u ${CURRENT_USER} > /dev/null 2>&1; then
USERNAME=${CURRENT_USER}
break
fi
done
if [ "${USERNAME}" = "" ]; then
USERNAME=root
fi
elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then
USERNAME=root
fi
if [ "${NODE_VERSION}" = "none" ]; then
export NODE_VERSION=
fi
# Ensure apt is in non-interactive to avoid prompts
export DEBIAN_FRONTEND=noninteractive
# Install curl, apt-transport-https, tar, or gpg if missing
if ! dpkg -s apt-transport-https curl ca-certificates tar > /dev/null 2>&1 || ! type gpg > /dev/null 2>&1; then
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
apt-get update
fi
apt-get -y install --no-install-recommends apt-transport-https curl ca-certificates tar gnupg2
fi
# Install yarn
if type yarn > /dev/null 2>&1; then
echo "Yarn already installed."
else
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | (OUT=$(apt-key add - 2>&1) || echo $OUT)
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
apt-get update
apt-get -y install --no-install-recommends yarn
fi
# Install the specified node version if NVM directory already exists, then exit
if [ -d "${NVM_DIR}" ]; then
echo "NVM already installed."
if [ "${NODE_VERSION}" != "" ]; then
su ${USERNAME} -c "source $NVM_DIR/nvm.sh && nvm install ${NODE_VERSION} && nvm clear-cache"
fi
exit 0
fi
# Run NVM installer as non-root if needed
mkdir -p ${NVM_DIR}
chown ${USERNAME} ${NVM_DIR}
su ${USERNAME} -c "$(cat << EOF
set -e
# Do not update profile - we'll do this manually
export PROFILE=/dev/null
curl -so- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
source ${NVM_DIR}/nvm.sh
if [ "${NODE_VERSION}" != "" ]; then
nvm alias default ${NODE_VERSION}
fi
nvm clear-cache
EOF
)" 2>&1
if [ "${UPDATE_RC}" = "true" ]; then
echo "Updating /etc/bash.bashrc and /etc/zsh/zshrc with NVM scripts..."
(cat <<EOF
export NVM_DIR="${NVM_DIR}"
sudoIf()
{
if [ "\$(id -u)" -ne 0 ]; then
sudo "\$@"
else
"\$@"
fi
}
if [ "\$(stat -c '%U' \$NVM_DIR)" != "${USERNAME}" ]; then
if [ "\$(id -u)" -eq 0 ] || type sudo > /dev/null 2>&1; then
echo "Fixing permissions of \"\$NVM_DIR\"..."
sudoIf chown -R ${USERNAME}:root \$NVM_DIR
else
echo "Warning: NVM directory is not owned by ${USERNAME} and sudo is not installed. Unable to correct permissions."
fi
fi
[ -s "\$NVM_DIR/nvm.sh" ] && . "\$NVM_DIR/nvm.sh"
[ -s "\$NVM_DIR/bash_completion" ] && . "\$NVM_DIR/bash_completion"
EOF
) | tee -a /etc/bash.bashrc >> /etc/zsh/zshrc
fi
echo "Done!"
================================================
FILE: .devcontainer/library-scripts/python-debian.sh
================================================
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/master/script-library/docs/python.md
#
# Syntax: ./python-debian.sh [Python Version] [Python intall path] [PIPX_HOME] [non-root user] [Update rc files flag] [install tools]
PYTHON_VERSION=${1:-"3.8.3"}
PYTHON_INSTALL_PATH=${2:-"/usr/local/python${PYTHON_VERSION}"}
export PIPX_HOME=${3:-"/usr/local/py-utils"}
USERNAME=${4:-"automatic"}
UPDATE_RC=${5:-"true"}
INSTALL_PYTHON_TOOLS=${6:-"true"}
set -e
if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1
fi
# Determine the appropriate non-root user
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
USERNAME=""
POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)")
for CURRENT_USER in ${POSSIBLE_USERS[@]}; do
if id -u ${CURRENT_USER} > /dev/null 2>&1; then
USERNAME=${CURRENT_USER}
break
fi
done
if [ "${USERNAME}" = "" ]; then
USERNAME=root
fi
elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then
USERNAME=root
fi
function updaterc() {
if [ "${UPDATE_RC}" = "true" ]; then
echo "Updating /etc/bash.bashrc and /etc/zsh/zshrc..."
echo -e "$1" | tee -a /etc/bash.bashrc >> /etc/zsh/zshrc
fi
}
export DEBIAN_FRONTEND=noninteractive
# Install python from source if needed
if [ "${PYTHON_VERSION}" != "none" ]; then
if [ -d "${PYTHON_INSTALL_PATH}" ]; then
echo "Path ${PYTHON_INSTALL_PATH} already exists. Assuming Python already installed."
else
echo "Building Python ${PYTHON_VERSION} from source..."
# Install prereqs if missing
PREREQ_PKGS="curl ca-certificates tar make build-essential libffi-dev \
libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncurses5-dev libncursesw5-dev xz-utils tk-dev"
if ! dpkg -s ${PREREQ_PKGS} > /dev/null 2>&1; then
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
apt-get update
fi
apt-get -y install --no-install-recommends ${PREREQ_PKGS}
fi
# Download and build from src
mkdir -p /tmp/python-src "${PYTHON_INSTALL_PATH}"
cd /tmp/python-src
curl -sSL -o /tmp/python-dl.tgz "https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tgz"
tar -xzf /tmp/python-dl.tgz -C "/tmp/python-src" --strip-components=1
./configure --prefix="${PYTHON_INSTALL_PATH}" --enable-optimizations --with-ensurepip=install
make -j 8
make install
rm -rf /tmp/python-dl.tgz /tmp/python-src
cd /tmp
chown -R ${USERNAME} "${PYTHON_INSTALL_PATH}"
ln -s ${PYTHON_INSTALL_PATH}/bin/python3 ${PYTHON_INSTALL_PATH}/bin/python
ln -s ${PYTHON_INSTALL_PATH}/bin/pip3 ${PYTHON_INSTALL_PATH}/bin/pip
ln -s ${PYTHON_INSTALL_PATH}/bin/idle3 ${PYTHON_INSTALL_PATH}/bin/idle
ln -s ${PYTHON_INSTALL_PATH}/bin/pydoc3 ${PYTHON_INSTALL_PATH}/bin/pydoc
ln -s ${PYTHON_INSTALL_PATH}/bin/python3-config ${PYTHON_INSTALL_PATH}/bin/python-config
updaterc "export PATH=${PYTHON_INSTALL_PATH}/bin:\${PATH}"
fi
fi
# If not installing python tools, exit
if [ "${INSTALL_PYTHON_TOOLS}" != "true" ]; then
echo "Done!"
exit 0;
fi
DEFAULT_UTILS="\
pylint \
flake8 \
autopep8 \
black \
yapf \
mypy \
pydocstyle \
pycodestyle \
bandit \
pipenv \
virtualenv"
export PIPX_BIN_DIR=${PIPX_HOME}/bin
export PATH=${PYTHON_INSTALL_PATH}/bin:${PIPX_BIN_DIR}:${PATH}
# Update pip
echo "Updating pip..."
python3 -m pip install --no-cache-dir --upgrade pip
# Install tools
mkdir -p ${PIPX_BIN_DIR}
chown -R ${USERNAME} ${PIPX_HOME} ${PIPX_BIN_DIR}
su ${USERNAME} -c "$(cat << EOF
set -e
echo "Installing Python tools..."
export PIPX_HOME=${PIPX_HOME}
export PIPX_BIN_DIR=${PIPX_BIN_DIR}
export PYTHONUSERBASE=/tmp/pip-tmp
export PIP_CACHE_DIR=/tmp/pip-tmp/cache
export PATH=${PATH}
pip3 install --disable-pip-version-check --no-warn-script-location --no-cache-dir --user pipx
/tmp/pip-tmp/bin/pipx install --pip-args=--no-cache-dir pipx
echo "${DEFAULT_UTILS}" | xargs -n 1 /tmp/pip-tmp/bin/pipx install --system-site-packages --pip-args '--no-cache-dir --force-reinstall'
chown -R ${USERNAME} ${PIPX_HOME}
rm -rf /tmp/pip-tmp
EOF
)"
updaterc "export PIPX_HOME=${PIPX_HOME}\nexport PIPX_BIN_DIR=${PIPX_BIN_DIR}\nexport PATH=\${PATH}:\${PIPX_BIN_DIR}"
================================================
FILE: .gitattributes
================================================
calendars/_version.py export-subst
exchange_calendars/_version.py export-subst
================================================
FILE: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "github-actions" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"
# reverted because dependabot can't ignore files
# - package-ecosystem: "pip" # See documentation for possible values
# directory: "/etc" # Location of package manifests
# schedule:
# interval: "daily"
================================================
FILE: .github/pull_request_template.md
================================================
**Workflow to add a new Exchange Calendar**
It's recommended that whilst working through the process reference be made to existing calendar and test classes.
- [ ] Add calendar module `exchange_calendars/exchange_calendar_{Exchange MIC}.py`. Module should contain a subclass of the abstract base class `ExchangeCalendar` (in `exchange_calendars/exchange_calendar.py`).
- [ ] Name subclass `{Exchange MIC}ExchangeCalendar`.
- [ ] Override methods and properties as required, being guided by ExchangeCalendar documentation and in-code comments. All abstract properties must be overriden.
- [ ] Include references / links for holidays and timings (either to class documentation or as comments).
- [ ] Import calendar class to `exchange_calendars/calendar_utils.py` and add class to `_default_calendar_factories`.
- [ ] Add calendar test module `tests/test_{Exchange MIC}_calendar.py` Module should contain a subclass of the test base class `ExchangeCalendarTestBase` (in `tests/test_exchange_calendars.py`).
- [ ] Name subclass `Test{Exchange MIC}Calendar`.
- [ ] Override fixtures as required, being guided by ExchangeCalendarTestBase documentation and in-code comments. The `calendar_cls` and `max_session_hours` fixtures must be overriden.
- [ ] Add a .csv file containing expected timings to `tests/resources/{Exchange MIC}.csv`. This file be generated by executing `python etc/make_exchange_calendar_test_csv.py {Exchange MIC}`. See script's documentation.
- [ ] Add new exchange to Calendars table of README.md.
- [ ] PR it!
**Workflow to modify an existing Exchange Calendar**
- [ ] Modify calendar class as required.
- [ ] Modify the test resources file (e.g `tests/resources/{Exchange MIC}.csv`), either manually or by executing `python etc/make_exchange_calendar_test_csv.py {Exchange MIC}`.
- [ ] Check if any of the fixtures in `tests/test_{Exchange MIC}_calendar.py` need updating to reflect your changes.
- [ ] Add references to any new/modified holidays in `exchange_calendars/exchange_calendar_{Exchange MIC}.py`.
================================================
FILE: .github/release-drafter-config.yml
================================================
name-template: '$NEXT_PATCH_VERSION 🌈'
tag-template: '$NEXT_PATCH_VERSION'
categories:
- title: 'API Changes'
labels:
- 'api'
- title: 'Benchmark Changes'
labels:
- 'bench'
- title: 'Build Changes'
labels:
- 'build'
- title: 'Bug Fixes'
labels:
- 'bug'
- title: 'Calendar Updates'
labels:
- 'calendar update'
- title: 'Deprecation'
labels:
- 'deprecation'
- title: 'Development Enhancements'
labels:
- 'development'
- title: 'Documentation Updates'
labels:
- 'documentation'
- title: 'Enhancements'
labels:
- 'enhancement'
- title: 'Maintenance'
labels:
- 'maintenance'
- title: 'Reverts'
labels:
- 'revert'
- title: 'Style Changes'
labels:
- 'style'
- title: 'Test Changes'
labels:
- 'test'
- title: 'Release Changes'
labels:
- 'release'
template: |
# What’s Changed
$CHANGES
================================================
FILE: .github/workflows/benchmark.yml
================================================
name: Benchmark
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
benchmark:
name: Performance regression check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install Python
run: uv python install
- name: Install the project
run: uv sync --locked --group test --no-cache
- name: Run benchmark
run: uv run -- pytest etc/bench.py --benchmark-json output.json
- name: Download previous benchmark data
uses: actions/cache@v5.0.4
with:
path: ./cache
key: ${{ runner.os }}-benchmark
- name: Store benchmark result
uses: rhysd/github-action-benchmark@v1
with:
tool: 'pytest'
output-file-path: output.json
external-data-json-path: ./cache/benchmark-data.json
fail-on-alert: true
# GitHub API token to make a commit comment
github-token: ${{ secrets.GITHUB_TOKEN }}
# Enable alert commit comment
comment-on-alert: true
alert-threshold: "150%"
================================================
FILE: .github/workflows/labeler.yml
================================================
name: "Pull Request Labeler"
on:
pull_request_target:
types: [opened, synchronize, reopened, edited]
jobs:
pr-labeler:
runs-on: ubuntu-latest
steps:
- name: Label the PR
uses: gerrymanoim/pr-prefix-labeler@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/main.yml
================================================
name: CI
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
- uses: pre-commit/action@v3.0.1
build-and-test:
needs: pre-commit
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.10", "3.14"]
steps:
- uses: actions/checkout@v6
- name: Install uv and set the Python version
uses: astral-sh/setup-uv@v7
with:
python-version: ${{ matrix.python-version }}
- name: Install the project
run: uv sync --locked --group test --no-dev --no-cache
- if: runner.os != 'Windows'
name: Set up Python tzdata on Linux and macOS
run: |
PYTHONTZPATH=$(python -c "import os; print(os.path.dirname(os.__file__))")
echo "PYTHONTZPATH=$PYTHONTZPATH" >> $GITHUB_ENV
- if: runner.os == 'Windows'
name: Set up Python tzdata on Windows
run: |
$PYTHONTZPATH = python -c "import os; print(os.path.dirname(os.__file__))"
echo "PYTHONTZPATH=$PYTHONTZPATH" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Test with pytest
run: uv run -- pytest tests -n auto --dist loadscope
- name: Set up minimum environment and run tests
shell: bash
run: |
if [ "${{ matrix.python-version }}" == "3.14" ]; then
GROUP="test_py14"
else
GROUP="test_min"
fi
uv lock --resolution lowest-direct
uv sync --frozen --resolution lowest-direct --group "$GROUP" --no-dev --no-cache
uv run --frozen --resolution lowest-direct --group "$GROUP" -- pytest tests -n auto --dist loadscope
uv pip list
================================================
FILE: .github/workflows/master-merge.yml
================================================
name: On Master Merge
on:
push:
branches:
- master
jobs:
draft-release-publish:
name: Draft a new release
runs-on: ubuntu-latest
steps:
# Drafts your next Release notes as Pull Requests are merged into "master"
- uses: release-drafter/release-drafter@v7
with:
config-name: release-drafter-config.yml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/release.yml
================================================
name: Publish Python 🐍 distributions 📦 to PyPI
on:
release:
types: [published]
permissions:
id-token: write
contents: read
jobs:
build-n-publish:
name: Build and publish Python 🐍 distributions 📦 to TestPyPI
runs-on: ubuntu-latest
environment:
name: pypi
steps:
- uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install Python
run: uv python install
- name: Build
run: uv build
- name: Publish distribution 📦 to Test PyPI
run: uv publish --index testpypi
- name: Check test install and import
run: |
sleep 5 # Wait for Test Pypi to publish
# Include pypi index for deps not available from test pypi...
uv run \
--with exchange-calendars \
--refresh-package exchange-calendars \
--index https://test.pypi.org/simple \
--index https://pypi.org/simple \
--index-strategy unsafe-best-match \
--no-project \
--isolated \
-- \
python -c 'import exchange_calendars; print(f"{exchange_calendars.__version__=}")'
- name: Publish distribution 📦 to PyPI
run: uv publish
- name: Check install and import
run: |
sleep 5 # Wait for Pypi to publish
uv run \
--with exchange-calendars \
--refresh-package exchange-calendars \
--no-project \
--isolated \
-- \
python -c 'import exchange_calendars;print(f"{exchange_calendars.__version__=}")'
================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
_version.py
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv*
env/
venv*/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
.ipynb_checkpoints/
etc/lunar-ecliptic-longitude/*
etc/solar-ecliptic-longitude/*
# Vscode
.vscode
# not intended for inclusion to public project
/_local
================================================
FILE: .pre-commit-config.yaml
================================================
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.13.0
hooks:
# Run the linter.
- id: ruff-check
# Run the formatter.
- id: ruff-format
================================================
FILE: .python-version
================================================
>=3.10
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2018 Quantopian, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: MANIFEST.in
================================================
recursive-exclude .devcontainer *
recursive-exclude .github *
================================================
FILE: README.md
================================================
# exchange_calendars
[](https://pypi.org/project/exchange-calendars/)   [](https://github.com/astral-sh/ruff) [](https://results.pre-commit.ci/latest/github/gerrymanoim/exchange_calendars/master)
A Python library for defining and querying calendars for security exchanges.
Calendars for more than [50 exchanges](#Calendars) available out-the-box! If you still can't find the calendar you're looking for, [create a new one](#How-can-I-create-a-new-calendar)!
## Installation
```bash
$ pip install exchange_calendars
```
## Quick Start
```python
import exchange_calendars as xcals
```
Get a list of available calendars:
```python
>>> xcals.get_calendar_names(include_aliases=False)[5:10]
['CMES', 'IEPA', 'XAMS', 'XASX', 'XBKK']
```
Get a calendar:
```python
>>> xnys = xcals.get_calendar("XNYS") # New York Stock Exchange
>>> xhkg = xcals.get_calendar("XHKG") # Hong Kong Stock Exchange
```
Query the schedule:
```python
>>> xhkg.schedule.loc["2021-12-29":"2022-01-04"]
```
<!-- base of output from `xhkg.schedule.loc["2021-12-29":"2022-01-04"].to_html()` -->
<table border="1" class="dataframe" style="width: 100%">
<colgroup>
<col span="1" style="width: 20%;">
<col span="1" style="width: 20%;">
<col span="1" style="width: 20%;">
<col span="1" style="width: 20%;">
<col span="1" style="width: 20%;">
</colgroup>
<thead> <tr style="text-align: right; font-size: 13px"> <th></th> <th>open</th> <th>break_start</th> <th>break_end</th> <th>close</th> </tr> </thead> <tbody style="text-align: right; font-size: 11px"> <tr> <th>2021-12-29</th> <td>2021-12-29 01:30:00+00:00</td> <td>2021-12-29 04:00:00+00:00</td> <td>2021-12-29 05:00:00+00:00</td> <td>2021-12-29 08:00:00+00:00</td> </tr> <tr> <th>2021-12-30</th> <td>2021-12-30 01:30:00+00:00</td> <td>2021-12-30 04:00:00+00:00</td> <td>2021-12-30 05:00:00+00:00</td> <td>2021-12-30 08:00:00+00:00</td> </tr> <tr> <th>2021-12-31</th> <td>2021-12-31 01:30:00+00:00</td> <td>NaT</td> <td>NaT</td> <td>2021-12-31 04:00:00+00:00</td> </tr> <tr> <th>2022-01-03</th> <td>2022-01-03 01:30:00+00:00</td> <td>2022-01-03 04:00:00+00:00</td> <td>2022-01-03 05:00:00+00:00</td> <td>2022-01-03 08:00:00+00:00</td> </tr> <tr> <th>2022-01-04</th> <td>2022-01-04 01:30:00+00:00</td> <td>2022-01-04 04:00:00+00:00</td> <td>2022-01-04 05:00:00+00:00</td> <td>2022-01-04 08:00:00+00:00</td> </tr> </tbody>
</table>
### Working with **sessions**
```python
>>> xnys.is_session("2022-01-01")
False
>>> xnys.sessions_in_range("2022-01-01", "2022-01-11")
DatetimeIndex(['2022-01-03', '2022-01-04', '2022-01-05', '2022-01-06',
'2022-01-07', '2022-01-10', '2022-01-11'],
dtype='datetime64[ns]', freq='C')
>>> xnys.sessions_window("2022-01-03", 7)
DatetimeIndex(['2022-01-03', '2022-01-04', '2022-01-05', '2022-01-06',
'2022-01-07', '2022-01-10', '2022-01-11'],
dtype='datetime64[ns]', freq='C')
>>> xnys.date_to_session("2022-01-01", direction="next")
Timestamp('2022-01-03 00:00:00', freq='C')
>>> xnys.previous_session("2022-01-11")
Timestamp('2022-01-10 00:00:00', freq='C')
>>> xhkg.trading_index(
... "2021-12-30", "2021-12-31", period="90min", force=True
... )
IntervalIndex([[2021-12-30 01:30:00, 2021-12-30 03:00:00), [2021-12-30 03:00:00, 2021-12-30 04:00:00), [2021-12-30 05:00:00, 2021-12-30 06:30:00), [2021-12-30 06:30:00, 2021-12-30 08:00:00), [2021-12-31 01:30:00, 2021-12-31 03:00:00), [2021-12-31 03:00:00, 2021-12-31 04:00:00)], dtype='interval[datetime64[ns, UTC], left]')
```
See the [sessions tutorial](docs/tutorials/sessions.ipynb) for a deeper dive into sessions.
### Working with **minutes**
```python
>>> xhkg.session_minutes("2022-01-03")
DatetimeIndex(['2022-01-03 01:30:00+00:00', '2022-01-03 01:31:00+00:00',
'2022-01-03 01:32:00+00:00', '2022-01-03 01:33:00+00:00',
'2022-01-03 01:34:00+00:00', '2022-01-03 01:35:00+00:00',
'2022-01-03 01:36:00+00:00', '2022-01-03 01:37:00+00:00',
'2022-01-03 01:38:00+00:00', '2022-01-03 01:39:00+00:00',
...
'2022-01-03 07:50:00+00:00', '2022-01-03 07:51:00+00:00',
'2022-01-03 07:52:00+00:00', '2022-01-03 07:53:00+00:00',
'2022-01-03 07:54:00+00:00', '2022-01-03 07:55:00+00:00',
'2022-01-03 07:56:00+00:00', '2022-01-03 07:57:00+00:00',
'2022-01-03 07:58:00+00:00', '2022-01-03 07:59:00+00:00'],
dtype='datetime64[ns, UTC]', length=330, freq=None)
>>> mins = [ "2022-01-03 " + tm for tm in ["01:29", "01:30", "04:20", "07:59", "08:00"] ]
>>> [ xhkg.is_trading_minute(minute) for minute in mins ]
[False, True, False, True, False] # by default minutes are closed on the left side
>>> xhkg.is_break_minute("2022-01-03 04:20")
True
>>> xhkg.previous_close("2022-01-03 08:10")
Timestamp('2022-01-03 08:00:00+0000', tz='UTC')
>>> xhkg.previous_minute("2022-01-03 08:10")
Timestamp('2022-01-03 07:59:00+0000', tz='UTC')
```
Check out the [minutes tutorial](docs/tutorials/minutes.ipynb) for a deeper dive that includes an explanation of the concept of 'minutes' and how the "side" option determines which minutes are treated as trading minutes.
## Tutorials
* [sessions.ipynb](docs/tutorials/sessions.ipynb) - all things [sessions](#Working-with-sessions).
* [minutes.ipynb](docs/tutorials/minutes.ipynb) - all things [minutes](#Working-with-minutes). Don't miss this one!
* [calendar_properties.ipynb](docs/tutorials/calendar_properties.ipynb) - calendar constrution and a walk through the schedule and all other calendar properties.
* [calendar_methods.ipynb](docs/tutorials/calendar_methods.ipynb) - a walk through all the methods available to interrogate a calendar.
* [trading_index.ipynb](docs/tutorials/trading_index.ipynb) - a method that warrants a tutorial all of its own.
Hopefully you'll find that `exchange_calendars` has the method you need to get the information you want. If it doesn't, either [PR](https://github.com/gerrymanoim/exchange_calendars/pulls) it or [raise an issue](https://github.com/gerrymanoim/exchange_calendars/issues) and let us know!
## Command Line Usage
Print a unix-cal like calendar straight from the command line (holidays are indicated by brackets)...
```bash
ecal XNYS 2020
```
2020
January February March
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
[ 1] 2 3 [ 4] [ 1]
[ 5] 6 7 8 9 10 [11] [ 2] 3 4 5 6 7 [ 8] [ 1] 2 3 4 5 6 [ 7]
[12] 13 14 15 16 17 [18] [ 9] 10 11 12 13 14 [15] [ 8] 9 10 11 12 13 [14]
[19][20] 21 22 23 24 [25] [16][17] 18 19 20 21 [22] [15] 16 17 18 19 20 [21]
[26] 27 28 29 30 31 [23] 24 25 26 27 28 [29] [22] 23 24 25 26 27 [28]
[29] 30 31
April May June
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 3 [ 4] 1 [ 2] 1 2 3 4 5 [ 6]
[ 5] 6 7 8 9 [10][11] [ 3] 4 5 6 7 8 [ 9] [ 7] 8 9 10 11 12 [13]
[12] 13 14 15 16 17 [18] [10] 11 12 13 14 15 [16] [14] 15 16 17 18 19 [20]
[19] 20 21 22 23 24 [25] [17] 18 19 20 21 22 [23] [21] 22 23 24 25 26 [27]
[26] 27 28 29 30 [24][25] 26 27 28 29 [30] [28] 29 30
[31]
July August September
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 [ 3][ 4] [ 1] 1 2 3 4 [ 5]
[ 5] 6 7 8 9 10 [11] [ 2] 3 4 5 6 7 [ 8] [ 6][ 7] 8 9 10 11 [12]
[12] 13 14 15 16 17 [18] [ 9] 10 11 12 13 14 [15] [13] 14 15 16 17 18 [19]
[19] 20 21 22 23 24 [25] [16] 17 18 19 20 21 [22] [20] 21 22 23 24 25 [26]
[26] 27 28 29 30 31 [23] 24 25 26 27 28 [29] [27] 28 29 30
[30] 31
October November December
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 [ 3] 1 2 3 4 [ 5]
[ 4] 5 6 7 8 9 [10] [ 1] 2 3 4 5 6 [ 7] [ 6] 7 8 9 10 11 [12]
[11] 12 13 14 15 16 [17] [ 8] 9 10 11 12 13 [14] [13] 14 15 16 17 18 [19]
[18] 19 20 21 22 23 [24] [15] 16 17 18 19 20 [21] [20] 21 22 23 24 [25][26]
[25] 26 27 28 29 30 [31] [22] 23 24 25 [26] 27 [28] [27] 28 29 30 31
[29] 30
```bash
ecal XNYS 1 2020
```
January 2020
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 31
## Frequently Asked Questions
### **How can I create a new calendar?**
First off, make sure the calendar you're after hasn't already been defined; exchange calendars comes with over [50 pre-defined calendars](#Calendars), including major security exchanges.
If you can't find what you're after, a custom calendar can be created as a subclass of [ExchangeCalendar](exchange_calendars/exchange_calendar.py). [This workflow](.github/pull_request_template.md) describes the process to add a new calendar to `exchange_calendars`. Just follow the relevant parts.
To access the new calendar via `get_calendar` call either `xcals.register_calendar` or `xcals.register_calendar_type` to register, respectively, a specific calendar instance or a calendar factory (i.e. the subclass).
### **Can I contribute a new calendar to exchange calendars?**
Yes please! The workflow can be found [here](.github/pull_request_template.md).
### **`<calendar>` is missing a holiday, has a wrong time, should have a break etc...**
**All** of the exchange calendars are maintained by user contributions. If a calendar you care about needs revising, please open a [PR](https://github.com/gerrymanoim/exchange_calendars/pulls) - that's how this thing works! (Never contributed to a project before and it all seems a bit daunting? Check [this out](https://github.com/firstcontributions/first-contributions/blob/main/README.md) and don't look back!)
You'll find the workflow to modify an existing calendar [here](.github/pull_request_template.md).
### **What times are considered open and closed?**
`exchange_calendars` attempts to be broadly useful by considering an exchange to be open only during periods of regular trading. During any pre-trading, post-trading or auction period the exchange is treated as closed. An exchange is also treated as closed during any observed lunch break.
See the [minutes tutorial](docs/tutorials/minutes.ipynb) for a detailed explanation of which minutes an exchange is considered open over. If you previously used `trading_calendars`, or `exchange_calendars` prior to release 3.4, then this is the place to look for answers to questions of how the definition of trading minutes has changed over time (and is now stable and flexible!).
## Calendars
| Exchange | ISO Code | Country | Version Added | Exchange Website (English) |
|---------------------------------|----------| -------------- |---------------| ------------------------------------------------------------ |
| New York Stock Exchange | XNYS | USA | 1.0 | https://www.nyse.com/index |
| CBOE Futures | XCBF | USA | 1.0 | https://markets.cboe.com/us/futures/overview/ |
| Chicago Mercantile Exchange | CMES | USA | 1.0 | https://www.cmegroup.com/ |
| ICE US | IEPA | USA | 1.0 | https://www.theice.com/index |
| Toronto Stock Exchange | XTSE | Canada | 1.0 | https://www.tsx.com/ |
| BMF Bovespa | BVMF | Brazil | 1.0 | http://www.b3.com.br/en_us/ |
| London Stock Exchange | XLON | England | 1.0 | https://www.londonstockexchange.com/ |
| Euronext Amsterdam | XAMS | Netherlands | 1.2 | https://www.euronext.com/en/regulation/amsterdam |
| Euronext Brussels | XBRU | Belgium | 1.2 | https://www.euronext.com/en/regulation/brussels |
| Euronext Lisbon | XLIS | Portugal | 1.2 | https://www.euronext.com/en/regulation/lisbon |
| Euronext Paris | XPAR | France | 1.2 | https://www.euronext.com/en/regulation/paris |
| Frankfurt Stock Exchange | XFRA | Germany | 1.2 | http://en.boerse-frankfurt.de/ |
| SIX Swiss Exchange | XSWX | Switzerland | 1.2 | https://www.six-group.com/en/home.html |
| Tokyo Stock Exchange | XTKS | Japan | 1.2 | https://www.jpx.co.jp/english/ |
| Australian Securities Exchange | XASX | Australia | 1.3 | https://www.asx.com.au/ |
| Bolsa de Madrid | XMAD | Spain | 1.3 | https://www.bolsamadrid.es |
| Borsa Italiana | XMIL | Italy | 1.3 | https://www.borsaitaliana.it |
| New Zealand Exchange | XNZE | New Zealand | 1.3 | https://www.nzx.com/ |
| Wiener Borse | XWBO | Austria | 1.3 | https://www.wienerborse.at/en/ |
| Hong Kong Stock Exchange | XHKG | Hong Kong | 1.3 | https://www.hkex.com.hk/?sc_lang=en |
| Copenhagen Stock Exchange | XCSE | Denmark | 1.4 | http://www.nasdaqomxnordic.com/ |
| Helsinki Stock Exchange | XHEL | Finland | 1.4 | http://www.nasdaqomxnordic.com/ |
| Stockholm Stock Exchange | XSTO | Sweden | 1.4 | http://www.nasdaqomxnordic.com/ |
| Oslo Stock Exchange | XOSL | Norway | 1.4 | https://www.oslobors.no/ob_eng/ |
| Irish Stock Exchange | XDUB | Ireland | 1.4 | http://www.ise.ie/ |
| Bombay Stock Exchange | XBOM | India | 1.5 | https://www.bseindia.com |
| Singapore Exchange | XSES | Singapore | 1.5 | https://www.sgx.com |
| Shanghai Stock Exchange | XSHG | China | 1.5 | http://english.sse.com.cn |
| Korea Exchange | XKRX | South Korea | 1.6 | http://global.krx.co.kr |
| Iceland Stock Exchange | XICE | Iceland | 1.7 | http://www.nasdaqomxnordic.com/ |
| Poland Stock Exchange | XWAR | Poland | 1.9 | http://www.gpw.pl |
| Santiago Stock Exchange | XSGO | Chile | 1.9 | https://www.bolsadesantiago.com/ |
| Colombia Securities Exchange | XBOG | Colombia | 1.9 | https://www.bvc.com.co/nueva/https://www.bvc.com.co/nueva/ |
| Mexican Stock Exchange | XMEX | Mexico | 1.9 | https://www.bmv.com.mx |
| Lima Stock Exchange | XLIM | Peru | 1.9 | https://www.bvl.com.pe |
| Prague Stock Exchange | XPRA | Czech Republic | 1.9 | https://www.pse.cz/en/ |
| Budapest Stock Exchange | XBUD | Hungary | 1.10 | https://bse.hu/ |
| Athens Stock Exchange | ASEX | Greece | 1.10 | http://www.helex.gr/ |
| Istanbul Stock Exchange | XIST | Turkey | 1.10 | https://www.borsaistanbul.com/en/ |
| Johannesburg Stock Exchange | XJSE | South Africa | 1.10 | https://www.jse.co.za/z |
| Malaysia Stock Exchange | XKLS | Malaysia | 1.11 | http://www.bursamalaysia.com/market/ |
| Moscow Exchange | XMOS | Russia | 1.11 | https://www.moex.com/en/ |
| Philippine Stock Exchange | XPHS | Philippines | 1.11 | https://www.pse.com.ph/ |
| Stock Exchange of Thailand | XBKK | Thailand | 1.11 | https://www.set.or.th/set/mainpage.do?language=en&country=US |
| Indonesia Stock Exchange | XIDX | Indonesia | 1.11 | https://www.idx.co.id/ |
| Taiwan Stock Exchange Corp. | XTAI | Taiwan | 1.11 | https://www.twse.com.tw/en/ |
| Buenos Aires Stock Exchange | XBUE | Argentina | 1.11 | https://www.bcba.sba.com.ar/ |
| Pakistan Stock Exchange | XKAR | Pakistan | 1.11 | https://www.psx.com.pk/ |
| Xetra | XETR | Germany | 2.1 | https://www.xetra.com/ |
| Tel Aviv Stock Exchange | XTAE | Israel | 2.1 | https://www.tase.co.il/ |
| Astana International Exchange | AIXK | Kazakhstan | 3.2 | https://www.aix.kz/ |
| Bucharest Stock Exchange | XBSE | Romania | 3.2 | https://www.bvb.ro/ |
| Saudi Stock Exchange | XSAU | Saudi Arabia | 4.2 | https://www.saudiexchange.sa/ |
| European Energy Exchange AG | XEEE | Germany | 4.5.5 | https://www.eex.com |
| Hamburg Stock Exchange | XHAM | Germany | 4.5.5 | https://www.boerse-hamburg.de |
| Duesseldorf Stock Exchange | XDUS | Germany | 4.5.5 | https://www.boerse-duesseldorf.de |
| Luxembourg Stock Exchange | XLUX | Luxembourg | 4.8 | https://www.luxse.com/ |
| Tallinn Stock Exchange | XTAL | Estonia | 4.11 | https://nasdaqbaltic.com |
| Riga Stock Exchange | XRIS | Latvia | 4.11 | https://nasdaqbaltic.com |
| Vilnius Stock Exchange | XLIT | Lithuania | 4.11 | https://nasdaqbaltic.com |
| Cyprus Stock Exchange | XCYS | Cyprus | 4.11.1 | https://www.cse.com.cy/en-GB/home |
| Bermuda Stock Exchange | XBDA | Bermuda | 4.11.1 | https://www.bsx.com |
| Zagreb Stock Exchange | XZAG | Croatia | 4.11.1 | https://www.zse.hr/en |
| Ljubljana Stock Exchange | XLJU | Slovenia | 4.11.3 | https://ljse.si/en |
| Bratislava Stock Exchange | XBRA | Slovakia | 4.11.3 | https://www.bsse.sk/bcpb/en |
| Belgrade Stock Exchange | XBEL | Serbia | 4.11.3 | https://www.belex.rs/eng |
| Eurex | XEUR | Germany | 4.13.2 | https://www.eurex.com/ex-en/ |
| Börse Stuttgart | XSTU | Germany | 4.13.2 | https://www.boerse-stuttgart.de/en |
> Note that exchange calendars are defined by their [ISO-10383](https://www.iso20022.org/10383/iso-10383-market-identifier-codes) market identifier code.
## market-prices
Much of the post v3 development of `exchange_calendars` was driven by the [`market_prices`](https://github.com/maread99/market_prices) library. Check it out if you like the idea of using `exchange_calendars` to create meaningful OHLCV datasets. It works out-the-box with freely available data!
## Deprecations and Renaming
### Methods renamed in version 4.0.3 and removed in 4.3
| Previous name | New name |
| ------------- | -------- |
| bound_start | bound_min |
| bound_end | bound_max |
### Methods deprecated in 4.0 and removed in 4.3
| Deprecated method | Reason |
| ----------------- | ------ |
| sessions_closes | use `.closes[start:end]` |
| sessions_opens | use `.opens[start:end]` |
### Methods with a parameter renamed in 4.0
| Method
| ------
| is_session |
| is_open_on_minute |
| minutes_in_range |
| minutes_window |
| next_close |
| next_minute |
| next_open |
| previous_close |
| previous_minute |
| previous_open |
| session_break_end |
| session_break_start |
| session_close |
| session_open |
| sessions_in_range |
| sessions_window |
### Methods renamed in version 3.4 and removed in 4.0
| Previous name | New name |
| ------------- | -------- |
| all_minutes | minutes |
| all_minutes_nanos | minutes_nanos |
| all_sessions | sessions |
| break_start_and_end_for_session | session_break_start_end |
| date_to_session_label | date_to_session |
| first_trading_minute | first_minute |
| first_trading_session | first_session |
| has_breaks | sessions_has_break |
| last_trading_minute | last_minute |
| last_trading_session | last_session |
| next_session_label | next_session |
| open_and_close_for_session | session_open_close |
| previous_session_label | previous_session |
| market_break_ends_nanos | break_ends_nanos |
| market_break_starts_nanos | break_starts_nanos |
| market_closes_nanos | closes_nanos |
| market_opens_nanos | opens_nanos |
| minute_index_to_session_labels | minutes_to_sessions |
| minute_to_session_label | minute_to_session |
| minutes_count_for_sessions_in_range | sessions_minutes_count |
| minutes_for_session | session_minutes |
| minutes_for_sessions_in_range | sessions_minutes |
| session_closes_in_range | sessions_closes |
| session_distance | sessions_distance |
| session_opens_in_range | sessions_opens |
### Other methods deprecated in 3.4 and removed in 4.0
| Removed Method
| -----------------
| execution_minute_for_session
| execution_minute_for_sessions_in_range
| execution_time_from_close
| execution_time_from_open
================================================
FILE: docs/changes_archive.md
================================================
**NOTE**: This file is NOT a comprehensive changes log but rather an archive of sections temporarily included to the README to advise of significant changes.
## **v4 released** (June 2022)
**The earliest stable version of v4 is 4.0.1** (not 4.0).
### What's changed?
Version 4.0.1 completes the transition to a more consistent interface across the package. The most significant changes are:
* **Sessions are now timezone-naive** (previously UTC).
* Schedule columns now have timezone set as UTC (whilst the times have always been defined in terms of UTC, previously the dtype was timezone-naive).
* The following schedule columns were renamed:
* 'market_open' renamed as 'open'.
* 'market_close' renamed as 'close'.
* Default calendar 'side' for all calendars is now "left" (previously "right" for 24-hour calendars and "both" for all others). This **changes the minutes that are considered trading minutes by default** (see [minutes tutorial](docs/tutorials/minutes.ipynb) for an explanation of trading minutes).
* The 'count' parameter of `sessions_window` and `minutes_window` methods now reflects the window length (previously window length + 1).
* New `is_open_at_time` calendar method to evaluate if an exchange is open as at a specific instance (as opposed to over an evaluated minute).
* The minimum Python version supported is now 3.8 (previously 3.7).
* Parameters have been renamed for some methods (list [here](#Methods-with-a-parameter-renamed-in-40))
* The following methods have been deprecated:
* `sessions_opens` (use `.opens[start:end]`)
* `sessions_closes` (use `.closes[start:end]`)
* Methods deprecated in 3.4 have been removed (lists [here](#Methods-renamed-in-version-34-and-removed-in-40) and [here](#Other-methods-deprecated-in-34-and-removed-in-40))
See the [4.0 release todo](https://github.com/gerrymanoim/exchange_calendars/issues/61) for a full list of changes and corresponding PRs.
Please offer any feedback at the [v4 discussion](https://github.com/gerrymanoim/exchange_calendars/discussions/202).
## **Changes in 3.4** (released October 2021)
The 3.4 release introduced notable new features and documentation, including:
* [Tutorials](#Tutorials). Five of them!
* New calendar methods [#71](https://github.com/gerrymanoim/exchange_calendars/pull/71) (see [calendar_methods.ipynb](docs/tutorials/calendar_methods.ipynb) for usage), including:
* trading_index (tutorial [trading_index.ipynb](docs/tutorials/trading_index.ipynb))
* is_trading_minute
* is_break_minute
* minute_offset
* session_offset
* minute_offset_by_sessions
* Calendar's now have a `side` parameter to determine which of the open, close, break-start and break-end minutes are treated as trading minutes [#71](https://github.com/gerrymanoim/exchange_calendars/pull/71).
* 24 hour calendars are now truly 24 hours (open/close times are no longer one minute later/earlier than the actual open/close) [#71](https://github.com/gerrymanoim/exchange_calendars/pull/71).
* Some calendar methods have been renamed to improve consistency (table of changes [here](#Methods-renamed-in-version-34)) [#85](https://github.com/gerrymanoim/exchange_calendars/issues/85). The previous names will continue to be available until version 4.0. NOTE: Some newly named methods have also made changes to parameter names, for example from `session_label` to `session` and from `start_session_label` to `start`.
* Under-the-bonnet work has sped up many methods.
* A test suite overhaul ([#71](https://github.com/gerrymanoim/exchange_calendars/pull/71), [#92](https://github.com/gerrymanoim/exchange_calendars/pull/92), [#96](https://github.com/gerrymanoim/exchange_calendars/pull/96)) has made it simpler to define and test calendars.
Please offer any feedback at the [3.4 discussion](https://github.com/gerrymanoim/exchange_calendars/discussions/107).
================================================
FILE: docs/dev/depenencies_update.md
================================================
## **Workflow to update dependencies using uv**
- Set up new local 'deps' branch.
- Update `uv.lock` file and sync local environment to reflect latest dependencies:
```
uv lock --upgrade
uv sync
```
- Make sure tests passing locally with new dependencies.
- Export uv.lock to a requirements.txt file (to provide reference for non-uv clients).
```
uv export --format requirements-txt --no-emit-project --no-hashes --no-dev -o requirements.txt
```
- Commit changes.
- Make PR to main branch.
================================================
FILE: docs/tutorials/calendar_methods.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Calendar methods\n",
"\n",
"This tutorial offers a walk through of all the `ExchangeCalendar` methods (for properties see the [calendar properties](./calendar_properties.ipynb) tutorial).\n",
"\n",
"The following sections cover methods according to the nature of the argument(s) they take:\n",
"* [Methods that query a Date](#Methods-that-query-a-Date) \n",
"* [Methods that query a Session](#Methods-that-query-a-Session) \n",
"* [Methods that query a Minute](#Methods-that-query-a-Minute) \n",
"* [Methods that query multiple TradingMinute](#Methods-that-query-multiple-TradingMinute) \n",
"* [Methods that query a range of dates](#Methods-that-query-a-range-of-dates)\n",
"* [Methods that query a time](#Methods-that-query-a-time)\n",
"\n",
"The following sections cover methods that evaluate an index of trading minutes or sessions:\n",
"* [Methods that evaluate an index of contiguous trading minutes](#Methods-that-evaluate-an-index-of-contiguous-trading-minutes)\n",
"* [Methods that evaluate an index of contiguous sessions](#Methods-that-evaluate-an-index-of-contiguous-sessions)\n",
"\n",
"`Date` and `Session` refer to types for 'session' parameters (see [sessions.ipynb](./sessions.ipynb) for a tutorial on how to work with sessions).\n",
"\n",
"`Minute` and `TradingMinute` refer to types for 'minute' parameters (see [minutes.ipynb](./minutes.ipynb) for a tutorial on how to work with mintues)."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"# setup\n",
"import exchange_calendars as xcals\n",
"import pandas as pd\n",
"\n",
"one_minute = pd.Timedelta(1, \"T\")\n",
"\n",
"nys = xcals.get_calendar(\"XNYS\") # New York Stock Exchange\n",
"hkg = xcals.get_calendar(\"XHKG\") # Hong Kong Stock Exchange"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Methods that query a Date"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The argument of methods in this section takes a `Date` type."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>open</th>\n",
" <th>break_start</th>\n",
" <th>break_end</th>\n",
" <th>close</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2021-12-31</th>\n",
" <td>2021-12-31 14:30:00+00:00</td>\n",
" <td>NaT</td>\n",
" <td>NaT</td>\n",
" <td>2021-12-31 21:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2022-01-03</th>\n",
" <td>2022-01-03 14:30:00+00:00</td>\n",
" <td>NaT</td>\n",
" <td>NaT</td>\n",
" <td>2022-01-03 21:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2022-01-04</th>\n",
" <td>2022-01-04 14:30:00+00:00</td>\n",
" <td>NaT</td>\n",
" <td>NaT</td>\n",
" <td>2022-01-04 21:00:00+00:00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" open break_start break_end \\\n",
"2021-12-31 2021-12-31 14:30:00+00:00 NaT NaT \n",
"2022-01-03 2022-01-03 14:30:00+00:00 NaT NaT \n",
"2022-01-04 2022-01-04 14:30:00+00:00 NaT NaT \n",
"\n",
" close \n",
"2021-12-31 2021-12-31 21:00:00+00:00 \n",
"2022-01-03 2022-01-03 21:00:00+00:00 \n",
"2022-01-04 2022-01-04 21:00:00+00:00 "
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# for reference, all times are UTC\n",
"nys.schedule.loc[\"2021-12-31\":\"2022-01-04\"]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`is_session`** queries if a date represents a session."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(False, True)"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.is_session(\"2022-01-01\"), nys.is_session(\"2022-01-04\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`date_to_session`** will return the the passed `date` if `date` represents a session, or otherwise the nearest session in the passed `direction`."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2022-01-04 00:00:00')"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# date is a session so `direction` is ignored\n",
"nys.date_to_session(\"2022-01-04\", direction=\"next\")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2022-01-03 00:00:00', freq='C')"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.date_to_session(\"2022-01-01\", direction=\"next\")"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2021-12-31 00:00:00', freq='C')"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.date_to_session(\"2022-01-01\", direction=\"previous\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A ValueError is raised if `direction` is not passed and `date` is not a session."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"nys.date_to_session(\"2022-01-01\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```\n",
"---------------------------------------------------------------------------\n",
"ValueError Traceback (most recent call last)\n",
"Input In [7], in <cell line: 1>()\n",
"----> 1 nys.date_to_session(\"2022-01-01\")\n",
"\n",
"ValueError: `date` '2022-01-01 00:00:00' does not represent a session. Consider passing a `direction`.\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Methods that query a Session\n",
"\n",
"The argument of methods in this section takes a `Session` type.\n",
"\n",
"The following methods can be used to return the **open, close** and **break times** of a session..."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>open</th>\n",
" <th>break_start</th>\n",
" <th>break_end</th>\n",
" <th>close</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2022-01-04</th>\n",
" <td>2022-01-04 01:30:00+00:00</td>\n",
" <td>2022-01-04 04:00:00+00:00</td>\n",
" <td>2022-01-04 05:00:00+00:00</td>\n",
" <td>2022-01-04 08:00:00+00:00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" open break_start \\\n",
"2022-01-04 2022-01-04 01:30:00+00:00 2022-01-04 04:00:00+00:00 \n",
"\n",
" break_end close \n",
"2022-01-04 2022-01-04 05:00:00+00:00 2022-01-04 08:00:00+00:00 "
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# for reference (all times are UTC)\n",
"session = \"2022-01-04\"\n",
"hkg.schedule.loc[[session]]"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2022-01-04 01:30:00+0000', tz='UTC'),\n",
" Timestamp('2022-01-04 08:00:00+0000', tz='UTC'))"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.session_open(session), hkg.session_close(session)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2022-01-04 01:30:00+0000', tz='UTC'),\n",
" Timestamp('2022-01-04 08:00:00+0000', tz='UTC'))"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# or\n",
"hkg.session_open_close(session)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2022-01-04 04:00:00+0000', tz='UTC'),\n",
" Timestamp('2022-01-04 05:00:00+0000', tz='UTC'))"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.session_break_start(session), hkg.session_break_end(session)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2022-01-04 04:00:00+0000', tz='UTC'),\n",
" Timestamp('2022-01-04 05:00:00+0000', tz='UTC'))"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# or\n",
"hkg.session_break_start_end(session)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2022-01-04 09:30:00+0800', tz='Asia/Hong_Kong')"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# in local time\n",
"hkg.session_open(session).tz_convert(hkg.tz)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The **`session_*_minute`** methods return a boundary trading minute for a session or subsession."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2022-01-04 01:30:00+0000', tz='UTC'),\n",
" Timestamp('2022-01-04 07:59:00+0000', tz='UTC'))"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.session_first_minute(session), hkg.session_last_minute(session)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2022-01-04 03:59:00+0000', tz='UTC'),\n",
" Timestamp('2022-01-04 05:00:00+0000', tz='UTC'))"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.session_last_am_minute(session), hkg.session_first_pm_minute(session)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2022-01-04 01:30:00+0000', tz='UTC'),\n",
" Timestamp('2022-01-04 07:59:00+0000', tz='UTC'))"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# or get first and last minutes together...\n",
"hkg.session_first_last_minute(session)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2022-01-04 01:31:00+0000', tz='UTC'),\n",
" Timestamp('2022-01-04 08:00:00+0000', tz='UTC'))"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# NB with \"right\" side...\n",
"hkg_right = xcals.get_calendar(\"XHKG\", side=\"right\")\n",
"hkg_right.session_first_last_minute(session)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`session_has_break`** to query if a session has a break."
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Hong Kong has a break, at least on `session`...\n",
"hkg.session_has_break(session)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# but New York does not\n",
"nys.session_has_break(session)"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>open</th>\n",
" <th>break_start</th>\n",
" <th>break_end</th>\n",
" <th>close</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2022-01-04</th>\n",
" <td>2022-01-04 14:30:00+00:00</td>\n",
" <td>NaT</td>\n",
" <td>NaT</td>\n",
" <td>2022-01-04 21:00:00+00:00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" open break_start break_end \\\n",
"2022-01-04 2022-01-04 14:30:00+00:00 NaT NaT \n",
"\n",
" close \n",
"2022-01-04 2022-01-04 21:00:00+00:00 "
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# ...\n",
"nys.schedule.loc[[session]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`next_session`** and **`previous_session`** do what they say on the tin."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'2022-01-04'"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# just to recall...\n",
"session"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2022-01-03 00:00:00', freq='C')"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.previous_session(session)"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2022-01-05 00:00:00', freq='C')"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.next_session(session)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`session_offset`** takes a 'count' argument which provides for offsetting a session by a given number of sessions. If `count` is -1 or 1 then the method behaves as `previous_session` and `next_session` respectively."
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2022-01-03 00:00:00', freq='C'),\n",
" Timestamp('2022-01-05 00:00:00', freq='C'))"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.session_offset(session, count=-1), nys.session_offset(session, count=1)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2021-12-31 00:00:00', freq='C'),\n",
" Timestamp('2022-01-06 00:00:00', freq='C'))"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.session_offset(session, -2), nys.session_offset(session, 2)"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2021-10-22 00:00:00', freq='C'),\n",
" Timestamp('2022-03-17 00:00:00', freq='C'))"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.session_offset(session, -50), nys.session_offset(session, 50)"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2022-01-04 00:00:00', freq='C')"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# going nowhere...\n",
"nys.session_offset(session, 0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`session_minutes`** returns an index of all the trading minutes of the passed session."
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2022-01-04 01:30:00+00:00', '2022-01-04 01:31:00+00:00',\n",
" '2022-01-04 01:32:00+00:00', '2022-01-04 01:33:00+00:00',\n",
" '2022-01-04 01:34:00+00:00', '2022-01-04 01:35:00+00:00',\n",
" '2022-01-04 01:36:00+00:00', '2022-01-04 01:37:00+00:00',\n",
" '2022-01-04 01:38:00+00:00', '2022-01-04 01:39:00+00:00',\n",
" ...\n",
" '2022-01-04 07:50:00+00:00', '2022-01-04 07:51:00+00:00',\n",
" '2022-01-04 07:52:00+00:00', '2022-01-04 07:53:00+00:00',\n",
" '2022-01-04 07:54:00+00:00', '2022-01-04 07:55:00+00:00',\n",
" '2022-01-04 07:56:00+00:00', '2022-01-04 07:57:00+00:00',\n",
" '2022-01-04 07:58:00+00:00', '2022-01-04 07:59:00+00:00'],\n",
" dtype='datetime64[ns, UTC]', length=330, freq=None)"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.session_minutes(session)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Methods that query a Minute\n",
"\n",
"The argument of methods in this section takes a `Minute` type."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`is_trading_minute`** returns a boolean indicating if a minute is a trading minute."
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>open</th>\n",
" <th>break_start</th>\n",
" <th>break_end</th>\n",
" <th>close</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2022-01-04</th>\n",
" <td>2022-01-04 01:30:00+00:00</td>\n",
" <td>2022-01-04 04:00:00+00:00</td>\n",
" <td>2022-01-04 05:00:00+00:00</td>\n",
" <td>2022-01-04 08:00:00+00:00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" open break_start \\\n",
"2022-01-04 2022-01-04 01:30:00+00:00 2022-01-04 04:00:00+00:00 \n",
"\n",
" break_end close \n",
"2022-01-04 2022-01-04 05:00:00+00:00 2022-01-04 08:00:00+00:00 "
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# for reference\n",
"hkg.schedule.loc[[\"2022-01-04\"]]"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.is_trading_minute(\"2022-01-04 01:25\")"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.is_trading_minute(\"2022-01-04 01:35\")"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"break_minute = \"2022-01-04 04:35\"\n",
"hkg.is_trading_minute(break_minute)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`is_break_minute`** returns a boolean indicating if a minute lies within a lunch break. Break minutes lie between the last trading minute of the morning subsession and first trading minute of the afternoon subsession, exclusive of both (a break minute cannot be a trading minute)."
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.is_break_minute(break_minute)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`is_open_on_minute`** can take an optional `include_breaks` argument. If `include_breaks` is False (the default) then the method behaves in the same way as `is_trading_minute`. If `include_breaks` is True then the method will return True if `minute` is either a trading minute or a break minute (otherwise returns False)."
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.is_open_on_minute(break_minute)"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.is_open_on_minute(break_minute, ignore_breaks=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`minute_to_trading_minute`** will return the passed `minute` if `minute` is a trading minute, or otherwise the closest minute in the passed `direction`."
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2010-10-27 14:15:00+0000', tz='UTC'), True)"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# define a trading minute\n",
"trading_minute = nys.first_minutes[\"2010-10-27\"] + pd.Timedelta(45, \"T\")\n",
"trading_minute, nys.is_trading_minute(trading_minute)"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-27 14:15:00+0000', tz='UTC')"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# minute is a trading_minute, so `direction` ignored\n",
"nys.minute_to_trading_minute(trading_minute, direction=\"next\")"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2010-10-27 13:27:00+0000', tz='UTC'), False)"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# define a non-trading minute\n",
"non_trading_minute = nys.first_minutes[\"2010-10-27\"] - pd.Timedelta(3, \"T\")\n",
"non_trading_minute, nys.is_trading_minute(non_trading_minute)"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-27 13:30:00+0000', tz='UTC')"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minute_to_trading_minute(non_trading_minute, direction=\"next\")"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-26 19:59:00+0000', tz='UTC')"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minute_to_trading_minute(non_trading_minute, direction=\"previous\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A ValueError is raised if `direction` is not passed and `minute` is not a trading minute."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"nys.minute_to_trading_minute(non_trading_minute)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```\n",
"---------------------------------------------------------------------------\n",
"ValueError Traceback (most recent call last)\n",
"Input In [41], in <cell line: 1>()\n",
"----> 1 nys.minute_to_trading_minute(non_trading_minute)\n",
"\n",
"ValueError: `minute` '2010-10-27 13:27:00+00:00' is not a trading minute. Consider passing `direction` as 'next' or 'previous'.\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`previous_open`**, **`next_open`**, **`previous_close`** and **`next_close`** will return the previous or next open or close relative to the passed `minute`. NB Which minutes are treated as trading minutes is irrelevant."
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>open</th>\n",
" <th>break_start</th>\n",
" <th>break_end</th>\n",
" <th>close</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2022-01-04</th>\n",
" <td>2022-01-04 14:30:00+00:00</td>\n",
" <td>NaT</td>\n",
" <td>NaT</td>\n",
" <td>2022-01-04 21:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2022-01-05</th>\n",
" <td>2022-01-05 14:30:00+00:00</td>\n",
" <td>NaT</td>\n",
" <td>NaT</td>\n",
" <td>2022-01-05 21:00:00+00:00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" open break_start break_end \\\n",
"2022-01-04 2022-01-04 14:30:00+00:00 NaT NaT \n",
"2022-01-05 2022-01-05 14:30:00+00:00 NaT NaT \n",
"\n",
" close \n",
"2022-01-04 2022-01-04 21:00:00+00:00 \n",
"2022-01-05 2022-01-05 21:00:00+00:00 "
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# for reference\n",
"nys.schedule.loc[\"2022-01-04\":\"2022-01-05\"]"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2022-01-05 14:30:00+0000', tz='UTC')"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"open_05 = nys.session_open(\"2022-01-05\")\n",
"open_05"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2022-01-04 14:30:00+0000', tz='UTC'),\n",
" Timestamp('2022-01-06 14:30:00+0000', tz='UTC'))"
]
},
"execution_count": 44,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.previous_open(open_05), nys.next_open(open_05)"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2022-01-05 14:30:00+0000', tz='UTC')"
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.previous_open(open_05 + one_minute)"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2022-01-04 21:00:00+0000', tz='UTC'),\n",
" Timestamp('2022-01-05 21:00:00+0000', tz='UTC'))"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.previous_close(open_05), nys.next_close(open_05)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`previous_minute`** and **`next_minute`** return the first trading minute prior to / following `minute`."
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2022-01-05 14:30:00+0000', tz='UTC')"
]
},
"execution_count": 47,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"minute = nys.first_minutes[\"2022-01-05\"]\n",
"minute"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2022-01-04 20:59:00+0000', tz='UTC'),\n",
" Timestamp('2022-01-05 14:31:00+0000', tz='UTC'))"
]
},
"execution_count": 48,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.previous_minute(minute), nys.next_minute(minute)"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2022-01-05 14:28:00+0000', tz='UTC')"
]
},
"execution_count": 49,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"minute -= (one_minute * 2)\n",
"minute"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2022-01-04 20:59:00+0000', tz='UTC'),\n",
" Timestamp('2022-01-05 14:30:00+0000', tz='UTC'))"
]
},
"execution_count": 50,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.previous_minute(minute), nys.next_minute(minute)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`minute_offset`** takes a 'count' argument which provides for offsetting a trading minute by the given number of minutes. If count is -1 or 1 then the method behaves as `previous_minute` and `next_minute` respectively."
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-27 14:15:00+0000', tz='UTC')"
]
},
"execution_count": 51,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# recalling\n",
"trading_minute"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2010-10-27 14:14:00+0000', tz='UTC'),\n",
" Timestamp('2010-10-27 14:16:00+0000', tz='UTC'))"
]
},
"execution_count": 52,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minute_offset(trading_minute, count=-1), nys.minute_offset(trading_minute, 1)"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2010-10-27 14:10:00+0000', tz='UTC'),\n",
" Timestamp('2010-10-27 14:20:00+0000', tz='UTC'))"
]
},
"execution_count": 53,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minute_offset(trading_minute, -5), nys.minute_offset(trading_minute, 5)"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2010-10-27 13:30:00+0000', tz='UTC'),\n",
" Timestamp('2010-10-27 19:59:00+0000', tz='UTC'))"
]
},
"execution_count": 54,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minute_offset(trading_minute, -45), nys.minute_offset(trading_minute, 344)"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2010-10-26 19:59:00+0000', tz='UTC'),\n",
" Timestamp('2010-10-28 13:30:00+0000', tz='UTC'))"
]
},
"execution_count": 55,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minute_offset(trading_minute, -46), nys.minute_offset(trading_minute, 345)"
]
},
{
"cell_type": "code",
"execution_count": 56,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2010-10-15 16:15:00+0000', tz='UTC'),\n",
" Timestamp('2010-11-05 18:45:00+0000', tz='UTC'))"
]
},
"execution_count": 56,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minute_offset(trading_minute, -3000), nys.minute_offset(trading_minute, 3000)"
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-27 14:15:00+0000', tz='UTC')"
]
},
"execution_count": 57,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# and of course\n",
"nys.minute_offset(trading_minute, 0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`minute_to_session`** returns the session associated with `minute`. If `minute` is a trading minute or a break minute then this will be the session of which the minute is a trading/break minute."
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-27 00:00:00', freq='C')"
]
},
"execution_count": 58,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minute_to_session(trading_minute)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If `minute` is not a trading or break minute then the return is determined by the optional `direction` parameter. If `direction` is \"next\" the return will be the closest session after `minute`, whilst if `direction` is \"previous\" the return will be the closest session before `minute`."
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-27 13:27:00+0000', tz='UTC')"
]
},
"execution_count": 59,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# for reference\n",
"non_trading_minute"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-27 00:00:00', freq='C')"
]
},
"execution_count": 60,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# default `direction` is \"next\"\n",
"nys.minute_to_session(non_trading_minute)"
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-26 00:00:00', freq='C')"
]
},
"execution_count": 61,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minute_to_session(non_trading_minute, direction=\"previous\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`direction` can also take \"none\", in which case `minute` is required to be a trading or break minute. To the contrary a ValueError is raised:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"nys.minute_to_session(non_trading_minute, direction=\"none\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```\n",
"---------------------------------------------------------------------------\n",
"ValueError Traceback (most recent call last)\n",
"Input In [62], in <cell line: 1>()\n",
"----> 1 nys.minute_to_session(non_trading_minute, direction=\"none\")\n",
"\n",
"ValueError: `minute` '2010-10-27 13:27:00+00:00' is not a trading minute. Consider passing `direction` as 'next' or 'previous'.\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`minute_to_past_session`** returns a session that closed before the given `minute`. If the passed `minute` is a trading minute then the method will NOT return the session of which `minute` is a trading minute, but rather a prior session."
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-27 14:15:00+0000', tz='UTC')"
]
},
"execution_count": 63,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# recalling\n",
"trading_minute"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-26 00:00:00', freq='C')"
]
},
"execution_count": 64,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minute_to_past_session(trading_minute)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note how the above differs to `minute_to_session`..."
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-27 00:00:00', freq='C')"
]
},
"execution_count": 65,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minute_to_session(trading_minute)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`minute_to_past_session` can take an optional `count` argument (default 1) to offset the past session returned."
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-26 00:00:00', freq='C')"
]
},
"execution_count": 66,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# as default\n",
"nys.minute_to_past_session(trading_minute, count=1)"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-25 00:00:00', freq='C')"
]
},
"execution_count": 67,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minute_to_past_session(trading_minute, count=2)"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-22 00:00:00', freq='C')"
]
},
"execution_count": 68,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minute_to_past_session(trading_minute, count=3)\n",
"# jumping a weekend..."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`minute_to_future_session`** works in the same way as **`minute_to_past_session`** albeit looking fowards."
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-28 00:00:00', freq='C')"
]
},
"execution_count": 69,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minute_to_future_session(trading_minute)\n",
"# default count is 1"
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-29 00:00:00', freq='C')"
]
},
"execution_count": 70,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minute_to_future_session(trading_minute, count=2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`minute_offset_by_sessions`** offsets a trading minute by a given number of sessions, by default 1."
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-27 14:15:00+0000', tz='UTC')"
]
},
"execution_count": 71,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# recalling again\n",
"trading_minute"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-28 14:15:00+0000', tz='UTC', freq='C')"
]
},
"execution_count": 72,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minute_offset_by_sessions(trading_minute)\n",
"# default count is 1"
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-10-25 14:15:00+0000', tz='UTC', freq='C')"
]
},
"execution_count": 73,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minute_offset_by_sessions(trading_minute, count=-2)\n",
"# offseting 'backwards'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If a would-be offset minute is not a minute of the offset session then...\n",
"\n",
"If the would-be offset minute is later than the offset session's close, the offset session's last trading minute is returned."
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>close</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2020-12-23</th>\n",
" <td>2020-12-23 21:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2020-12-24</th>\n",
" <td>2020-12-24 18:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2020-12-28</th>\n",
" <td>2020-12-28 21:00:00+00:00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" close\n",
"2020-12-23 2020-12-23 21:00:00+00:00\n",
"2020-12-24 2020-12-24 18:00:00+00:00\n",
"2020-12-28 2020-12-28 21:00:00+00:00"
]
},
"execution_count": 74,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# for reference\n",
"nys.schedule.loc[\"2020-12-23\":\"2020-12-28\", \"close\"].to_frame()"
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2020-12-24 17:59:00+0000', tz='UTC')"
]
},
"execution_count": 75,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minute_offset_by_sessions(\"2020-12-23 20:22\", 1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If the would-be offset minute is earlier than the offset session's open, the offset session's first trading minute is returned."
]
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>open</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2011-03-03</th>\n",
" <td>2011-03-03 02:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2011-03-04</th>\n",
" <td>2011-03-04 02:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2011-03-07</th>\n",
" <td>2011-03-07 01:30:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2011-03-08</th>\n",
" <td>2011-03-08 01:30:00+00:00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" open\n",
"2011-03-03 2011-03-03 02:00:00+00:00\n",
"2011-03-04 2011-03-04 02:00:00+00:00\n",
"2011-03-07 2011-03-07 01:30:00+00:00\n",
"2011-03-08 2011-03-08 01:30:00+00:00"
]
},
"execution_count": 76,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# for reference\n",
"hkg.schedule.loc[\"'2011-03-03\":\"2011-03-08\", \"open\"].to_frame()"
]
},
{
"cell_type": "code",
"execution_count": 77,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2011-03-04 02:00:00+0000', tz='UTC')"
]
},
"execution_count": 77,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.minute_offset_by_sessions(\"2011-03-08 01:47\", count=-2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If the would-be offset minute is a break minute, the last pre-break trading minute is returned."
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>open</th>\n",
" <th>break_start</th>\n",
" <th>break_end</th>\n",
" <th>close</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2010-12-23</th>\n",
" <td>2010-12-23 02:00:00+00:00</td>\n",
" <td>2010-12-23 04:00:00+00:00</td>\n",
" <td>2010-12-23 05:00:00+00:00</td>\n",
" <td>2010-12-23 08:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2010-12-24</th>\n",
" <td>2010-12-24 02:00:00+00:00</td>\n",
" <td>NaT</td>\n",
" <td>NaT</td>\n",
" <td>2010-12-24 04:30:00+00:00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" open break_start \\\n",
"2010-12-23 2010-12-23 02:00:00+00:00 2010-12-23 04:00:00+00:00 \n",
"2010-12-24 2010-12-24 02:00:00+00:00 NaT \n",
"\n",
" break_end close \n",
"2010-12-23 2010-12-23 05:00:00+00:00 2010-12-23 08:00:00+00:00 \n",
"2010-12-24 NaT 2010-12-24 04:30:00+00:00 "
]
},
"execution_count": 78,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# for reference\n",
"hkg.schedule.loc[\"2010-12-23\":\"2010-12-24\"]"
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2010-12-23 03:59:00+0000', tz='UTC')"
]
},
"execution_count": 79,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.minute_offset_by_sessions(\"2010-12-24 04:15\", count=-1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Methods that evaluate an index of contiguous trading minutes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`minutes_in_range`** returns all trading minutes within and inclusive of `start` and `end`. The parameters take `Minute` type (i.e. they do not need to represent actual trading minutes)."
]
},
{
"cell_type": "code",
"execution_count": 80,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>open</th>\n",
" <th>break_start</th>\n",
" <th>break_end</th>\n",
" <th>close</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2022-01-04</th>\n",
" <td>2022-01-04 01:30:00+00:00</td>\n",
" <td>2022-01-04 04:00:00+00:00</td>\n",
" <td>2022-01-04 05:00:00+00:00</td>\n",
" <td>2022-01-04 08:00:00+00:00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" open break_start \\\n",
"2022-01-04 2022-01-04 01:30:00+00:00 2022-01-04 04:00:00+00:00 \n",
"\n",
" break_end close \n",
"2022-01-04 2022-01-04 05:00:00+00:00 2022-01-04 08:00:00+00:00 "
]
},
"execution_count": 80,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# recalling...\n",
"hkg.schedule.loc[[\"2022-01-04\"]]"
]
},
{
"cell_type": "code",
"execution_count": 81,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2022-01-04 03:55:00+00:00', '2022-01-04 03:56:00+00:00',\n",
" '2022-01-04 03:57:00+00:00', '2022-01-04 03:58:00+00:00',\n",
" '2022-01-04 03:59:00+00:00', '2022-01-04 05:00:00+00:00',\n",
" '2022-01-04 05:01:00+00:00', '2022-01-04 05:02:00+00:00',\n",
" '2022-01-04 05:03:00+00:00', '2022-01-04 05:04:00+00:00',\n",
" '2022-01-04 05:05:00+00:00'],\n",
" dtype='datetime64[ns, UTC]', freq=None)"
]
},
"execution_count": 81,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.minutes_in_range(\"2022-01-04 03:55\", \"2022-01-04 05:05\")"
]
},
{
"cell_type": "code",
"execution_count": 82,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2022-01-04 05:00:00+00:00', '2022-01-04 05:01:00+00:00',\n",
" '2022-01-04 05:02:00+00:00', '2022-01-04 05:03:00+00:00',\n",
" '2022-01-04 05:04:00+00:00', '2022-01-04 05:05:00+00:00'],\n",
" dtype='datetime64[ns, UTC]', freq=None)"
]
},
"execution_count": 82,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# `start` does not have to represent a trading minute\n",
"hkg.minutes_in_range(\"2022-01-04 04:30\", \"2022-01-04 05:05\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Alternatively, **`minutes_window`** can be used to create an index of trading minutes of a defined length, anchored by the passed `minute`."
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2022-01-04 07:55:00+00:00', '2022-01-04 07:56:00+00:00',\n",
" '2022-01-04 07:57:00+00:00', '2022-01-04 07:58:00+00:00',\n",
" '2022-01-04 07:59:00+00:00', '2022-01-05 01:30:00+00:00',\n",
" '2022-01-05 01:31:00+00:00', '2022-01-05 01:32:00+00:00',\n",
" '2022-01-05 01:33:00+00:00', '2022-01-05 01:34:00+00:00'],\n",
" dtype='datetime64[ns, UTC]', freq=None)"
]
},
"execution_count": 83,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.minutes_window(\"2022-01-04 07:55\", count=10)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Or to work backwards from `minute`..."
]
},
{
"cell_type": "code",
"execution_count": 84,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2022-01-04 07:46:00+00:00', '2022-01-04 07:47:00+00:00',\n",
" '2022-01-04 07:48:00+00:00', '2022-01-04 07:49:00+00:00',\n",
" '2022-01-04 07:50:00+00:00', '2022-01-04 07:51:00+00:00',\n",
" '2022-01-04 07:52:00+00:00', '2022-01-04 07:53:00+00:00',\n",
" '2022-01-04 07:54:00+00:00', '2022-01-04 07:55:00+00:00'],\n",
" dtype='datetime64[ns, UTC]', freq=None)"
]
},
"execution_count": 84,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.minutes_window(\"2022-01-04 07:55\", count=-10)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Methods that query multiple TradingMinute"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`minutes_to_sessions`** does for multiple TradingMinute what `minute_to_session` does for one. However, this method is limited by requiring every minute of the passed `minutes` parameter to be a trading minute (i.e. there's no `direction` parameter available for this one). Also, whilst minutes do not need to be contiguous, they do need to be in ascending order."
]
},
{
"cell_type": "code",
"execution_count": 85,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2022-09-02 2022-09-02 13:35:00+00:00\n",
"2022-09-06 2022-09-06 13:35:00+00:00\n",
"2022-09-07 2022-09-07 13:35:00+00:00\n",
"2022-09-08 2022-09-08 13:35:00+00:00\n",
"2022-09-09 2022-09-09 13:35:00+00:00\n",
"Freq: C, Name: first_minutes, dtype: datetime64[ns, UTC]"
]
},
"execution_count": 85,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# set up a minute index to pass as `minutes`..\n",
"ser = nys.first_minutes[-200:-195] + (one_minute * 5)\n",
"ser"
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2022-09-02 13:35:00+00:00', '2022-09-08 13:35:00+00:00',\n",
" '2022-09-09 13:35:00+00:00'],\n",
" dtype='datetime64[ns, UTC]', name='first_minutes', freq=None)"
]
},
"execution_count": 86,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# still setting up 'minutes'\n",
"mins = pd.DatetimeIndex(ser)\n",
"mins = mins[:1].union(mins[-2:], sort=False)\n",
"mins"
]
},
{
"cell_type": "code",
"execution_count": 87,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2022-09-02', '2022-09-08', '2022-09-09'], dtype='datetime64[ns]', freq=None)"
]
},
"execution_count": 87,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minutes_to_sessions(mins)"
]
},
{
"cell_type": "code",
"execution_count": 88,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2022-09-02', '2022-09-06', '2022-09-07', '2022-09-08',\n",
" '2022-09-09'],\n",
" dtype='datetime64[ns]', freq=None)"
]
},
"execution_count": 88,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# NB `minutes` can also be passed as a Series...\n",
"nys.minutes_to_sessions(ser)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Methods that evaluate an index of contiguous sessions"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`sessions_in_range`** does for sessions what `minutes_in_range` does for minutes. Returns an index of all the sessions between `start` and `end`. Parameters take `Date` type (i.e. they do not need to represent actual sessions)."
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2022-01-03', '2022-01-04', '2022-01-05', '2022-01-06',\n",
" '2022-01-07', '2022-01-10', '2022-01-11', '2022-01-12',\n",
" '2022-01-13', '2022-01-14',\n",
" ...\n",
" '2022-12-16', '2022-12-19', '2022-12-20', '2022-12-21',\n",
" '2022-12-22', '2022-12-23', '2022-12-27', '2022-12-28',\n",
" '2022-12-29', '2022-12-30'],\n",
" dtype='datetime64[ns]', length=251, freq='C')"
]
},
"execution_count": 89,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.sessions_in_range(\"2022\", \"2022-12-31\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`sessions_window`** holds no surprises if you're familiar with `minutes_window`..."
]
},
{
"cell_type": "code",
"execution_count": 90,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2021-12-23', '2021-12-27', '2021-12-28'], dtype='datetime64[ns]', freq='C')"
]
},
"execution_count": 90,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.sessions_window(\"2021-12-23\", 3)"
]
},
{
"cell_type": "code",
"execution_count": 91,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2021-12-21', '2021-12-22', '2021-12-23'], dtype='datetime64[ns]', freq='C')"
]
},
"execution_count": 91,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.sessions_window(\"2021-12-23\", -3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Methods that query a range of dates\n",
"\n",
"The methods in this section query sessions that fall within the range of dates from `start` through `end` (inclusive of both). Both parameters take a `Date` (i.e the passed values can but do not have to represent an actual session)."
]
},
{
"cell_type": "code",
"execution_count": 92,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>open</th>\n",
" <th>break_start</th>\n",
" <th>break_end</th>\n",
" <th>close</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2021-12-23</th>\n",
" <td>2021-12-23 14:30:00+00:00</td>\n",
" <td>NaT</td>\n",
" <td>NaT</td>\n",
" <td>2021-12-23 21:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2021-12-27</th>\n",
" <td>2021-12-27 14:30:00+00:00</td>\n",
" <td>NaT</td>\n",
" <td>NaT</td>\n",
" <td>2021-12-27 21:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2021-12-28</th>\n",
" <td>2021-12-28 14:30:00+00:00</td>\n",
" <td>NaT</td>\n",
" <td>NaT</td>\n",
" <td>2021-12-28 21:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2021-12-29</th>\n",
" <td>2021-12-29 14:30:00+00:00</td>\n",
" <td>NaT</td>\n",
" <td>NaT</td>\n",
" <td>2021-12-29 21:00:00+00:00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" open break_start break_end \\\n",
"2021-12-23 2021-12-23 14:30:00+00:00 NaT NaT \n",
"2021-12-27 2021-12-27 14:30:00+00:00 NaT NaT \n",
"2021-12-28 2021-12-28 14:30:00+00:00 NaT NaT \n",
"2021-12-29 2021-12-29 14:30:00+00:00 NaT NaT \n",
"\n",
" close \n",
"2021-12-23 2021-12-23 21:00:00+00:00 \n",
"2021-12-27 2021-12-27 21:00:00+00:00 \n",
"2021-12-28 2021-12-28 21:00:00+00:00 \n",
"2021-12-29 2021-12-29 21:00:00+00:00 "
]
},
"execution_count": 92,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"start, end = \"2021-12-23\", \"2021-12-29\"\n",
"# for reference\n",
"nys.schedule.loc[start:end]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`sessions_distance`** returns the number of sessions in the range."
]
},
{
"cell_type": "code",
"execution_count": 93,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4"
]
},
"execution_count": 93,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.sessions_distance(start, end)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`sessions_minutes`** returns an index comprised of the trading minutes of all sessions in the given range."
]
},
{
"cell_type": "code",
"execution_count": 94,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2021-12-23 14:30:00+00:00', '2021-12-23 14:31:00+00:00',\n",
" '2021-12-23 14:32:00+00:00', '2021-12-23 14:33:00+00:00',\n",
" '2021-12-23 14:34:00+00:00', '2021-12-23 14:35:00+00:00',\n",
" '2021-12-23 14:36:00+00:00', '2021-12-23 14:37:00+00:00',\n",
" '2021-12-23 14:38:00+00:00', '2021-12-23 14:39:00+00:00',\n",
" ...\n",
" '2021-12-29 20:50:00+00:00', '2021-12-29 20:51:00+00:00',\n",
" '2021-12-29 20:52:00+00:00', '2021-12-29 20:53:00+00:00',\n",
" '2021-12-29 20:54:00+00:00', '2021-12-29 20:55:00+00:00',\n",
" '2021-12-29 20:56:00+00:00', '2021-12-29 20:57:00+00:00',\n",
" '2021-12-29 20:58:00+00:00', '2021-12-29 20:59:00+00:00'],\n",
" dtype='datetime64[ns, UTC]', length=1560, freq=None)"
]
},
"execution_count": 94,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.sessions_minutes(start, end)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`sessions_minutes_count`** returns just the number of trading minutes corresponding to the sessions."
]
},
{
"cell_type": "code",
"execution_count": 95,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1560"
]
},
"execution_count": 95,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.sessions_minutes_count(start, end)"
]
},
{
"cell_type": "code",
"execution_count": 96,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1560"
]
},
"execution_count": 96,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# i.e. `sessions_minutes_count` behaves as...\n",
"len(nys.sessions_minutes(start, end))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Methods that query a time\n",
"\n",
"`is_open_at_time` is rather unique in that it is not concerned with any specific `Minute` or `Date` but rather only if the exchange is considered open as at a given instance. The calendar's side has no effect on the return. Consequently, \n",
"even if the calendar's side is \"both\" it's possible to query if the market is open as at a time specified with second or greater accuracy."
]
},
{
"cell_type": "code",
"execution_count": 99,
"metadata": {},
"outputs": [],
"source": [
"hkg_both = xcals.get_calendar(\"XHKG\", side=\"both\")"
]
},
{
"cell_type": "code",
"execution_count": 100,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>open</th>\n",
" <th>break_start</th>\n",
" <th>break_end</th>\n",
" <th>close</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2022-01-04</th>\n",
" <td>2022-01-04 01:30:00+00:00</td>\n",
" <td>2022-01-04 04:00:00+00:00</td>\n",
" <td>2022-01-04 05:00:00+00:00</td>\n",
" <td>2022-01-04 08:00:00+00:00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" open break_start \\\n",
"2022-01-04 2022-01-04 01:30:00+00:00 2022-01-04 04:00:00+00:00 \n",
"\n",
" break_end close \n",
"2022-01-04 2022-01-04 05:00:00+00:00 2022-01-04 08:00:00+00:00 "
]
},
"execution_count": 100,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# recalling...\n",
"hkg.schedule.loc[[\"2022-01-04\"]]"
]
},
{
"cell_type": "code",
"execution_count": 101,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 101,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"timestamp = pd.Timestamp(\"2022-01-04 07:59:59\")\n",
"hkg_both.is_open_at_time(timestamp)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that unlike other methods, the input has to be an instance of `pd.Timestamp`. If passed as timezone-naive (as here) it will be assumed to represent UTC.\n",
"\n",
"`is_open_at_time` can take a 'side' option to determine if the exchange will be considered open or closed on a session's bounds:\n",
"* **\"left\"** (default) - treat exchange as open on session open and any break-end, treat as closed on session close and any break-start.\n",
"* **\"right\"** - treat exchange as open on session close and any break-start, treat as closed on session open and any break-end.\n",
"* **\"both\"** - treat exchange as open on all of session open, close and any break-start and break-end.\n",
"* **\"neither\"** - treat exchange as closed on all of session open, close and any break-start and break-end.\n",
"\n",
"It can also take an `ignore_breaks` options which, as for `is_open_on_minute`, will treat the exchange as open during any break."
]
},
{
"cell_type": "code",
"execution_count": 102,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[True, False, True, False]"
]
},
"execution_count": 102,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sides = (\"left\", \"right\", \"both\", \"neither\")\n",
"timestamp = pd.Timestamp(\"2022-01-04 01:30:00\")\n",
"[ hkg.is_open_at_time(timestamp, side=side) for side in sides ]"
]
},
{
"cell_type": "code",
"execution_count": 103,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[False, True, True, False]"
]
},
"execution_count": 103,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"timestamp = pd.Timestamp(\"2022-01-04 04:00:00\")\n",
"[ hkg.is_open_at_time(timestamp, side=side) for side in sides ]"
]
},
{
"cell_type": "code",
"execution_count": 104,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[True, True, True, True]"
]
},
"execution_count": 104,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"[ hkg.is_open_at_time(timestamp, side, ignore_breaks=True) for side in sides ]"
]
},
{
"cell_type": "code",
"execution_count": 105,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[True, True, True, True]"
]
},
"execution_count": 105,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"timestamp = pd.Timestamp(\"2022-01-04 03:59:59\")\n",
"[ hkg.is_open_at_time(timestamp, side=side) for side in sides ]"
]
},
{
"cell_type": "code",
"execution_count": 106,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[False, False, False, False]"
]
},
"execution_count": 106,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"timestamp = pd.Timestamp(\"2022-01-04 04:00:01\")\n",
"[ hkg.is_open_at_time(timestamp, side=side) for side in sides ]"
]
},
{
"cell_type": "code",
"execution_count": 107,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[False, False, False, False]"
]
},
"execution_count": 107,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"[ hkg.is_open_at_time(timestamp, side, ignore_breaks=False) for side in sides ]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### **`trading_index`** \n",
"Saving the best for last, `trading_index` provides for creating a trading index of given `period` over a range of sessions. It's options provide so much flexibility that it's got it's own tutorial at [trading_index.ipynb](./trading_index.ipynb). \n",
"\n",
"Here's a taster..."
]
},
{
"cell_type": "code",
"execution_count": 108,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"('2021-12-23', '2021-12-29')"
]
},
"execution_count": 108,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# recalling\n",
"start, end"
]
},
{
"cell_type": "code",
"execution_count": 109,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2021-12-23 14:30:00+00:00', '2021-12-23 14:45:00+00:00',\n",
" '2021-12-23 15:00:00+00:00', '2021-12-23 15:15:00+00:00',\n",
" '2021-12-23 15:30:00+00:00', '2021-12-23 15:45:00+00:00',\n",
" '2021-12-23 16:00:00+00:00', '2021-12-23 16:15:00+00:00',\n",
" '2021-12-23 16:30:00+00:00', '2021-12-23 16:45:00+00:00',\n",
" ...\n",
" '2021-12-29 18:30:00+00:00', '2021-12-29 18:45:00+00:00',\n",
" '2021-12-29 19:00:00+00:00', '2021-12-29 19:15:00+00:00',\n",
" '2021-12-29 19:30:00+00:00', '2021-12-29 19:45:00+00:00',\n",
" '2021-12-29 20:00:00+00:00', '2021-12-29 20:15:00+00:00',\n",
" '2021-12-29 20:30:00+00:00', '2021-12-29 20:45:00+00:00'],\n",
" dtype='datetime64[ns, UTC]', length=104, freq=None)"
]
},
"execution_count": 109,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.trading_index(start, end, \"15min\", intervals=False)"
]
},
{
"cell_type": "code",
"execution_count": 110,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2021-12-23 14:54:00+00:00', '2021-12-23 15:18:00+00:00',\n",
" '2021-12-23 15:42:00+00:00', '2021-12-23 16:06:00+00:00',\n",
" '2021-12-23 16:30:00+00:00', '2021-12-23 16:54:00+00:00',\n",
" '2021-12-23 17:18:00+00:00', '2021-12-23 17:42:00+00:00',\n",
" '2021-12-23 18:06:00+00:00', '2021-12-23 18:30:00+00:00',\n",
" '2021-12-23 18:54:00+00:00', '2021-12-23 19:18:00+00:00',\n",
" '2021-12-23 19:42:00+00:00', '2021-12-23 20:06:00+00:00',\n",
" '2021-12-23 20:30:00+00:00', '2021-12-23 20:54:00+00:00',\n",
" '2021-12-23 21:18:00+00:00'],\n",
" dtype='datetime64[ns, UTC]', freq=None)"
]
},
"execution_count": 110,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.trading_index(start, start, \"24min\", closed=\"right\", intervals=False)"
]
},
{
"cell_type": "code",
"execution_count": 111,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2021-12-23 14:30:00+00:00', '2021-12-23 14:54:00+00:00',\n",
" '2021-12-23 15:18:00+00:00', '2021-12-23 15:42:00+00:00',\n",
" '2021-12-23 16:06:00+00:00', '2021-12-23 16:30:00+00:00',\n",
" '2021-12-23 16:54:00+00:00', '2021-12-23 17:18:00+00:00',\n",
" '2021-12-23 17:42:00+00:00', '2021-12-23 18:06:00+00:00',\n",
" '2021-12-23 18:30:00+00:00', '2021-12-23 18:54:00+00:00',\n",
" '2021-12-23 19:18:00+00:00', '2021-12-23 19:42:00+00:00',\n",
" '2021-12-23 20:06:00+00:00', '2021-12-23 20:30:00+00:00',\n",
" '2021-12-23 20:54:00+00:00'],\n",
" dtype='datetime64[ns, UTC]', freq=None)"
]
},
"execution_count": 111,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.trading_index(start, start, \"24min\", force_close=True, intervals=False)"
]
},
{
"cell_type": "code",
"execution_count": 112,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"IntervalIndex([[2021-12-23 14:30:00, 2021-12-23 14:50:00), [2021-12-23 14:50:00, 2021-12-23 15:10:00), [2021-12-23 15:10:00, 2021-12-23 15:30:00), [2021-12-23 15:30:00, 2021-12-23 15:50:00), [2021-12-23 15:50:00, 2021-12-23 16:10:00) ... [2021-12-29 19:30:00, 2021-12-29 19:50:00), [2021-12-29 19:50:00, 2021-12-29 20:10:00), [2021-12-29 20:10:00, 2021-12-29 20:30:00), [2021-12-29 20:30:00, 2021-12-29 20:50:00), [2021-12-29 20:50:00, 2021-12-29 21:10:00)], dtype='interval[datetime64[ns, UTC], left]')"
]
},
"execution_count": 112,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"index = nys.trading_index(start, end, \"20min\", intervals=True)\n",
"index"
]
},
{
"cell_type": "code",
"execution_count": 113,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>left_side</th>\n",
" <th>right_side</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>[2021-12-23 14:30:00, 2021-12-23 14:50:00)</th>\n",
" <td>2021-12-23 14:30:00+00:00</td>\n",
" <td>2021-12-23 14:50:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[2021-12-23 14:50:00, 2021-12-23 15:10:00)</th>\n",
" <td>2021-12-23 14:50:00+00:00</td>\n",
" <td>2021-12-23 15:10:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[2021-12-23 15:10:00, 2021-12-23 15:30:00)</th>\n",
" <td>2021-12-23 15:10:00+00:00</td>\n",
" <td>2021-12-23 15:30:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[2021-12-23 15:30:00, 2021-12-23 15:50:00)</th>\n",
" <td>2021-12-23 15:30:00+00:00</td>\n",
" <td>2021-12-23 15:50:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[2021-12-23 15:50:00, 2021-12-23 16:10:00)</th>\n",
" <td>2021-12-23 15:50:00+00:00</td>\n",
" <td>2021-12-23 16:10:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[2021-12-29 19:30:00, 2021-12-29 19:50:00)</th>\n",
" <td>2021-12-29 19:30:00+00:00</td>\n",
" <td>2021-12-29 19:50:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[2021-12-29 19:50:00, 2021-12-29 20:10:00)</th>\n",
" <td>2021-12-29 19:50:00+00:00</td>\n",
" <td>2021-12-29 20:10:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[2021-12-29 20:10:00, 2021-12-29 20:30:00)</th>\n",
" <td>2021-12-29 20:10:00+00:00</td>\n",
" <td>2021-12-29 20:30:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[2021-12-29 20:30:00, 2021-12-29 20:50:00)</th>\n",
" <td>2021-12-29 20:30:00+00:00</td>\n",
" <td>2021-12-29 20:50:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[2021-12-29 20:50:00, 2021-12-29 21:10:00)</th>\n",
" <td>2021-12-29 20:50:00+00:00</td>\n",
" <td>2021-12-29 21:10:00+00:00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>80 rows × 2 columns</p>\n",
"</div>"
],
"text/plain": [
" left_side \\\n",
"[2021-12-23 14:30:00, 2021-12-23 14:50:00) 2021-12-23 14:30:00+00:00 \n",
"[2021-12-23 14:50:00, 2021-12-23 15:10:00) 2021-12-23 14:50:00+00:00 \n",
"[2021-12-23 15:10:00, 2021-12-23 15:30:00) 2021-12-23 15:10:00+00:00 \n",
"[2021-12-23 15:30:00, 2021-12-23 15:50:00) 2021-12-23 15:30:00+00:00 \n",
"[2021-12-23 15:50:00, 2021-12-23 16:10:00) 2021-12-23 15:50:00+00:00 \n",
"... ... \n",
"[2021-12-29 19:30:00, 2021-12-29 19:50:00) 2021-12-29 19:30:00+00:00 \n",
"[2021-12-29 19:50:00, 2021-12-29 20:10:00) 2021-12-29 19:50:00+00:00 \n",
"[2021-12-29 20:10:00, 2021-12-29 20:30:00) 2021-12-29 20:10:00+00:00 \n",
"[2021-12-29 20:30:00, 2021-12-29 20:50:00) 2021-12-29 20:30:00+00:00 \n",
"[2021-12-29 20:50:00, 2021-12-29 21:10:00) 2021-12-29 20:50:00+00:00 \n",
"\n",
" right_side \n",
"[2021-12-23 14:30:00, 2021-12-23 14:50:00) 2021-12-23 14:50:00+00:00 \n",
"[2021-12-23 14:50:00, 2021-12-23 15:10:00) 2021-12-23 15:10:00+00:00 \n",
"[2021-12-23 15:10:00, 2021-12-23 15:30:00) 2021-12-23 15:30:00+00:00 \n",
"[2021-12-23 15:30:00, 2021-12-23 15:50:00) 2021-12-23 15:50:00+00:00 \n",
"[2021-12-23 15:50:00, 2021-12-23 16:10:00) 2021-12-23 16:10:00+00:00 \n",
"... ... \n",
"[2021-12-29 19:30:00, 2021-12-29 19:50:00) 2021-12-29 19:50:00+00:00 \n",
"[2021-12-29 19:50:00, 2021-12-29 20:10:00) 2021-12-29 20:10:00+00:00 \n",
"[2021-12-29 20:10:00, 2021-12-29 20:30:00) 2021-12-29 20:30:00+00:00 \n",
"[2021-12-29 20:30:00, 2021-12-29 20:50:00) 2021-12-29 20:50:00+00:00 \n",
"[2021-12-29 20:50:00, 2021-12-29 21:10:00) 2021-12-29 21:10:00+00:00 \n",
"\n",
"[80 rows x 2 columns]"
]
},
"execution_count": 113,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# just to see it clearer...\n",
"pd.DataFrame(dict(left_side=index.left, right_side=index.right), index=index)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python38 xcals",
"language": "python",
"name": "py38_xcals"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
},
"widgets": {
"application/vnd.jupyter.widget-state+json": {
"state": {},
"version_major": 2,
"version_minor": 0
}
}
},
"nbformat": 4,
"nbformat_minor": 4
}
================================================
FILE: docs/tutorials/calendar_properties.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Calendar construction and properties\n",
"\n",
"This tutorial covers calendar construction and offers a walk through of `ExchangeCalendar` properties (for methods see the [calendar methods](./calendar_methods.ipynb) tutorial).\n",
"\n",
"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/master#how-can-i-create-a-new-calendar) section of the [README](https://github.com/gerrymanoim/exchange_calendars/tree/master))."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"# set up\n",
"import exchange_calendars as xcals\n",
"import pandas as pd\n",
"\n",
"hkg = xcals.get_calendar(\"XHKG\") # Hong Kong Stock Exchange\n",
"nys = xcals.get_calendar(\"XNYS\") # New York Stock Exchange"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Calendar construction\n",
"\n",
"The **`default_start`** and **`default_end`** class methods return the default calendar bounds, usually '20 years ago' and '1 year from now' respectively. These bounds represent the limits within which sessions and minutes can be interrogated and queried via the calendar's properties and methods."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2002-06-27 00:00:00'), Timestamp('2023-06-27 00:00:00'))"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.default_start(), nys.default_end()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `sessions` property returns all sessions covered by a calendar. The New York calendar created above can be seen to cover sessions over the period defined by the default bounds."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2002-06-27', '2002-06-28', '2002-07-01', '2002-07-02',\n",
" '2002-07-03', '2002-07-05', '2002-07-08', '2002-07-09',\n",
" '2002-07-10', '2002-07-11',\n",
" ...\n",
" '2023-06-13', '2023-06-14', '2023-06-15', '2023-06-16',\n",
" '2023-06-20', '2023-06-21', '2023-06-22', '2023-06-23',\n",
" '2023-06-26', '2023-06-27'],\n",
" dtype='datetime64[ns]', length=5286, freq='C')"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.sessions"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Alternatively the calendar bounds can be defined by passing the `start` and/or `end` parameters to `get_calendar` (or directly to a calendar class)."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2020-02-19', '2020-02-20', '2020-02-21', '2020-02-24',\n",
" '2020-02-25', '2020-02-26', '2020-02-27', '2020-02-28',\n",
" '2020-03-02', '2020-03-03',\n",
" ...\n",
" '2025-12-17', '2025-12-18', '2025-12-19', '2025-12-22',\n",
" '2025-12-23', '2025-12-24', '2025-12-26', '2025-12-29',\n",
" '2025-12-30', '2025-12-31'],\n",
" dtype='datetime64[ns]', length=1477, freq='C')"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cal = xcals.get_calendar(\"XNYS\", start=\"2020-02-19\", end=\"2025-12-31\")\n",
"cal.sessions"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Some calendars have min and/or max bounds outside of which a calendar cannot be created. The **`bound_min`/`bound_max`** class methods return the earliest/latest date from/to which a calendar class can be constructed, or None if there is no limit:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('1960-01-01 00:00:00'), Timestamp('2049-12-31 00:00:00'))"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.bound_min(), hkg.bound_max()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.bound_min() == nys.bound_max() == None"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`valid_sides`** is a class method that returns all side values that can be passed to the constructor's `side` parameter:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['both', 'left', 'right', 'neither']"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.valid_sides()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The side values available to 24 hour calendars is necessarily more limited."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['left', 'right']"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"open24 = xcals.get_calendar(\"24/7\", side=\"right\")\n",
"open24.valid_sides()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"NB the actual calendar side is returned by the **`side`** property (the default side for all calendars is \"left\")."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"('left', 'right')"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.side, open24.side"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"See the [minutes](./minutes.ipynb) tutorial for an explanation of how a calendar's side determines which minutes are treated as trading minutes."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### General Calendar Properties"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'XNYS'"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.name"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.tz # timezone"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'left'"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.side"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`day`** returns a `CustomBusinessDay` for the calendar:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<CustomBusinessDay>"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.day"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2021-12-29', '2021-12-30', '2021-12-31', '2022-01-03',\n",
" '2022-01-04', '2022-01-05'],\n",
" dtype='datetime64[ns]', freq='C')"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# for reference\n",
"nys.sessions_in_range(\"2021-12-29\", \"2022-01-05\")"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2022-01-04 00:00:00')"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.Timestamp(\"2021-12-31\") + (nys.day * 2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`has_break`** queries if _any_ calendar session has a break"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.has_break"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Sessions and Minutes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**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'."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### All of them"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2002-06-27', '2002-06-28', '2002-07-01', '2002-07-02',\n",
" '2002-07-03', '2002-07-05', '2002-07-08', '2002-07-09',\n",
" '2002-07-10', '2002-07-11',\n",
" ...\n",
" '2023-06-13', '2023-06-14', '2023-06-15', '2023-06-16',\n",
" '2023-06-20', '2023-06-21', '2023-06-22', '2023-06-23',\n",
" '2023-06-26', '2023-06-27'],\n",
" dtype='datetime64[ns]', length=5286, freq='C')"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.sessions # DatetimeIndex representing all calendar sessions"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2002-06-27 13:30:00+00:00', '2002-06-27 13:31:00+00:00',\n",
" '2002-06-27 13:32:00+00:00', '2002-06-27 13:33:00+00:00',\n",
" '2002-06-27 13:34:00+00:00', '2002-06-27 13:35:00+00:00',\n",
" '2002-06-27 13:36:00+00:00', '2002-06-27 13:37:00+00:00',\n",
" '2002-06-27 13:38:00+00:00', '2002-06-27 13:39:00+00:00',\n",
" ...\n",
" '2023-06-27 19:50:00+00:00', '2023-06-27 19:51:00+00:00',\n",
" '2023-06-27 19:52:00+00:00', '2023-06-27 19:53:00+00:00',\n",
" '2023-06-27 19:54:00+00:00', '2023-06-27 19:55:00+00:00',\n",
" '2023-06-27 19:56:00+00:00', '2023-06-27 19:57:00+00:00',\n",
" '2023-06-27 19:58:00+00:00', '2023-06-27 19:59:00+00:00'],\n",
" dtype='datetime64[ns, UTC]', length=2053440, freq=None)"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.minutes # DatetimeIndex representing every calendar trading minute"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Calendar Bounds"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2002-06-27 00:00:00', freq='C'),\n",
" Timestamp('2023-06-27 00:00:00', freq='C'))"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.first_session, nys.last_session"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2002-06-27 13:30:00+0000', tz='UTC'),\n",
" Timestamp('2023-06-27 19:59:00+0000', tz='UTC'))"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.first_minute, nys.last_minute"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Timestamp('2002-06-27 13:30:00+0000', tz='UTC'),\n",
" Timestamp('2023-06-27 20:00:00+0000', tz='UTC'))"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.first_session_open, nys.last_session_close"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Schedule (open, close and break times)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>open</th>\n",
" <th>break_start</th>\n",
" <th>break_end</th>\n",
" <th>close</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2002-06-27</th>\n",
" <td>2002-06-27 02:00:00+00:00</td>\n",
" <td>2002-06-27 04:00:00+00:00</td>\n",
" <td>2002-06-27 05:00:00+00:00</td>\n",
" <td>2002-06-27 08:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2002-06-28</th>\n",
" <td>2002-06-28 02:00:00+00:00</td>\n",
" <td>2002-06-28 04:00:00+00:00</td>\n",
" <td>2002-06-28 05:00:00+00:00</td>\n",
" <td>2002-06-28 08:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2002-07-02</th>\n",
" <td>2002-07-02 02:00:00+00:00</td>\n",
" <td>2002-07-02 04:00:00+00:00</td>\n",
" <td>2002-07-02 05:00:00+00:00</td>\n",
" <td>2002-07-02 08:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2002-07-03</th>\n",
" <td>2002-07-03 02:00:00+00:00</td>\n",
" <td>2002-07-03 04:00:00+00:00</td>\n",
" <td>2002-07-03 05:00:00+00:00</td>\n",
" <td>2002-07-03 08:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2002-07-04</th>\n",
" <td>2002-07-04 02:00:00+00:00</td>\n",
" <td>2002-07-04 04:00:00+00:00</td>\n",
" <td>2002-07-04 05:00:00+00:00</td>\n",
" <td>2002-07-04 08:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2023-06-20</th>\n",
" <td>2023-06-20 01:30:00+00:00</td>\n",
" <td>2023-06-20 04:00:00+00:00</td>\n",
" <td>2023-06-20 05:00:00+00:00</td>\n",
" <td>2023-06-20 08:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2023-06-21</th>\n",
" <td>2023-06-21 01:30:00+00:00</td>\n",
" <td>2023-06-21 04:00:00+00:00</td>\n",
" <td>2023-06-21 05:00:00+00:00</td>\n",
" <td>2023-06-21 08:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2023-06-23</th>\n",
" <td>2023-06-23 01:30:00+00:00</td>\n",
" <td>2023-06-23 04:00:00+00:00</td>\n",
" <td>2023-06-23 05:00:00+00:00</td>\n",
" <td>2023-06-23 08:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2023-06-26</th>\n",
" <td>2023-06-26 01:30:00+00:00</td>\n",
" <td>2023-06-26 04:00:00+00:00</td>\n",
" <td>2023-06-26 05:00:00+00:00</td>\n",
" <td>2023-06-26 08:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2023-06-27</th>\n",
" <td>2023-06-27 01:30:00+00:00</td>\n",
" <td>2023-06-27 04:00:00+00:00</td>\n",
" <td>2023-06-27 05:00:00+00:00</td>\n",
" <td>2023-06-27 08:00:00+00:00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5182 rows × 4 columns</p>\n",
"</div>"
],
"text/plain": [
" open break_start \\\n",
"2002-06-27 2002-06-27 02:00:00+00:00 2002-06-27 04:00:00+00:00 \n",
"2002-06-28 2002-06-28 02:00:00+00:00 2002-06-28 04:00:00+00:00 \n",
"2002-07-02 2002-07-02 02:00:00+00:00 2002-07-02 04:00:00+00:00 \n",
"2002-07-03 2002-07-03 02:00:00+00:00 2002-07-03 04:00:00+00:00 \n",
"2002-07-04 2002-07-04 02:00:00+00:00 2002-07-04 04:00:00+00:00 \n",
"... ... ... \n",
"2023-06-20 2023-06-20 01:30:00+00:00 2023-06-20 04:00:00+00:00 \n",
"2023-06-21 2023-06-21 01:30:00+00:00 2023-06-21 04:00:00+00:00 \n",
"2023-06-23 2023-06-23 01:30:00+00:00 2023-06-23 04:00:00+00:00 \n",
"2023-06-26 2023-06-26 01:30:00+00:00 2023-06-26 04:00:00+00:00 \n",
"2023-06-27 2023-06-27 01:30:00+00:00 2023-06-27 04:00:00+00:00 \n",
"\n",
" break_end close \n",
"2002-06-27 2002-06-27 05:00:00+00:00 2002-06-27 08:00:00+00:00 \n",
"2002-06-28 2002-06-28 05:00:00+00:00 2002-06-28 08:00:00+00:00 \n",
"2002-07-02 2002-07-02 05:00:00+00:00 2002-07-02 08:00:00+00:00 \n",
"2002-07-03 2002-07-03 05:00:00+00:00 2002-07-03 08:00:00+00:00 \n",
"2002-07-04 2002-07-04 05:00:00+00:00 2002-07-04 08:00:00+00:00 \n",
"... ... ... \n",
"2023-06-20 2023-06-20 05:00:00+00:00 2023-06-20 08:00:00+00:00 \n",
"2023-06-21 2023-06-21 05:00:00+00:00 2023-06-21 08:00:00+00:00 \n",
"2023-06-23 2023-06-23 05:00:00+00:00 2023-06-23 08:00:00+00:00 \n",
"2023-06-26 2023-06-26 05:00:00+00:00 2023-06-26 08:00:00+00:00 \n",
"2023-06-27 2023-06-27 05:00:00+00:00 2023-06-27 08:00:00+00:00 \n",
"\n",
"[5182 rows x 4 columns]"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sch = hkg.schedule\n",
"sch"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The schedule is a pandas DataFrame. It shows the dates the exchange is open and describes the bounds when the exchange is open for regular trading on each of those dates.\n",
"\n",
"The index represents the calendar's sessions as a timezone-naive pandas `DatetimeIndex`. 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** and columns have dtype as `datetime64[ns, UTC]`."
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2002-06-27 2002-06-27 02:00:00+00:00\n",
"2002-06-28 2002-06-28 02:00:00+00:00\n",
"2002-07-02 2002-07-02 02:00:00+00:00\n",
"2002-07-03 2002-07-03 02:00:00+00:00\n",
"2002-07-04 2002-07-04 02:00:00+00:00\n",
" ... \n",
"2023-06-20 2023-06-20 01:30:00+00:00\n",
"2023-06-21 2023-06-21 01:30:00+00:00\n",
"2023-06-23 2023-06-23 01:30:00+00:00\n",
"2023-06-26 2023-06-26 01:30:00+00:00\n",
"2023-06-27 2023-06-27 01:30:00+00:00\n",
"Freq: C, Name: open, Length: 5182, dtype: datetime64[ns, UTC]"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sch.open"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The break_start/break_end columns take `pd.NaT` in the event that a session does not have a break."
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>open</th>\n",
" <th>break_start</th>\n",
" <th>break_end</th>\n",
" <th>close</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2021-12-23</th>\n",
" <td>2021-12-23 01:30:00+00:00</td>\n",
" <td>2021-12-23 04:00:00+00:00</td>\n",
" <td>2021-12-23 05:00:00+00:00</td>\n",
" <td>2021-12-23 08:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2021-12-24</th>\n",
" <td>2021-12-24 01:30:00+00:00</td>\n",
" <td>NaT</td>\n",
" <td>NaT</td>\n",
" <td>2021-12-24 04:00:00+00:00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2021-12-28</th>\n",
" <td>2021-12-28 01:30:00+00:00</td>\n",
" <td>2021-12-28 04:00:00+00:00</td>\n",
" <td>2021-12-28 05:00:00+00:00</td>\n",
" <td>2021-12-28 08:00:00+00:00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" open break_start \\\n",
"2021-12-23 2021-12-23 01:30:00+00:00 2021-12-23 04:00:00+00:00 \n",
"2021-12-24 2021-12-24 01:30:00+00:00 NaT \n",
"2021-12-28 2021-12-28 01:30:00+00:00 2021-12-28 04:00:00+00:00 \n",
"\n",
" break_end close \n",
"2021-12-23 2021-12-23 05:00:00+00:00 2021-12-23 08:00:00+00:00 \n",
"2021-12-24 NaT 2021-12-24 04:00:00+00:00 \n",
"2021-12-28 2021-12-28 05:00:00+00:00 2021-12-28 08:00:00+00:00 "
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.schedule.loc[\"2021-12-23\":\"2021-12-28\"]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The calendar properties **`opens`**, **`closes`**, **`break_starts`** and **`break_ends`** return the corresponding column of the schedule as a `pd.Series`."
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2002-06-27 2002-06-27 02:00:00+00:00\n",
"2002-06-28 2002-06-28 02:00:00+00:00\n",
"2002-07-02 2002-07-02 02:00:00+00:00\n",
"2002-07-03 2002-07-03 02:00:00+00:00\n",
"2002-07-04 2002-07-04 02:00:00+00:00\n",
" ... \n",
"2023-06-20 2023-06-20 01:30:00+00:00\n",
"2023-06-21 2023-06-21 01:30:00+00:00\n",
"2023-06-23 2023-06-23 01:30:00+00:00\n",
"2023-06-26 2023-06-26 01:30:00+00:00\n",
"2023-06-27 2023-06-27 01:30:00+00:00\n",
"Freq: C, Name: open, Length: 5182, dtype: datetime64[ns, UTC]"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.opens"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2021-12-23 2021-12-23 08:00:00+00:00\n",
"2021-12-24 2021-12-24 04:00:00+00:00\n",
"2021-12-28 2021-12-28 08:00:00+00:00\n",
"Freq: C, Name: close, dtype: datetime64[ns, UTC]"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hkg.closes[\"2021-12-23\":\"2021-12-28\"]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"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."
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2018-07-03', '2018-11-23', '2018-12-24', '2019-07-03',\n",
" '2019-11-29', '2019-12-24', '2020-11-27', '2020-12-24',\n",
" '2021-11-26', '2022-11-25'],\n",
" dtype='datetime64[ns]', freq=None)"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nys.early_closes[-10:]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Bound Trading Minutes by-sessions"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"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."
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
gitextract_kugg5ghl/
├── .devcontainer/
│ ├── Dockerfile
│ ├── base.Dockerfile
│ ├── devcontainer.json
│ └── library-scripts/
│ ├── README.md
│ ├── common-debian.sh
│ ├── node-debian.sh
│ └── python-debian.sh
├── .gitattributes
├── .github/
│ ├── dependabot.yml
│ ├── pull_request_template.md
│ ├── release-drafter-config.yml
│ └── workflows/
│ ├── benchmark.yml
│ ├── labeler.yml
│ ├── main.yml
│ ├── master-merge.yml
│ └── release.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .python-version
├── LICENSE
├── MANIFEST.in
├── README.md
├── docs/
│ ├── changes_archive.md
│ ├── dev/
│ │ └── depenencies_update.md
│ └── tutorials/
│ ├── calendar_methods.ipynb
│ ├── calendar_properties.ipynb
│ ├── minutes.ipynb
│ ├── sessions.ipynb
│ └── trading_index.ipynb
├── etc/
│ ├── __init__.py
│ ├── bench.py
│ ├── check_holidays.py
│ ├── ecal
│ ├── factory_bounds.py
│ ├── lunisolar
│ ├── make_exchange_calendar_test_csv.py
│ └── update_xkrx_holidays.py
├── exchange_calendars/
│ ├── __init__.py
│ ├── always_open.py
│ ├── calendar_helpers.py
│ ├── calendar_utils.py
│ ├── common_holidays.py
│ ├── ecal.py
│ ├── errors.py
│ ├── exchange_calendar.py
│ ├── exchange_calendar_aixk.py
│ ├── exchange_calendar_asex.py
│ ├── exchange_calendar_bvmf.py
│ ├── exchange_calendar_cmes.py
│ ├── exchange_calendar_iepa.py
│ ├── exchange_calendar_xams.py
│ ├── exchange_calendar_xasx.py
│ ├── exchange_calendar_xbda.py
│ ├── exchange_calendar_xbel.py
│ ├── exchange_calendar_xbkk.py
│ ├── exchange_calendar_xbog.py
│ ├── exchange_calendar_xbom.py
│ ├── exchange_calendar_xbra.py
│ ├── exchange_calendar_xbru.py
│ ├── exchange_calendar_xbse.py
│ ├── exchange_calendar_xbud.py
│ ├── exchange_calendar_xbue.py
│ ├── exchange_calendar_xcbf.py
│ ├── exchange_calendar_xcse.py
│ ├── exchange_calendar_xcys.py
│ ├── exchange_calendar_xdub.py
│ ├── exchange_calendar_xdus.py
│ ├── exchange_calendar_xeee.py
│ ├── exchange_calendar_xetr.py
│ ├── exchange_calendar_xeur.py
│ ├── exchange_calendar_xfra.py
│ ├── exchange_calendar_xham.py
│ ├── exchange_calendar_xhel.py
│ ├── exchange_calendar_xhkg.py
│ ├── exchange_calendar_xice.py
│ ├── exchange_calendar_xidx.py
│ ├── exchange_calendar_xist.py
│ ├── exchange_calendar_xjse.py
│ ├── exchange_calendar_xkar.py
│ ├── exchange_calendar_xkls.py
│ ├── exchange_calendar_xkrx.py
│ ├── exchange_calendar_xlim.py
│ ├── exchange_calendar_xlis.py
│ ├── exchange_calendar_xlit.py
│ ├── exchange_calendar_xlju.py
│ ├── exchange_calendar_xlon.py
│ ├── exchange_calendar_xlux.py
│ ├── exchange_calendar_xmad.py
│ ├── exchange_calendar_xmex.py
│ ├── exchange_calendar_xmil.py
│ ├── exchange_calendar_xmos.py
│ ├── exchange_calendar_xnys.py
│ ├── exchange_calendar_xnze.py
│ ├── exchange_calendar_xosl.py
│ ├── exchange_calendar_xpar.py
│ ├── exchange_calendar_xphs.py
│ ├── exchange_calendar_xpra.py
│ ├── exchange_calendar_xris.py
│ ├── exchange_calendar_xsau.py
│ ├── exchange_calendar_xses.py
│ ├── exchange_calendar_xsgo.py
│ ├── exchange_calendar_xshg.py
│ ├── exchange_calendar_xsto.py
│ ├── exchange_calendar_xstu.py
│ ├── exchange_calendar_xswx.py
│ ├── exchange_calendar_xtae.py
│ ├── exchange_calendar_xtai.py
│ ├── exchange_calendar_xtal.py
│ ├── exchange_calendar_xtks.py
│ ├── exchange_calendar_xtse.py
│ ├── exchange_calendar_xwar.py
│ ├── exchange_calendar_xwbo.py
│ ├── exchange_calendar_xzag.py
│ ├── lunisolar_holidays.py
│ ├── pandas_extensions/
│ │ ├── __init__.py
│ │ ├── holiday.py
│ │ ├── korean_holiday.py
│ │ └── offsets.py
│ ├── precomputed_exchange_calendar.py
│ ├── tase_holidays.py
│ ├── us_futures_calendar.py
│ ├── us_holidays.py
│ ├── utils/
│ │ ├── __init__.py
│ │ └── pandas_utils.py
│ ├── weekday_calendar.py
│ ├── xbkk_holidays.py
│ ├── xkls_holidays.py
│ ├── xkrx_holidays.py
│ └── xtks_holidays.py
├── pyproject.toml
├── requirements.txt
├── ruff.toml
└── tests/
├── __init__.py
├── resources/
│ ├── 24-5.csv
│ ├── 24-7.csv
│ ├── aixk.csv
│ ├── asex.csv
│ ├── bvmf.csv
│ ├── cmes.csv
│ ├── iepa.csv
│ ├── test.csv
│ ├── xams.csv
│ ├── xasx.csv
│ ├── xbda.csv
│ ├── xbel.csv
│ ├── xbkk.csv
│ ├── xbog.csv
│ ├── xbom.csv
│ ├── xbra.csv
│ ├── xbru.csv
│ ├── xbse.csv
│ ├── xbud.csv
│ ├── xbue.csv
│ ├── xcbf.csv
│ ├── xcse.csv
│ ├── xcys.csv
│ ├── xdub.csv
│ ├── xdus.csv
│ ├── xeee.csv
│ ├── xetr.csv
│ ├── xeur.csv
│ ├── xfra.csv
│ ├── xham.csv
│ ├── xhel.csv
│ ├── xhkg.csv
│ ├── xice.csv
│ ├── xidx.csv
│ ├── xist.csv
│ ├── xjse.csv
│ ├── xkar.csv
│ ├── xkls.csv
│ ├── xkrx.csv
│ ├── xlim.csv
│ ├── xlis.csv
│ ├── xlit.csv
│ ├── xlju.csv
│ ├── xlon.csv
│ ├── xlux.csv
│ ├── xmad.csv
│ ├── xmex.csv
│ ├── xmil.csv
│ ├── xmos.csv
│ ├── xnys.csv
│ ├── xnze.csv
│ ├── xosl.csv
│ ├── xpar.csv
│ ├── xphs.csv
│ ├── xpra.csv
│ ├── xris.csv
│ ├── xsau.csv
│ ├── xses.csv
│ ├── xsgo.csv
│ ├── xshg.csv
│ ├── xsto.csv
│ ├── xstu.csv
│ ├── xswx.csv
│ ├── xtae.csv
│ ├── xtai.csv
│ ├── xtal.csv
│ ├── xtks.csv
│ ├── xtse.csv
│ ├── xwar.csv
│ ├── xwbo.csv
│ └── xzag.csv
├── test_aixk_calendar.py
├── test_always_open.py
├── test_asex_calendar.py
├── test_bvmf_calendar.py
├── test_calendar_dispatcher.py
├── test_calendar_helpers.py
├── test_cmes_calendar.py
├── test_exchange_calendar.py
├── test_iepa_calendar.py
├── test_utils.py
├── test_weekday_calendar.py
├── test_xams_calendar.py
├── test_xasx_calendar.py
├── test_xbda_calendar.py
├── test_xbel_calendar.py
├── test_xbkk_calendar.py
├── test_xbog_calendar.py
├── test_xbom_calendar.py
├── test_xbra_calendar.py
├── test_xbru_calendar.py
├── test_xbse_calendar.py
├── test_xbud_calendar.py
├── test_xbue_calendar.py
├── test_xcbf_calendar.py
├── test_xcse_calendar.py
├── test_xcys_calendar.py
├── test_xdub_calendar.py
├── test_xdus_calendar.py
├── test_xeee_calendar.py
├── test_xetr_calendar.py
├── test_xeur_calendar.py
├── test_xfra_calendar.py
├── test_xham_calendar.py
├── test_xhel_calendar.py
├── test_xhkg_calendar.py
├── test_xice_calendar.py
├── test_xidx_calendar.py
├── test_xist_calendar.py
├── test_xjse_calendar.py
├── test_xkar_calendar.py
├── test_xkls_calendar.py
├── test_xkrx_calendar.py
├── test_xlim_calendar.py
├── test_xlis_calendar.py
├── test_xlit_calendar.py
├── test_xlju_calendar.py
├── test_xlon_calendar.py
├── test_xlux_calendar.py
├── test_xmad_calendar.py
├── test_xmex_calendar.py
├── test_xmil_calendar.py
├── test_xmos_calendar.py
├── test_xnys_calendar.py
├── test_xnze_calendar.py
├── test_xosl_calendar.py
├── test_xpar_calendar.py
├── test_xphs_calendar.py
├── test_xpra_calendar.py
├── test_xris_calendar.py
├── test_xsau_calendar.py
├── test_xses_calendar.py
├── test_xsgo_calendar.py
├── test_xshg_calendar.py
├── test_xsto_calendar.py
├── test_xstu_calendar.py
├── test_xswx_calendar.py
├── test_xtae_calendar.py
├── test_xtai_calendar.py
├── test_xtal_calendar.py
├── test_xtks_calendar.py
├── test_xtse_calendar.py
├── test_xwar_calendar.py
├── test_xwbo_calendar.py
└── test_xzag_calendar.py
SYMBOL INDEX (1460 symbols across 164 files)
FILE: etc/bench.py
function construct_all_calendars (line 14) | def construct_all_calendars():
function is_open_on_minute_bench (line 30) | def is_open_on_minute_bench(cal, timestamps):
function test_calendar_construction (line 35) | def test_calendar_construction(benchmark):
function test_is_open_on_minute (line 39) | def test_is_open_on_minute(benchmark):
FILE: etc/check_holidays.py
class TimestampType (line 11) | class TimestampType(click.ParamType):
method __init__ (line 21) | def __init__(self, tz=None):
method name (line 25) | def name(self):
method convert (line 28) | def convert(self, value, param, ctx):
function check_holidays (line 39) | def check_holidays(
function _check_range (line 87) | def _check_range(start, end, holidays, cal, calendar_name):
function main (line 178) | def main(
FILE: etc/factory_bounds.py
class FactoryBounds (line 25) | class FactoryBounds:
class _FindFactoryBounds (line 57) | class _FindFactoryBounds:
method __init__ (line 60) | def __init__(self, Factory: xcals.ExchangeCalendar, watch: bool = Fals...
method calendar_name (line 66) | def calendar_name(self) -> str:
method today (line 73) | def today(self) -> pd.Timestamp:
method _get_calendar (line 76) | def _get_calendar(
method _is_valid_date (line 94) | def _is_valid_date(
method _get_a_valid_date_by_trying_every_x_days (line 106) | def _get_a_valid_date_by_trying_every_x_days(
method _first_offset (line 126) | def _first_offset(self) -> pd.DateOffset:
method _is_first_offset (line 129) | def _is_first_offset(self, offset: pd.DateOffset) -> bool:
method _offset_iterator (line 132) | def _offset_iterator(
method _is_valid_bound (line 151) | def _is_valid_bound(
method _try_short_cut (line 160) | def _try_short_cut(
method _initial_value (line 187) | def _initial_value(bound: Literal["start", "end"]) -> pd.Timestamp:
method _get_bound (line 192) | def _get_bound(
method bounds (line 228) | def bounds(self) -> FactoryBounds:
function find_factory_bounds (line 238) | def find_factory_bounds(
function _find_bounds_all_factories (line 272) | def _find_bounds_all_factories(watch=False) -> dict[str, FactoryBounds]:
function _factory_bounds_resource_path (line 285) | def _factory_bounds_resource_path() -> pathlib.PurePath:
function _bake_all_calendar_bounds (line 292) | def _bake_all_calendar_bounds(all_calendar_bounds: dict["str", FactoryBo...
function _retrieve_all_calendars_bounds (line 312) | def _retrieve_all_calendars_bounds() -> dict["str", FactoryBounds]:
function _get_all_calendars_bounds_exceptions (line 322) | def _get_all_calendars_bounds_exceptions() -> tuple[type[Exception], ...]:
function all_calendars_bounds (line 334) | def all_calendars_bounds() -> pd.DataFrame:
function get_calendar_bounds (line 364) | def get_calendar_bounds(
FILE: etc/update_xkrx_holidays.py
function download_krx_holidays_as_dict (line 13) | def download_krx_holidays_as_dict(year=None, page_first_call=False):
function get_precomputed_krx_holidays_online (line 73) | def get_precomputed_krx_holidays_online(from_year=None, to_year=None):
function update_dupmed_precomputed_krx_holidays (line 90) | def update_dupmed_precomputed_krx_holidays():
FILE: exchange_calendars/always_open.py
class AlwaysOpenCalendar (line 7) | class AlwaysOpenCalendar(ExchangeCalendar):
FILE: exchange_calendars/calendar_helpers.py
function next_divider_idx (line 39) | def next_divider_idx(dividers: np.ndarray, minute_val: int) -> int:
function previous_divider_idx (line 49) | def previous_divider_idx(dividers: np.ndarray, minute_val: int) -> int:
function compute_minutes (line 58) | def compute_minutes(
function one_minute_earlier (line 101) | def one_minute_earlier(arr: np.ndarray) -> np.ndarray:
function one_minute_later (line 108) | def one_minute_later(arr: np.ndarray) -> np.ndarray:
function is_date (line 115) | def is_date(ts: pd.Timestamp) -> bool:
function to_utc (line 134) | def to_utc(ts: pd.Timestamp) -> pd.Timestamp:
function parse_timestamp (line 151) | def parse_timestamp( # noqa: C901, PLR0912
function parse_date_or_minute (line 253) | def parse_date_or_minute(
function parse_trading_minute (line 290) | def parse_trading_minute(
function parse_date (line 324) | def parse_date(
function parse_session (line 394) | def parse_session(
class _TradingIndex (line 433) | class _TradingIndex:
method __init__ (line 448) | def __init__(
method closed_right (line 515) | def closed_right(self) -> bool:
method closed_left (line 519) | def closed_left(self) -> bool:
method verify_non_overlapping (line 522) | def verify_non_overlapping(self):
method _create_index_for_sessions (line 562) | def _create_index_for_sessions(
method _trading_index (line 606) | def _trading_index(self) -> np.ndarray:
method curtail_for_times (line 652) | def curtail_for_times(
method trading_index (line 669) | def trading_index(self) -> pd.DatetimeIndex:
method _override_defaults (line 679) | def _override_defaults(self, **kwargs):
method trading_index_intervals (line 686) | def trading_index_intervals(self) -> pd.IntervalIndex:
FILE: exchange_calendars/calendar_utils.py
class ExchangeCalendarDispatcher (line 190) | class ExchangeCalendarDispatcher:
method __init__ (line 207) | def __init__(self, calendars, calendar_factories, aliases):
method _fabricate (line 214) | def _fabricate(self, name: str, **kwargs) -> ExchangeCalendar:
method _get_cached_factory_output (line 224) | def _get_cached_factory_output(
method get_calendar (line 237) | def get_calendar(
method get_calendar_names (line 328) | def get_calendar_names(
method has_calendar (line 361) | def has_calendar(self, name):
method register_calendar (line 371) | def register_calendar(self, name, calendar, force=False):
method register_calendar_type (line 399) | def register_calendar_type(self, name, calendar_type, force=False):
method register_calendar_alias (line 430) | def register_calendar_alias(self, alias, real_name, force=False):
method resolve_alias (line 468) | def resolve_alias(self, name: str):
method aliases_to_names (line 511) | def aliases_to_names(self) -> dict[str, str]:
method names_to_aliases (line 527) | def names_to_aliases(self) -> dict[str, list[str]]:
method deregister_calendar (line 546) | def deregister_calendar(self, name):
method clear_calendars (line 559) | def clear_calendars(self):
FILE: exchange_calendars/common_holidays.py
function new_years_day (line 9) | def new_years_day(start_date=None, end_date=None, observance=None, days_...
function new_years_eve (line 21) | def new_years_eve(
function epiphany (line 40) | def epiphany(
function anzac_day (line 59) | def anzac_day(start_date=None, end_date=None, observance=None, days_of_w...
function european_labour_day (line 71) | def european_labour_day(
function holy_wednesday (line 89) | def holy_wednesday(start_date=None, end_date=None, days_of_week=None):
function maundy_thursday (line 101) | def maundy_thursday(start_date=None, end_date=None, days_of_week=None):
function ascension_day (line 113) | def ascension_day(start_date=None, end_date=None):
function whit_monday (line 124) | def whit_monday(start_date=None, end_date=None):
function corpus_christi (line 135) | def corpus_christi(start_date=None, end_date=None):
function orthodox_ash_monday (line 146) | def orthodox_ash_monday(start_date=None, end_date=None):
function orthodox_good_friday (line 157) | def orthodox_good_friday(start_date=None, end_date=None):
function orthodox_easter_monday (line 168) | def orthodox_easter_monday(start_date=None, end_date=None):
function orthodox_easter_tuesday (line 179) | def orthodox_easter_tuesday(start_date=None, end_date=None):
function orthodox_pentecost (line 190) | def orthodox_pentecost(start_date=None, end_date=None):
function orthodox_whit_monday (line 201) | def orthodox_whit_monday(start_date=None, end_date=None):
function midsummer_eve (line 212) | def midsummer_eve(start_date=None, end_date=None):
function saint_peter_and_saint_paul_day (line 223) | def saint_peter_and_saint_paul_day(
function assumption_day (line 237) | def assumption_day(start_date=None, end_date=None, observance=None, days...
function all_saints_day (line 249) | def all_saints_day(start_date=None, end_date=None, observance=None, days...
function immaculate_conception (line 261) | def immaculate_conception(
function christmas_eve (line 275) | def christmas_eve(start_date=None, end_date=None, observance=None, days_...
function christmas (line 287) | def christmas(start_date=None, end_date=None, observance=None, days_of_w...
function weekend_christmas (line 299) | def weekend_christmas(start_date=None, end_date=None, observance=None):
function boxing_day (line 315) | def boxing_day(start_date=None, end_date=None, observance=None, days_of_...
function weekend_boxing_day (line 327) | def weekend_boxing_day(start_date=None, end_date=None, observance=None):
FILE: exchange_calendars/ecal.py
function error (line 24) | def error(msg):
function _render_month (line 29) | def _render_month(calendar, year, month, print_year):
function _concat_lines (line 69) | def _concat_lines(strings, width):
function _int_arg (line 90) | def _int_arg(v, name):
function parse_args (line 97) | def parse_args(argv):
function main (line 129) | def main(argv=None):
FILE: exchange_calendars/errors.py
class CalendarError (line 27) | class CalendarError(Exception):
method __init__ (line 30) | def __init__(self, **kwargs):
method __str__ (line 33) | def __str__(self):
class InvalidCalendarName (line 40) | class InvalidCalendarName(CalendarError):
class CalendarNameCollision (line 48) | class CalendarNameCollision(CalendarError):
class CyclicCalendarAlias (line 57) | class CyclicCalendarAlias(CalendarError):
class NoSessionsError (line 65) | class NoSessionsError(CalendarError):
class NotSessionError (line 80) | class NotSessionError(ValueError):
method __init__ (line 98) | def __init__(self, calendar: ExchangeCalendar, ts: pd.Timestamp, param...
method __str__ (line 103) | def __str__(self) -> str:
class DateOutOfBounds (line 124) | class DateOutOfBounds(ValueError):
method __init__ (line 140) | def __init__(self, calendar: ExchangeCalendar, date: pd.Timestamp, par...
method __str__ (line 145) | def __str__(self) -> str:
class NotTradingMinuteError (line 165) | class NotTradingMinuteError(ValueError):
method __init__ (line 180) | def __init__(
method __str__ (line 190) | def __str__(self) -> str:
class MinuteOutOfBounds (line 210) | class MinuteOutOfBounds(ValueError):
method __init__ (line 227) | def __init__(
method __str__ (line 234) | def __str__(self) -> str:
class RequestedSessionOutOfBounds (line 254) | class RequestedSessionOutOfBounds(ValueError):
method __init__ (line 269) | def __init__(self, calendar: ExchangeCalendar, too_early: bool):
method __str__ (line 275) | def __str__(self) -> str:
class RequestedMinuteOutOfBounds (line 282) | class RequestedMinuteOutOfBounds(ValueError):
method __init__ (line 297) | def __init__(self, calendar: ExchangeCalendar, too_early: bool):
method __str__ (line 303) | def __str__(self) -> str:
class IndexOverlapError (line 310) | class IndexOverlapError(ValueError):
class IntervalsOverlapError (line 314) | class IntervalsOverlapError(IndexOverlapError):
method __str__ (line 318) | def __str__(self):
class IndicesOverlapError (line 329) | class IndicesOverlapError(IndexOverlapError):
method __str__ (line 333) | def __str__(self):
FILE: exchange_calendars/exchange_calendar.py
function selection (line 74) | def selection(
function _group_times (line 89) | def _group_times(
class deprecate (line 112) | class deprecate: # noqa: N801
method __init__ (line 115) | def __init__(
method __call__ (line 123) | def __call__(self, f: Callable) -> Callable:
method _message (line 131) | def _message(self, f: Callable) -> str:
class HolidayCalendar (line 141) | class HolidayCalendar(AbstractHolidayCalendar):
method __init__ (line 142) | def __init__(self, rules):
class ExchangeCalendar (line 146) | class ExchangeCalendar(ABC):
method bound_min (line 234) | def bound_min(cls) -> pd.Timestamp | None:
method bound_max (line 252) | def bound_max(cls) -> pd.Timestamp | None:
method default_start (line 270) | def default_start(cls) -> pd.Timestamp:
method default_end (line 282) | def default_end(cls) -> pd.Timestamp:
method __init__ (line 293) | def __init__( # noqa: PLR0915 # can lose noqa post changes when min ...
method name (line 428) | def name(self) -> str:
method _bound_min_error_msg (line 432) | def _bound_min_error_msg(self, start: pd.Timestamp) -> str:
method _bound_max_error_msg (line 445) | def _bound_max_error_msg(self, end: pd.Timestamp) -> str:
method tz (line 459) | def tz(self) -> ZoneInfo:
method open_times (line 465) | def open_times(self) -> Sequence[tuple[pd.Timestamp | None, datetime.t...
method break_start_times (line 497) | def break_start_times(
method break_end_times (line 508) | def break_end_times(
method close_times (line 520) | def close_times(self) -> Sequence[tuple[pd.Timestamp | None, datetime....
method weekmask (line 551) | def weekmask(self) -> str:
method open_offset (line 563) | def open_offset(self) -> int:
method close_offset (line 578) | def close_offset(self) -> int:
method regular_holidays (line 593) | def regular_holidays(self) -> HolidayCalendar | None:
method adhoc_holidays (line 598) | def adhoc_holidays(self) -> list[pd.Timestamp]:
method special_opens (line 609) | def special_opens(self) -> list[tuple[datetime.time, HolidayCalendar |...
method special_opens_adhoc (line 641) | def special_opens_adhoc(
method special_closes (line 665) | def special_closes(self) -> list[tuple[datetime.time, HolidayCalendar ...
method special_closes_adhoc (line 697) | def special_closes_adhoc(
method apply_special_offsets (line 721) | def apply_special_offsets(
method day (line 755) | def day(self) -> CustomBusinessDay:
method valid_sides (line 764) | def valid_sides(cls) -> list[str]:
method side (line 771) | def side(self) -> Literal["left", "right", "both", "neither"]:
method sessions (line 795) | def sessions(self) -> pd.DatetimeIndex:
method sessions_nanos (line 800) | def sessions_nanos(self) -> np.ndarray:
method opens (line 805) | def opens(self) -> pd.Series:
method closes (line 819) | def closes(self) -> pd.Series:
method break_starts (line 833) | def break_starts(self) -> pd.Series:
method break_ends (line 849) | def break_ends(self) -> pd.Series:
method first_minutes_nanos (line 865) | def first_minutes_nanos(self) -> np.ndarray:
method last_minutes_nanos (line 872) | def last_minutes_nanos(self) -> np.ndarray:
method last_am_minutes_nanos (line 879) | def last_am_minutes_nanos(self) -> np.ndarray:
method first_pm_minutes_nanos (line 886) | def first_pm_minutes_nanos(self) -> np.ndarray:
method _minutes_as_series (line 892) | def _minutes_as_series(self, nanos: np.ndarray, name: str) -> pd.Series:
method first_minutes (line 899) | def first_minutes(self) -> pd.Series:
method last_minutes (line 904) | def last_minutes(self) -> pd.Series:
method last_am_minutes (line 909) | def last_am_minutes(self) -> pd.Series:
method first_pm_minutes (line 914) | def first_pm_minutes(self) -> pd.Series:
method _minutes (line 920) | def _minutes(
method minutes (line 935) | def minutes(self) -> pd.DatetimeIndex:
method minutes_nanos (line 940) | def minutes_nanos(self) -> np.ndarray:
method first_session (line 947) | def first_session(self) -> pd.Timestamp:
method last_session (line 952) | def last_session(self) -> pd.Timestamp:
method first_session_open (line 957) | def first_session_open(self) -> pd.Timestamp:
method last_session_close (line 962) | def last_session_close(self) -> pd.Timestamp:
method first_minute (line 967) | def first_minute(self) -> pd.Timestamp:
method last_minute (line 972) | def last_minute(self) -> pd.Timestamp:
method has_break (line 977) | def has_break(self) -> bool:
method late_opens (line 984) | def late_opens(self) -> pd.DatetimeIndex:
method early_closes (line 992) | def early_closes(self) -> pd.DatetimeIndex:
method _get_session_idx (line 1001) | def _get_session_idx(self, session: Date, _parse=True) -> int:
method session_open (line 1008) | def session_open(self, session: Session, _parse: bool = True) -> pd.Ti...
method session_close (line 1014) | def session_close(self, session: Session, _parse: bool = True) -> pd.T...
method session_break_start (line 1020) | def session_break_start(
method session_break_end (line 1031) | def session_break_end(
method session_open_close (line 1042) | def session_open_close(
method session_break_start_end (line 1062) | def session_break_start_end(
method _get_session_minute_from_nanos (line 1082) | def _get_session_minute_from_nanos(
method session_first_minute (line 1088) | def session_first_minute(
method session_last_minute (line 1095) | def session_last_minute(
method session_last_am_minute (line 1102) | def session_last_am_minute(
method session_first_pm_minute (line 1109) | def session_first_pm_minute(
method session_first_last_minute (line 1116) | def session_first_last_minute(
method session_has_break (line 1127) | def session_has_break(self, session: Session, _parse: bool = True) -> ...
method next_session (line 1144) | def next_session(self, session: Session, _parse: bool = True) -> pd.Ti...
method previous_session (line 1171) | def previous_session(self, session: Session, _parse: bool = True) -> p...
method session_minutes (line 1193) | def session_minutes(
method session_offset (line 1211) | def session_offset(
method _get_date_idx (line 1245) | def _get_date_idx(self, date: Date, _parse=True) -> int:
method _date_oob (line 1259) | def _date_oob(self, date: pd.Timestamp) -> bool:
method is_session (line 1265) | def is_session(self, date: Date, _parse: bool = True) -> bool:
method date_to_session (line 1283) | def date_to_session(
method _get_minute_idx (line 1329) | def _get_minute_idx(self, minute: Minute, _parse=True) -> int:
method _minute_oob (line 1342) | def _minute_oob(self, minute: Minute) -> bool:
method is_trading_minute (line 1349) | def is_trading_minute(self, minute: Minute, _parse: bool = True) -> bool:
method is_break_minute (line 1379) | def is_break_minute(self, minute: Minute, _parse: bool = True) -> bool:
method is_open_on_minute (line 1404) | def is_open_on_minute(
method is_open_at_time (line 1442) | def is_open_at_time(
method next_open (line 1531) | def next_open(self, minute: Minute, _parse: bool = True) -> pd.Timestamp:
method next_close (line 1561) | def next_close(self, minute: Minute, _parse: bool = True) -> pd.Timest...
method previous_open (line 1590) | def previous_open(self, minute: Minute, _parse: bool = True) -> pd.Tim...
method previous_close (line 1620) | def previous_close(self, minute: Minute, _parse: bool = True) -> pd.Ti...
method next_minute (line 1650) | def next_minute(self, minute: Minute, _parse: bool = True) -> pd.Times...
method previous_minute (line 1679) | def previous_minute(self, minute: Minute, _parse: bool = True) -> pd.T...
method minute_to_session (line 1708) | def minute_to_session( # noqa: C901
method minute_to_past_session (line 1789) | def minute_to_past_session(
method minute_to_future_session (line 1829) | def minute_to_future_session(
method minute_to_trading_minute (line 1873) | def minute_to_trading_minute(
method minute_offset (line 1927) | def minute_offset(
method minute_offset_by_sessions (line 1961) | def minute_offset_by_sessions( # noqa: C901, PLR0912
method _get_minutes_slice (line 2037) | def _get_minutes_slice(self, start: Minute, end: Minute, _parse=True) ...
method minutes_in_range (line 2046) | def minutes_in_range(
method minutes_window (line 2064) | def minutes_window(
method minutes_distance (line 2103) | def minutes_distance(self, start: Minute, end: Minute, _parse: bool = ...
method minutes_to_sessions (line 2129) | def minutes_to_sessions(self, minutes: pd.DatetimeIndex) -> pd.Datetim...
method _parse_start_end_dates (line 2188) | def _parse_start_end_dates(
method _get_sessions_slice (line 2195) | def _get_sessions_slice(self, start: Date, end: Date, _parse=True) -> ...
method sessions_in_range (line 2202) | def sessions_in_range(
method sessions_has_break (line 2223) | def sessions_has_break(self, start: Date, end: Date, _parse: bool = Tr...
method sessions_window (line 2242) | def sessions_window(
method sessions_distance (line 2279) | def sessions_distance(self, start: Date, end: Date, _parse: bool = Tru...
method sessions_minutes (line 2304) | def sessions_minutes(
method sessions_minutes_count (line 2329) | def sessions_minutes_count(
method trading_index (line 2355) | def trading_index( # noqa: C901
method _special_dates (line 2728) | def _special_dates(
method _calculate_special_opens (line 2802) | def _calculate_special_opens(
method _calculate_special_closes (line 2812) | def _calculate_special_closes(
function _check_breaks_match (line 2823) | def _check_breaks_match(break_starts_nanos: np.ndarray, break_ends_nanos...
function scheduled_special_times (line 2838) | def scheduled_special_times(
function _adjust_special_dates (line 2891) | def _adjust_special_dates(
function _remove_breaks_for_special_dates (line 2927) | def _remove_breaks_for_special_dates(
FILE: exchange_calendars/exchange_calendar_aixk.py
function weekend_plus_two_days (line 24) | def weekend_plus_two_days(dt: datetime) -> datetime:
class AIXKExchangeCalendar (line 160) | class AIXKExchangeCalendar(ExchangeCalendar):
method bound_min (line 202) | def bound_min(cls) -> pd.Timestamp:
method _bound_min_error_msg (line 205) | def _bound_min_error_msg(self, start: pd.Timestamp) -> str:
method regular_holidays (line 210) | def regular_holidays(self):
method adhoc_holidays (line 235) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_asex.py
class ASEXExchangeCalendar (line 77) | class ASEXExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 115) | def regular_holidays(self):
method adhoc_holidays (line 137) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_bvmf.py
class BVMFExchangeCalendar (line 150) | class BVMFExchangeCalendar(ExchangeCalendar):
method adhoc_holidays (line 196) | def adhoc_holidays(self):
method regular_holidays (line 201) | def regular_holidays(self):
method special_opens (line 227) | def special_opens(self):
FILE: exchange_calendars/exchange_calendar_cmes.py
class CMESExchangeCalendar (line 43) | class CMESExchangeCalendar(ExchangeCalendar):
method open_offset (line 65) | def open_offset(self):
method regular_holidays (line 69) | def regular_holidays(self):
method adhoc_holidays (line 89) | def adhoc_holidays(self):
method special_closes (line 93) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_iepa.py
class IEPAExchangeCalendar (line 25) | class IEPAExchangeCalendar(ExchangeCalendar):
method open_offset (line 44) | def open_offset(self):
method special_closes (line 48) | def special_closes(self):
method adhoc_holidays (line 66) | def adhoc_holidays(self):
method regular_holidays (line 77) | def regular_holidays(self):
FILE: exchange_calendars/exchange_calendar_xams.py
class XAMSExchangeCalendar (line 58) | class XAMSExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 93) | def regular_holidays(self):
method special_closes (line 110) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_xasx.py
class XASXExchangeCalendar (line 166) | class XASXExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 199) | def regular_holidays(self):
method adhoc_holidays (line 222) | def adhoc_holidays(self):
method special_closes (line 233) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_xbda.py
function bermuda_day_observance (line 27) | def bermuda_day_observance(dt: datetime) -> datetime | None:
function national_heroes_day_observance (line 43) | def national_heroes_day_observance(dt: datetime) -> datetime | None:
function queens_birthday_observance (line 56) | def queens_birthday_observance(dt: datetime) -> datetime | None:
class XBDAExchangeCalendar (line 155) | class XBDAExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 183) | def regular_holidays(self):
method special_closes (line 203) | def special_closes(self):
method adhoc_holidays (line 216) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xbel.py
function sunday_to_tuesday (line 21) | def sunday_to_tuesday(dt: datetime) -> datetime:
class XBELExchangeCalendar (line 46) | class XBELExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 70) | def regular_holidays(self):
method adhoc_holidays (line 87) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xbkk.py
class XBKKExchangeCalendar (line 51) | class XBKKExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 90) | def regular_holidays(self):
method adhoc_holidays (line 114) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xbog.py
class XBOGExchangeCalendar (line 130) | class XBOGExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 172) | def regular_holidays(self):
FILE: exchange_calendars/exchange_calendar_xbom.py
class XBOMExchangeCalendar (line 477) | class XBOMExchangeCalendar(PrecomputedExchangeCalendar):
method precomputed_holidays (line 495) | def precomputed_holidays(cls):
method special_weekmasks (line 499) | def special_weekmasks(self):
method day (line 516) | def day(self):
FILE: exchange_calendars/exchange_calendar_xbra.py
class XBRAExchangeCalendar (line 40) | class XBRAExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 73) | def regular_holidays(self):
method adhoc_holidays (line 96) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xbru.py
class XBRUExchangeCalendar (line 58) | class XBRUExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 93) | def regular_holidays(self):
method special_closes (line 110) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_xbse.py
class XBSEExchangeCalendar (line 75) | class XBSEExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 110) | def regular_holidays(self):
FILE: exchange_calendars/exchange_calendar_xbud.py
function bridge_mon (line 38) | def bridge_mon(dt: datetime.datetime) -> datetime.datetime | None:
function bridge_fri (line 47) | def bridge_fri(dt: datetime.datetime) -> datetime.datetime | None:
class XBUDExchangeCalendar (line 124) | class XBUDExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 159) | def regular_holidays(self):
FILE: exchange_calendars/exchange_calendar_xbue.py
function nearest_monday (line 43) | def nearest_monday(dt: datetime.datetime) -> datetime.datetime:
function cultural_diversity_observance (line 60) | def cultural_diversity_observance(dt: datetime.datetime) -> datetime.dat...
function not_2018 (line 70) | def not_2018(dt: datetime.datetime) -> datetime.datetime | None:
class XBUEExchangeCalendar (line 217) | class XBUEExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 264) | def regular_holidays(self):
method adhoc_holidays (line 293) | def adhoc_holidays(self):
method special_closes (line 354) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_xcbf.py
class XCBFExchangeCalendar (line 27) | class XCBFExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 48) | def regular_holidays(self):
method special_closes (line 65) | def special_closes(self):
method adhoc_holidays (line 78) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xcse.py
class XCSEExchangeCalendar (line 63) | class XCSEExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 95) | def regular_holidays(self):
FILE: exchange_calendars/exchange_calendar_xcys.py
class XCYSExchangeCalendar (line 46) | class XCYSExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 81) | def regular_holidays(self):
method adhoc_holidays (line 106) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xdub.py
class XDUBExchangeCalendar (line 114) | class XDUBExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 146) | def regular_holidays(self):
method adhoc_holidays (line 167) | def adhoc_holidays(self):
method special_closes (line 171) | def special_closes(self):
method special_closes_adhoc (line 185) | def special_closes_adhoc(self):
FILE: exchange_calendars/exchange_calendar_xdus.py
class XDUSExchangeCalendar (line 66) | class XDUSExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 105) | def regular_holidays(self):
method adhoc_holidays (line 122) | def adhoc_holidays(self):
method special_closes (line 129) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_xeee.py
class XEEEExchangeCalendar (line 24) | class XEEEExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 52) | def regular_holidays(self):
FILE: exchange_calendars/exchange_calendar_xetr.py
class XETRExchangeCalendar (line 80) | class XETRExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 114) | def regular_holidays(self):
method adhoc_holidays (line 131) | def adhoc_holidays(self):
method special_closes (line 138) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_xeur.py
class XEURExchangeCalendar (line 31) | class XEURExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 59) | def regular_holidays(self):
FILE: exchange_calendars/exchange_calendar_xfra.py
class XFRAExchangeCalendar (line 79) | class XFRAExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 112) | def regular_holidays(self):
method adhoc_holidays (line 129) | def adhoc_holidays(self):
method special_closes (line 136) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_xham.py
class XHAMExchangeCalendar (line 66) | class XHAMExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 105) | def regular_holidays(self):
method adhoc_holidays (line 122) | def adhoc_holidays(self):
method special_closes (line 129) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_xhel.py
class XHELExchangeCalendar (line 53) | class XHELExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 84) | def regular_holidays(self):
FILE: exchange_calendars/exchange_calendar_xhkg.py
function process_queen_birthday (line 63) | def process_queen_birthday(dt):
function boxing_day_obs (line 238) | def boxing_day_obs(dt):
class XHKGExchangeCalendar (line 244) | class XHKGExchangeCalendar(PrecomputedExchangeCalendar):
method precomputed_holidays (line 295) | def precomputed_holidays(cls):
method _earliest_precomputed_year (line 307) | def _earliest_precomputed_year(cls) -> int:
method _latest_precomputed_year (line 311) | def _latest_precomputed_year(cls) -> int:
method regular_holidays (line 315) | def regular_holidays(self):
method adhoc_holidays (line 335) | def adhoc_holidays(self):
method special_closes (line 395) | def special_closes(self):
method special_closes_adhoc (line 435) | def special_closes_adhoc(self):
FILE: exchange_calendars/exchange_calendar_xice.py
class XICEExchangeCalendar (line 67) | class XICEExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 100) | def regular_holidays(self):
FILE: exchange_calendars/exchange_calendar_xidx.py
class XIDXExchangeCalendar (line 28) | class XIDXExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 67) | def regular_holidays(self):
method adhoc_holidays (line 495) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xist.py
class XISTExchangeCalendar (line 94) | class XISTExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 129) | def regular_holidays(self):
method adhoc_holidays (line 143) | def adhoc_holidays(self):
method special_closes (line 175) | def special_closes(self):
method special_closes_adhoc (line 184) | def special_closes_adhoc(self):
FILE: exchange_calendars/exchange_calendar_xjse.py
class XJSEExchangeCalendar (line 27) | class XJSEExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 65) | def regular_holidays(self):
method adhoc_holidays (line 136) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xkar.py
class XKARExchangeCalendar (line 27) | class XKARExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 77) | def regular_holidays(self):
method adhoc_holidays (line 425) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xkls.py
class XKLSExchangeCalendar (line 47) | class XKLSExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 91) | def regular_holidays(self):
method adhoc_holidays (line 104) | def adhoc_holidays(self):
method special_closes_adhoc (line 123) | def special_closes_adhoc(self):
FILE: exchange_calendars/exchange_calendar_xkrx.py
class XKRXExchangeCalendar (line 36) | class XKRXExchangeCalendar(PrecomputedExchangeCalendar):
method special_weekmasks (line 122) | def special_weekmasks(self):
method precomputed_holidays (line 134) | def precomputed_holidays(cls) -> list[pd.Timestamp]:
method _earliest_precomputed_year (line 138) | def _earliest_precomputed_year(cls) -> int:
method _latest_precomputed_year (line 142) | def _latest_precomputed_year(cls) -> int:
method regular_holidays (line 148) | def regular_holidays(self):
method special_offsets (line 155) | def special_offsets(self):
method special_offsets_adhoc (line 189) | def special_offsets_adhoc(
method _adjust_special_offsets (line 222) | def _adjust_special_offsets(
method apply_special_offsets (line 282) | def apply_special_offsets(
method day (line 351) | def day(self):
class PrecomputedXKRXExchangeCalendar (line 366) | class PrecomputedXKRXExchangeCalendar(PrecomputedExchangeCalendar):
method precomputed_holidays (line 405) | def precomputed_holidays(cls):
FILE: exchange_calendars/exchange_calendar_xlim.py
class XLIMExchangeCalendar (line 101) | class XLIMExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 140) | def regular_holidays(self):
method adhoc_holidays (line 164) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xlis.py
class XLISExchangeCalendar (line 98) | class XLISExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 134) | def regular_holidays(self):
method special_closes (line 158) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_xlit.py
class XLITExchangeCalendar (line 35) | class XLITExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 67) | def regular_holidays(self):
method adhoc_holidays (line 89) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xlju.py
class XLJUExchangeCalendar (line 38) | class XLJUExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 70) | def regular_holidays(self):
method adhoc_holidays (line 94) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xlon.py
class XLONExchangeCalendar (line 163) | class XLONExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 198) | def regular_holidays(self):
method adhoc_holidays (line 220) | def adhoc_holidays(self):
method special_closes (line 254) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_xlux.py
class XLUXExchangeCalendar (line 25) | class XLUXExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 54) | def regular_holidays(self):
method special_closes (line 67) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_xmad.py
class XMADExchangeCalendar (line 91) | class XMADExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 133) | def regular_holidays(self):
method special_closes (line 156) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_xmex.py
class XMEXExchangeCalendar (line 76) | class XMEXExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 111) | def regular_holidays(self):
method adhoc_holidays (line 132) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xmil.py
class XMILExchangeCalendar (line 44) | class XMILExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 76) | def regular_holidays(self):
FILE: exchange_calendars/exchange_calendar_xmos.py
function new_years_eve_observance (line 31) | def new_years_eve_observance(dt: datetime.datetime) -> datetime.datetime...
function new_years_day_observance (line 36) | def new_years_day_observance(dt: datetime.datetime) -> datetime.datetime...
function new_years_holiday_observance (line 41) | def new_years_holiday_observance(dt: datetime.datetime) -> datetime.date...
function orthodox_christmas_observance (line 46) | def orthodox_christmas_observance(dt: datetime.datetime) -> datetime.dat...
function defender_of_fatherland_observance (line 51) | def defender_of_fatherland_observance(
function victory_day_observance (line 59) | def victory_day_observance(dt: datetime.datetime) -> datetime.datetime |...
function day_of_russia_observance (line 64) | def day_of_russia_observance(dt: datetime.datetime) -> datetime.datetime...
function unity_day_observance (line 69) | def unity_day_observance(dt: datetime.datetime) -> datetime.datetime | N...
class XMOSExchangeCalendar (line 255) | class XMOSExchangeCalendar(ExchangeCalendar):
method special_weekmasks (line 290) | def special_weekmasks(self):
method regular_holidays (line 347) | def regular_holidays(self):
method adhoc_holidays (line 368) | def adhoc_holidays(self):
method day (line 384) | def day(self):
FILE: exchange_calendars/exchange_calendar_xnys.py
class XNYSExchangeCalendar (line 76) | class XNYSExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 168) | def regular_holidays(self):
method adhoc_holidays (line 198) | def adhoc_holidays(self):
method special_closes (line 221) | def special_closes(self):
method special_closes_adhoc (line 247) | def special_closes_adhoc(self):
FILE: exchange_calendars/exchange_calendar_xnze.py
class XNZEExchangeCalendar (line 161) | class XNZEExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 196) | def regular_holidays(self):
method adhoc_holidays (line 216) | def adhoc_holidays(self):
method special_closes (line 235) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_xosl.py
class XOSLExchangeCalendar (line 53) | class XOSLExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 85) | def regular_holidays(self):
method special_closes (line 104) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_xpar.py
class XPARExchangeCalendar (line 56) | class XPARExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 91) | def regular_holidays(self):
method special_closes (line 107) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_xphs.py
function only_friday (line 38) | def only_friday(dt: datetime.datetime) -> datetime.datetime | None:
function ninoy_aquino_day_observed (line 47) | def ninoy_aquino_day_observed(dt: datetime.datetime) -> datetime.datetim...
function bonifacio_day_observed (line 60) | def bonifacio_day_observed(dt: datetime.datetime) -> datetime.datetime |...
class XPHSExchangeCalendar (line 214) | class XPHSExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 257) | def regular_holidays(self):
method adhoc_holidays (line 281) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xpra.py
class XPRAExchangeCalendar (line 90) | class XPRAExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 126) | def regular_holidays(self):
method adhoc_holidays (line 147) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xris.py
class XRISExchangeCalendar (line 40) | class XRISExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 69) | def regular_holidays(self):
method adhoc_holidays (line 88) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xsau.py
class XSAUExchangeCalendar (line 49) | class XSAUExchangeCalendar(ExchangeCalendar):
method bound_min (line 64) | def bound_min(cls) -> pd.Timestamp:
method bound_max (line 68) | def bound_max(cls) -> pd.Timestamp:
method regular_holidays (line 72) | def regular_holidays(self):
method weekmask (line 76) | def weekmask(self):
method adhoc_holidays (line 80) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xses.py
class XSESExchangeCalendar (line 424) | class XSESExchangeCalendar(PrecomputedExchangeCalendar):
method precomputed_holidays (line 452) | def precomputed_holidays(cls):
FILE: exchange_calendars/exchange_calendar_xsgo.py
function summer_solstice (line 48) | def summer_solstice(dt: datetime.datetime) -> datetime.datetime:
function national_day_of_indigenous_peoples_observed (line 59) | def national_day_of_indigenous_peoples_observed(
function nearest_monday (line 74) | def nearest_monday(dt: datetime.datetime) -> datetime.datetime:
function tuesday_and_wednesday_to_friday (line 89) | def tuesday_and_wednesday_to_friday(dt: datetime.datetime) -> datetime.d...
function not_2010 (line 104) | def not_2010(dt: datetime.datetime) -> datetime.datetime | None:
class XSGOExchangeCalendar (line 203) | class XSGOExchangeCalendar(ExchangeCalendar):
method close_times (line 249) | def close_times(self):
method regular_holidays (line 256) | def regular_holidays(self):
method adhoc_holidays (line 282) | def adhoc_holidays(self):
method special_closes (line 299) | def special_closes(self):
method _starting_dates_and_close_times (line 311) | def _starting_dates_and_close_times(self):
FILE: exchange_calendars/exchange_calendar_xshg.py
class XSHGExchangeCalendar (line 620) | class XSHGExchangeCalendar(PrecomputedExchangeCalendar):
method precomputed_holidays (line 642) | def precomputed_holidays(cls):
method bound_min (line 646) | def bound_min(cls) -> pd.Timestamp:
FILE: exchange_calendars/exchange_calendar_xsto.py
class XSTOExchangeCalendar (line 91) | class XSTOExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 130) | def regular_holidays(self):
method special_closes (line 150) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_xstu.py
class XSTUExchangeCalendar (line 30) | class XSTUExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 58) | def regular_holidays(self):
FILE: exchange_calendars/exchange_calendar_xswx.py
class XSWXExchangeCalendar (line 60) | class XSWXExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 91) | def regular_holidays(self):
FILE: exchange_calendars/exchange_calendar_xtae.py
class SundayUntil2026 (line 76) | class SundayUntil2026(HolidayCalendar):
method __init__ (line 77) | def __init__(self):
method holidays (line 80) | def holidays(self, start=None, end=None, return_name=False): # noqa: ...
class FridayFrom2026 (line 92) | class FridayFrom2026(HolidayCalendar):
method __init__ (line 93) | def __init__(self):
method holidays (line 96) | def holidays(self, start=None, end=None, return_name=False): # noqa: ...
class XTAEExchangeCalendar (line 108) | class XTAEExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 162) | def regular_holidays(self):
method adhoc_holidays (line 189) | def adhoc_holidays(self):
method special_closes (line 204) | def special_closes(self):
method special_weekmasks (line 236) | def special_weekmasks(self):
method day (line 248) | def day(self):
FILE: exchange_calendars/exchange_calendar_xtai.py
function check_after_2013 (line 48) | def check_after_2013(dt: datetime.datetime) -> bool:
function check_between_2013_2024 (line 53) | def check_between_2013_2024(dt: datetime.datetime) -> bool:
function before_chinese_new_year_offset (line 58) | def before_chinese_new_year_offset(holidays):
function chinese_new_year_offset (line 66) | def chinese_new_year_offset(holidays):
function evalute_tomb_sweeping_weekday_extra (line 74) | def evalute_tomb_sweeping_weekday_extra(dt: pd.DatetimeIndex) -> pd.Date...
function nearest_weekday_from_2014 (line 92) | def nearest_weekday_from_2014(dt: datetime.datetime) -> datetime.datetime:
function holidays_nearest_weekday_from_2014 (line 100) | def holidays_nearest_weekday_from_2014(
function nearest_weekday_2014_thr_2023 (line 111) | def nearest_weekday_2014_thr_2023(dt: datetime.datetime) -> datetime.dat...
function manual_nearest_weekday_2014_thr_2023 (line 119) | def manual_nearest_weekday_2014_thr_2023(holidays):
function manual_extra_days_07_thr_2023 (line 131) | def manual_extra_days_07_thr_2023(holidays):
function bridge_mon (line 150) | def bridge_mon(
function bridge_fri (line 171) | def bridge_fri(
class XTAIExchangeCalendar (line 414) | class XTAIExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 448) | def regular_holidays(self):
method adhoc_holidays (line 471) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xtal.py
class XTALExchangeCalendar (line 29) | class XTALExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 58) | def regular_holidays(self):
method adhoc_holidays (line 77) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xtks.py
class XTKSExchangeCalendar (line 50) | class XTKSExchangeCalendar(ExchangeCalendar):
method bound_min (line 95) | def bound_min(cls) -> pd.Timestamp:
method regular_holidays (line 100) | def regular_holidays(self):
method adhoc_holidays (line 140) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xtse.py
class XTSEExchangeCalendar (line 97) | class XTSEExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 137) | def regular_holidays(self):
method adhoc_holidays (line 156) | def adhoc_holidays(self):
method special_closes (line 161) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_xwar.py
function not_2004 (line 37) | def not_2004(dt: datetime.datetime) -> datetime.datetime | None:
class XWARExchangeCalendar (line 80) | class XWARExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 118) | def regular_holidays(self):
method adhoc_holidays (line 139) | def adhoc_holidays(self):
FILE: exchange_calendars/exchange_calendar_xwbo.py
class XWBOExchangeCalendar (line 92) | class XWBOExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 132) | def regular_holidays(self):
method special_closes (line 156) | def special_closes(self):
FILE: exchange_calendars/exchange_calendar_xzag.py
class XZAGExchangeCalendar (line 49) | class XZAGExchangeCalendar(ExchangeCalendar):
method regular_holidays (line 82) | def regular_holidays(self):
method adhoc_holidays (line 108) | def adhoc_holidays(self):
FILE: exchange_calendars/pandas_extensions/holiday.py
class Holiday (line 20) | class Holiday(PandasHoliday):
method __init__ (line 26) | def __init__(
method __repr__ (line 68) | def __repr__(self) -> str:
method dates (line 82) | def dates(self, start_date, end_date, return_name=False):
method _apply_offset (line 91) | def _apply_offset(self, dates):
method _apply_observance (line 105) | def _apply_observance(self, dates):
method _apply_rule (line 122) | def _apply_rule(self, dates, apply_offset=True, apply_observance=True):
function combine (line 130) | def combine(pre_holidays):
class AbstractHolidayCalendar (line 137) | class AbstractHolidayCalendar(PandasAbstractHolidayCalendar):
method holidays (line 143) | def holidays(self, start=None, end=None, return_name=False):
FILE: exchange_calendars/pandas_extensions/korean_holiday.py
function is_naive (line 14) | def is_naive(dt):
class KoreanHoliday (line 18) | class KoreanHoliday(Holiday):
method _apply_rule (line 28) | def _apply_rule(
function to_korean_datetime (line 41) | def to_korean_datetime(dt):
function is_saturday (line 48) | def is_saturday(dt):
function is_sunday (line 52) | def is_sunday(dt):
function is_holiday_saturday (line 56) | def is_holiday_saturday(dt):
function is_already_korean_holiday (line 61) | def is_already_korean_holiday(dt):
function alternative_holiday_func (line 74) | def alternative_holiday_func(dt, is_already_holiday, since):
function is_already_holiday (line 91) | def is_already_holiday(dt):
function is_already_holiday_for_alternative_holiday_including_saturday (line 95) | def is_already_holiday_for_alternative_holiday_including_saturday(dt):
function is_already_holiday_for_alternative_holiday_without_saturday (line 106) | def is_already_holiday_for_alternative_holiday_without_saturday(dt):
function alternative_holiday_for_seollal_and_chuseok (line 113) | def alternative_holiday_for_seollal_and_chuseok(dt):
function alternative_holiday_for_childrens_day (line 121) | def alternative_holiday_for_childrens_day(dt):
function alternative_holiday (line 129) | def alternative_holiday(dt):
function next_business_day (line 137) | def next_business_day(dt):
function last_business_day (line 143) | def last_business_day(dt):
class KoreanSolarHoliday (line 149) | class KoreanSolarHoliday(KoreanHoliday):
function korean_lunar_to_solar (line 153) | def korean_lunar_to_solar(year, month, day, is_intercalation=False):
function korean_lunar_to_solar_datetime (line 163) | def korean_lunar_to_solar_datetime(dt, is_intercalation=False):
function korean_solar_to_lunar (line 170) | def korean_solar_to_lunar(year, month, day):
function korean_solar_to_lunar_datetime (line 178) | def korean_solar_to_lunar_datetime(dt, round_down: bool):
class KoreanLunarHoliday (line 199) | class KoreanLunarHoliday(KoreanHoliday):
method _reference_dates (line 207) | def _reference_dates(self, start_date, end_date, strict=False):
FILE: exchange_calendars/pandas_extensions/offsets.py
class CompositeCustomBusinessDay (line 16) | class CompositeCustomBusinessDay(CustomBusinessDay):
method __init__ (line 28) | def __init__(
method __setstate__ (line 43) | def __setstate__(self, state):
method business_days (line 48) | def business_days(self):
method business_days (line 57) | def business_days(self, business_days):
method _as_custom_business_day (line 108) | def _as_custom_business_day(self):
method _custom_business_day_for (line 118) | def _custom_business_day_for(
method _moved (line 137) | def _moved(self, from_date, to_date, bday):
method _apply (line 145) | def _apply(self, other):
method is_on_offset (line 175) | def is_on_offset(self, dt):
function _is_normalized (line 183) | def _is_normalized(dt):
function _to_dt64D (line 192) | def _to_dt64D(dt): # noqa: N802
function _get_calendar (line 209) | def _get_calendar(weekmask, holidays, calendar):
class MultipleWeekmaskCustomBusinessDay (line 244) | class MultipleWeekmaskCustomBusinessDay(CompositeCustomBusinessDay):
method __init__ (line 257) | def __init__(
method __setstate__ (line 290) | def __setstate__(self, state):
method weekmasks (line 295) | def weekmasks(self):
method weekmasks (line 299) | def weekmasks(self, weekmasks):
class SingleConstructorOffset (line 303) | class SingleConstructorOffset(BaseOffset):
method __reduce__ (line 304) | def __reduce__(self): ...
class OrthodoxEaster (line 307) | class OrthodoxEaster(SingleConstructorOffset):
method __setstate__ (line 312) | def __setstate__(self, state):
method _apply (line 317) | def _apply(self, other: datetime) -> datetime:
method is_on_offset (line 341) | def is_on_offset(self, dt: datetime) -> bool:
FILE: exchange_calendars/precomputed_exchange_calendar.py
class PrecomputedExchangeCalendar (line 9) | class PrecomputedExchangeCalendar(ExchangeCalendar):
method precomputed_holidays (line 16) | def precomputed_holidays(self) -> pd.DatetimeIndex | list[pd.Timestamp]:
method adhoc_holidays (line 24) | def adhoc_holidays(self) -> pd.DatetimeIndex | list[pd.Timestamp]:
method _earliest_precomputed_year (line 28) | def _earliest_precomputed_year(cls) -> int:
method _latest_precomputed_year (line 32) | def _latest_precomputed_year(cls) -> int:
method bound_min (line 36) | def bound_min(cls) -> pd.Timestamp:
method bound_max (line 40) | def bound_max(cls) -> pd.Timestamp:
method _bound_min_error_msg (line 43) | def _bound_min_error_msg(self, start: pd.Timestamp) -> str:
method _bound_max_error_msg (line 50) | def _bound_max_error_msg(self, end: pd.Timestamp) -> str:
FILE: exchange_calendars/tase_holidays.py
function _purim (line 23) | def _purim(year):
function _passover (line 31) | def _passover(year):
function _memorial_day (line 39) | def _memorial_day(year):
function _pentecost (line 63) | def _pentecost(year):
function _fast_day (line 70) | def _fast_day(year):
function _new_year (line 77) | def _new_year(year):
function _yom_kippur (line 85) | def _yom_kippur(year):
function _sukkoth (line 92) | def _sukkoth(year):
function _simchat_torah (line 99) | def _simchat_torah(year):
function _hebrew_year (line 106) | def _hebrew_year(year):
function purim (line 123) | def purim(year):
function passover (line 130) | def passover(year):
function memorial_day (line 138) | def memorial_day(year):
function pentecost (line 162) | def pentecost(year):
function fast_day (line 170) | def fast_day(year):
function new_year (line 184) | def new_year(year):
function yom_kippur (line 192) | def yom_kippur(year):
function sukkoth (line 200) | def sukkoth(year):
function simchat_torah (line 207) | def simchat_torah(year):
function _is_normalized (line 215) | def _is_normalized(dt):
class _HolidayOffset (line 224) | class _HolidayOffset(Easter):
method holiday (line 230) | def holiday(self):
method _apply (line 237) | def _apply(self, other):
method is_on_offset (line 265) | def is_on_offset(self, dt):
class _Purim (line 274) | class _Purim(_HolidayOffset):
method holiday (line 276) | def holiday(self):
class _Passover (line 280) | class _Passover(_HolidayOffset):
method holiday (line 282) | def holiday(self):
class _MemorialDay (line 286) | class _MemorialDay(_HolidayOffset):
method holiday (line 288) | def holiday(self):
class _Pentecost (line 292) | class _Pentecost(_HolidayOffset):
method holiday (line 294) | def holiday(self):
class _FastDay (line 298) | class _FastDay(_HolidayOffset):
method holiday (line 300) | def holiday(self):
class _NewYear (line 304) | class _NewYear(_HolidayOffset):
method holiday (line 306) | def holiday(self):
class _YomKippur (line 310) | class _YomKippur(_HolidayOffset):
method holiday (line 312) | def holiday(self):
class _YomKippurEveObserved (line 316) | class _YomKippurEveObserved(_HolidayOffset):
method holiday (line 323) | def holiday(self):
method _apply (line 327) | def _apply(self, other):
method is_on_offset (line 367) | def is_on_offset(self, dt):
class _Sukkoth (line 381) | class _Sukkoth(_HolidayOffset):
method holiday (line 383) | def holiday(self):
class _SimchatTorah (line 387) | class _SimchatTorah(_HolidayOffset):
method holiday (line 389) | def holiday(self):
FILE: exchange_calendars/us_futures_calendar.py
class QuantopianUSFuturesCalendar (line 20) | class QuantopianUSFuturesCalendar(ExchangeCalendar):
method execution_time_from_open (line 47) | def execution_time_from_open(self, open_dates):
method execution_time_from_close (line 50) | def execution_time_from_close(self, close_dates):
method execution_minutes_for_session (line 53) | def execution_minutes_for_session(
method execution_minutes_for_sessions_in_range (line 73) | def execution_minutes_for_sessions_in_range(self, start, stop):
method regular_holidays (line 83) | def regular_holidays(self):
FILE: exchange_calendars/us_holidays.py
function following_tuesday_every_four_years_observance (line 21) | def following_tuesday_every_four_years_observance(dt):
FILE: exchange_calendars/utils/pandas_utils.py
function days_at_time (line 10) | def days_at_time(
function vectorized_sunday_to_monday (line 69) | def vectorized_sunday_to_monday(dtix):
function longest_run (line 88) | def longest_run(ser: pd.Series) -> pd.Index:
function indexes_union (line 130) | def indexes_union(indexes: list[pd.Index]) -> pd.Index:
FILE: exchange_calendars/weekday_calendar.py
class WeekdayCalendar (line 7) | class WeekdayCalendar(ExchangeCalendar):
FILE: exchange_calendars/xbkk_holidays.py
function new_years_eve_observance (line 15) | def new_years_eve_observance(dt: datetime.datetime) -> datetime.datetime...
function new_years_day_observance (line 20) | def new_years_day_observance(dt: datetime.datetime) -> datetime.datetime...
function songkran_festival_last_day_observance (line 25) | def songkran_festival_last_day_observance(dt: datetime.datetime) -> date...
FILE: exchange_calendars/xtks_holidays.py
function sunday_to_tuesday (line 11) | def sunday_to_tuesday(dt):
function sunday_to_wednesday (line 20) | def sunday_to_wednesday(dt):
FILE: tests/test_aixk_calendar.py
class TestAIXKCalendar (line 8) | class TestAIXKCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method start_bound (line 18) | def start_bound(self):
method regular_holidays_sample (line 22) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 59) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 75) | def non_holidays_sample(self):
FILE: tests/test_always_open.py
class TestAlwaysOpenCalendar (line 10) | class TestAlwaysOpenCalendar(ExchangeCalendarTestBase):
method all_calendars_with_answers (line 12) | def all_calendars_with_answers(self, request, calendars, answers):
method calendar_cls (line 16) | def calendar_cls(self):
method max_session_hours (line 20) | def max_session_hours(self):
method test_open_every_day (line 25) | def test_open_every_day(self, default_calendar_with_answers):
method test_open_every_minute (line 30) | def test_open_every_minute(self, calendars, answers, one_minute):
FILE: tests/test_asex_calendar.py
class TestASEXCalendar (line 10) | class TestASEXCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 12) | def calendar_cls(self):
method max_session_hours (line 16) | def max_session_hours(self):
method regular_holidays_sample (line 21) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 76) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 92) | def non_holidays_sample(self):
method test_close_time_change (line 127) | def test_close_time_change(self, default_calendar):
FILE: tests/test_bvmf_calendar.py
class TestBVMFCalendar (line 7) | class TestBVMFCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 17) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 50) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 54) | def non_holidays_sample(self):
method late_opens_sample (line 62) | def late_opens_sample(self):
FILE: tests/test_calendar_dispatcher.py
class CalendarDispatcherTestCase (line 21) | class CalendarDispatcherTestCase(TestCase):
method setup_class (line 23) | def setup_class(cls):
method setup_method (line 33) | def setup_method(self, method): # noqa: ARG002
method teardown_method (line 40) | def teardown_method(self, method): # noqa: ARG002
method teardown_class (line 44) | def teardown_class(cls):
method test_follow_alias_chain (line 47) | def test_follow_alias_chain(self):
method test_add_new_aliases (line 57) | def test_add_new_aliases(self):
method test_remove_aliases (line 76) | def test_remove_aliases(self):
method test_reject_alias_that_already_exists (line 81) | def test_reject_alias_that_already_exists(self):
method test_allow_alias_override_with_force (line 88) | def test_allow_alias_override_with_force(self):
method test_reject_cyclic_aliases (line 93) | def test_reject_cyclic_aliases(self):
method test_get_calendar_names (line 105) | def test_get_calendar_names(self):
method test_aliases_to_names (line 115) | def test_aliases_to_names(self):
method test_names_to_aliases (line 124) | def test_names_to_aliases(self):
method test_get_calendar (line 130) | def test_get_calendar(self):
method test_get_calendar_kwargs (line 134) | def test_get_calendar_kwargs(self):
method test_get_calendar_cache (line 155) | def test_get_calendar_cache(self):
FILE: tests/test_calendar_helpers.py
function test_constants (line 32) | def test_constants():
function one_min (line 40) | def one_min() -> abc.Iterator[pd.Timedelta]:
function test_is_date (line 44) | def test_is_date(one_min):
function test_is_utc (line 66) | def test_is_utc():
function one_day (line 80) | def one_day() -> abc.Iterator[pd.DateOffset]:
function calendar (line 86) | def calendar() -> abc.Iterator[calendar_utils.XHKGExchangeCalendar]:
function param_name (line 91) | def param_name() -> abc.Iterator[str]:
function utc (line 96) | def utc(request) -> abc.Iterator[str]:
function malformed (line 101) | def malformed(request) -> abc.Iterator[str]:
function minute (line 106) | def minute() -> abc.Iterator[str]:
function minute_mult (line 117) | def minute_mult(request) -> abc.Iterator[str | pd.Timestamp]:
function date (line 122) | def date(calendar) -> abc.Iterator[str]:
function date_mult (line 137) | def date_mult(request, calendar) -> abc.Iterator[str | pd.Timestamp]:
function second (line 146) | def second() -> abc.Iterator[str]:
function sides (line 151) | def sides(request) -> abc.Iterator[str]:
function session (line 156) | def session() -> abc.Iterator[str]:
function trading_minute (line 161) | def trading_minute() -> abc.Iterator[str]:
function minute_too_early (line 166) | def minute_too_early(calendar, one_min) -> abc.Iterator[pd.Timestamp]:
function minute_too_late (line 171) | def minute_too_late(calendar, one_min) -> abc.Iterator[pd.Timestamp]:
function date_too_early (line 176) | def date_too_early(calendar, one_day) -> abc.Iterator[pd.Timestamp]:
function date_too_late (line 181) | def date_too_late(calendar, one_day) -> abc.Iterator[pd.Timestamp]:
function test_parse_timestamp_with_date (line 185) | def test_parse_timestamp_with_date(date_mult, param_name, calendar, utc):
function test_parse_timestamp_with_minute (line 196) | def test_parse_timestamp_with_minute(minute_mult, param_name, calendar, ...
function test_parse_timestamp_with_second (line 207) | def test_parse_timestamp_with_second(second, sides, param_name):
function test_parse_timestamp_error_malformed (line 224) | def test_parse_timestamp_error_malformed(malformed, param_name, calendar):
function test_parse_timestamp_error_oob (line 235) | def test_parse_timestamp_error_oob(
function test_parse_date_or_minute_for_minute (line 263) | def test_parse_date_or_minute_for_minute(
function test_parse_date_or_minute_for_date (line 276) | def test_parse_date_or_minute_for_date(calendar, param_name, date, date_...
function test_parse_date_or_minute_oob (line 282) | def test_parse_date_or_minute_oob(
function test_parse_date (line 322) | def test_parse_date(date_mult, param_name):
function test_parse_date_errors (line 328) | def test_parse_date_errors(calendar, param_name, date_too_early, date_to...
function test_parse_session (line 362) | def test_parse_session(
function test_parse_trading_minute (line 382) | def test_parse_trading_minute(
function st_align (line 406) | def st_align() -> st.SearchStrategy[pd.Timedelta]:
class TestTradingIndex (line 413) | class TestTradingIndex:
method answers (line 442) | def answers(self) -> abc.Iterator[dict[str, Answers]]:
method calendars (line 450) | def calendars(self, answers) -> abc.Iterator[dict[str, ExchangeCalenda...
method calendars_with_answers (line 459) | def calendars_with_answers(
method _st_times_different (line 469) | def _st_times_different(draw, ans) -> tuple[pd.Timestamp, pd.Timestamp]:
method _st_start_end (line 477) | def _st_start_end(draw, ans) -> tuple[pd.Timestamp, pd.Timestamp]:
method st_start_end (line 496) | def st_start_end(
method st_periods (line 508) | def st_periods(
method could_overlap (line 520) | def could_overlap(
method evaluate_overrun (line 545) | def evaluate_overrun(
method sessions_bounds (line 564) | def sessions_bounds(
method test_indices_fuzz (line 678) | def test_indices_fuzz(
method test_intervals_fuzz (line 801) | def test_intervals_fuzz(
method test_for_empty_with_neither_fuzz (line 902) | def test_for_empty_with_neither_fuzz(
method test_daily_fuzz (line 950) | def test_daily_fuzz(
method test_overlap_error_fuzz (line 984) | def test_overlap_error_fuzz(self, data, name, calendars, answers, clos...
method curtail_all (line 1045) | def curtail_all(self, request) -> abc.Iterator[bool]:
method cal_start_end (line 1050) | def cal_start_end(
method ti_for_overlap (line 1061) | def ti_for_overlap(
method test_overlaps (line 1087) | def test_overlaps(self, ti_for_overlap, answers):
method ti_for_overlap_error_negative_case (line 1114) | def ti_for_overlap_error_negative_case(
method test_overlaps_2 (line 1137) | def test_overlaps_2(self, ti_for_overlap_error_negative_case):
method test_force (line 1149) | def test_force(self, cal_start_end):
method test_ignore_breaks (line 1181) | def test_ignore_breaks(self, cal_start_end):
method cal_with_ans_align (line 1209) | def cal_with_ans_align(self) -> abc.Iterator[tuple[ExchangeCalendar, A...
method dates_align (line 1226) | def dates_align(
method test_align (line 1253) | def test_align( # noqa: C901, PLR0915
method test_align_overlap (line 1392) | def test_align_overlap(self, cal_with_ans_align, dates_align, one_min):
method test_start_end_times (line 1459) | def test_start_end_times(self, one_min, calendars): # noqa: PLR0915
method test_parsing_errors (line 1755) | def test_parsing_errors(self, cal_start_end):
FILE: tests/test_cmes_calendar.py
class TestCMESCalendar (line 8) | class TestCMESCalendar(ExchangeCalendarTestBase):
method all_calendars_with_answers (line 10) | def all_calendars_with_answers(self, request, calendars, answers):
method calendar_cls (line 14) | def calendar_cls(self):
method max_session_hours (line 18) | def max_session_hours(self):
method regular_holidays_sample (line 22) | def regular_holidays_sample(self):
method early_closes_sample (line 27) | def early_closes_sample(self):
method early_closes_sample_time (line 38) | def early_closes_sample_time(self):
FILE: tests/test_exchange_calendar.py
class FakeCalendar (line 41) | class FakeCalendar(ExchangeCalendar):
class TestCalendarRegistration (line 48) | class TestCalendarRegistration:
method dispatcher (line 50) | def dispatcher(self) -> abc.Iterator[ExchangeCalendarDispatcher]:
method dummy_cal_type (line 56) | def dummy_cal_type(self) -> abc.Iterator[type[FakeCalendar]]:
method dummy_cal (line 60) | def dummy_cal(self, dummy_cal_type) -> abc.Iterator[FakeCalendar]:
method test_register_calendar (line 63) | def test_register_calendar(self, dispatcher, dummy_cal):
method test_register_calendar_type (line 78) | def test_register_calendar_type(self, dispatcher, dummy_cal_type):
method test_both_places_are_checked (line 83) | def test_both_places_are_checked(self, dispatcher, dummy_cal):
method test_force_registration (line 97) | def test_force_registration(self, dispatcher, dummy_cal_type):
function test_default_calendars (line 109) | def test_default_calendars():
function test_days_at_time (line 167) | def test_days_at_time(day, day_offset, time_offset, tz, expected):
function get_csv (line 174) | def get_csv(name: str) -> pd.DataFrame:
class Answers (line 202) | class Answers:
method __init__ (line 228) | def __init__(
method name (line 239) | def name(self) -> str:
method side (line 244) | def side(self) -> str:
method answers (line 251) | def answers(self) -> pd.DataFrame:
method sessions (line 256) | def sessions(self) -> pd.DatetimeIndex:
method opens (line 261) | def opens(self) -> pd.Series:
method closes (line 266) | def closes(self) -> pd.Series:
method break_starts (line 271) | def break_starts(self) -> pd.Series:
method break_ends (line 276) | def break_ends(self) -> pd.Series:
method get_next_session (line 282) | def get_next_session(self, session: pd.Timestamp) -> pd.Timestamp:
method get_next_sessions (line 289) | def get_next_sessions(self, session: pd.Timestamp, count: int) -> pd.T...
method get_prev_sessions (line 298) | def get_prev_sessions(self, session: pd.Timestamp, count: int) -> pd.T...
method session_has_break (line 307) | def session_has_break(self, session: pd.Timestamp) -> bool:
method get_sessions_sample (line 312) | def get_sessions_sample(sessions: pd.DatetimeIndex):
method get_sessions_minutes (line 335) | def get_sessions_minutes(
method get_session_minutes (line 373) | def get_session_minutes(
method get_session_break_minutes (line 399) | def get_session_break_minutes(self, session: pd.Timestamp) -> pd.Datet...
method get_session_edge_minutes (line 408) | def get_session_edge_minutes(
method has_a_session_with_break (line 445) | def has_a_session_with_break(self) -> pd.DatetimeIndex:
method has_a_session_without_break (line 450) | def has_a_session_without_break(self) -> bool:
method first_session (line 457) | def first_session(self) -> pd.Timestamp:
method last_session (line 462) | def last_session(self) -> pd.Timestamp:
method sessions_range (line 467) | def sessions_range(self) -> tuple[pd.Timestamp, pd.Timestamp]:
method first_session_open (line 472) | def first_session_open(self) -> pd.Timestamp:
method last_session_close (line 477) | def last_session_close(self) -> pd.Timestamp:
method first_minute (line 482) | def first_minute(self) -> pd.Timestamp:
method last_minute (line 487) | def last_minute(self) -> pd.Timestamp:
method trading_minutes_range (line 492) | def trading_minutes_range(self) -> tuple[pd.Timestamp, pd.Timestamp]:
method minute_too_early (line 499) | def minute_too_early(self) -> pd.Timestamp:
method minute_too_late (line 504) | def minute_too_late(self) -> pd.Timestamp:
method session_too_early (line 509) | def session_too_early(self) -> pd.Timestamp:
method session_too_late (line 514) | def session_too_late(self) -> pd.Timestamp:
method first_minutes (line 521) | def first_minutes(self) -> pd.Series:
method first_minutes_plus_one (line 531) | def first_minutes_plus_one(self) -> pd.Series:
method first_minutes_less_one (line 536) | def first_minutes_less_one(self) -> pd.Series:
method last_minutes (line 541) | def last_minutes(self) -> pd.Series:
method last_minutes_plus_one (line 551) | def last_minutes_plus_one(self) -> pd.Series:
method last_minutes_less_one (line 556) | def last_minutes_less_one(self) -> pd.Series:
method last_am_minutes (line 561) | def last_am_minutes(self) -> pd.Series:
method last_am_minutes_plus_one (line 574) | def last_am_minutes_plus_one(self) -> pd.Series:
method last_am_minutes_less_one (line 579) | def last_am_minutes_less_one(self) -> pd.Series:
method first_pm_minutes (line 584) | def first_pm_minutes(self) -> pd.Series:
method first_pm_minutes_plus_one (line 597) | def first_pm_minutes_plus_one(self) -> pd.Series:
method first_pm_minutes_less_one (line 602) | def first_pm_minutes_less_one(self) -> pd.Series:
method _mask_breaks (line 609) | def _mask_breaks(self) -> pd.Series:
method sessions_with_break (line 613) | def sessions_with_break(self) -> pd.DatetimeIndex:
method sessions_without_break (line 617) | def sessions_without_break(self) -> pd.DatetimeIndex:
method sessions_without_break_run (line 621) | def sessions_without_break_run(self) -> pd.DatetimeIndex:
method sessions_without_break_range (line 629) | def sessions_without_break_range(self) -> tuple[pd.Timestamp, pd.Times...
method _mask_sessions_without_gap_after (line 640) | def _mask_sessions_without_gap_after(self) -> pd.Series:
method _mask_sessions_without_gap_before (line 656) | def _mask_sessions_without_gap_before(self) -> pd.Series:
method sessions_without_gap_after (line 672) | def sessions_without_gap_after(self) -> pd.DatetimeIndex:
method sessions_with_gap_after (line 682) | def sessions_with_gap_after(self) -> pd.DatetimeIndex:
method sessions_without_gap_before (line 688) | def sessions_without_gap_before(self) -> pd.DatetimeIndex:
method sessions_with_gap_before (line 698) | def sessions_with_gap_before(self) -> pd.DatetimeIndex:
method sessions_unchanging_times_run (line 706) | def sessions_unchanging_times_run(self) -> pd.DatetimeIndex:
method _get_sessions_with_times_different_to_next_session (line 713) | def _get_sessions_with_times_different_to_next_session(
method _sessions_with_opens_different_to_next_session (line 760) | def _sessions_with_opens_different_to_next_session(
method _sessions_with_closes_different_to_next_session (line 766) | def _sessions_with_closes_different_to_next_session(
method _sessions_with_break_start_different_to_next_session (line 772) | def _sessions_with_break_start_different_to_next_session(
method _sessions_with_break_end_different_to_next_session (line 778) | def _sessions_with_break_end_different_to_next_session(
method sessions_next_open_earlier (line 784) | def sessions_next_open_earlier(self) -> pd.DatetimeIndex:
method sessions_next_open_later (line 788) | def sessions_next_open_later(self) -> pd.DatetimeIndex:
method sessions_next_open_different (line 792) | def sessions_next_open_different(self) -> pd.DatetimeIndex:
method sessions_next_close_earlier (line 796) | def sessions_next_close_earlier(self) -> pd.DatetimeIndex:
method sessions_next_close_later (line 800) | def sessions_next_close_later(self) -> pd.DatetimeIndex:
method sessions_next_close_different (line 804) | def sessions_next_close_different(self) -> pd.DatetimeIndex:
method sessions_next_break_start_earlier (line 808) | def sessions_next_break_start_earlier(self) -> pd.DatetimeIndex:
method sessions_next_break_start_later (line 812) | def sessions_next_break_start_later(self) -> pd.DatetimeIndex:
method sessions_next_break_start_different (line 816) | def sessions_next_break_start_different(self) -> pd.DatetimeIndex:
method sessions_next_break_end_earlier (line 822) | def sessions_next_break_end_earlier(self) -> pd.DatetimeIndex:
method sessions_next_break_end_later (line 826) | def sessions_next_break_end_later(self) -> pd.DatetimeIndex:
method sessions_next_break_end_different (line 830) | def sessions_next_break_end_different(self) -> pd.DatetimeIndex:
method _get_sessions_with_has_break_different_to_next_session (line 836) | def _get_sessions_with_has_break_different_to_next_session(
method sessions_with_break_next_session_without_break (line 861) | def sessions_with_break_next_session_without_break(self) -> pd.Datetim...
method sessions_without_break_next_session_with_break (line 865) | def sessions_without_break_next_session_with_break(self) -> pd.Datetim...
method sessions_next_time_different (line 869) | def sessions_next_time_different(self) -> pd.DatetimeIndex:
method _create_changing_times_session_block (line 888) | def _create_changing_times_session_block(
method _get_normal_session_block (line 907) | def _get_normal_session_block(self) -> pd.DatetimeIndex:
method _get_session_block (line 929) | def _get_session_block(
method session_blocks (line 954) | def session_blocks(self) -> dict[str, pd.DatetimeIndex]:
method session_block_generator (line 1078) | def session_block_generator(self) -> abc.Iterator[tuple[str, pd.Dateti...
method session_block_minutes (line 1085) | def session_block_minutes(self) -> dict[str, pd.DatetimeIndex]:
method sessions_sample (line 1102) | def sessions_sample(self) -> pd.DatetimeIndex:
method non_sessions (line 1115) | def non_sessions(self) -> pd.DatetimeIndex:
method sessions_range_defined_by_non_sessions (line 1123) | def sessions_range_defined_by_non_sessions(
method non_sessions_run (line 1154) | def non_sessions_run(self) -> pd.DatetimeIndex:
method non_sessions_range (line 1173) | def non_sessions_range(self) -> tuple[pd.Timestamp, pd.Timestamp] | None:
method _evaluate_trading_and_break_minutes (line 1183) | def _evaluate_trading_and_break_minutes(self) -> tuple[tuple, tuple]:
method trading_minutes (line 1264) | def trading_minutes(self) -> tuple[tuple[tuple[pd.Timestamp], pd.Times...
method trading_minutes_only (line 1283) | def trading_minutes_only(self) -> abc.Iterator[pd.Timestamp]:
method trading_minute (line 1289) | def trading_minute(self) -> pd.Timestamp:
method break_minutes (line 1294) | def break_minutes(self) -> tuple[tuple[tuple[pd.Timestamp], pd.Timesta...
method break_minutes_only (line 1310) | def break_minutes_only(self) -> abc.Iterator[pd.Timestamp]:
method non_trading_minutes (line 1316) | def non_trading_minutes(
method non_trading_minutes_only (line 1362) | def non_trading_minutes_only(self) -> abc.Iterator[pd.Timestamp]:
method _trading_minute_to_break_minute (line 1369) | def _trading_minute_to_break_minute(
method trading_minute_to_break_minute_next (line 1389) | def trading_minute_to_break_minute_next(
method trading_minute_to_break_minute_prev (line 1432) | def trading_minute_to_break_minute_prev(
method prev_next_open_close_minutes (line 1477) | def prev_next_open_close_minutes( # noqa: PLR0915
method __repr__ (line 1648) | def __repr__(self) -> str:
function no_parsing (line 1652) | def no_parsing(f: typing.Callable):
class ExchangeCalendarTestBase (line 1657) | class ExchangeCalendarTestBase:
method calendar_cls (line 1701) | def calendar_cls(self) -> abc.Iterator[type[ExchangeCalendar]]:
method max_session_hours (line 1711) | def max_session_hours(self) -> abc.Iterator[int | float]:
method all_calendars_with_answers (line 1725) | def all_calendars_with_answers(
method start_bound (line 1735) | def start_bound(self) -> abc.Iterator[pd.Timestamp | None]:
method end_bound (line 1741) | def end_bound(self) -> abc.Iterator[pd.Timestamp | None]:
method regular_holidays_sample (line 1752) | def regular_holidays_sample(self) -> abc.Iterator[list[str]]:
method non_holidays_sample (line 1781) | def non_holidays_sample(self) -> abc.Iterator[list[str]]:
method adhoc_holidays_sample (line 1820) | def adhoc_holidays_sample(self) -> abc.Iterator[list[str]]:
method late_opens_sample (line 1837) | def late_opens_sample(self) -> abc.Iterator[list[str]]:
method early_closes_sample (line 1857) | def early_closes_sample(self) -> abc.Iterator[list[str]]:
method early_closes_sample_time (line 1877) | def early_closes_sample_time(self) -> abc.Iterator[pd.Timedelta | None]:
method early_closes_weekdays (line 1898) | def early_closes_weekdays(self) -> abc.Iterator[tuple[int]]:
method early_closes_weekdays_sample (line 1911) | def early_closes_weekdays_sample(self):
method early_closes_weekdays_sample_time (line 1930) | def early_closes_weekdays_sample_time(self) -> abc.Iterator[pd.Timedel...
method non_early_closes_sample (line 1947) | def non_early_closes_sample(self) -> abc.Iterator[list[str]]:
method non_early_closes_sample_time (line 1972) | def non_early_closes_sample_time(self) -> abc.Iterator[pd.Timedelta | ...
method test_testbase_integrity (line 1994) | def test_testbase_integrity(self):
method name (line 2027) | def name(self, calendar_cls) -> abc.Iterator[str]:
method has_24h_session (line 2032) | def has_24h_session(self, name) -> abc.Iterator[bool]:
method default_side (line 2037) | def default_side(self) -> abc.Iterator[str]:
method sides (line 2042) | def sides(self, has_24h_session) -> abc.Iterator[list[str]]:
method answers (line 2052) | def answers(self, name, sides) -> abc.Iterator[dict[str, Answers]]:
method default_answers (line 2057) | def default_answers(self, answers, default_side) -> abc.Iterator[Answe...
method calendars (line 2061) | def calendars(
method default_calendar (line 2070) | def default_calendar(
method calendars_with_answers (line 2076) | def calendars_with_answers(
method default_calendar_with_answers (line 2083) | def default_calendar_with_answers(
method one_minute (line 2091) | def one_minute(self) -> abc.Iterator[pd.Timedelta]:
method today (line 2095) | def today(self) -> abc.Iterator[pd.Timedelta]:
method all_directions (line 2099) | def all_directions(self, request) -> abc.Iterator[str]:
method valid_overrides (line 2104) | def valid_overrides(self) -> abc.Iterator[list[str]]:
method non_valid_overrides (line 2132) | def non_valid_overrides(self, valid_overrides) -> abc.Iterator[list[st...
method daylight_savings_dates (line 2143) | def daylight_savings_dates(
method late_opens (line 2173) | def late_opens(
method early_closes (line 2214) | def early_closes(
method test_base_integrity (line 2254) | def test_base_integrity(self, calendar_cls, non_valid_overrides):
method test_calculated_against_csv (line 2266) | def test_calculated_against_csv(self, default_calendar_with_answers):
method test_start_end (line 2270) | def test_start_end(self, default_answers, calendar_cls):
method test_invalid_input (line 2285) | def test_invalid_input(self, calendar_cls, sides, default_answers, name):
method test_bound_min (line 2320) | def test_bound_min(self, calendar_cls, start_bound, end_bound, today):
method test_bound_max (line 2335) | def test_bound_max(self, calendar_cls, end_bound, today):
method test_sanity_check_session_lengths (line 2350) | def test_sanity_check_session_lengths(self, default_calendar, max_sess...
method test_adhoc_holidays_specification (line 2355) | def test_adhoc_holidays_specification(self, default_calendar):
method test_daylight_savings (line 2360) | def test_daylight_savings(self, default_calendar, daylight_savings_dat...
method test_sessions (line 2392) | def test_sessions(self, default_calendar_with_answers):
method test_opens_closes_break_starts_ends (line 2398) | def test_opens_closes_break_starts_ends(self, default_calendar_with_an...
method test_minutes_properties (line 2411) | def test_minutes_properties(self, all_calendars_with_answers):
method test_minutes (line 2434) | def test_minutes(self, all_calendars_with_answers, one_minute): # noq...
method test_calendar_bounds_properties (line 2532) | def test_calendar_bounds_properties(self, all_calendars_with_answers):
method test_has_break (line 2551) | def test_has_break(self, default_calendar_with_answers):
method test_regular_holidays_sample (line 2555) | def test_regular_holidays_sample(self, default_calendar, regular_holid...
method test_adhoc_holidays_sample (line 2561) | def test_adhoc_holidays_sample(self, default_calendar, adhoc_holidays_...
method test_non_holidays_sample (line 2567) | def test_non_holidays_sample(self, default_calendar, non_holidays_samp...
method test_late_opens_sample (line 2573) | def test_late_opens_sample(self, default_calendar, late_opens_sample):
method test_early_closes_sample (line 2579) | def test_early_closes_sample(self, default_calendar, early_closes_samp...
method test_early_closes_sample_time (line 2585) | def test_early_closes_sample_time(
method test_early_closes_weekdays (line 2603) | def test_early_closes_weekdays(
method test_early_closes_weekdays_time (line 2614) | def test_early_closes_weekdays_time(
method test_non_early_closes_sample (line 2639) | def test_non_early_closes_sample(self, default_calendar, non_early_clo...
method test_non_early_closes_sample_time (line 2645) | def test_non_early_closes_sample_time(
method test_late_opens (line 2663) | def test_late_opens(self, default_calendar, late_opens):
method test_early_closes (line 2673) | def test_early_closes(self, default_calendar, early_closes):
method test_session_open_close_break_start_end (line 2685) | def test_session_open_close_break_start_end(self, default_calendar_wit...
method test_session_minute_methods (line 2724) | def test_session_minute_methods(self, all_calendars_with_answers):
method test_session_has_break (line 2759) | def test_session_has_break(self, default_calendar_with_answers):
method test_next_prev_session (line 2769) | def test_next_prev_session(self, default_calendar_with_answers):
method test_session_minutes (line 2793) | def test_session_minutes(self, all_calendars_with_answers):
method test_session_offset (line 2803) | def test_session_offset(self, default_calendar_with_answers):
method test_is_session (line 2842) | def test_is_session(self, default_calendar_with_answers):
method test_date_to_session (line 2852) | def test_date_to_session(self, default_calendar_with_answers):
method test_is_trading_minute (line 2906) | def test_is_trading_minute(self, all_calendars_with_answers):
method test_is_break_minute (line 2919) | def test_is_break_minute(self, all_calendars_with_answers):
method test_is_open_on_minute (line 2932) | def test_is_open_on_minute(self, all_calendars_with_answers):
method test_is_open_at_time (line 2951) | def test_is_open_at_time(self, all_calendars_with_answers, one_minute)...
method test_prev_next_open_close (line 3056) | def test_prev_next_open_close(self, default_calendar_with_answers):
method test_prev_next_minute (line 3093) | def test_prev_next_minute(self, all_calendars_with_answers, one_minute...
method test_minute_to_session (line 3199) | def test_minute_to_session(self, all_calendars_with_answers, all_direc...
method test_minute_to_past_session (line 3251) | def test_minute_to_past_session(self, all_calendars_with_answers, one_...
method test_minute_to_future_session (line 3291) | def test_minute_to_future_session(self, all_calendars_with_answers, on...
method test_minute_to_trading_minute (line 3331) | def test_minute_to_trading_minute(self, all_calendars_with_answers, al...
method test_minute_offset (line 3368) | def test_minute_offset(self, all_calendars_with_answers, one_minute):
method test_minute_offset_by_sessions (line 3417) | def test_minute_offset_by_sessions(self, all_calendars_with_answers): ...
method test_minutes_in_range (line 3561) | def test_minutes_in_range(self, all_calendars_with_answers, one_minute):
method test_minutes_window (line 3597) | def test_minutes_window(self, all_calendars_with_answers):
method test_minutes_distance (line 3663) | def test_minutes_distance(self, all_calendars_with_answers, one_minute):
method test_minutes_to_sessions (line 3694) | def test_minutes_to_sessions(self, all_calendars_with_answers):
method test_sessions_in_range (line 3716) | def test_sessions_in_range(self, default_calendar_with_answers):
method test_sessions_has_break (line 3737) | def test_sessions_has_break(self, default_calendar_with_answers):
method test_sessions_window (line 3763) | def test_sessions_window(self, default_calendar_with_answers):
method test_sessions_distance (line 3799) | def test_sessions_distance(self, default_calendar_with_answers):
method test_sessions_minutes (line 3820) | def test_sessions_minutes(self, all_calendars_with_answers):
method test_sessions_minutes_count (line 3840) | def test_sessions_minutes_count(self, all_calendars_with_answers):
method test_trading_index (line 3863) | def test_trading_index(self, calendars, answers): # noqa: C901, PLR0915
method test_deprecated (line 3961) | def test_deprecated(self, default_calendar_with_answers):
class EuronextCalendarTestBase (line 3995) | class EuronextCalendarTestBase(ExchangeCalendarTestBase):
method early_closes_sample_time (line 4002) | def early_closes_sample_time(self):
method non_early_closes_sample_time (line 4008) | def non_early_closes_sample_time(self):
method additional_regular_holidays_sample (line 4014) | def additional_regular_holidays_sample(self):
method additional_non_holidays_sample (line 4018) | def additional_non_holidays_sample(self):
method max_session_hours (line 4024) | def max_session_hours(self):
method regular_holidays_sample (line 4028) | def regular_holidays_sample(self, additional_regular_holidays_sample):
method non_holidays_sample (line 4041) | def non_holidays_sample(self, additional_non_holidays_sample):
method early_closes_sample (line 4055) | def early_closes_sample(self):
method non_early_closes_sample (line 4060) | def non_early_closes_sample(self):
FILE: tests/test_iepa_calendar.py
class TestIEPACalendar (line 8) | class TestIEPACalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 23) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 27) | def non_holidays_sample(self):
method early_closes_sample (line 31) | def early_closes_sample(self):
method early_closes_sample_time (line 42) | def early_closes_sample_time(self):
FILE: tests/test_utils.py
function T (line 4) | def T(x): # noqa: N802
FILE: tests/test_weekday_calendar.py
class TestWeekdayCalendar (line 10) | class TestWeekdayCalendar(ExchangeCalendarTestBase):
method all_calendars_with_answers (line 12) | def all_calendars_with_answers(self, request, calendars, answers):
method calendar_cls (line 16) | def calendar_cls(self):
method max_session_hours (line 20) | def max_session_hours(self):
method test_open_every_weekday (line 25) | def test_open_every_weekday(self, default_calendar_with_answers):
method test_open_every_weekday_minute (line 30) | def test_open_every_weekday_minute(self, calendars, answers, one_minute):
FILE: tests/test_xams_calendar.py
class TestXAMSCalendar (line 7) | class TestXAMSCalendar(EuronextCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method additional_regular_holidays_sample (line 13) | def additional_regular_holidays_sample(self):
method additional_non_holidays_sample (line 23) | def additional_non_holidays_sample(self):
FILE: tests/test_xasx_calendar.py
class TestXASXCalendar (line 9) | class TestXASXCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 11) | def calendar_cls(self):
method max_session_hours (line 15) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 51) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 56) | def non_holidays_sample(self):
method early_closes_sample (line 61) | def early_closes_sample(self):
method early_closes_sample_time (line 81) | def early_closes_sample_time(self):
method non_early_closes_sample (line 85) | def non_early_closes_sample(self):
method non_early_closes_sample_time (line 91) | def non_early_closes_sample_time(self):
FILE: tests/test_xbda_calendar.py
class TestXBDACalendar (line 8) | class TestXBDACalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method non_holidays_sample (line 90) | def non_holidays_sample(self):
method early_closes_sample (line 100) | def early_closes_sample(self):
method early_closes_sample_time (line 109) | def early_closes_sample_time(self):
FILE: tests/test_xbel_calendar.py
class TestXBELExchangeCalendar (line 6) | class TestXBELExchangeCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 8) | def calendar_cls(self):
method max_session_hours (line 12) | def max_session_hours(self):
method regular_holidays_sample (line 17) | def regular_holidays_sample(self):
method non_holidays_sample (line 32) | def non_holidays_sample(self):
FILE: tests/test_xbkk_calendar.py
class TestXBKKCalendar (line 7) | class TestXBKKCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 17) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 58) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 71) | def non_holidays_sample(self):
FILE: tests/test_xbog_calendar.py
class TestXBOGCalendar (line 7) | class TestXBOGCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 17) | def regular_holidays_sample(self):
method non_holidays_sample (line 57) | def non_holidays_sample(self):
FILE: tests/test_xbom_calendar.py
class TestXBOMCalendar (line 8) | class TestXBOMCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method start_bound (line 14) | def start_bound(self):
method end_bound (line 18) | def end_bound(self):
method max_session_hours (line 22) | def max_session_hours(self):
method regular_holidays_sample (line 27) | def regular_holidays_sample(self):
method non_holidays_sample (line 46) | def non_holidays_sample(self):
FILE: tests/test_xbra_calendar.py
class TestXBRAExchangeCalendar (line 6) | class TestXBRAExchangeCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 8) | def calendar_cls(self):
method max_session_hours (line 12) | def max_session_hours(self):
method regular_holidays_sample (line 17) | def regular_holidays_sample(self):
method non_holidays_sample (line 37) | def non_holidays_sample(self):
FILE: tests/test_xbru_calendar.py
class TestXBRUCalendar (line 7) | class TestXBRUCalendar(EuronextCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method additional_regular_holidays_sample (line 13) | def additional_regular_holidays_sample(self):
method additional_non_holidays_sample (line 23) | def additional_non_holidays_sample(self):
FILE: tests/test_xbse_calendar.py
class TestXBSECalendar (line 7) | class TestXBSECalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 52) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 76) | def non_holidays_sample(self):
FILE: tests/test_xbud_calendar.py
class TestXBUDCalendar (line 8) | class TestXBUDCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 67) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 71) | def non_holidays_sample(self):
FILE: tests/test_xbue_calendar.py
class TestXBUECalendar (line 8) | class TestXBUECalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method non_holidays_sample (line 56) | def non_holidays_sample(self):
method early_closes_sample (line 96) | def early_closes_sample(self):
method early_closes_sample_time (line 101) | def early_closes_sample_time(self):
FILE: tests/test_xcbf_calendar.py
class TestXCBFCalendar (line 8) | class TestXCBFCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 36) | def adhoc_holidays_sample(self):
method early_closes_sample (line 46) | def early_closes_sample(self):
method early_closes_sample_time (line 50) | def early_closes_sample_time(self):
FILE: tests/test_xcse_calendar.py
class TestXCSECalendar (line 7) | class TestXCSECalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method non_holidays_sample (line 39) | def non_holidays_sample(self):
FILE: tests/test_xcys_calendar.py
class TestXCYSExchangeCalendar (line 6) | class TestXCYSExchangeCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 8) | def calendar_cls(self):
method max_session_hours (line 12) | def max_session_hours(self):
method regular_holidays_sample (line 16) | def regular_holidays_sample(self):
method non_holidays_sample (line 38) | def non_holidays_sample(self):
FILE: tests/test_xdub_calendar.py
class TestXDUBCalendar (line 8) | class TestXDUBCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 52) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 56) | def non_holidays_sample(self):
method early_closes_sample (line 65) | def early_closes_sample(self):
method early_closes_sample_time (line 77) | def early_closes_sample_time(self):
method non_early_closes_sample (line 81) | def non_early_closes_sample(self):
method non_early_closes_sample_time (line 92) | def non_early_closes_sample_time(self):
FILE: tests/test_xdus_calendar.py
class TestXDUSCalendar (line 8) | class TestXDUSCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 40) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 47) | def non_holidays_sample(self):
method early_closes_sample (line 65) | def early_closes_sample(self):
method early_closes_sample_time (line 72) | def early_closes_sample_time(self):
FILE: tests/test_xeee_calendar.py
class TestXEEECalendar (line 7) | class TestXEEECalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method non_holidays_sample (line 32) | def non_holidays_sample(self):
FILE: tests/test_xetr_calendar.py
class TestXETRCalendar (line 8) | class TestXETRCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 40) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 47) | def non_holidays_sample(self):
method early_closes_sample (line 65) | def early_closes_sample(self):
method early_closes_sample_time (line 72) | def early_closes_sample_time(self):
FILE: tests/test_xeur_calendar.py
class TestXEURCalendar (line 7) | class TestXEURCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method non_holidays_sample (line 50) | def non_holidays_sample(self):
FILE: tests/test_xfra_calendar.py
class TestXFRACalendar (line 8) | class TestXFRACalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 40) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 47) | def non_holidays_sample(self):
method early_closes_sample (line 65) | def early_closes_sample(self):
method early_closes_sample_time (line 72) | def early_closes_sample_time(self):
FILE: tests/test_xham_calendar.py
class TestXHAMCalendar (line 8) | class TestXHAMCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 40) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 47) | def non_holidays_sample(self):
method early_closes_sample (line 65) | def early_closes_sample(self):
method early_closes_sample_time (line 72) | def early_closes_sample_time(self):
FILE: tests/test_xhel_calendar.py
class TestXHELCalendar (line 7) | class TestXHELCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 17) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 37) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 41) | def non_holidays_sample(self):
FILE: tests/test_xhkg_calendar.py
class TestXHKGCalendar (line 9) | class TestXHKGCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 11) | def calendar_cls(self):
method max_session_hours (line 15) | def max_session_hours(self):
method start_bound (line 19) | def start_bound(self):
method end_bound (line 23) | def end_bound(self):
method adhoc_holidays_sample (line 27) | def adhoc_holidays_sample(self):
method early_closes_sample (line 195) | def early_closes_sample(self):
method early_closes_sample_time (line 199) | def early_closes_sample_time(self):
FILE: tests/test_xice_calendar.py
class TestXICECalendar (line 7) | class TestXICECalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 38) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 42) | def non_holidays_sample(self):
FILE: tests/test_xidx_calendar.py
class TestXIDXCalendar (line 8) | class TestXIDXCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method test_trading_days (line 19) | def test_trading_days(self, default_calendar):
method test_holidays_in_year (line 96) | def test_holidays_in_year(self, default_calendar, year, holidays):
FILE: tests/test_xist_calendar.py
class TestXISTCalendar (line 8) | class TestXISTCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 38) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 59) | def non_holidays_sample(self):
method early_closes_sample (line 91) | def early_closes_sample(self):
method early_closes_sample_time (line 99) | def early_closes_sample_time(self):
FILE: tests/test_xjse_calendar.py
class TestXJSECalendar (line 9) | class TestXJSECalendar(ExchangeCalendarTestBase):
method calendar_cls (line 11) | def calendar_cls(self):
method max_session_hours (line 15) | def max_session_hours(self):
method test_no_weekend_sessions (line 19) | def test_no_weekend_sessions(self, default_calendar):
method test_holidays_in_year (line 85) | def test_holidays_in_year(self, default_calendar, year, holidays):
FILE: tests/test_xkar_calendar.py
class TestXKARCalendar (line 8) | class TestXKARCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method non_holidays_sample (line 23) | def non_holidays_sample(self):
method test_holidays_in_year (line 58) | def test_holidays_in_year(self, default_calendar, year, holidays):
FILE: tests/test_xkls_calendar.py
class TestXKLSCalendar (line 8) | class TestXKLSCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 51) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 55) | def non_holidays_sample(self):
method early_closes_sample (line 91) | def early_closes_sample(self):
method early_closes_sample_time (line 98) | def early_closes_sample_time(self):
FILE: tests/test_xkrx_calendar.py
class TestXKRXCalendar (line 11) | class TestXKRXCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 13) | def calendar_cls(self):
method start_bound (line 17) | def start_bound(self):
method end_bound (line 21) | def end_bound(self):
method max_session_hours (line 25) | def max_session_hours(self):
method regular_holidays_sample (line 30) | def regular_holidays_sample(self):
method non_holidays_sample (line 86) | def non_holidays_sample(self):
method adhoc_holidays_sample (line 102) | def adhoc_holidays_sample(self):
method test_late_opens (line 109) | def test_late_opens(self, default_calendar, late_opens): # noqa: ARG002
method test_historical_regular_holidays_fall_into_precomputed_holidays (line 116) | def test_historical_regular_holidays_fall_into_precomputed_holidays(
method test_feb_29_2022_in_lunar_calendar (line 139) | def test_feb_29_2022_in_lunar_calendar(self, default_calendar):
FILE: tests/test_xlim_calendar.py
class TestXLIMCalendar (line 7) | class TestXLIMCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 44) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 63) | def non_holidays_sample(self):
FILE: tests/test_xlis_calendar.py
class TestXLISCalendar (line 8) | class TestXLISCalendar(EuronextCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method early_closes_sample_time (line 14) | def early_closes_sample_time(self):
method non_early_closes_sample_time (line 18) | def non_early_closes_sample_time(self):
method additional_regular_holidays_sample (line 22) | def additional_regular_holidays_sample(self):
method additional_non_holidays_sample (line 39) | def additional_non_holidays_sample(self):
FILE: tests/test_xlit_calendar.py
class TestXLITExchangeCalendar (line 8) | class TestXLITExchangeCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method non_holidays_sample (line 38) | def non_holidays_sample(self):
FILE: tests/test_xlju_calendar.py
class TestXLJUCalendar (line 6) | class TestXLJUCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 8) | def calendar_cls(self):
method max_session_hours (line 12) | def max_session_hours(self):
method regular_holidays_sample (line 17) | def regular_holidays_sample(self):
method non_holidays_sample (line 38) | def non_holidays_sample(self):
FILE: tests/test_xlon_calendar.py
class TestXLONCalendar (line 7) | class TestXLONCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 17) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 31) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 44) | def non_holidays_sample(self):
method early_closes_sample (line 49) | def early_closes_sample(self):
FILE: tests/test_xlux_calendar.py
class TestXLUXCalendar (line 8) | class TestXLUXCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method non_holidays_sample (line 66) | def non_holidays_sample(self):
method early_closes_sample (line 73) | def early_closes_sample(self):
method early_closes_sample_time (line 90) | def early_closes_sample_time(self):
FILE: tests/test_xmad_calendar.py
class TestXMADCalendar (line 8) | class TestXMADCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method non_holidays_sample (line 56) | def non_holidays_sample(self):
method early_closes_sample (line 91) | def early_closes_sample(self):
method early_closes_sample_time (line 105) | def early_closes_sample_time(self):
FILE: tests/test_xmex_calendar.py
class TestXMEXCalendar (line 7) | class TestXMEXCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 48) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 52) | def non_holidays_sample(self):
FILE: tests/test_xmil_calendar.py
class TestXMILCalendar (line 7) | class TestXMILCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method non_holidays_sample (line 33) | def non_holidays_sample(self):
FILE: tests/test_xmos_calendar.py
class TestXMOSCalendar (line 7) | class TestXMOSCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method non_holidays_sample (line 69) | def non_holidays_sample(self):
FILE: tests/test_xnys_calendar.py
class TestXNYSCalendar (line 8) | class TestXNYSCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 43) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 69) | def non_holidays_sample(self):
method early_closes_sample (line 76) | def early_closes_sample(self):
method early_closes_sample_time (line 91) | def early_closes_sample_time(self):
method non_early_closes_sample (line 95) | def non_early_closes_sample(self):
method non_early_closes_sample_time (line 104) | def non_early_closes_sample_time(self):
FILE: tests/test_xnze_calendar.py
class TestXNZECalendar (line 8) | class TestXNZECalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 45) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 54) | def non_holidays_sample(self):
method early_closes_sample (line 67) | def early_closes_sample(self):
method early_closes_sample_time (line 78) | def early_closes_sample_time(self):
method non_early_closes_sample (line 82) | def non_early_closes_sample(self):
method non_early_closes_sample_time (line 89) | def non_early_closes_sample_time(self):
FILE: tests/test_xosl_calendar.py
class TestXOSLCalendar (line 8) | class TestXOSLCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method non_holidays_sample (line 37) | def non_holidays_sample(self):
method early_closes_sample (line 59) | def early_closes_sample(self):
method early_closes_sample_time (line 64) | def early_closes_sample_time(self):
method non_early_closes_sample (line 68) | def non_early_closes_sample(self):
method non_early_closes_sample_time (line 73) | def non_early_closes_sample_time(self):
FILE: tests/test_xpar_calendar.py
class TestXPARCalendar (line 7) | class TestXPARCalendar(EuronextCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method additional_regular_holidays_sample (line 13) | def additional_regular_holidays_sample(self):
method additional_non_holidays_sample (line 22) | def additional_non_holidays_sample(self):
FILE: tests/test_xphs_calendar.py
class TestXPHSCalendar (line 7) | class TestXPHSCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 52) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 75) | def non_holidays_sample(self):
FILE: tests/test_xpra_calendar.py
class TestXPRACalendar (line 7) | class TestXPRACalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 43) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 51) | def non_holidays_sample(self):
FILE: tests/test_xris_calendar.py
class TestXRISCalendar (line 6) | class TestXRISCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 8) | def calendar_cls(self):
method max_session_hours (line 12) | def max_session_hours(self):
method regular_holidays_sample (line 17) | def regular_holidays_sample(self):
method non_holidays_sample (line 34) | def non_holidays_sample(self):
FILE: tests/test_xsau_calendar.py
class TestXASUCalendar (line 8) | class TestXASUCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method start_bound (line 14) | def start_bound(self):
method end_bound (line 18) | def end_bound(self):
method max_session_hours (line 22) | def max_session_hours(self):
method regular_holidays_sample (line 26) | def regular_holidays_sample(self):
FILE: tests/test_xses_calendar.py
class TestXSESCalendar (line 8) | class TestXSESCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method start_bound (line 14) | def start_bound(self):
method end_bound (line 18) | def end_bound(self):
method max_session_hours (line 22) | def max_session_hours(self):
method regular_holidays_sample (line 27) | def regular_holidays_sample(self):
FILE: tests/test_xsgo_calendar.py
class TestXSGOCalendar (line 9) | class TestXSGOCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 11) | def calendar_cls(self):
method max_session_hours (line 15) | def max_session_hours(self):
method regular_holidays_sample (line 20) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 76) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 88) | def non_holidays_sample(self):
method early_closes_sample (line 145) | def early_closes_sample(self):
method early_closes_sample_time (line 152) | def early_closes_sample_time(self):
method test_additional_early_closes_sample (line 157) | def test_additional_early_closes_sample(self, default_calendar):
method test_close_time_change (line 177) | def test_close_time_change(self, default_calendar):
FILE: tests/test_xshg_calendar.py
class TestXSHGCalendar (line 8) | class TestXSHGCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method start_bound (line 19) | def start_bound(self):
method end_bound (line 23) | def end_bound(self):
method regular_holidays_sample (line 27) | def regular_holidays_sample(self):
FILE: tests/test_xsto_calendar.py
class TestXSTOCalendar (line 8) | class TestXSTOCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method non_holidays_sample (line 43) | def non_holidays_sample(self):
method early_closes_sample (line 75) | def early_closes_sample(self):
method early_closes_sample_time (line 87) | def early_closes_sample_time(self):
FILE: tests/test_xstu_calendar.py
class TestXSTUCalendar (line 7) | class TestXSTUCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 41) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 45) | def non_holidays_sample(self):
method early_closes_sample (line 54) | def early_closes_sample(self):
method early_closes_sample_time (line 58) | def early_closes_sample_time(self):
FILE: tests/test_xswx_calendar.py
class TestIXSWXCalendar (line 7) | class TestIXSWXCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
FILE: tests/test_xtae_calendar.py
class TestXTAECalendar (line 8) | class TestXTAECalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method early_closes_sample (line 61) | def early_closes_sample(self):
method early_closes_sample_time (line 92) | def early_closes_sample_time(self):
method early_closes_weekdays (line 96) | def early_closes_weekdays(self):
method early_closes_weekdays_sample (line 100) | def early_closes_weekdays_sample(self):
method early_closes_weekdays_sample_time (line 108) | def early_closes_weekdays_sample_time(self):
method non_early_closes_sample (line 112) | def non_early_closes_sample(self):
method non_early_closes_sample_time (line 124) | def non_early_closes_sample_time(self):
class TestXTAECalendarEarlyCloseSundaysBefore2026 (line 128) | class TestXTAECalendarEarlyCloseSundaysBefore2026(ExchangeCalendarTestBa...
method calendar_cls (line 130) | def calendar_cls(self):
method max_session_hours (line 134) | def max_session_hours(self):
method early_closes_weekdays_sample (line 139) | def early_closes_weekdays_sample(self):
method early_closes_weekdays_sample_time (line 147) | def early_closes_weekdays_sample_time(self):
FILE: tests/test_xtai_calendar.py
class TestXTAICalendar (line 7) | class TestXTAICalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method non_holidays_sample (line 63) | def non_holidays_sample(self):
FILE: tests/test_xtal_calendar.py
class TestXTALCalendar (line 6) | class TestXTALCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 8) | def calendar_cls(self):
method max_session_hours (line 12) | def max_session_hours(self):
method regular_holidays_sample (line 17) | def regular_holidays_sample(self):
method non_holidays_sample (line 34) | def non_holidays_sample(self):
FILE: tests/test_xtks_calendar.py
class TestXTKSCalendar (line 24) | class TestXTKSCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 26) | def calendar_cls(self):
method max_session_hours (line 30) | def max_session_hours(self):
method start_bound (line 34) | def start_bound(self):
method silver_week_holidays (line 38) | def silver_week_holidays(self):
method golden_week_holidays (line 76) | def golden_week_holidays(self):
method regular_holidays_sample (line 97) | def regular_holidays_sample(self, silver_week_holidays, golden_week_ho...
method adhoc_holidays_sample (line 267) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 278) | def non_holidays_sample(self):
method test_golden_week_holidays (line 285) | def test_golden_week_holidays(self):
method test_emperors_birthday (line 331) | def test_emperors_birthday(self):
FILE: tests/test_xtse_calendar.py
class TestXTSECalendar (line 8) | class TestXTSECalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 40) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 47) | def non_holidays_sample(self):
method early_closes_sample (line 56) | def early_closes_sample(self):
method early_closes_sample_time (line 66) | def early_closes_sample_time(self):
method non_early_closes_sample (line 70) | def non_early_closes_sample(self):
method non_early_closes_sample_time (line 76) | def non_early_closes_sample_time(self):
FILE: tests/test_xwar_calendar.py
class TestXWARCalendar (line 7) | class TestXWARCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 9) | def calendar_cls(self):
method max_session_hours (line 13) | def max_session_hours(self):
method regular_holidays_sample (line 18) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 46) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 58) | def non_holidays_sample(self):
FILE: tests/test_xwbo_calendar.py
class TestXWBOCalendar (line 8) | class TestXWBOCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 10) | def calendar_cls(self):
method max_session_hours (line 14) | def max_session_hours(self):
method regular_holidays_sample (line 19) | def regular_holidays_sample(self):
method adhoc_holidays_sample (line 60) | def adhoc_holidays_sample(self):
method non_holidays_sample (line 64) | def non_holidays_sample(self):
method early_closes_sample (line 101) | def early_closes_sample(self):
method early_closes_sample_time (line 111) | def early_closes_sample_time(self):
FILE: tests/test_xzag_calendar.py
class TestXZAGCalendar (line 6) | class TestXZAGCalendar(ExchangeCalendarTestBase):
method calendar_cls (line 8) | def calendar_cls(self):
method max_session_hours (line 12) | def max_session_hours(self):
method regular_holidays_sample (line 17) | def regular_holidays_sample(self):
method non_holidays_sample (line 34) | def non_holidays_sample(self):
Copy disabled (too large)
Download .json
Condensed preview — 278 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (34,907K chars).
[
{
"path": ".devcontainer/Dockerfile",
"chars": 1292,
"preview": "# [Choice] Python version: 3, 3.11, 3.12, 3.13\nARG VARIANT=3\nFROM mcr.microsoft.com/vscode/devcontainers/python:${VARIAN"
},
{
"path": ".devcontainer/base.Dockerfile",
"chars": 2469,
"preview": "# [Choice] Python version: 3, 3.8, 3.7, 3.6\nARG VARIANT=3\nFROM python:${VARIANT}\n\n# [Option] Install zsh\nARG INSTALL_ZSH"
},
{
"path": ".devcontainer/devcontainer.json",
"chars": 1773,
"preview": "{\n\t\"name\": \"Python 3\",\n\t\"build\": {\n\t\t\"dockerfile\": \"Dockerfile\",\n\t\t\"context\": \"..\",\n\t\t\"args\": {\n\t\t\t// Update 'VARIANT' t"
},
{
"path": ".devcontainer/library-scripts/README.md",
"chars": 484,
"preview": "# Warning: Folder contents may be replaced\n\nThe contents of this folder will be automatically replaced with a file of th"
},
{
"path": ".devcontainer/library-scripts/common-debian.sh",
"chars": 10789,
"preview": "#!/usr/bin/env bash\n#---------------------------------------------------------------------------------------------------"
},
{
"path": ".devcontainer/library-scripts/node-debian.sh",
"chars": 4022,
"preview": "#!/bin/bash\n#-----------------------------------------------------------------------------------------------------------"
},
{
"path": ".devcontainer/library-scripts/python-debian.sh",
"chars": 5132,
"preview": "#!/usr/bin/env bash\n#---------------------------------------------------------------------------------------------------"
},
{
"path": ".gitattributes",
"chars": 79,
"preview": "calendars/_version.py export-subst\nexchange_calendars/_version.py export-subst\n"
},
{
"path": ".github/dependabot.yml",
"chars": 732,
"preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
},
{
"path": ".github/pull_request_template.md",
"chars": 2041,
"preview": "**Workflow to add a new Exchange Calendar**\n\nIt's recommended that whilst working through the process reference be made "
},
{
"path": ".github/release-drafter-config.yml",
"chars": 949,
"preview": "name-template: '$NEXT_PATCH_VERSION 🌈'\ntag-template: '$NEXT_PATCH_VERSION'\ncategories:\n - title: 'API Changes'\n labe"
},
{
"path": ".github/workflows/benchmark.yml",
"chars": 1121,
"preview": "name: Benchmark\n\non:\n push:\n branches:\n - master\n pull_request:\n branches:\n - master\njobs:\n benchmark"
},
{
"path": ".github/workflows/labeler.yml",
"chars": 297,
"preview": "name: \"Pull Request Labeler\"\non:\n pull_request_target:\n types: [opened, synchronize, reopened, edited]\n\njobs:\n pr-l"
},
{
"path": ".github/workflows/main.yml",
"chars": 1859,
"preview": "name: CI\n\non:\n push:\n branches:\n - master\n pull_request:\n branches:\n - master\n\njobs:\n\n pre-commit:\n "
},
{
"path": ".github/workflows/master-merge.yml",
"chars": 423,
"preview": "name: On Master Merge\n\non:\n push:\n branches:\n - master\n\njobs:\n draft-release-publish:\n name: Draft a new re"
},
{
"path": ".github/workflows/release.yml",
"chars": 1549,
"preview": "name: Publish Python 🐍 distributions 📦 to PyPI\non:\n release:\n types: [published]\n\npermissions:\n id-token: write\n c"
},
{
"path": ".gitignore",
"chars": 2207,
"preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packagi"
},
{
"path": ".pre-commit-config.yaml",
"chars": 377,
"preview": "repos:\n - repo: https://github.com/pre-commit/pre-commit-hooks\n rev: v6.0.0\n hooks:\n - id: check-yaml\n "
},
{
"path": ".python-version",
"chars": 7,
"preview": ">=3.10\n"
},
{
"path": "LICENSE",
"chars": 11347,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "MANIFEST.in",
"chars": 62,
"preview": "recursive-exclude .devcontainer *\nrecursive-exclude .github *\n"
},
{
"path": "README.md",
"chars": 24925,
"preview": "# exchange_calendars\n\n[](https://pypi.org/project/exchange-cale"
},
{
"path": "docs/changes_archive.md",
"chars": 3866,
"preview": "**NOTE**: This file is NOT a comprehensive changes log but rather an archive of sections temporarily included to the REA"
},
{
"path": "docs/dev/depenencies_update.md",
"chars": 519,
"preview": "## **Workflow to update dependencies using uv**\n\n- Set up new local 'deps' branch.\n- Update `uv.lock` file and sync loca"
},
{
"path": "docs/tutorials/calendar_methods.ipynb",
"chars": 90325,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# Calendar methods\\n\",\n \"\\n\",\n "
},
{
"path": "docs/tutorials/calendar_properties.ipynb",
"chars": 37096,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# Calendar construction and propert"
},
{
"path": "docs/tutorials/minutes.ipynb",
"chars": 29917,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# Minutes tutorial\"\n ]\n },\n {\n "
},
{
"path": "docs/tutorials/sessions.ipynb",
"chars": 22135,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# Sessions tutorial\"\n ]\n },\n {\n"
},
{
"path": "docs/tutorials/trading_index.ipynb",
"chars": 149703,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# `trading_index`\\n\",\n \"\\n\",\n "
},
{
"path": "etc/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "etc/bench.py",
"chars": 1493,
"preview": "import itertools\n\nimport pandas as pd\n\nfrom exchange_calendars import get_calendar\nfrom exchange_calendars.calendar_help"
},
{
"path": "etc/check_holidays.py",
"chars": 5725,
"preview": "from functools import partial\n\nimport click\nimport pandas as pd\n\nfrom exchange_calendars import get_calendar\nfrom exchan"
},
{
"path": "etc/ecal",
"chars": 3612,
"preview": "#!/usr/bin/env python\nimport io\nimport sys\n\nimport pandas as pd\n\n# ruff: noqa: T201\n\nmonths = [\n \"January\",\n \"Febr"
},
{
"path": "etc/factory_bounds.py",
"chars": 12758,
"preview": "\"\"\"Classes and functions to explore the bounds of calendar factories.\n\nJul 21. Module written (prior to implementation o"
},
{
"path": "etc/lunisolar",
"chars": 50342,
"preview": "#!/usr/bin/env python\n\"\"\"Lunisolar calendar calculations.\n\nUtilities for computing the dates of holidays based on lunar "
},
{
"path": "etc/make_exchange_calendar_test_csv.py",
"chars": 3014,
"preview": "\"\"\"\nThis script can be used to generate the CSV files used in the exchange calendar\ntests. The CSVs include a calendar's"
},
{
"path": "etc/update_xkrx_holidays.py",
"chars": 4348,
"preview": "from pathlib import Path\nimport requests\n\nimport pandas as pd\n\n# Precomputed/adhoc KRX holidays can be checked here\n# ht"
},
{
"path": "exchange_calendars/__init__.py",
"chars": 1717,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/always_open.py",
"chars": 411,
"preview": "from datetime import time\n\nfrom .exchange_calendar import ExchangeCalendar\nfrom exchange_calendars.calendar_helpers impo"
},
{
"path": "exchange_calendars/calendar_helpers.py",
"chars": 24793,
"preview": "from __future__ import annotations\n\nimport contextlib\nimport datetime\nfrom typing import Literal, TYPE_CHECKING\nfrom zon"
},
{
"path": "exchange_calendars/calendar_utils.py",
"chars": 21604,
"preview": "from typing import Literal\n\nfrom .calendar_helpers import parse_date, Date\nfrom .always_open import AlwaysOpenCalendar\nf"
},
{
"path": "exchange_calendars/common_holidays.py",
"chars": 11753,
"preview": "import pandas as pd\nfrom pandas.tseries.holiday import FR, DateOffset, Easter, Holiday\nfrom pandas.tseries.offsets impor"
},
{
"path": "exchange_calendars/ecal.py",
"chars": 3648,
"preview": "import io\nimport sys\n\nimport pandas as pd\n\n# ruff: noqa: T201\n\nmonths = [\n \"January\",\n \"February\",\n \"March\",\n "
},
{
"path": "exchange_calendars/errors.py",
"chars": 10839,
"preview": "#\n# Copyright 2015 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar.py",
"chars": 105954,
"preview": "# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use "
},
{
"path": "exchange_calendars/exchange_calendar_aixk.py",
"chars": 6691,
"preview": "from datetime import (\n time,\n datetime,\n timedelta,\n)\nfrom itertools import chain\nfrom zoneinfo import ZoneInf"
},
{
"path": "exchange_calendars/exchange_calendar_asex.py",
"chars": 4333,
"preview": "#\n# Copyright 2019 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_bvmf.py",
"chars": 5863,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_cmes.py",
"chars": 3245,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_iepa.py",
"chars": 2022,
"preview": "from datetime import time\nfrom itertools import chain\nfrom zoneinfo import ZoneInfo\n\nfrom pandas import Timestamp\nfrom p"
},
{
"path": "exchange_calendars/exchange_calendar_xams.py",
"chars": 2923,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xasx.py",
"chars": 6946,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xbda.py",
"chars": 6088,
"preview": "from datetime import time, datetime\nfrom zoneinfo import ZoneInfo\n\nimport pandas as pd\nfrom pandas.tseries.holiday impor"
},
{
"path": "exchange_calendars/exchange_calendar_xbel.py",
"chars": 4495,
"preview": "from datetime import (\n time,\n datetime,\n timedelta,\n)\nfrom itertools import chain\nfrom zoneinfo import ZoneInf"
},
{
"path": "exchange_calendars/exchange_calendar_xbkk.py",
"chars": 3449,
"preview": "#\n# Copyright 2019 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xbog.py",
"chars": 4720,
"preview": "#\n# Copyright 2019 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xbom.py",
"chars": 12634,
"preview": "from datetime import time\nfrom zoneinfo import ZoneInfo\n\nimport pandas as pd\nimport functools\n\nfrom pandas.tseries.offse"
},
{
"path": "exchange_calendars/exchange_calendar_xbra.py",
"chars": 2971,
"preview": "from datetime import time\nfrom zoneinfo import ZoneInfo\n\nimport pandas as pd\nfrom pandas.tseries.holiday import (\n Ho"
},
{
"path": "exchange_calendars/exchange_calendar_xbru.py",
"chars": 2970,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xbse.py",
"chars": 2730,
"preview": "from datetime import time\nfrom zoneinfo import ZoneInfo\n\nfrom pandas.tseries.holiday import Holiday\nfrom pandas.tseries."
},
{
"path": "exchange_calendars/exchange_calendar_xbud.py",
"chars": 5927,
"preview": "#\n# Copyright 2019 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xbue.py",
"chars": 9001,
"preview": "#\n# Copyright 2019 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xcbf.py",
"chars": 1948,
"preview": "from datetime import time\nfrom itertools import chain\nfrom zoneinfo import ZoneInfo\n\nfrom pandas.tseries.holiday import "
},
{
"path": "exchange_calendars/exchange_calendar_xcse.py",
"chars": 2777,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xcys.py",
"chars": 3144,
"preview": "from datetime import time\nfrom zoneinfo import ZoneInfo\nfrom .pandas_extensions.offsets import OrthodoxEaster\nfrom panda"
},
{
"path": "exchange_calendars/exchange_calendar_xdub.py",
"chars": 4353,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xdus.py",
"chars": 3221,
"preview": "# LICENSE HERE\n\nfrom datetime import time\nfrom zoneinfo import ZoneInfo\n\nfrom pandas import Timestamp\nfrom pandas.tserie"
},
{
"path": "exchange_calendars/exchange_calendar_xeee.py",
"chars": 1546,
"preview": "from datetime import time\nfrom zoneinfo import ZoneInfo\n\nfrom pandas.tseries.holiday import EasterMonday, GoodFriday\n\nfr"
},
{
"path": "exchange_calendars/exchange_calendar_xetr.py",
"chars": 3711,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xeur.py",
"chars": 1466,
"preview": "from datetime import time\nfrom zoneinfo import ZoneInfo\n\nfrom pandas.tseries.holiday import EasterMonday, GoodFriday\n\nfr"
},
{
"path": "exchange_calendars/exchange_calendar_xfra.py",
"chars": 3667,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xham.py",
"chars": 3221,
"preview": "# LICENSE HERE\n\nfrom datetime import time\nfrom zoneinfo import ZoneInfo\n\nfrom pandas import Timestamp\nfrom pandas.tserie"
},
{
"path": "exchange_calendars/exchange_calendar_xhel.py",
"chars": 2458,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xhkg.py",
"chars": 16048,
"preview": "# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use "
},
{
"path": "exchange_calendars/exchange_calendar_xice.py",
"chars": 2904,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xidx.py",
"chars": 14598,
"preview": "#\n# Copyright 2019 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xist.py",
"chars": 5351,
"preview": "#\n# Copyright 2019 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xjse.py",
"chars": 5170,
"preview": "#\n# Copyright 2019 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xkar.py",
"chars": 13031,
"preview": "#\n# Copyright 2019 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xkls.py",
"chars": 3287,
"preview": "#\n# Copyright 2019 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xkrx.py",
"chars": 13093,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xlim.py",
"chars": 4402,
"preview": "#\n# Copyright 2019 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xlis.py",
"chars": 3887,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xlit.py",
"chars": 2602,
"preview": "from datetime import time\nfrom zoneinfo import ZoneInfo\n\nimport pandas as pd\nfrom pandas.tseries.holiday import EasterMo"
},
{
"path": "exchange_calendars/exchange_calendar_xlju.py",
"chars": 2853,
"preview": "from datetime import time\nfrom zoneinfo import ZoneInfo\n\nfrom pandas.tseries.holiday import (\n Holiday,\n GoodFrida"
},
{
"path": "exchange_calendars/exchange_calendar_xlon.py",
"chars": 7332,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xlux.py",
"chars": 1829,
"preview": "from datetime import time\nfrom zoneinfo import ZoneInfo\n\nfrom pandas.tseries.holiday import EasterMonday, GoodFriday\n\nfr"
},
{
"path": "exchange_calendars/exchange_calendar_xmad.py",
"chars": 4613,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xmex.py",
"chars": 3683,
"preview": "#\n# Copyright 2019 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xmil.py",
"chars": 2177,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xmos.py",
"chars": 12432,
"preview": "#\n# Copyright 2019 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xnys.py",
"chars": 9403,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xnze.py",
"chars": 6943,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xosl.py",
"chars": 2731,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xpar.py",
"chars": 2832,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xphs.py",
"chars": 12925,
"preview": "#\n# Copyright 2019 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xpra.py",
"chars": 3561,
"preview": "#\n# Copyright 2019 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xris.py",
"chars": 3277,
"preview": "from datetime import time\nfrom zoneinfo import ZoneInfo\n\nimport pandas as pd\nfrom pandas.tseries.holiday import (\n Ho"
},
{
"path": "exchange_calendars/exchange_calendar_xsau.py",
"chars": 2683,
"preview": "from datetime import time\r\nfrom itertools import chain\r\nfrom zoneinfo import ZoneInfo\r\n\r\nimport pandas as pd\r\nfrom panda"
},
{
"path": "exchange_calendars/exchange_calendar_xses.py",
"chars": 11543,
"preview": "from datetime import time\nfrom zoneinfo import ZoneInfo\n\nimport pandas as pd\n\nfrom .precomputed_exchange_calendar import"
},
{
"path": "exchange_calendars/exchange_calendar_xsgo.py",
"chars": 8538,
"preview": "#\n# Copyright 2019 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xshg.py",
"chars": 14758,
"preview": "from datetime import time\nfrom zoneinfo import ZoneInfo\n\nimport pandas as pd\n\nfrom .precomputed_exchange_calendar import"
},
{
"path": "exchange_calendars/exchange_calendar_xsto.py",
"chars": 3918,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xstu.py",
"chars": 1467,
"preview": "from datetime import time\nfrom zoneinfo import ZoneInfo\n\nfrom pandas.tseries.holiday import EasterMonday, GoodFriday\nfro"
},
{
"path": "exchange_calendars/exchange_calendar_xswx.py",
"chars": 2476,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xtae.py",
"chars": 7838,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xtai.py",
"chars": 13878,
"preview": "# Copyright 2019 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use "
},
{
"path": "exchange_calendars/exchange_calendar_xtal.py",
"chars": 2215,
"preview": "from datetime import time\nfrom zoneinfo import ZoneInfo\n\nimport pandas as pd\nfrom pandas.tseries.holiday import EasterMo"
},
{
"path": "exchange_calendars/exchange_calendar_xtks.py",
"chars": 4657,
"preview": "from datetime import time\nfrom itertools import chain\nfrom zoneinfo import ZoneInfo\n\nimport pandas as pd\n\nfrom .exchange"
},
{
"path": "exchange_calendars/exchange_calendar_xtse.py",
"chars": 3796,
"preview": "from datetime import time\nfrom itertools import chain\nfrom zoneinfo import ZoneInfo\n\nimport pandas as pd\nfrom pandas.tse"
},
{
"path": "exchange_calendars/exchange_calendar_xwar.py",
"chars": 3664,
"preview": "#\n# Copyright 2019 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xwbo.py",
"chars": 4277,
"preview": "#\n# Copyright 2018 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not us"
},
{
"path": "exchange_calendars/exchange_calendar_xzag.py",
"chars": 3326,
"preview": "from datetime import time\nfrom zoneinfo import ZoneInfo\n\nimport pandas as pd\nfrom pandas.tseries.holiday import (\n Ho"
},
{
"path": "exchange_calendars/lunisolar_holidays.py",
"chars": 13602,
"preview": "\"\"\"Lunisolar calendar calculations.\n\nSee exchange_calendars/etc/lunisolar for code to calculate\n\"\"\"\n\nimport pandas as pd"
},
{
"path": "exchange_calendars/pandas_extensions/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "exchange_calendars/pandas_extensions/holiday.py",
"chars": 6309,
"preview": "# https://github.com/pandas-dev/pandas/blob/master/pandas/tseries/holiday.py\n\nimport warnings\n\nfrom pandas.tseries.holid"
},
{
"path": "exchange_calendars/pandas_extensions/korean_holiday.py",
"chars": 7737,
"preview": "import datetime\nimport pandas as pd\nfrom zoneinfo import ZoneInfo\n\nfrom pandas.tseries.offsets import Day\nfrom korean_lu"
},
{
"path": "exchange_calendars/pandas_extensions/offsets.py",
"chars": 11604,
"preview": "# https://github.com/pandas-dev/pandas/blob/master/pandas/tseries/offsets.py\n# https://github.com/pandas-dev/pandas/blob"
},
{
"path": "exchange_calendars/precomputed_exchange_calendar.py",
"chars": 1744,
"preview": "from abc import abstractmethod\n\nimport numpy as np\nimport pandas as pd\n\nfrom .exchange_calendar import ExchangeCalendar\n"
},
{
"path": "exchange_calendars/tase_holidays.py",
"chars": 16165,
"preview": "from datetime import date, datetime\n\nimport pandas as pd\nfrom pandas._libs.tslibs.conversion import localize_pydatetime\n"
},
{
"path": "exchange_calendars/us_futures_calendar.py",
"chars": 2795,
"preview": "from datetime import time\nfrom zoneinfo import ZoneInfo\n\nimport numpy as np\nimport pandas as pd\nfrom pandas.tseries.holi"
},
{
"path": "exchange_calendars/us_holidays.py",
"chars": 10190,
"preview": "\"\"\"\nUS Holidays\n\nMany historical holidays were derived from the pdf at\netc/NYSE-Historical-Closings.pdf. Originally post"
},
{
"path": "exchange_calendars/utils/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "exchange_calendars/utils/pandas_utils.py",
"chars": 4706,
"preview": "import datetime\nfrom zoneinfo import ZoneInfo\n\nimport numpy as np\nimport pandas as pd\n\nfrom exchange_calendars.calendar_"
},
{
"path": "exchange_calendars/weekday_calendar.py",
"chars": 399,
"preview": "from datetime import time\n\nfrom exchange_calendars.calendar_helpers import UTC\nfrom .exchange_calendar import ExchangeCa"
},
{
"path": "exchange_calendars/xbkk_holidays.py",
"chars": 8791,
"preview": "import datetime\n\nimport pandas as pd\nfrom pandas.tseries.holiday import (\n Holiday,\n next_monday_or_tuesday,\n s"
},
{
"path": "exchange_calendars/xkls_holidays.py",
"chars": 13557,
"preview": "from datetime import timedelta\n\nimport pandas as pd\nfrom pandas.tseries.holiday import Holiday, sunday_to_monday\n\nfrom ."
},
{
"path": "exchange_calendars/xkrx_holidays.py",
"chars": 36365,
"preview": "import pandas as pd\n\nfrom pandas.tseries.offsets import Day\n\nfrom .pandas_extensions.holiday import Holiday\nfrom .pandas"
},
{
"path": "exchange_calendars/xtks_holidays.py",
"chars": 10349,
"preview": "from datetime import timedelta\n\nfrom dateutil.relativedelta import MO\nfrom pandas import DateOffset, Timestamp\nfrom pand"
},
{
"path": "pyproject.toml",
"chars": 3499,
"preview": "[build-system]\nrequires = [\"setuptools>=77.0.0\", \"wheel\", \"setuptools_scm[toml]>=6.2\"]\nbuild-backend = \"setuptools.build"
},
{
"path": "requirements.txt",
"chars": 861,
"preview": "# This file was autogenerated by uv via the following command:\n# uv export --format requirements-txt --no-emit-projec"
},
{
"path": "ruff.toml",
"chars": 3338,
"preview": "# File as ruff default values except where noted via commented out default value.\n\n# Exclude a variety of commonly ignor"
},
{
"path": "tests/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "tests/resources/24-5.csv",
"chars": 16999,
"preview": ",open,close,break_start,break_end\n2018-01-01T00:00:00Z,2018-01-01T00:00:00Z,2018-01-02T00:00:00Z,,\n2018-01-02T00:00:00Z,"
},
{
"path": "tests/resources/24-7.csv",
"chars": 23824,
"preview": ",open,close,break_start,break_end\n2016-01-01T00:00:00Z,2016-01-01T00:00:00Z,2016-01-02T00:00:00Z,,\n2016-01-02T00:00:00Z,"
},
{
"path": "tests/resources/aixk.csv",
"chars": 113849,
"preview": ",open,close,break_start,break_end\n2017-01-04T00:00:00Z,2017-01-04T05:00:00Z,2017-01-04T11:00:00Z,,\n2017-01-05T00:00:00Z,"
},
{
"path": "tests/resources/asex.csv",
"chars": 496439,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T08:00:00Z,1990-01-02T15:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/bvmf.csv",
"chars": 588609,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T12:00:00Z,1990-01-02T19:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/cmes.csv",
"chars": 461924,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-01T23:00:00Z,1990-01-02T23:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/iepa.csv",
"chars": 461924,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T01:00:00Z,1990-01-02T23:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/test.csv",
"chars": 114134,
"preview": ",open,close,break_start,break_end\n2019-01-01T00:00:00Z,2019-01-01T07:59:00Z,2019-01-01T17:15:00Z,2019-01-01T13:58:00Z,20"
},
{
"path": "tests/resources/xams.csv",
"chars": 492279,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T08:00:00Z,1990-01-02T16:30:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xasx.csv",
"chars": 577884,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-01T23:00:00Z,1990-01-02T05:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xbda.csv",
"chars": 114044,
"preview": ",open,close,break_start,break_end\n2020-01-02T00:00:00Z,2020-01-02T13:00:00Z,2020-01-02T20:30:00Z,,\n2020-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xbel.csv",
"chars": 81219,
"preview": ",open,close,break_start,break_end\n2022-01-04T00:00:00Z,2022-01-04T08:30:00Z,2022-01-04T13:00:00Z,,\n2022-01-05T00:00:00Z,"
},
{
"path": "tests/resources/xbkk.csv",
"chars": 589064,
"preview": ",open,close,break_start,break_end\n1990-01-03T00:00:00Z,1990-01-03T03:00:00Z,1990-01-03T09:30:00Z,,\n1990-01-04T00:00:00Z,"
},
{
"path": "tests/resources/xbog.csv",
"chars": 486819,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T14:30:00Z,1990-01-02T21:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xbom.csv",
"chars": 482269,
"preview": ",open,close,break_start,break_end\n1997-01-01T00:00:00Z,1997-01-01T03:45:00Z,1997-01-01T10:00:00Z,,\n1997-01-02T00:00:00Z,"
},
{
"path": "tests/resources/xbra.csv",
"chars": 97209,
"preview": ",open,close,break_start,break_end\n2020-01-02T00:00:00Z,2020-01-02T10:00:00Z,2020-01-02T14:30:00Z,,\n2020-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xbru.csv",
"chars": 492344,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T08:00:00Z,1990-01-02T16:30:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xbse.csv",
"chars": 560724,
"preview": ",open,close,break_start,break_end\n1990-01-03T00:00:00Z,1990-01-03T08:00:00Z,1990-01-03T15:45:00Z,,\n1990-01-04T00:00:00Z,"
},
{
"path": "tests/resources/xbud.csv",
"chars": 499559,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T08:00:00Z,1990-01-02T16:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xbue.csv",
"chars": 498389,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T13:00:00Z,1990-01-02T19:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xcbf.csv",
"chars": 547139,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T14:30:00Z,1990-01-02T21:15:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xcse.csv",
"chars": 571384,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T08:00:00Z,1990-01-02T16:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xcys.csv",
"chars": 192304,
"preview": ",open,close,break_start,break_end\n2014-01-02T00:00:00Z,2014-01-02T08:30:00Z,2014-01-02T15:00:00Z,,\n2014-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xdub.csv",
"chars": 507099,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T08:00:00Z,1990-01-02T16:28:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xdus.csv",
"chars": 561894,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T07:00:00Z,1990-01-02T21:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xeee.csv",
"chars": 585684,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T07:00:00Z,1990-01-02T17:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xetr.csv",
"chars": 552404,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T08:00:00Z,1990-01-02T16:30:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xeur.csv",
"chars": 82649,
"preview": ",open,close,break_start,break_end\n2026-01-02T00:00:00Z,2026-01-02T07:00:00Z,2026-01-02T21:00:00Z,,\n2026-01-05T00:00:00Z,"
},
{
"path": "tests/resources/xfra.csv",
"chars": 561894,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T08:00:00Z,1990-01-02T16:30:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xham.csv",
"chars": 561894,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T07:00:00Z,1990-01-02T21:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xhel.csv",
"chars": 486559,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T08:00:00Z,1990-01-02T16:30:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xhkg.csv",
"chars": 921989,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T02:00:00Z,1990-01-02T08:00:00Z,1990-01-02T04:00:00Z,19"
},
{
"path": "tests/resources/xice.csv",
"chars": 145764,
"preview": ",open,close,break_start,break_end\n2010-01-04T00:00:00Z,2010-01-04T09:30:00Z,2010-01-04T15:30:00Z,,\n2010-01-05T00:00:00Z,"
},
{
"path": "tests/resources/xidx.csv",
"chars": 578534,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T02:00:00Z,1990-01-02T08:50:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xist.csv",
"chars": 502614,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T08:00:00Z,1990-01-02T16:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xjse.csv",
"chars": 499819,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T07:00:00Z,1990-01-02T15:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xkar.csv",
"chars": 585944,
"preview": ",open,close,break_start,break_end\n1990-01-01T00:00:00Z,1990-01-01T04:32:00Z,1990-01-01T10:30:00Z,,\n1990-01-02T00:00:00Z,"
},
{
"path": "tests/resources/xkls.csv",
"chars": 595889,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T01:00:00Z,1990-01-02T09:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xkrx.csv",
"chars": 862379,
"preview": ",open,close,break_start,break_end\n1986-01-04T00:00:00Z,1986-01-04T02:00:00Z,1986-01-04T06:30:00Z,1986-01-04T03:00:00Z,19"
},
{
"path": "tests/resources/xlim.csv",
"chars": 587179,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T13:00:00Z,1990-01-02T20:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xlis.csv",
"chars": 488119,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T08:00:00Z,1990-01-02T16:30:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xlit.csv",
"chars": 64839,
"preview": ",open,close,break_start,break_end\n2022-01-03T00:00:00Z,2022-01-03T08:00:00Z,2022-01-03T14:00:00Z,,\n2022-01-04T00:00:00Z,"
},
{
"path": "tests/resources/xlju.csv",
"chars": 97339,
"preview": ",open,close,break_start,break_end\n2020-01-03T00:00:00Z,2020-01-03T08:15:00Z,2020-01-03T14:15:00Z,,\n2020-01-06T00:00:00Z,"
},
{
"path": "tests/resources/xlon.csv",
"chars": 553509,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T08:00:00Z,1990-01-02T16:30:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xlux.csv",
"chars": 432609,
"preview": ",open,close,break_start,break_end\n2000-01-03T00:00:00Z,2000-01-03T08:00:00Z,2000-01-03T16:40:00Z,,\n2000-01-04T00:00:00Z,"
},
{
"path": "tests/resources/xmad.csv",
"chars": 592444,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T08:00:00Z,1990-01-02T16:30:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xmex.csv",
"chars": 503979,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T14:30:00Z,1990-01-02T21:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xmil.csv",
"chars": 490784,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T08:00:00Z,1990-01-02T16:30:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xmos.csv",
"chars": 572034,
"preview": ",open,close,break_start,break_end\n1990-01-03T00:00:00Z,1990-01-03T07:00:00Z,1990-01-03T15:45:00Z,,\n1990-01-04T00:00:00Z,"
},
{
"path": "tests/resources/xnys.csv",
"chars": 541094,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T14:30:00Z,1990-01-02T21:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xnze.csv",
"chars": 550909,
"preview": ",open,close,break_start,break_end\n1990-01-03T00:00:00Z,1990-01-02T21:00:00Z,1990-01-03T03:45:00Z,,\n1990-01-04T00:00:00Z,"
},
{
"path": "tests/resources/xosl.csv",
"chars": 486299,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T08:00:00Z,1990-01-02T15:20:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xpar.csv",
"chars": 493059,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T08:00:00Z,1990-01-02T16:30:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xphs.csv",
"chars": 588609,
"preview": ",open,close,break_start,break_end\n1990-01-01T00:00:00Z,1990-01-01T01:30:00Z,1990-01-01T07:30:00Z,,\n1990-01-02T00:00:00Z,"
},
{
"path": "tests/resources/xpra.csv",
"chars": 501184,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T08:00:00Z,1990-01-02T15:20:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xris.csv",
"chars": 64839,
"preview": ",open,close,break_start,break_end\n2022-01-03T00:00:00Z,2022-01-03T08:00:00Z,2022-01-03T14:00:00Z,,\n2022-01-04T00:00:00Z,"
},
{
"path": "tests/resources/xsau.csv",
"chars": 145699,
"preview": ",open,close,break_start,break_end\n2021-01-03T00:00:00Z,2021-01-03T07:00:00Z,2021-01-03T12:00:00Z,,\n2021-01-04T00:00:00Z,"
},
{
"path": "tests/resources/xses.csv",
"chars": 669209,
"preview": ",open,close,break_start,break_end\n1986-01-02T00:00:00Z,1986-01-02T01:00:00Z,1986-01-02T09:00:00Z,,\n1986-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xsgo.csv",
"chars": 584189,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T12:30:00Z,1990-01-02T20:00:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xshg.csv",
"chars": 924979,
"preview": ",open,close,break_start,break_end\n1990-12-03T00:00:00Z,1990-12-03T01:30:00Z,1990-12-03T07:00:00Z,1990-12-03T03:30:00Z,19"
},
{
"path": "tests/resources/xsto.csv",
"chars": 486494,
"preview": ",open,close,break_start,break_end\n1990-01-02T00:00:00Z,1990-01-02T08:00:00Z,1990-01-02T16:30:00Z,,\n1990-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xstu.csv",
"chars": 32989,
"preview": ",open,close,break_start,break_end\n2025-01-02T00:00:00Z,2025-01-02T06:30:00Z,2025-01-02T21:00:00Z,,\n2025-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xswx.csv",
"chars": 485129,
"preview": ",open,close,break_start,break_end\n1990-01-03T00:00:00Z,1990-01-03T08:00:00Z,1990-01-03T16:30:00Z,,\n1990-01-04T00:00:00Z,"
},
{
"path": "tests/resources/xtae.csv",
"chars": 127954,
"preview": ",open,close,break_start,break_end\n2019-01-01T00:00:00Z,2019-01-01T07:59:00Z,2019-01-01T15:15:00Z,,\n2019-01-02T00:00:00Z,"
},
{
"path": "tests/resources/xtai.csv",
"chars": 2044219,
"preview": ",open,close,break_start,break_end\n1911-01-02T00:00:00Z,1911-01-02T01:00:00Z,1911-01-02T05:30:00Z,,\n1911-01-03T00:00:00Z,"
},
{
"path": "tests/resources/xtal.csv",
"chars": 65424,
"preview": ",open,close,break_start,break_end\n2022-01-03T00:00:00Z,2022-01-03T08:00:00Z,2022-01-03T14:00:00Z,,\n2022-01-04T00:00:00Z,"
},
{
"path": "tests/resources/xtks.csv",
"chars": 694399,
"preview": ",open,close,break_start,break_end\n2000-01-04T00:00:00Z,2000-01-04T00:00:00Z,2000-01-04T06:00:00Z,2000-01-04T02:30:00Z,20"
}
]
// ... and 78 more files (download for full content)
About this extraction
This page contains the full source code of the gerrymanoim/exchange_calendars GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 278 files (32.7 MB), approximately 8.6M tokens, and a symbol index with 1460 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.