# 02 — Date Sequences, GBD Rules, and RFIS Logic ## Endur Projection Methods Framework --- ## 1. What Is a Date Sequence? A **date sequence** in Endur is a named, ordered list of specific dates that represent meaningful market events — contract expiry dates, publication dates, or physical delivery dates. They are configured in Endur under "Date Sequences" and attached to a deal via the Reset Convention field. Date sequences are **not derivable from calendar arithmetic**. They must be exported from Endur and loaded into the calculation engine. ### Known Date Sequences in This Framework | Sequence Name | Description | Used By | |---|---|---| | `arg_trm` | Argus Term physical delivery dates for oil markets. Last GBD on or before the 25th of the month preceding the delivery month. Not equivalent to standard business-day calendars. | TMA Argus/Platts | | `dmo_one_cme_xxv_minusgbd_three` | CME/NYMEX WTI crude oil futures contract expiry dates. Calculated as: last GBD on or before the 25th of the preceding month, then minus 3 additional GBDs (with holiday adjustments). | TMA Nymex/CME | > **Critical:** The prior-calendar-month GBD approximation is **structurally incorrect** for both TMA methods. > Always use the sequence data below. --- ## 2. arg_trm Date Sequence — Authoritative Data Used by **TMA Argus/Platts**. These dates define the boundaries of Argus pricing periods. | Sequence_Date | DoW | Delivery_Period | |---|---|---| | 12/25/2025 | Thu | Jan-2026 | | 01/23/2026 | Fri | Feb-2026 | | 02/25/2026 | Wed | Mar-2026 | | 03/25/2026 | Wed | Apr-2026 | | 04/24/2026 | Fri | May-2026 | | 05/25/2026 | Mon | Jun-2026 | | 06/25/2026 | Thu | Jul-2026 | | 07/24/2026 | Fri | Aug-2026 | | 08/25/2026 | Tue | Sep-2026 | | 09/25/2026 | Fri | Oct-2026 | | 10/23/2026 | Fri | Nov-2026 | | 11/25/2026 | Wed | Dec-2026 | | 12/25/2026 | Fri | Jan-2027 | | 01/25/2027 | Mon | Feb-2027 | | 02/25/2027 | Thu | Mar-2027 | | 03/25/2027 | Thu | Apr-2027 | | 04/23/2027 | Fri | May-2027 | | 05/25/2027 | Tue | Jun-2027 | | 06/25/2027 | Fri | Jul-2027 | | 07/23/2027 | Fri | Aug-2027 | | 08/25/2027 | Wed | Sep-2027 | | 09/24/2027 | Fri | Oct-2027 | | 10/25/2027 | Mon | Nov-2027 | | 11/25/2027 | Thu | Dec-2027 | | 12/24/2027 | Fri | Jan-2028 | | 01/25/2028 | Wed | Feb-2028 | | 02/25/2028 | Fri | Mar-2028 | | 03/24/2028 | Fri | Apr-2028 | | 04/25/2028 | Tue | May-2028 | | 05/25/2028 | Fri | Jun-2028 | | 06/23/2028 | Fri | Jul-2028 | --- ## 3. dmo_one_cme_xxv_minusgbd_three Date Sequence — Authoritative Data Used by **TMA Nymex/CME**. These dates define the WTI futures expiry boundaries. | Sequence_Date | DoW | Contract_Month | |---|---|---| | 12/19/2025 | Fri | Jan-2026 | | 01/20/2026 | Tue | Feb-2026 | | 02/20/2026 | Fri | Mar-2026 | | 03/20/2026 | Fri | Apr-2026 | | 04/21/2026 | Tue | May-2026 | | 05/19/2026 | Tue | Jun-2026 | | 06/22/2026 | Mon | Jul-2026 | | 07/21/2026 | Tue | Aug-2026 | | 08/20/2026 | Thu | Sep-2026 | | 09/22/2026 | Tue | Oct-2026 | | 10/20/2026 | Tue | Nov-2026 | | 11/20/2026 | Fri | Dec-2026 | | 12/21/2026 | Mon | Jan-2027 | | 01/20/2027 | Wed | Feb-2027 | | 02/22/2027 | Mon | Mar-2027 | | 03/22/2027 | Mon | Apr-2027 | | 04/20/2027 | Tue | May-2027 | | 05/20/2027 | Thu | Jun-2027 | | 06/22/2027 | Tue | Jul-2027 | | 07/20/2027 | Tue | Aug-2027 | | 08/20/2027 | Fri | Sep-2027 | | 09/21/2027 | Tue | Oct-2027 | | 10/20/2027 | Wed | Nov-2027 | | 11/19/2027 | Fri | Dec-2027 | | 12/20/2027 | Mon | Jan-2028 | | 01/20/2028 | Fri | Feb-2028 | | 02/22/2028 | Tue | Mar-2028 | | 03/21/2028 | Tue | Apr-2028 | | 04/20/2028 | Thu | May-2028 | | 05/22/2028 | Wed | Jun-2028 | | 06/20/2028 | Wed | Jul-2028 | | 07/20/2028 | Thu | Aug-2028 | --- ## 4. How TMA Methods Use Date Sequences TMA methods define their pricing window using two sequence look-ups from the BOL date, going back two positions to establish a Pivot_Anchor. ### Calculation Procedure Given BOL Date (TMA methods use No Roll — BOL date is used as-is): 1. Find `currDate` = the smallest sequence date **≥ BOL Date**. - If BOL Date falls exactly on a sequence date → `currDate` = BOL Date itself (stay on same entry). 2. `Pivot_Anchor` = `currDate` −2 entries in the sequence. 3. `Window_Start` = NextGBD(`Pivot_Anchor`) [= `1d>-2seq`] 4. `Window_End` = `Pivot_Anchor` +1 entry [= `1seq`] 5. `Num_Days` = CountGBDs(Window_Start, Window_End) inclusive. 6. Include_Pivot = **Include** — Window_Start is a reset date. ### Worked Example — TMA Nymex/CME, BOL = 03/18/2026 From the dmo_one_cme_xxv_minusgbd_three sequence: - `currDate` = 03/20/2026 (Fri) — smallest CME date > 03/18/2026 - `Pivot_Anchor` = currDate −2 entries: 03/20 → 02/20 → **01/20/2026 (Tue)** - `Window_Start` = NextGBD(01/20/2026) = **01/21/2026 (Wed)** - `Window_End` = 01/20 +1 entry = **02/20/2026 (Fri)** - `Num_Days` = GBDs from 01/21 to 02/20 = **22** (Presidents' Day 02/16 excluded) ### Worked Example — TMA Argus/Platts, BOL = 03/18/2026 From the arg_trm sequence: - `currDate` = 03/25/2026 (Wed) — smallest arg_trm date > 03/18/2026 - `Pivot_Anchor` = currDate −2 entries: 03/25 → 02/25 → **01/23/2026 (Fri)** - `Window_Start` = NextGBD(01/23/2026) = **01/26/2026 (Mon)** - `Window_End` = 01/23 +1 entry = **02/25/2026 (Wed)** - `Num_Days` = GBDs from 01/26 to 02/25 = **22** (Presidents' Day 02/16 excluded) > **Note on BOL falling on a sequence date:** If BOL = 02/25/2026 (an arg_trm boundary), > currDate = **02/25/2026** (BOL itself, since ≥ rule). Pivot_Anchor = 02/25 −2 = 12/25/2025. > Window_Start = NextGBD(12/25/2025) = 12/26/2025 Fri. Window_End = 12/25 +1 = 01/23/2026 Fri. > Num_Days = 19 GBDs (12/26/2025–01/23/2026; excl. New Year's 01/01 and MLK Day 01/19). --- ## 5. Good Business Day (GBD) Rules ### 5.1 Definition A date is a **Good Business Day (GBD)** if: - It is a **weekday** (Monday–Friday), **AND** - It is **not** in the holiday list (bank holidays and exchange closures). ### 5.2 GBD Arithmetic Functions | Function | Definition | |---|---| | `NextGBD(date)` | The first GBD strictly after `date`. | | `PrevGBD(date)` | The first GBD strictly before `date`. | | `AddGBDs(date, n)` | Move forward (n > 0) or backward (n < 0) exactly n GBDs from `date`. | | `CountGBDs(start, end)` | Count of GBDs from `start` to `end` inclusive. | | `IsGBD(date)` | Returns True if `date` is a Good Business Day. | --- ## 6. Non-GBD Roll Rules When the BOL Date falls on a weekend or bank holiday, the Non-GBD Roll Rule determines the effective anchor before the Pivot Date Offset is applied. ### 6.1 Roll Rule Reference Table | Rule Value | Convention | When BOL = Saturday | |---|---|---| | `+SatSunHol` | Following | → Monday | | `-SatSunHol` | Preceding | → Friday | | `-Sat+Sun+MonHol-Hol` | Token-based (see 6.2) | → **Friday** (−Sat token = backward) | | `No Roll` | None | Stays as Saturday | ### 6.2 Token-Based Evaluation: `-Sat+Sun+MonHol-Hol` Tokens evaluated left-to-right; **first match wins**; evaluation stops immediately. | Day Type | Token | Direction | Result | |---|---|---|---| | Saturday | `−Sat` | Backward | → Friday | | Sunday | `+Sun` | Forward | → Monday | | Monday that is a holiday | `+MonHol` | Forward | → Tuesday (or next GBD) | | Any other holiday | `−Hol` | Backward | → previous GBD | **Examples:** - BOL = Saturday 03/28/2026 → `−Sat` → **Friday 03/27/2026** - BOL = Sunday 03/29/2026 → `+Sun` → **Monday 03/30/2026** - BOL = Monday 01/19/2026 (MLK Day) → `+MonHol` → **Tuesday 01/20/2026** - BOL = Friday 04/03/2026 (Good Friday) → `−Hol` → **Thursday 04/02/2026** > ⚠️ **Saturday rolls BACKWARD (not forward) under this rule.** The `−Sat` token is the first > to match and directs a backward roll to Friday. ### 6.3 Window Boundary Calculation Sequence ``` 1. Effective_BOL = RollNonGBD(BOL_Date, Non_GBD_Roll_Rule) 2. Pivot_Date = Effective_BOL + Pivot_Date_Offset (symbolic or numeric) 3. Window_Start = Pivot_Date + Before_Pivot_Offset [then roll if non-GBD: Before_Offset_Roll = Before] 4. Window_End = Pivot_Date + After_Pivot_Offset [then roll if non-GBD: After_Offset_Roll = After] 5. Enumerate reset dates in [Window_Start, Window_End] using Reset_Sym_Date step 6. If Include_Pivot = Exclude → remove Pivot_Date from reset list 7. Num_Days = count of remaining reset dates ``` --- ## 7. Symbolic Date References | Symbol | Resolves To | |---|---| | `1lom` | Last calendar day of the Pivot's month (e.g. 03/31, 02/28). May be non-GBD → rolls to last GBD. | | `-1lom` | Last calendar day of the month **before** the Pivot's month. | | `-2lom` | Last calendar day two months before the Pivot's month. | | `1d>-1lom` | 1 GBD after last of prior month = **first GBD of current month**. | | `1cd>-1lom` | 1 calendar day after last of prior month = **first calendar day of current month** (may be Sat/Sun). | | `1d>-2lom` | 1 GBD after last of two months ago = **first GBD of prior month**. | | `1cd>-2lom` | 1 calendar day after last of two months ago = **first calendar day of prior month**. | | `0monday` | Monday of the week containing the BOL date. | | `-1monday` | Monday of the **week before** the BOL date's week. | | `1low` | Friday of the Pivot's week. | | `1d>-2arg_trm` | First GBD after the second-previous arg_trm date = Pivot start for TMA Argus. | | `-1arg_trm` | The previous arg_trm date = Window_End for TMA Argus. | | `1d>-2dmo_one_cme_xxv_minusgbd_three` | First GBD after the second-previous CME date = Pivot start for TMA CME. | | `-1dmo_one_cme_xxv_minusgbd_three` | The previous CME date = Window_End for TMA CME. | --- ## 8. RFIS and RFIE: Contract Expiration Dates > **Critical definition:** RFIS and RFIE are **contract expiration dates**, not "Rate Fixing > Interest" dates. They represent the expiry of the pricing index contract associated with a deal. ### 8.1 How RFIS Is Determined 1. **Reset Roll Convention** — attaches a named date sequence to the deal. 2. **Nearby** — selects which entry in that sequence becomes the RFIS date. | Nearby Value | RFIS Date | |---|---| | `0` | RFIS = the reset date itself | | `1` | RFIS = the first (prompt) expiry in the date sequence | | `2` | RFIS = the second expiry in the sequence | | `N` | RFIS = the Nth expiry | ### 8.2 RFI_Shift ``` RFIS_final = AddGBDs(RFIS_resolved, RFI_Shift) ``` Standard: `RFI_Shift = 0` (no shift). ### 8.3 RFIS vs Pricing Window RFIS/RFIE define the **contract period** (which contract month is being priced). The pricing window (Window_Start to Window_End) is separate — it defines the set of daily reset dates over which prices are averaged. --- ## 9. Holiday Calendar The GBD engine requires a holiday list populated with actual bank and exchange closure dates. **US Holiday Calendar (applied to all test cases):** | Date | DoW | Holiday | |---|---|---| | 01/01/2026 | Thu | New Year's Day | | 01/19/2026 | Mon | Martin Luther King Jr. Day | | 02/16/2026 | Mon | Presidents' Day | | 04/03/2026 | Fri | Good Friday | | 05/25/2026 | Mon | Memorial Day | | 07/03/2026 | Fri | Independence Day (observed) | | 09/07/2026 | Mon | Labor Day | | 11/26/2026 | Thu | Thanksgiving Day | | 12/25/2026 | Fri | Christmas Day | Good Friday is treated as a non-GBD for commodity pricing (observed by NYMEX/ICE/Argus). --- *Source: Endur system documentation, ArgTRM_Dates.xlsx, CME_Dates.xlsx, user domain knowledge*