gs-quant 工作日统计函数business_day_count完全指南:精确计算两个日期之间的营业日数量
【免费下载链接】gs-quantPython toolkit for quantitative finance项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant
business_day_count是 Goldman Sachs 开源量化工具包 gs-quant 中gs_quant.datetime.date模块的核心日期工具之一,用于统计两个日期(或两组日期)之间的营业日(business day)数量,是金融领域计算工作日、交易日与计息周期的基石函数。本文将结合仓库源码(gs_quant/datetime/date.py)与测试用例,完整解析其参数语义、日历体系、向量化能力与真实应用场景,帮助你直接在量化研究与策略开发中落地使用。
函数签名与返回值语义
business_day_count的定义如下:
def business_day_count( begin_dates: DateOrDates, end_dates: DateOrDates, calendars: Union[str, tuple[str, ...]] = (), week_mask: Optional[str] = None, ) -> Union[int, tuple[int, ...]]:其中DateOrDates = Union[dt.date, Iterable[dt.date]](gs_quant/datetime/date.py)。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
begin_dates | dt.date或日期可迭代对象 | 必填 | 起始日期(可批量传入) |
end_dates | dt.date或日期可迭代对象 | 必填 | 结束日期(可批量传入) |
calendars | str或tuple[str, ...] | () | 用于确定节假日的工作日历,见下文"日历体系" |
week_mask | Optional[str] | None | 自定义"周末"分布,默认以周六、周日为周末 |
返回值:传入单个日期时返回int(营业日数量);传入日期集合时返回tuple[int, ...],每个元素对应一对日期的营业日数量,顺序与输入一致。
核心语义:结束日期是排他性的
该函数底层直接封装numpy.busday_count(gs_quant/datetime/date.py),因此继承 NumPy 的边界语义:
end_dates当天不计入结果,统计的是区间[begin, end)内的营业日数量;- 起始日期自身若为营业日则计入。
例如business_day_count(dt.date(2024, 1, 1), dt.date(2024, 1, 8))统计的是 1 月 1 日(含)到 1 月 8 日(不含)之间按日历过滤后的工作日数。这一点在计算"距到期日还有多少个交易日""过去 N 个交易日的波动率"等场景中需要特别注意,避免重复加一天或少算一天。
开箱即用的最小示例
官方文档给出的典型用法(docs/functions/gs_quant.datetime.date.business_day_count.rst)为:
import datetime as dt today = dt.date.today() bus_days = business_day_count(today, today + dt.timedelta(days=7))更完整的示例:
import datetime as dt from gs_quant.datetime import business_day_count # 单日期对:计算 7 个自然日跨度内的营业日数 business_day_count(dt.date(2024, 1, 1), dt.date(2024, 1, 8)) # 例如输出: 5 (若 1/1 为周一且无节假日) # 指定交易所日历(如纽约证券交易所) business_day_count(dt.date(2019, 7, 1), dt.date(2019, 7, 8), calendars='NYSE') # 向量化:同时计算多组日期对 begin = (dt.date(2024, 1, 1), dt.date(2024, 2, 1)) end = (dt.date(2024, 2, 1), dt.date(2024, 3, 1)) business_day_count(begin, end) # 返回 tuple[int, ...]注意gs_quant.datetime包通过from .date import *导出了该函数(gs_quant/datetime/init.py),因此可以直接from gs_quant.datetime import business_day_count。
日历体系:calendars参数与GsCalendar
business_day_count的日历逻辑完全委托给 GsCalendar:
calendar = GsCalendar.get(calendars) res = np.busday_count(begin_dates, end_dates, busdaycal=calendar.business_day_calendar(week_mask))calendars 支持的取值类型
calendars参数可接受:
- 字符串:如
'NYSE'(纽约证券交易所)、'LSE'、'TSE'等交易所标识; - 字符串元组:如
('NYSE', 'LSE'),表示同时考虑多个交易所的节假日; PricingLocation枚举:如PricingLocation.NYC、PricingLocation.LDN、PricingLocation.HKG、PricingLocation.TKO(gs_quant/common.py 中定义);Currency枚举:如Currency.USD、Currency.GBP,按货币关联的节假日历;- 空元组
()(默认):不叠加任何节假日,只按week_mask过滤周末。
从源码看,GsCalendar构造函数会把字符串/枚举统一包装为元组(gs_quant/datetime/gscalendar.py),并在holidays属性中把输入拆分为"货币"与"交易所"两组,分别从两个数据集拉取节假日(gs_quant/datetime/gscalendar.py):
- 交易所节假日来自
Dataset.GS.HOLIDAY,按exchange字段查询; - 货币节假日来自
Dataset.GS.HOLIDAY_CURRENCY,按currency字段查询; - 两组合并去重后,作为 NumPy
busdaycalendar的holidays传入。
这意味着一旦你指定了真实交易所或货币,business_day_count统计的就是同时剔除周末与官方节假日的真实交易日数量,而不是简单剔除周六日。
日期范围限制与缓存
GsCalendar对节假日数据有明确的时间边界(gs_quant/datetime/gscalendar.py):
DATE_LOW_LIMIT = dt.date(1952, 1, 1) DATE_HIGH_LIMIT = dt.date(2052, 12, 31)即节假日查询覆盖 1952-01-01 至 2052-12-31,超出该范围的日期无法获得完整的节假日数据。另外,节假日结果缓存在 TTL 缓存中(maxsize=128, ttl=600,即 10 分钟过期,gs_quant/datetime/gscalendar.py),重复计算相同日历参数时不会反复请求数据集。
说明:若在未配置
GsSession的环境中使用指定日历(如'NYSE'),底层依赖数据集服务;默认参数calendars=()的纯周末统计则完全本地化,无需联网。
自定义周末:week_mask参数
week_mask用长度为 7 的字符串定义一周中哪些天是工作日,位置对应周一至周日,'1'表示工作日、'0'表示休息日。默认值为'1111100'(周一至周五工作,周六、周日休息),定义于GsCalendar.DEFAULT_WEEK_MASK(gs_quant/datetime/gscalendar.py)。
常见定制:
# 周日至周四工作(中东市场风格) business_day_count(d1, d2, week_mask='0111110') # 仅周一至周五,但把周三视为休息日(极端演示) business_day_count(d1, d2, week_mask='1101101')向量化批量计算
begin_dates与end_dates均支持可迭代对象,底层一次性交给np.busday_count批量求值,返回tuple。这在以下场景极为高效:
# 批量计算一组估值日到各自到期日的剩余交易日 valuation_dates = (dt.date(2024, 3, 1), dt.date(2024, 3, 4), dt.date(2024, 3, 5)) maturity_dates = (dt.date(2024, 6, 1), dt.date(2024, 6, 1), dt.date(2024, 6, 1)) remaining_days = business_day_count(valuation_dates, maturity_dates)批量调用时要求两个集合长度一致、按位置一一对应。返回值始终是tuple(即使只有一个元素),便于后续与 pandas Series 或列表对齐。
仓库内的真实应用:波动率年化换算
仓库内容目录中的 inflation_covid19_recovery_trade.ipynb 展示了business_day_count的一个典型实战用法——把区间波动率按交易日数量换算成年化波动率:
from gs_quant.datetime import business_day_offset, business_day_count vol_3m = infla_vol.iloc[-1] * np.sqrt(business_day_count(back_3m, today))这里business_day_count(back_3m, today)计算出回溯区间内的实际营业日数量,作为波动率年化(sqrt(N)缩放)的指数。这类"用工作日而非自然日做时间度量"的做法,正是该函数在量化研究中最常见的用途——波动率、收益率、周转率等指标的年化分母都应当使用交易日历。
与兄弟函数配合使用
business_day_count属于gs_quant.datetime.date模块中完整的工作日工具族(docs/datetime.rst),四者组合可覆盖绝大多数日期运算:
- is_business_day:判断某日期是否为营业日,同样支持
calendars与week_mask; - business_day_offset:对日期施加营业日偏移并滚动到最近营业日(
roll支持'raise'/'forward'/'preceding'等),常与business_day_count配套使用——先定位日期,再统计天数; - prev_business_date:返回给定日期(默认今天)的前一个营业日;
- date_range:按营业日步长生成日期序列。
一个完整的工作流示例:
import datetime as dt from gs_quant.datetime import business_day_count, business_day_offset # 找到今天之前的第 5 个营业日,再统计这两个点之间的营业日数(即 5) start = business_day_offset(dt.date.today(), -5, roll='preceding') n = business_day_count(start, dt.date.today())边界条件、注意事项与测试验证
排他性边界
再次强调:end_dates当天不计入统计。这是 NumPybusday_count的既定语义,也是最容易踩的坑。若你需要包含结束日当天的"闭区间"计数,请自行+1或把结束日期顺延一天。
输入校验
begin_dates与end_dates必须都是日期或日期集合且长度匹配;calendars传入不存在的日历标识时,GsCalendar.holidays_from_dataset会通过数据集覆盖范围(coverage)做校验(gs_quant/datetime/gscalendar.py):当前版本默认skip_valid_check=True仅记录Ignoring invalid calendar ...警告,未来版本将抛ValueError。因此生产环境应确保日历标识真实有效。
测试佐证
仓库测试目录中gs_quant/test/datetime_/test_gscalendar.py通过 mock 数据集验证了GsCalendar对单一日历(PricingLocation.NYC)与元组日历((NYC, LDN))的节假日加载行为,并展示了节假日数据来源Dataset.get_data的调用方式;同目录 test_date.py 则覆盖了日期模块的其余功能。这些测试可作为你理解日历数据流和自行验证行为的参考。
适用前提与限制小结
- 适用版本与运行环境:以当前仓库代码为准,函数依赖 NumPy 与
gs_quant包内模块,导入前需确保依赖可用; - 日历数据依赖:使用
calendars指定真实交易所/货币时依赖数据集服务与GsSession配置;仅做周末过滤时(默认参数)无需网络; - 时间范围:节假日数据覆盖 1952-01-01 至 2052-12-31,超出范围的日期无法获得完整节假日信息;
- 缓存机制:节假日结果 10 分钟 TTL 缓存,调用
GsCalendar.reset()可主动清空(gs_quant/datetime/gscalendar.py)。
掌握business_day_count的边界语义、日历参数与向量化特性,即可在 gs-quant 中精准度量交易区间、完成波动率年化、计算剩余交易日等高频量化任务;结合business_day_offset、is_business_day等兄弟函数,可以构建完整、可靠的交易日历运算体系。
【免费下载链接】gs-quantPython toolkit for quantitative finance项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考