A comprehensive Python package providing China stock exchange holiday data for both Shanghai/Shenzhen (SHSZ) and Hong Kong (HKEX) markets. This package serves as a reliable data source and utility library for financial applications that need to determine trading days.
- Dual Market Support: Covers both mainland China and Hong Kong markets
- Multiple Data Sources: Local files, cached data, and remote fetching
- Zipline Integration: Provides exchange calendars for algorithmic trading
- CLI Tools: Command-line utilities for data extraction
- Caching Mechanism: LRU cache for performance optimization
- Comprehensive API: Functions for trading day calculations
cn_stock_holidays/data.txt
cn_stock_holidays/data_hk.txt
# Shanghai/Shenzhen data
wget https://raw.githubusercontent.com/rainx/cn_stock_holidays/main/cn_stock_holidays/data.txt
# Or using curl
curl https://raw.githubusercontent.com/rainx/cn_stock_holidays/main/cn_stock_holidays/data.txtThe data files store all holidays for China stock exchanges (excluding regular weekend closures on Saturday and Sunday), with one date per line in the format:
YYYYMMDD
Hong Kong market data supports both regular holidays and half-day trading days. The format is:
YYYYMMDD # Regular holiday
YYYYMMDD,h # Half-day trading day
Half-day trading days are days when the market is open for only part of the day (typically morning session only). Common half-day trading days in Hong Kong include:
- Christmas Eve (December 24)
- New Year's Eve (December 31)
- Lunar New Year's Eve
- Day before major holidays (Qingming Festival, National Day)
Important: Half-day trading days are still considered trading days by all standard functions (is_trading_day(), next_trading_day(), etc.). Use is_half_day_trading_day() to specifically detect half-day trading days.
This project supports uv, a fast Python package installer:
# Install uv first
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install the package
uv pip install cn-stock-holidayspip install cn-stock-holidaysgit clone https://github.com/rainx/cn_stock_holidays.git
cd cn_stock_holidays
uv sync --dev # Install with uv
# or
pip install -e . # Install with pip# For Shanghai/Shenzhen market
import cn_stock_holidays.data as shsz
# For Hong Kong market
import cn_stock_holidays.data_hk as hkex# Get holiday data
holidays = shsz.get_cached() # Get from cache or local file
holidays = shsz.get_local() # Read from package data file
holidays = shsz.get_remote_and_cache() # Fetch from network and cache
# Trading day operations
is_trading = shsz.is_trading_day(date) # Check if date is a trading day
prev_day = shsz.previous_trading_day(date) # Get previous trading day
next_day = shsz.next_trading_day(date) # Get next trading day
# Get trading days in range
for trading_day in shsz.trading_days_between(start_date, end_date):
print(trading_day)
# Data synchronization
shsz.sync_data() # Sync data if expired
shsz.check_expired() # Check if data needs update# Import Hong Kong market functions
import cn_stock_holidays.data_hk as hkex
# Standard trading day functions (same as Shanghai/Shenzhen)
is_trading = hkex.is_trading_day(date)
prev_day = hkex.previous_trading_day(date)
next_day = hkex.next_trading_day(date)
# Half-day trading detection (Hong Kong market only)
is_half_day = hkex.is_half_day_trading_day(date) # Check if date is a half-day trading day
# Get data with half-day trading support
holidays, half_days = hkex.get_cached_with_half_day() # Returns (holidays_set, half_days_set)
# Data synchronization with half-day support
hkex.sync_data_with_half_day() # Sync data if expired
hkex.check_expired_with_half_day() # Check if data needs updateHelp on module cn_stock_holidays.data:
FUNCTIONS
check_expired()
Check if local or cached data needs update
:return: True/False
get_cached()
Get from cache version, if not existing, use txt file in package data
:return: A set/list contains all holiday data, elements with datetime.date format
get_local()
Read data from package data file
:return: A list contains all holiday data, elements with datetime.date format
get_remote_and_cache()
Get newest data file from network and cache on local machine
:return: A list contains all holiday data, elements with datetime.date format
is_trading_day(dt)
:param dt: datetime.datetime or datetime.date
:return: True if trading day, False otherwise
next_trading_day(dt)
:param dt: datetime.datetime or datetime.date
:return: Next trading day as datetime.date
previous_trading_day(dt)
:param dt: datetime.datetime or datetime.date
:return: Previous trading day as datetime.date
sync_data()
Synchronize data if expired
trading_days_between(start, end)
:param start, end: Start and end time, datetime.datetime or datetime.date
:return: A generator for available trading dates in Chinese marketFrom version 0.10 onwards, we use functools.lru_cache on get_cached for better performance. If needed, you can clear the cache using:
get_cached.cache_clear()# Sync Shanghai/Shenzhen data
cn-stock-holiday-sync
# Sync Hong Kong data
cn-stock-holiday-sync-hk# Get trading days between dates
get-day-list --start 2024-01-01 --end 2024-01-31 --daytype workday
# Get holidays between dates
get-day-list --start 2024-01-01 --end 2024-01-31 --daytype holiday
# For Hong Kong market
get-day-list --market hk --start 2024-01-01 --end 2024-01-31 --daytype workdayThe package includes scripts to check data expiration and fetch updates from the web. You can set up automatic updates using cron:
# Daily sync at midnight
0 0 * * * /usr/local/bin/cn-stock-holiday-sync > /tmp/cn_stock_holiday_sync.logFind the absolute path of sync commands:
# Shanghai/Shenzhen
which cn-stock-holiday-sync
# Hong Kong
which cn-stock-holiday-sync-hkFor algorithmic trading with Zipline:
from cn_stock_holidays.zipline import SHSZExchangeCalendar, HKExchangeCalendar
# Use in Zipline
calendar = SHSZExchangeCalendar() # Shanghai/Shenzhen
calendar = HKExchangeCalendar() # Hong Kong# Clone and setup
git clone https://github.com/rainx/cn_stock_holidays.git
cd cn_stock_holidays
# Install with uv (recommended)
uv sync --dev
# Or with pip
pip install -e .[dev]# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=cn_stock_holidays
# Format code
uv run black .
# Type checking
uv run mypy cn_stock_holidays/This project uses PyPI Trusted Publisher for secure automated publishing. The CI workflow automatically publishes to PyPI when a new tag is pushed.
To publish a new version:
- Update version in
pyproject.toml - Create and push a new tag:
git tag v2.0.1 git push origin v2.0.1
- The CI workflow will automatically test, build, and publish to PyPI
Security Benefits:
- No need to manage long-lived API tokens
- Short-lived authentication tokens (15 minutes)
- Repository-specific permissions
- Automated OIDC authentication
See Trusted Publisher Setup for detailed configuration instructions.
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests and ensure code quality
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.