ORE's AdvanceCalendar Convention Field

Table of Contents

Summary

AdvanceCalendar is a field on ORE's FXConvention (and, by the same pattern, on commodity conventions) used specifically to advance — roll forward — the dates ORE computes for an FX instrument: the spot date from trade date, and the maturity date from spot. It is therefore a fundamentally different kind of calendar from business_day_calendar and settlement_calendar: those answer "is this day a valid business/settlement day," while AdvanceCalendar is consumed directly by date arithmetic (Calendar::advance()), not membership tests. Like every other ORE calendar field, its XML value is a comma-joined list of calendar names under JointCalendar union semantics — in practice almost always the pair's own two legs, but stored and resolved explicitly rather than derived on the fly.

Detail

What it actually does

ORE resolves the spot and maturity dates of an FX instrument by advancing directly off the convention's AdvanceCalendar, not off any generically derived business-day calendar:

// OREAnalytics/orea/engine/parsensitivityinstrumentbuilder.cpp
Date spot = conv->advanceCalendar().advance(today, conv->spotDays() * Days);
Date maturity = conv->advanceCalendar().advance(spot, term);

The same field backs FX option pricing and FX vol curve construction (OREData/ored/portfolio/fxoption.cpp, OREData/ored/marketdata/fxvolcurve.cpp, both assign spotCalendar_ = fxConv->advanceCalendar()), and yield-curve bootstrapping for FX-forward-implied points (OREData/ored/marketdata/yieldcurve.cpp). ORE's own User Guide documents the fallback behaviour for FX forwards explicitly: "For cash settlement and if a FXIndex is specified defaults to the fx convention (field 'AdvanceCalendar') if left blank or omitted, otherwise to NullCalendar (no holidays)" (Docs/UserGuide/tradedata/fxforward.tex).

XML example

From ORE's own example configuration (Examples/MinimalSetup/Input/conventions.xml):

<FXConvention>
  <Id>EUR-GBP-FX</Id>
  <SpotDays>2</SpotDays>
  <SourceCurrency>EUR</SourceCurrency>
  <TargetCurrency>GBP</TargetCurrency>
  <PointsFactor>1</PointsFactor>
  <AdvanceCalendar>TARGET,UK</AdvanceCalendar>
</FXConvention>

Other examples in the same repository show the same comma-joined shape: UK,TARGET, US,JP, UK,US — in every case, exactly the union of the pair's two legs' calendars, joined the same way currency.holiday_calendar is joined today.

Why it is stored explicitly rather than derived

Given that AdvanceCalendar almost always equals the union of the pair's two legs, it might look redundant with a generically computed business_day_calendar. ORE keeps it as an explicit, named convention field rather than a derived value for two reasons evident from its usage:

  • It is resolved once at convention-load time and consumed directly by date-arithmetic methods (advance()), not membership-tested per-date, so eager resolution avoids recomputing a union on every date calculation.
  • It is overridable per convention independently of the pair's two legs — nothing in ORE's schema constrains it to equal exactly SourceCurrency + TargetCurrency's calendars, even though every example configuration happens to set it that way.

Comma-joined, not a single calendar

Because every observed value is a comma-joined list of two or more calendar codes, AdvanceCalendar carries the same many-to-many shape as currency.holiday_calendar: a currency pair convention can need more than one calendar, so a reference-data model of this field is a junction (convention ↔ calendar), not a single nullable foreign key.

See also

Emacs 29.3 (Org mode 9.6.15)