Meeting schedules
This page lists what you need to read a central bank's meeting schedule, see which windows it lets you quote, and pin a decision the library doesn't ship. A meeting schedule lists a bank's decision days and the day each takes effect, which is where the front end of a curve steps.
Quick example
The example reads its quotes from the desk sheets; load them once and it runs as shown. It reads the three shipped schedules, marks a curve from a quote on a 2026 decision, and shows a quote on the last shipped decision being refused. Pinning a later decision so that quote marks a curve is the how-to Pin a meeting schedule.
use chrono::{Datelike, NaiveDate};
use helixio_docs_sheets::SOFR_CLOSE_DATE;
use helixrs::{
BusinessDayConvention, CentralBank, CollateralSpec, MarketContext, MeetingSchedule, QuoteSheet,
calendar,
};
fn date(year: i32, month: u32, day: u32) -> NaiveDate {
NaiveDate::from_ymd_opt(year, month, day).expect("a real calendar date")
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let close = date(SOFR_CLOSE_DATE.0, SOFR_CLOSE_DATE.1, SOFR_CLOSE_DATE.2);
// The library ships two years of decisions for three banks, 2026 and 2027. Each
// decision's effective date follows from its bank's rule.
let mut seeded = Vec::new();
for bank in [CentralBank::Fed, CentralBank::Ecb, CentralBank::Boe] {
let schedule = MeetingSchedule::seeded(bank.clone()).expect("a seeded bank");
let (decisions, effective) = (schedule.decisions(), schedule.effective_dates());
println!(
"{} {} decisions, {} to {}, last effective {}",
bank.code(),
decisions.len(),
decisions[0],
decisions[decisions.len() - 1],
effective[effective.len() - 1]
);
seeded.push((bank, schedule));
}
// A meeting swap covers the window from one decision's effective date to the
// next's. December 2026's window closes on the first 2027 decision, so a quote
// on it marks a curve; the last seeded decision opens no window, since no later
// decision closes it.
let fed = MeetingSchedule::seeded(CentralBank::Fed).expect("a seeded bank");
let horizon = date(2027, 3, 31);
let knots: Vec<NaiveDate> = fed.between(close, horizon).iter().map(|k| k.date).collect();
println!(
"Fed effective dates after the close {}",
knots.iter().map(NaiveDate::to_string).collect::<Vec<_>>().join(", ")
);
let usd = CollateralSpec::Currency("USD".parse().expect("a currency"));
let december = QuoteSheet::from_rows([
("USD-SOFR-MeetingOIS", "2026-12-09", 0.0380),
("USD-SOFR-OIS", "2Y", 0.0459),
("USD-SOFR-OIS", "5Y", 0.0471),
])
.expect("a well-formed sheet");
let marked = MarketContext::as_of(close).with_recipe_quotes(&usd, &december).expect("a closed window");
let (december_curve, _) = marked.curve(&"discount(USD)".parse().expect("a key")).expect("the USD curve");
let december_pillars = december_curve.parameter_count();
println!("a quote on the 9 December 2026 decision marks a curve with {december_pillars} pillars");
let last = fed.decisions()[fed.decisions().len() - 1];
let spelled = last.to_string();
let sheet = QuoteSheet::from_rows([
("USD-SOFR-MeetingOIS", spelled.as_str(), 0.0360),
("USD-SOFR-OIS", "2Y", 0.0459),
("USD-SOFR-OIS", "5Y", 0.0471),
])
.expect("a well-formed sheet");
let refused = MarketContext::as_of(close)
.with_recipe_quotes(&usd, &sheet)
.expect_err("a window with no closing decision must be refused");
println!("a quote on the last seeded decision, {last}, is refused");
Ok(())
}import datetime as dt
import helixio as hlx
from desk_sheets import SOFR_CLOSE_DATE
dates = hlx.dates
# The library ships two years of decisions for three banks, 2026 and 2027. Each
# decision's effective date follows from its bank's rule.
seeded = {}
for bank in ("FED", "ECB", "BOE"):
schedule = dates.MeetingSchedule.seeded(bank)
decisions, effective = schedule.decisions(), schedule.effective_dates()
seeded[bank] = (decisions, effective)
print(f"{bank} {len(decisions)} decisions, {decisions[0]} to {decisions[-1]}, last effective {effective[-1]}")
# A meeting swap covers the window from one decision's effective date to the
# next's. December 2026's window closes on the first 2027 decision, so a quote
# on it marks a curve; the last seeded decision opens no window, since no later
# decision closes it.
fed = dates.MeetingSchedule.seeded("FED")
knots = dates.meeting_dates("FED", SOFR_CLOSE_DATE, dt.date(2027, 3, 31))
print(f"Fed effective dates after the close {', '.join(d.isoformat() for d in knots)}")
december = {"USD-SOFR-MeetingOIS": {"2026-12-09": 0.0380}, "USD-SOFR-OIS": {"2Y": 0.0459, "5Y": 0.0471}}
marked = hlx.MarketContext(SOFR_CLOSE_DATE).with_recipe_quotes("USD", december)
december_pillars = marked.curve("discount(USD)").parameter_count()
print(f"a quote on the 9 December 2026 decision marks a curve with {december_pillars} pillars")
last = fed.decisions()[-1]
sheet = {"USD-SOFR-MeetingOIS": {last.isoformat(): 0.0360}, "USD-SOFR-OIS": {"2Y": 0.0459, "5Y": 0.0471}}
try:
hlx.MarketContext(SOFR_CLOSE_DATE).with_recipe_quotes("USD", sheet)
refused = None
except ValueError as error:
refused = str(error)
print(f"a quote on the last seeded decision, {last}, is {'refused' if refused else 'accepted'}")FED 16 decisions, 2026-01-28 to 2027-12-08, last effective 2027-12-09
ECB 16 decisions, 2026-01-29 to 2027-12-16, last effective 2027-12-22
BOE 16 decisions, 2026-02-05 to 2027-12-16, last effective 2027-12-16
Fed effective dates after the close 2026-10-29, 2026-12-10, 2027-01-28, 2027-03-18
a quote on the 9 December 2026 decision marks a curve with 3 pillars
a quote on the last seeded decision, 2027-12-08, is refused
How it's priced
With decision days and the bank's rule , the effective dates are , and the meeting windows are
A meeting quote on decision is the average overnight rate over , so it needs . A step curve puts a pillar at each , and its forward is flat across each window. Why markets quote meeting by meeting is covered in [how dates and conventions work.
API
| Symbol | Meaning | Rust | Python |
|---|---|---|---|
| a bank's decisions | MeetingSchedule::seeded, MeetingSchedule::new |
dates.MeetingSchedule.seeded, dates.MeetingSchedule |
|
| the effective dates | MeetingSchedule::effective_dates |
MeetingSchedule.effective_dates |
|
| in a range | the knots a curve pillars on | MeetingSchedule::between |
dates.meeting_dates |
| a pinned schedule | the schedule a market resolves against | MarketContext::with_meetings |
MarketContext.with_meetings |
| Argument | Type | Default | Meaning |
|---|---|---|---|
bank |
str | required | "FED", "ECB" or "BOE", for seeded, MeetingSchedule and meeting_dates; Rust takes a CentralBank |
decisions |
list of dates | required | MeetingSchedule(bank, decisions): the decision days, from which the effective dates follow |
start, end |
date | required | meeting_dates: the range, inclusive |
schedule |
MeetingSchedule or None |
None |
meeting_dates: read from this schedule instead of the shipped one |
schedule |
MeetingSchedule |
required | MarketContext.with_meetings: the schedule the market uses |
Defaults and limits
- Shipped schedules: the library ships two years of decisions for the Fed, the ECB and the Bank of England, 2026 and 2027. The Fed's 2027 dates are its published calendar, each tentative until the meeting before it confirms it.
- Effective dates: the Fed's take effect the next business day, the ECB's the following Wednesday, the Bank of England's on the decision day itself.
- The last window needs a later decision: a quote on the last shipped decision is refused, naming the decision, because no later decision closes its window. Pin a schedule with a later decision to quote it; see Pin a meeting schedule.
- A pinned schedule moves no value: two markets that differ only in their pinned schedule still compare equal.
!!! warning "A pinned decision is your assumption" A decision you add after the shipped ones is a desk's assumption, not a published date. Replace it with the bank's schedule when it's published.
See also
- Source:
crates/helixrs/src/statics/meetings.rs - Related pages:
- How dates and conventions work, for why the front end is quoted meeting by meeting.
- Pin a meeting schedule, the task step by step.
- Curve helpers, for meeting and turn rungs.
- Step curves, for the curve a schedule knots.
From the 0.0 line at revision bf7f2e2. Every printed number is that revision's own output.