Summary
Create a new documentation track for NumPy-backed, reproducible examples inspired by the real-world workflows in wilsonfreitas/brazilian-securities-lectures.
The external repository is an excellent source of realistic financial workflows, but it uses the legacy bizdays API style. The goal here is not to port those notebooks verbatim. Instead, we should extract the strongest use cases, adapt them to the current NumPy-backed public API, and turn them into a first-class examples section in this repository's documentation.
This should become the canonical place where users learn how to apply bizdays to real financial problems such as curve construction, maturity adjustment, contract settlement rules, and bond cash-flow scheduling.
Relationship to existing docs work
This issue is related to the broader documentation update in #59, but it is focused specifically on the examples strategy, example design, API adaptation, and reproducible datasets needed for a high-quality examples section.
Why this matters
The external lectures repository shows that bizdays is not only a calendar utility. In practice it is used as infrastructure for:
- maturity normalization
- business-day counting under market conventions
- mixed DU/DC workflows
- contract-specific settlement rules
- interpolation grids for yield curves
- bond and debenture cash-flow scheduling
- event-driven analysis over business-day sequences
That makes it ideal source material for a robust examples section. However, the current code in that repository reflects the legacy API style and notebook-era assumptions. If we copy it directly into the docs, we will document the wrong interface and carry over patterns that no longer represent the current package design.
Key decision
The new examples section must target the current NumPy-backed API only.
That means:
- examples should use the current top-level
bizdays.Calendar
- examples should prefer the vectorized behavior already built into the NumPy-backed methods
- examples should avoid teaching legacy
.vec usage as the primary path
- examples should use the current
Calendar.load calling convention
- examples should explain NumPy / pandas return shapes where relevant
- examples should be reproducible without depending on live external services
Findings from the external repository
Source repository evaluated:
wilsonfreitas/brazilian-securities-lectures
Main source files/notebooks inspected:
myfuncs.py
Brazilian Securities 1.ipynb
Brazilian Securities 2.ipynb
Brazilian Securities 3.ipynb
Brazilian Securities 4.ipynb
Compute historical COPOM chances estimates.ipynb
Estimate Nelson-Siegel-Svensson Coeficients using Government Bonds.ipynb
data/*.parquet
Distinct bizdays use cases identified
-
Basic business-day counting
- Compare market calendars and actual-day calendars
- Example shape in lectures:
Calendar(name='actual')
Calendar.load('ANBIMA.cal')
cal.bizdays(start, end)
- Documentation value: excellent beginner material
-
Settlement-date adjustment to the next business day
- Used repeatedly to normalize futures maturities and cash-flow dates
- Example shape in lectures:
series.map(cal.following)
cal.vec.adjust_next(...)
- Documentation value: essential
-
Vectorized business-day counting in pandas workflows
- Used throughout DataFrame-based pricing pipelines
- Example shape in lectures:
list(cal.vec.bizdays(df['DataRef'], df['Maturity']))
- Documentation value: essential
-
Curve construction from futures contracts
- Core pattern: adjust maturity -> count DU -> derive rate -> build interpolation grid
- Example shape in lectures:
- DI1 curve construction
cal.offset(refdate, 1) for first node
cal.vec.offset(refdate, tenors) for interpolation grid
- Documentation value: extremely high
-
Contract-specific maturity rules using getdate
- Used for contracts whose maturity is not a trivial calendar date
- Example shape in lectures:
cal.getdate('first wed before 15th day', year, month)
cal.getdate('first wed after 15th day', year, month)
cal.getdate('last bizday', year, month)
cal.getdate('15th day', year, month)
- Documentation value: high, especially for advanced examples
-
Two-calendar workflows (DU vs DC)
- ANBIMA calendar for business days / 252-day convention
actual calendar for calendar-day / 360-day convention
- Appears in DDI / DOL / FRC workflows
- Documentation value: very high, because it explains why market conventions matter
-
Bond and debenture cash-flow scheduling
- Coupon/fixing dates adjusted to business days
- Discounting performed on DU
- Documentation value: very high
-
Business-day sequences over historical periods
- Example shape in lectures:
MARKET_CALENDAR.seq('2021-09-01', '2021-11-01')
- Used to iterate over all business days in a historical analysis window
- Documentation value: strong advanced example
-
Event horizon counting
- Business days until next COPOM meeting
- Documentation value: good macro/event-driven example
Strongest examples to adapt for this repository
These are the best candidates for the future examples section, ordered roughly from foundational to advanced:
-
Load a calendar and count business days
- Compare
ANBIMA and actual
- Explain 252-day vs actual-day conventions
-
Adjust maturities in a pandas DataFrame
- Normalize a column of contract dates to the next business day
- Then compute DU to each maturity
-
Build a DI curve from futures data
- This is the strongest end-to-end workflow in the lecture material
- Covers settlement adjustment, DU, rate derivation, and interpolation-ready outputs
-
Use two calendars in the same pricing workflow
- Show why one instrument may require business-day counting while another leg uses actual days
-
Resolve contract maturity rules with getdate
- Especially the IND example (Wednesday around the 15th)
- Also BGI and CCM monthly rules
-
Generate interpolation nodes with business-day offsets
- Use business-day tenors and map them to actual maturity dates
-
Schedule and discount bond/debenture cash flows
- Adjust coupon dates and compute DU to each future payment
-
Iterate over business days in a historical window
- Use
seq for event-driven analysis (e.g. COPOM window)
Required adaptation: legacy-style examples -> NumPy-backed examples
The lecture repository is valuable for use cases, but many of its code shapes should not be copied as-is.
1. Calendar loading
Legacy lecture style:
bizdays.Calendar.load('ANBIMA.cal')
NumPy-backed docs should use:
Calendar.load(name='ANBIMA')
Calendar.load(name='B3')
Calendar.load(name='Actual')
Calendar.load(filename='path/to/calendar.json') for custom files
Notes:
- use the current keyword-only API
- do not teach
.cal packaged-calendar loading as the primary path
- document packaged JSON-backed calendars and provider prefixes separately
2. Replace .vec.* as the primary teaching path
Legacy lecture style:
cal.vec.bizdays(...)
cal.vec.adjust_next(...)
cal.vec.offset(...)
NumPy-backed docs should prefer:
cal.bizdays(...)
cal.adjust_next(...) / cal.following(...)
cal.offset(...)
The NumPy-backed Calendar already accepts scalar and sequence inputs. The examples section should teach that directly.
Good pandas-facing shapes to document explicitly:
maturity = pd.to_datetime(cal.following(df['Vencimento']))
du = cal.bizdays(df['DataRef'], maturity)
curve_dates = pd.to_datetime(cal.offset(refdate, tenors))
3. Return-shape adaptation for pandas examples
The new examples should explain that the NumPy-backed API returns NumPy arrays / numpy.datetime64 values for vectorized calls.
That means pandas examples may need explicit adaptation such as:
pd.to_datetime(...) when assigning date arrays back into a DataFrame
np.asarray(...) when users want plain numeric arrays
- avoiding unnecessary
list(...) wrappers inherited from the legacy generator-based API
This is important because a straight copy of legacy notebook code may still “work” in places, but it will hide the intended idioms of the new API.
4. Prefer direct array operations over row-wise .apply(...) where possible
The lecture repo uses row-wise DataFrame.apply(...) in several places because that was a natural fit for the legacy API and notebook prototyping.
For the NumPy-backed examples, prefer:
- column-wise operations
- direct vectorized calls
- precomputed arrays of years/months only when required by
getdate
Row-wise .apply(...) may still be acceptable for some getdate-driven rule examples, but it should not dominate the examples section.
5. Clarify aliases and naming
The examples should explain when these names are equivalent:
following() == adjust_next()
preceding() == adjust_previous()
The lecture material heavily uses following() and adjust_next(). The docs should choose a consistent primary style and note the alias.
Proposed examples structure for the docs
Tier 1 - Foundations
-
Count business days with built-in calendars
ANBIMA vs Actual
- scalar and pandas examples
-
Adjust dates to the next business day
- single date and Series examples
- explain
following / adjust_next
-
Offset dates by business days
- T+1, T+2, and a small tenor grid
Tier 2 - Pandas workflows
-
Compute DU for a contracts DataFrame
- assign normalized maturity dates
- compute DU column
-
Generate a curve date grid from business-day tenors
- use
offset on a vector of tenors
- convert back to pandas-friendly dates
-
Use two calendars in one workflow
ANBIMA and Actual
- show mixed DU/DC conventions clearly
Tier 3 - Market-rule examples
-
Model DI futures settlement and term structure inputs
- realistic but compact example derived from lecture patterns
-
Resolve special maturities with getdate
- IND: Wednesday around the 15th
- BGI: last business day of month
- CCM: 15th day rule
-
Iterate over business days in a historical window
seq for event-driven analysis
Tier 4 - Fixed-income workflows
-
Build coupon/fixing schedules on business days
- adjust coupon dates
- compute DU to payments
-
Price a simple fixed-rate bond or debenture cash-flow stream
- keep it small and reproducible
- use business-day discounting explicitly
Data reproducibility: do we need bundled data?
Short answer
Yes for the stronger market examples; no for the foundational examples.
No external data required
These examples can and should be fully self-contained:
- basic business-day counting
- adjusting dates with
following / adjust_next
- simple
offset examples
- simple
seq examples
- introductory
getdate examples
- small synthetic bond schedule examples
Data required for realistic market workflows
These examples are much stronger if they use stable fixture data rather than tiny synthetic toy data:
- DI futures curve example
- mixed-calendar contract examples (DDI / DOL / FRC style)
- interpolation-grid example based on real contract tenors
- event-window examples over historical contract snapshots
- richer bond/debenture examples if they depend on real market snapshots
Important constraint
The external lecture repository frequently depends on:
- live HTTP requests
- remote B3 pages
- SGS/BCB series
- notebook globals and helper modules
The docs for this repository should not depend on live services.
Existing upstream data
The lecture repository already contains static Parquet snapshots under data/, including:
data/2021-11-01.parquet
data/2021-11-05.parquet
data/contracts_2020_202111.parquet
data/contracts_202109_202111.parquet
data/contracts_202110_202111.parquet
This is a strong basis for building reproducible example fixtures.
Recommended data strategy for this repository
-
Keep foundational examples fully inline
- no downloads
- no fixtures
- fast to understand
-
Create small curated CSV fixtures for advanced market examples
- derive them from the upstream lecture snapshots
- trim to the minimum columns needed for each example
- keep each fixture purpose-specific and human-readable
-
Prefer CSV over Parquet for documentation fixtures
- easier for users to inspect
- avoids introducing a
pyarrow dependency just to run docs examples
- makes it easier to show example inputs directly in the docs
-
Document provenance clearly
- say that the fixture was derived from
brazilian-securities-lectures
- record the upstream file name / date snapshot
- keep a small script or notebook that regenerates the CSV from upstream data
-
Provide an upstream link for users who want the full dataset
- docs fixtures should stay small
- users can still explore the full lecture repository separately
Suggested fixture candidates
Rather than shipping one large dataset, prefer a few small fixtures such as:
-
di1-contracts-2021-11-01.csv
- enough rows to demonstrate maturity normalization, DU, and DI curve setup
-
mixed-futures-2021-11-01.csv
- enough rows to demonstrate ANBIMA vs Actual conventions
- include examples analogous to DDI / DOL / FRC style workflows
-
copom-window-2021-09-to-2021-11.csv
- enough rows to demonstrate
seq + event horizon counting
-
optionally bond-cashflow-sample.csv
- only if a realistic bond/debenture example is easier to explain from a fixture than from inline synthetic cash flows
Suggested minimum columns per fixture
For contracts-style examples, the docs likely only need a subset of columns such as:
DataRef
Mercadoria
CDVencimento
Vencimento
PUAtual
Potentially also:
For event-window examples, keep only what is strictly necessary.
Implementation notes for the future examples work
- Do not copy lecture notebooks into this repository as-is.
- Extract patterns, simplify them, and rewrite them around the current API.
- Use modern
Calendar.load(name=...) examples throughout.
- Favor array-oriented and pandas-oriented NumPy-backed usage.
- Where a market example would otherwise become too large, split it into:
- a tiny conceptual example
- a richer fixture-backed example
- Keep the examples section executable and deterministic if possible.
- If notebooks are included, they should be aligned with the same examples used in the prose docs.
Acceptance criteria
- Add a dedicated examples section to the documentation.
- Base the example topics on the real workflows identified in
brazilian-securities-lectures.
- Adapt all examples to the current NumPy-backed public API.
- Do not teach legacy
.vec usage as the primary interface in the new examples section.
- Use current
Calendar.load(name=...) / Calendar.load(filename=...) forms.
- Include at least:
- basic calendar counting
- pandas DU workflow
- business-day offsets
getdate-based rule example
- DI-curve-style workflow
- dual-calendar workflow
- business-day-sequence example
- Make advanced examples reproducible from static fixtures rather than live remote calls.
- If fixture data is added, keep it small, versioned, and documented with provenance.
- Clearly explain pandas/NumPy adaptation patterns where the new API differs from legacy notebook code.
Nice-to-have follow-ups
- Add tests or lightweight validation for the examples that are intended to stay current.
- Add a small provenance script that regenerates CSV fixtures from upstream snapshots.
- Cross-link the examples section from the README, docs index, and API reference.
Notes on gaps not covered by the lecture repository
The lecture repository is strong on real financial workflows, but it does not cover several important topics that should still be documented elsewhere:
- creating a
Calendar from scratch
- JSON calendar layout
list_calendars
pandas_market_calendars
preceding / adjust_previous
- custom holiday / weekday configuration
Those should remain part of the broader documentation plan, but this issue is specifically about turning the lecture-derived workflows into a modern, NumPy-backed examples section.
Summary
Create a new documentation track for NumPy-backed, reproducible examples inspired by the real-world workflows in
wilsonfreitas/brazilian-securities-lectures.The external repository is an excellent source of realistic financial workflows, but it uses the legacy bizdays API style. The goal here is not to port those notebooks verbatim. Instead, we should extract the strongest use cases, adapt them to the current NumPy-backed public API, and turn them into a first-class examples section in this repository's documentation.
This should become the canonical place where users learn how to apply
bizdaysto real financial problems such as curve construction, maturity adjustment, contract settlement rules, and bond cash-flow scheduling.Relationship to existing docs work
This issue is related to the broader documentation update in #59, but it is focused specifically on the examples strategy, example design, API adaptation, and reproducible datasets needed for a high-quality examples section.
Why this matters
The external lectures repository shows that
bizdaysis not only a calendar utility. In practice it is used as infrastructure for:That makes it ideal source material for a robust examples section. However, the current code in that repository reflects the legacy API style and notebook-era assumptions. If we copy it directly into the docs, we will document the wrong interface and carry over patterns that no longer represent the current package design.
Key decision
The new examples section must target the current NumPy-backed API only.
That means:
bizdays.Calendar.vecusage as the primary pathCalendar.loadcalling conventionFindings from the external repository
Source repository evaluated:
wilsonfreitas/brazilian-securities-lecturesMain source files/notebooks inspected:
myfuncs.pyBrazilian Securities 1.ipynbBrazilian Securities 2.ipynbBrazilian Securities 3.ipynbBrazilian Securities 4.ipynbCompute historical COPOM chances estimates.ipynbEstimate Nelson-Siegel-Svensson Coeficients using Government Bonds.ipynbdata/*.parquetDistinct bizdays use cases identified
Basic business-day counting
Calendar(name='actual')Calendar.load('ANBIMA.cal')cal.bizdays(start, end)Settlement-date adjustment to the next business day
series.map(cal.following)cal.vec.adjust_next(...)Vectorized business-day counting in pandas workflows
list(cal.vec.bizdays(df['DataRef'], df['Maturity']))Curve construction from futures contracts
cal.offset(refdate, 1)for first nodecal.vec.offset(refdate, tenors)for interpolation gridContract-specific maturity rules using
getdatecal.getdate('first wed before 15th day', year, month)cal.getdate('first wed after 15th day', year, month)cal.getdate('last bizday', year, month)cal.getdate('15th day', year, month)Two-calendar workflows (DU vs DC)
actualcalendar for calendar-day / 360-day conventionBond and debenture cash-flow scheduling
Business-day sequences over historical periods
MARKET_CALENDAR.seq('2021-09-01', '2021-11-01')Event horizon counting
Strongest examples to adapt for this repository
These are the best candidates for the future examples section, ordered roughly from foundational to advanced:
Load a calendar and count business days
ANBIMAandactualAdjust maturities in a pandas DataFrame
Build a DI curve from futures data
Use two calendars in the same pricing workflow
Resolve contract maturity rules with
getdateGenerate interpolation nodes with business-day offsets
Schedule and discount bond/debenture cash flows
Iterate over business days in a historical window
seqfor event-driven analysis (e.g. COPOM window)Required adaptation: legacy-style examples -> NumPy-backed examples
The lecture repository is valuable for use cases, but many of its code shapes should not be copied as-is.
1. Calendar loading
Legacy lecture style:
bizdays.Calendar.load('ANBIMA.cal')NumPy-backed docs should use:
Calendar.load(name='ANBIMA')Calendar.load(name='B3')Calendar.load(name='Actual')Calendar.load(filename='path/to/calendar.json')for custom filesNotes:
.calpackaged-calendar loading as the primary path2. Replace
.vec.*as the primary teaching pathLegacy lecture style:
cal.vec.bizdays(...)cal.vec.adjust_next(...)cal.vec.offset(...)NumPy-backed docs should prefer:
cal.bizdays(...)cal.adjust_next(...)/cal.following(...)cal.offset(...)The NumPy-backed
Calendaralready accepts scalar and sequence inputs. The examples section should teach that directly.Good pandas-facing shapes to document explicitly:
3. Return-shape adaptation for pandas examples
The new examples should explain that the NumPy-backed API returns NumPy arrays /
numpy.datetime64values for vectorized calls.That means pandas examples may need explicit adaptation such as:
pd.to_datetime(...)when assigning date arrays back into a DataFramenp.asarray(...)when users want plain numeric arrayslist(...)wrappers inherited from the legacy generator-based APIThis is important because a straight copy of legacy notebook code may still “work” in places, but it will hide the intended idioms of the new API.
4. Prefer direct array operations over row-wise
.apply(...)where possibleThe lecture repo uses row-wise
DataFrame.apply(...)in several places because that was a natural fit for the legacy API and notebook prototyping.For the NumPy-backed examples, prefer:
getdateRow-wise
.apply(...)may still be acceptable for somegetdate-driven rule examples, but it should not dominate the examples section.5. Clarify aliases and naming
The examples should explain when these names are equivalent:
following()==adjust_next()preceding()==adjust_previous()The lecture material heavily uses
following()andadjust_next(). The docs should choose a consistent primary style and note the alias.Proposed examples structure for the docs
Tier 1 - Foundations
Count business days with built-in calendars
ANBIMAvsActualAdjust dates to the next business day
following/adjust_nextOffset dates by business days
Tier 2 - Pandas workflows
Compute DU for a contracts DataFrame
Generate a curve date grid from business-day tenors
offseton a vector of tenorsUse two calendars in one workflow
ANBIMAandActualTier 3 - Market-rule examples
Model DI futures settlement and term structure inputs
Resolve special maturities with
getdateIterate over business days in a historical window
seqfor event-driven analysisTier 4 - Fixed-income workflows
Build coupon/fixing schedules on business days
Price a simple fixed-rate bond or debenture cash-flow stream
Data reproducibility: do we need bundled data?
Short answer
Yes for the stronger market examples; no for the foundational examples.
No external data required
These examples can and should be fully self-contained:
following/adjust_nextoffsetexamplesseqexamplesgetdateexamplesData required for realistic market workflows
These examples are much stronger if they use stable fixture data rather than tiny synthetic toy data:
Important constraint
The external lecture repository frequently depends on:
The docs for this repository should not depend on live services.
Existing upstream data
The lecture repository already contains static Parquet snapshots under
data/, including:data/2021-11-01.parquetdata/2021-11-05.parquetdata/contracts_2020_202111.parquetdata/contracts_202109_202111.parquetdata/contracts_202110_202111.parquetThis is a strong basis for building reproducible example fixtures.
Recommended data strategy for this repository
Keep foundational examples fully inline
Create small curated CSV fixtures for advanced market examples
Prefer CSV over Parquet for documentation fixtures
pyarrowdependency just to run docs examplesDocument provenance clearly
brazilian-securities-lecturesProvide an upstream link for users who want the full dataset
Suggested fixture candidates
Rather than shipping one large dataset, prefer a few small fixtures such as:
di1-contracts-2021-11-01.csvmixed-futures-2021-11-01.csvcopom-window-2021-09-to-2021-11.csvseq+ event horizon countingoptionally
bond-cashflow-sample.csvSuggested minimum columns per fixture
For contracts-style examples, the docs likely only need a subset of columns such as:
DataRefMercadoriaCDVencimentoVencimentoPUAtualPotentially also:
PUAnteriorVariacaoFor event-window examples, keep only what is strictly necessary.
Implementation notes for the future examples work
Calendar.load(name=...)examples throughout.Acceptance criteria
brazilian-securities-lectures..vecusage as the primary interface in the new examples section.Calendar.load(name=...)/Calendar.load(filename=...)forms.getdate-based rule exampleNice-to-have follow-ups
Notes on gaps not covered by the lecture repository
The lecture repository is strong on real financial workflows, but it does not cover several important topics that should still be documented elsewhere:
Calendarfrom scratchlist_calendarspandas_market_calendarspreceding/adjust_previousThose should remain part of the broader documentation plan, but this issue is specifically about turning the lecture-derived workflows into a modern, NumPy-backed examples section.