Task: Carry the FlexiSwap and BalanceGuaranteedSwap fields
Table of Contents
This page documents a task in the Rework the rates instruments to the instrument table rule story. It captures the goal, current status, acceptance, and any notes or results.
1. Goal
FlexiSwap and BalanceGuaranteedSwap trades import, store and export every element the ORE schema requires, so both leave the known export gaps.
2. Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Rework the rates instruments to the instrument table rule |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-10-10 |
3. Acceptance
- FlexiSwap stores OptionLongShort and its lower notional bounds, and the export writes them.
- BalanceGuaranteedSwap stores ReferenceSecurity, its tranches with their notionals, and the tranche schedule, and the export writes them.
- Both products re-read after export, and neither appears in the corpus gate's known export gaps.
- The inbox capture for this work is removed.
4. Plan
- Name what the schema requires.
flexiSwapDatarequiresOptionLongShortand the lower notional bounds.bgSwapDatarequiresReferenceSecurityandTranches, and aTranchesblock holds tranches (description, security id, seniority, dated notionals) and a schedule. - Model each as the family's pattern. A product's own scalar goes on its
fact table; a list goes in a child table keyed by the trade and the
ordinal, as
callable_swap_call_dateis. A schedule goes in the sharedinstrument_schedulerows under a new owner role, so no schedule table is repeated.flexi_swap_instrumentis a new fact table, because a flexi swap stored avanilla_swap_instrumentrow with no fields of its own.flexi_swap_lower_notionalholds one notional per row, with its block ordinal and currency.balance_guaranteed_swap_instrumentgainsreference_security.balance_guaranteed_swap_trancheandbalance_guaranteed_swap_tranche_notionalhold the tranches.instrument_scheduleaccepts the owner roletranches.
- Wire them. Generate the stacks, add them to the header's delete cascade and the catalogue's child list, seed the permissions, register the handlers, extend the carrier, the batch mapper, the export read and the import write.
- Map both ways. Forward and reverse mappers in the ORE mapper, the exporter dispatch, and round-trip cases with literal values.
5. Measurements
Every number this task claims about a tree, with the command that produced it
and the commit it was measured at. A number without both is not a measurement,
because a clean-up record describes a tree and trunk moves under a branch: a
consumer count, a gate's component count and a suite's size all change with no
code changing, and the reader of a bare number cannot tell which tree it came
from. Where the raw output matters, put it in an evidence/ file beside the
task and name that file in the Command column.
| What | Value | Command | Commit |
|---|---|---|---|
| ORE core suite | 633 cases, all passing, against a recreated database | ctest --preset linux-clang-debug-make -R ore.core |
working tree |
| Trading, ORE service and ORE API suites | 4, 1 and 1 test binaries, all passing | ctest ... -R trading, -R ore.service, -R ore.api |
working tree |
| Corpus gate's known export gaps that hold a rates document | 0 | known_export_gaps() in xml_exporter_directory_roundtrip_tests.cpp |
working tree |
| New tables | 4 (flexi_swap_instruments, flexi_swap_lower_notionals, balance_guaranteed_swap_tranches, balance_guaranteed_swap_tranche_notionals) |
git status --short projects/ores.sql/create/trading |
working tree |
| Handler permission seeding | 1012 codes seeded | check_handler_permissions.py |
working tree |
6. Notes
7. Test Scenarios
Manual QA scenarios (scaffolded via compass add test_scenario)
that verify this task. Link
new ones here as they're created; the scenario doc itself links back
via its "Verifies task" field.
| Scenario | State | Notes |
|---|---|---|
8. PRs
| PR | Title |
|---|---|
| #3067 | [trading,ore] Carry the FlexiSwap and BalanceGuaranteedSwap fields |
9. Review
| # | Comment summary | File | Decision | Notes |
|---|---|---|---|---|
| 1 | Float precision of notionals | swap_instrument_mapper.cpp | Decline | The generated xsd type is xsd::base<float>. The precision limit comes from the schema binding. Every other mapper has the same limit. |
| 2 | Empty LowerNotionalBounds block is dropped | swap_instrument_mapper.cpp | Decline | A block with no notional has no data to keep. No corpus file has one. |
| 3 | Block grouping uses the ordinal | swap_instrument_mapper.cpp | Decline | Forward mapping writes contiguous ordinals. Hand-entered rows must do the same. |
| 4 | Short table name agrees across files | trading_rate_instruments_create.sql | No change | Checked: create, drop, cascade and trigger files all use the short name. |
| 5 | Schedule owner role needs migration | instrument_schedule | No change | The project recreates the database. |
| 6 | Import is not atomic | ore_import_execute_handler.cpp | Decline | Same as the existing child-row loops. Not a regression. |
| 7 | No end-to-end import test | n/a | Decline | Stated as a limitation in the PR. Unit 8 proves the round trip. |
10. Result
FlexiSwap and BalanceGuaranteedSwap now import, store and export every element the ORE schema requires. Neither is a known export gap.
- FlexiSwap. A new fact table holds
OptionLongShort. The lower notional bounds are rows offlexi_swap_lower_notional, one per notional, with the block's ordinal and currency, so the export regroups them into the blocks the document stated. A flexi swap used to store an empty vanilla swap row. - BalanceGuaranteedSwap. The fact table gains
reference_security. The tranches are rows ofbalance_guaranteed_swap_trancheand their dated notionals are rows ofbalance_guaranteed_swap_tranche_notional. The tranche schedule reuses the sharedinstrument_schedulerows under the new owner roletranches, so no schedule table is repeated. - The path. The carrier, the batch mapper, the export read, the import write, the handlers, the permissions and the ORE mapper both ways all carry the new rows. The mapper cases check literal values from the two corpus documents.
- A table name is shorter than the convention. The generator cuts derived
identifiers at 63 characters but the C++ entity keeps the full table name, so
the conventional name for the tranche notionals would have made the SQL and
the entity disagree. The table is
ores_trading_bg_swap_tranche_notionals_tbland the model says why. The mismatch is a generator defect and is not fixed here. - The inbox capture for this work is removed.
Not done: the reverse mappers rebuild each leg's schedule from the header dates, as the other reverse mappers do, so the leg schedules of these two documents are not byte-equal to the source. The ER diagrams are not regenerated. No end-to-end ORE import ran against a live service.