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

  1. Name what the schema requires. flexiSwapData requires OptionLongShort and the lower notional bounds. bgSwapData requires ReferenceSecurity and Tranches, and a Tranches block holds tranches (description, security id, seniority, dated notionals) and a schedule.
  2. 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_date is. A schedule goes in the shared instrument_schedule rows under a new owner role, so no schedule table is repeated.
    • flexi_swap_instrument is a new fact table, because a flexi swap stored a vanilla_swap_instrument row with no fields of its own.
    • flexi_swap_lower_notional holds one notional per row, with its block ordinal and currency.
    • balance_guaranteed_swap_instrument gains reference_security.
    • balance_guaranteed_swap_tranche and balance_guaranteed_swap_tranche_notional hold the tranches.
    • instrument_schedule accepts the owner role tranches.
  3. 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.
  4. 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 of flexi_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 of balance_guaranteed_swap_tranche and their dated notionals are rows of balance_guaranteed_swap_tranche_notional. The tranche schedule reuses the shared instrument_schedule rows under the new owner role tranches, 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_tbl and 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.

Emacs 29.3 (Org mode 9.6.15)