gs-quant 日期工具:is_business_day交易日判断函数完整指南
【免费下载链接】gs-quantPython toolkit for quantitative finance项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant
本篇技术指南围绕 gs-quant(Python 量化金融工具包)gs_quant.datetime.date模块中的is_business_day函数展开,讲解其函数签名、参数语义、返回规则、底层实现(GsCalendar+ NumPy 工作日历)以及在真实回测与定价流程中的典型用法。读完本文,你将掌握如何借助 gs-quant 快速判断任意日期是否为工作日,并结合节假日日历、自定义周末掩码与批量日期输入,构建符合自身业务规则的交易日历逻辑。
1. 函数概览与签名
is_business_day是 gs-quant 日期处理模块的核心函数之一,定义于 gs_quant/datetime/date.py,其文档由 docs/functions/gs_quant.datetime.date.is_business_day.rst 通过 Sphinxautofunction指令自动生成。
完整签名如下:
def is_business_day( dates: DateOrDates, calendars: Union[str, tuple[str, ...]] = (), week_mask: Optional[str] = None, ) -> Union[bool, tuple[bool, ...]]其中DateOrDates = Union[dt.date, Iterable[dt.date]],即既可以传入单个日期,也可以传入一组可迭代的日期集合。该函数"判断每个日期是否为工作日",其判断标准由两部分叠加而成:默认周末定义(周六、周日)+ 可选节假日日历。
2. 参数语义详解
2.1dates:输入日期
- 支持单个
datetime.date对象,此时返回单个bool; - 支持日期可迭代对象(如列表、元组、NumPy 数组),此时返回与输入顺序一致的
tuple[bool, ...],每个元素对应一个日期的判断结果。
import datetime as dt # 单日期 → bool is_business_day(dt.date.today()) # 多日期 → tuple is_business_day([dt.date(2024, 12, 24), dt.date(2024, 12, 25), dt.date(2024, 12, 26)])2.2calendars:节假日日历
默认值为空元组(),即仅按周末规则判断,不叠加任何节假日。传入日历名称(字符串或字符串元组)后,会在周末判断的基础上进一步剔除节假日。日历名称的来源包括:
- 交易所代码(如
'NYSE'纽交所、'LSE'等),对应Dataset.GS.HOLIDAY数据集; - 货币代码(ISO 4217,如
'USD'、'GBP'),对应Dataset.GS.HOLIDAY_CURRENCY数据集; PricingLocation枚举成员(NYC/LDN/TKO/HKG),其定义位于 gs_quant/target/common.py,代表交易所所在地理区域。
官方文档示例:
>>> import datetime as dt >>> is_business_day(dt.date(2019, 7, 4), calendars=('NYSE',)) False # 2019-07-04 是美国独立日,NYSE 休市一个日期可以同时传入多个日历,例如calendars=('NYSE', 'USD'),只要任一日历将其标记为节假日即视为非工作日。
2.3week_mask:自定义周末掩码
week_mask用于自定义哪些天被视为"周末"。默认值为None,此时使用GsCalendar.DEFAULT_WEEK_MASK = '1111100',即周一至周五为工作日(1),周六、周日为周末(0)。掩码为 7 个字符的字符串,按周一到周日的顺序排列,遵循 NumPybusday系列函数的 weekmask 语法。
# 周一~周五工作日:'1111100' # 周日至周四工作日(如部分中东市场):'0111110' is_business_day(dt.date(2024, 12, 1), week_mask='0111110') # 2024-12-01 为周日3. 返回值规则
- 输入单个日期 → 返回
bool; - 输入日期集合 → 返回
tuple[bool, ...],长度与输入一致; - 工作日定义为:非周末(满足
week_mask)且不在所选日历的节假日列表中的日期。
从源码看,返回逻辑非常简洁:res = np.is_busday(dates, busdaycal=calendar.business_day_calendar(week_mask)),若结果类型为np.ndarray则转换为元组,否则直接返回布尔值。这意味着底层真正执行判断的是 NumPy 的numpy.is_busday,gs-quant 在其之上封装了节假日数据获取与工作日历构建的完整能力。
4. 底层实现:GsCalendar 与 NumPy 工作日历
4.1 调用链
is_business_day(dates, calendars, week_mask) └─ GsCalendar.get(calendars) # 构建日历对象 └─ GsCalendar.business_day_calendar() # 生成 np.busdaycalendar └─ np.is_busday(dates, busdaycal=...) # 逐日期判断核心实现位于 gs_quant/datetime/gscalendar.py:
calendar = GsCalendar.get(calendars) res = np.is_busday(dates, busdaycal=calendar.business_day_calendar(week_mask)) return tuple(res) if isinstance(res, np.ndarray) else res4.2GsCalendar关键属性
DATE_LOW_LIMIT = dt.date(1952, 1, 1)、DATE_HIGH_LIMIT = dt.date(2052, 12, 31):节假日数据查询的时间边界,超出此范围的日期不会获得节假日数据(数据源本身覆盖此区间)。DEFAULT_WEEK_MASK = '1111100':默认周末掩码。holidays属性:将传入的日历拆分为"货币"与"交易所"两类,分别从Dataset.GS.HOLIDAY(按exchange字段查询)与Dataset.GS.HOLIDAY_CURRENCY(按currency字段查询)两个数据集拉取休市日并取并集,两个数据集的枚举定义见 gs_quant/data/dataset.py。- 两级缓存:节假日列表使用
TTLCache(maxsize=128, ttl=600)(10 分钟)缓存,数据集覆盖信息使用TTLCache(maxsize=128, ttl=3600)(1 小时)缓存,重复调用不会反复请求数据服务。 skip_valid_check:默认True,当传入无效日历名称时会输出Ignoring invalid calendar {item}. This will throw in future versions of gs-quant.警告而非报错;传入False则直接抛出ValueError。business_day_calendar(week_mask):按week_mask键惰性构建并缓存numpy.busdaycalendar,将节假日列表转换为np.datetime64数组作为holidays参数。
4.3 货币与交易所的分类识别
GsCalendar.is_currency()用于区分传入项属于货币还是交易所:Currency枚举成员或可转换为 ISO 4217 货币代码的字符串被归为货币类,否则视为交易所。PricingLocation与Currency枚举均定义于 gs_quant/target/common.py(Currency见 L665,PricingLocation见 L4356)。
5. 实战示例
5.1 基本用法
import datetime as dt from gs_quant.datetime.date import is_business_day # 今天是否为工作日(默认周六、周日休市) is_business_day(dt.date.today()) # 指定日期是否为 NYSE 工作日(含节假日判断) is_business_day(dt.date(2019, 7, 4), calendars=('NYSE',)) # 独立日 → False # 批量判断 dates = [dt.date(2024, 12, 25), dt.date(2024, 12, 26)] is_business_day(dates, calendars=('NYSE',)) # (False, True) # 圣诞节休市,12 月 26 日开市5.2 结合时区"今天"使用
gs_quant.datetime.date.today(location)可返回指定定价地点(PricingLocation.NYC/LDN/TKO/HKG)的当前日期(gs_quant/datetime/date.py),可与is_business_day组合判断当地是否为交易日:
from gs_quant.common import PricingLocation from gs_quant.datetime.date import today, is_business_day is_business_day(today(PricingLocation.LDN), calendars=('LSE',))5.3 自定义周末:非标准交易周
# 将周日也视为工作日(如部分零售结算场景) is_business_day(dt.date(2024, 12, 1), week_mask='1111110') # 周日 → True6. 在真实业务流程中的应用
6.1 回测引擎中的交易日过滤
is_business_day并非孤立工具,它被 gs-quant 自身的回测引擎直接使用。在 gs_quant/backtests/predefined_asset_engine.py 与(L182)中,引擎根据策略配置的calendars参数过滤非交易日:
if self.calendars is None or self.calendars.lower() == 'weekend' or is_business_day(date, self.calendars): # 仅在交易日执行策略逻辑这说明calendars=None或'weekend'表示"仅按周末过滤",而传入交易所代码后则叠加节假日。相关测试 gs_quant/test/backtest/test_backtest_predefined.py 也通过 mockis_business_day来控制回测行为,验证了其在流程中的关键地位。
6.2 测试覆盖
仓库中的单元测试验证了底层日历行为:
- gs_quant/test/datetime_/test_gscalendar.py 通过 mock 数据验证
GsCalendar支持单一日历(如PricingLocation.NYC)与多元组日历(如(PricingLocation.NYC, PricingLocation.LDN)),并确认holidays属性能正确聚合两个市场的休市日; - 由于
is_business_day委托给np.is_busday,其布尔语义天然与 NumPy 保持一致,批量输入返回元组的行为可直接通过上述示例验证。
7. 与其他日期函数的配套使用
is_business_day属于 gs-quant 日期工具族(全部位于 gs_quant/datetime/date.py),它们共享calendars与week_mask两个参数,语义完全一致,可自由组合:
| 函数 | 作用 |
|---|---|
is_business_day(dates, calendars, week_mask) | 判断日期是否为工作日(本文主题) |
business_day_offset(dates, offsets, roll, calendars, week_mask) | 将日期沿工作日方向偏移 N 天,roll支持'raise'/'forward'/'preceding'等方向 |
business_day_count(begin_dates, end_dates, calendars, week_mask) | 统计两个日期之间的工作日天数 |
prev_business_date(dates, calendars, week_mask) | 返回给定日期前一个工作日(默认当天) |
date_range(begin, end, calendars, week_mask) | 生成一段连续的工作日日期序列 |
例如,判断"从今天起第 5 个工作日是否为工作日":
from gs_quant.datetime.date import business_day_offset, is_business_day target = business_day_offset(dt.date.today(), 5, roll='forward', calendars=('NYSE',)) is_business_day(target, calendars=('NYSE',)) # 恒为 True,偏移结果必然落在工作日business_day_offset与business_day_count同样基于GsCalendar与 NumPybusday系列函数(见 gs_quant/datetime/date.py),因此三者对节假日与周末的处理规则完全一致,适合组合进同一套日历逻辑中。
8. 使用建议与限制
- 网络依赖:传入
calendars后,节假日数据来自 gs-quant 数据服务(Dataset.GS.HOLIDAY/HOLIDAY_CURRENCY),需要有效的 gs-quant 会话配置;仅使用默认周末规则(不传calendars)则完全离线。 - 日期范围:节假日数据仅覆盖 1952-01-01 至 2052-12-31,超出该区间的日期无法获得节假日信息(仍可按周末规则判断)。
- 无效日历:默认
skip_valid_check=True时,无效日历名只产生警告;如需严格校验可显式构造GsCalendar(calendars, skip_valid_check=False)。 - 返回类型:批量输入始终返回元组而非 NumPy 数组,便于直接与 Python 原生逻辑互操作。
- 缓存:节假日数据有 10 分钟 TTL 缓存,长时间运行的任务中如需强制刷新可调用
GsCalendar.reset()清空缓存(见 gs_quant/datetime/gscalendar.py)。
掌握is_business_day及其背后的GsCalendar机制,你就能在 gs-quant 中统一处理"周末 + 节假日"的复合交易日语义,并将其无缝嵌入回测、定价日期推算与交易日历定制等场景。
【免费下载链接】gs-quantPython toolkit for quantitative finance项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考