A value set is the only place an ORE parameter's rule is written
Table of Contents
1. Summary
One table states what one ORE parameter accepts, once, and every other table that needs the answer points at it. A set states a kind, and the kind decides which of its other columns mean anything: an enumerated set states its values, a catalogue set names a relation to read, a range states a floor and a ceiling, a regex states a pattern. A set also states a cardinality, which says whether the document writes one value or a comma separated list of them; the kind then says what one value may be. Nothing else in the tree repeats the rule: the part tables carry no CHECK constraint on the columns a set governs, and a screen decides no rule of its own; it asks the store and draws the answer.
One fact may also be written several ways. ORE reads NONE and Unadjusted as
one convention, and a set that listed both as values offered one fact twice, so
a value row names the form a configuration holds and is a rendering when it
names one.
2. The five tables
| Table | States |
|---|---|
ores_reporting_ore_parameter_value_sets_tbl |
the rule: source_kind and cardinality, plus minimum, maximum, pattern, catalogue_code, is_ordered |
ores_reporting_ore_parameter_value_set_values_tbl |
the values of an enumerated set: value, label, display_order, is_active, canonical_value |
ores_reporting_ore_parameter_value_set_catalogues_tbl |
the relation a catalogue set reads, such as ores_refdata_currency_catalogue_v |
ores_reporting_ore_parameter_setting_value_sets_tbl |
the link from (scope, name) to a set, which is how a parameter finds its rule |
ores_reporting_ore_parameter_vocabularies_tbl |
the link from an ORE leaf's address to a set, which both leaf guards read |
3. The nine kinds
source_kind holds one of nine values, and
projects/ores.sql/create/reporting/reporting_ore_parameter_value_validate_fn_create.sql
is the only code that reads it. Everything a rule can say about one value is in
this list.
The seed uses seven of the nine on 2026-10-31: 149 sets are text, 75 number,
52 enumerated, 47 integer, 10 boolean, 7 catalogue and 2 regex, with no
range and no period set yet. The large text count is not a gap. A text
set is the honest answer for a parameter whose values ORE passes through, such as
a file path or a date, and it is recorded as a decision rather than left absent.
| Kind | What it checks | Where it reads |
|---|---|---|
enumerated |
the value is an active row of the set's values | the values table |
boolean |
true, false, Y or N, in any case |
nothing; the chart is in the function |
integer |
the value matches -?[0-9]+ and is in bounds |
the set row |
number |
the value parses as a number and is in bounds | the set row |
range |
the value is a number within minimum and maximum |
the set row |
regex |
the value matches pattern |
the set row |
catalogue |
the value is an active row of the relation the set names | the catalogue relation |
period |
nothing: a period is a value ORE parses, not a list to choose from | nothing |
text |
nothing: the set states that the parameter is free text | nothing |
4. The one cardinality
cardinality holds one or many, and it is what makes a list a rule rather
than a string. ORE writes a list into a single element, so 1Y,2Y,5Y is one value
in the XML and three periods in the rule, and a kind alone cannot tell that from
a single period. A set of cardinality many splits on the comma, trims each item,
holds every item to the kind's rule, and refuses an empty item, which is a
trailing or doubled comma. A set of cardinality one refuses the comma, because
a comma there is a document the engine cannot parse.
Keeping the two facts apart is what keeps the kinds at nine: the alternative is
period, period_list, number, number_list and a kind for every
combination, and a screen would have to read a name to know how to draw a
control. A screen reads the kind for the control and the cardinality for whether
the control repeats.
A set a source states may state a shape rather than a list. The ORE schema
restricts a simple type to a pattern, as date and calendar are restricted, or
to a range, as dayOfMonth is restricted to 1 through 31, and the set carries
that pattern or those bounds. A pattern is anchored when it is seeded, because a
set states what the whole value must be and Postgres matches a pattern anywhere
in a string otherwise.
A set that states its values may have been written from a source rather than by a
person. The ORE parser's map is one such source: parseVolatilityType accepts
three spellings and the set lists them. The ORE schema is the other: a simple type
such as dimensionType enumerates ATM, ATMTriangulated, Smile and
Constant, and the set states those four. Both are read at seed time, so a
spelling ORE adds arrives with a regeneration rather than a second edit.
A list need not say what one item is. curve.list is the set that says the leaf
holds many values and admits any item, and it is used for the three leaves whose
items no authority states: a delta written 25D, an expiry that may be a date or
a wildcard, and a pillar date. Those three sets of names are curated in
curve_value_sets.py beside the reason and the guide or code line it came from,
so the difference between a list of periods and a list of anything is data.
5. What a set looks like as data
The sets are seeded, not typed in. The curated input is
projects/ores.seeder/datasets/ore_pricing_engines/curation/value-sets.json
with value-sets-code.json for the codes, and
projects/ores.sql/utility/generate_value_sets.py writes the populate scripts;
--check fails the build when the committed SQL and the curation disagree. Each
row's description names the ORE source the rule was taken from, so a set can be
re-derived rather than guessed:
('curve.duplicate_pillar_policy', ores_utility_system_tenant_id_fn(), 0, 'Duplicate pillar policy', 'The values the ORE parser parseDuplicatePillarPolicy accepts, from its map at ' 'OREData/ored/utilities/parsers.cpp:1612.', 'enumerated', ..., 'Seed parameter value sets'),
6. The values a set governs
Three kinds of place hold a value a set governs, and each is reached differently.
<CurveConfiguration> <SwaptionVolatilities> <SwaptionVolatility> <CurveId>EUR_SWPTN</CurveId> <VolatilityType>Lognormal</VolatilityType> </SwaptionVolatility> </SwaptionVolatilities> </CurveConfiguration> <PricingEngines> <Product type="Swap"> <EngineParameters> <Parameter name="EnforceMonotoneVariance">true</Parameter> </EngineParameters> </Product> </PricingEngines>
- A curve or convention leaf, such as
VolatilityType, becomes a column of a refdata table, and the set is found through the element map's row for that leaf, as One map answers which ORE element a row is describes. - A named parameter, such as
EnforceMonotoneVariance, becomes a row of the pricing model's parameter table, and its set is found by(scope, name). - A run or engine setting becomes a column of an engine settings part table, and
its set is found by
(Setup, name).
All three land on the same link table and the same set. That is the point of the model: the rule is stated once whether the value arrives from a curve, a product or a run.
7. A rendering and the form a configuration holds
ORE reads one fact several ways. NONE, INDIFF, NotApplicable and
Unadjusted are one convention, and A360, Actual/360 and Act/360 are one
day counter. A set that listed them as values offered the same fact four times,
and a store that held the rendering it was handed held one fact two ways.
So a value row states both: canonical_value names the form a configuration
holds, and is empty when the row is that form. A control offers the rows whose
column is empty; a write of a row that names one converts it. The set therefore
answers three questions with one table: which renderings are accepted, what each
means, and which of them a configuration carries.
('convention.business_day_convention:NONE', ..., 'NONE', ..., 'Unadjusted', ...), ('convention.business_day_convention:Unadjusted', ..., 'Unadjusted', ..., null, ...),
The renderings are data. projects/ores.sql/utility/ore_renderings.json states,
for each table, the form a configuration holds and every rendering that means it.
Two readers take that file: the value sets, through ore_aliases.py, and the C++
reader, which converts with tables generated from it
(projects/ores.ore/core/src/domain/conventions_renderings.hpp). A generated table
is one statement that survives being compiled: the check fails when the committed
header differs from the file, and when the reader states a table of its own.
The parser map that accepts the renderings is a second source, and it answers a question the file cannot: which renderings a document may write. Two mismatches between the two are defects the reader cannot see, and the check named both while the sets were built: a rendering the parser accepts and the file omits is a document the engine reads and this store refuses, and a row the file holds that the parser never produces is a rule nothing can apply. One of each was found and corrected.
The form a configuration holds is one of those renderings, so a document may write
it. That is an invariant the generator enforces, and it is why the export needs no
second mapping: a form no document could write would be a second table, and would
state the fact twice. Four forms were the exception — ACT/360 (incl. last),
ACT/365 (Canadian Bond), ACT/365 (JGB) and Nearest — and each took the
spelling the schema states instead.
8. What is not settled
One gap is known, and it is a change rather than an open question.
- A set code the tables do not hold admits every value
(
…reporting_ore_parameter_value_validate_fn_create.sql:87). A guard that cannot find a rule cannot refuse, so a dangling link is silent. The shell check's completeness gate (see the enforcement note) catches a parameter with no set; it does not catch a typo in a set code, which only a foreign key would.
9. See also
- The ORE XML infrastructure — the structure note that orders this cluster; this page is its fifth step, and the one a reader needs before the enforcement page makes sense.
- The database refuses a value that
no value set states — completes this page by naming the one code path that
reads
source_kindand the four functions that call it. - One map answers which ORE element a row is — the lookup half: this page is what the lookup finds, and that page is what finds it.
- A stored value reaches the row in the form the value set names — completes this page on the write side: the mapping file states the renderings here, and that page states the two boundaries that read it.
- Consolidate the ORE element maps — the task that gives the leaf link one home before the alias work adds rows to the sets.