ORE import and export
Table of Contents
1. Summary
marketdata.v1.ops.import_market_data turns the text of an ORE market.txt and
fixings.txt into stored series, observations and fixings.
marketdata.v1.ops.export_market_data writes the tenant's store back out in the same two
formats. The import lives in
projects/ores.marketdata/core/src/service/import_service.cpp. Neither
operation needs a running producer.
2. Detail
2.1. The import request
import_market_data_request carries market_data_content, the full text of
an ORE market file, fixings_content, the full text of a fixings file, and
a source tag. Either content field may be empty, so one call can import one
file type or both. The parser accepts YYYYMMDD and YYYY-MM-DD dates and
whitespace or comma delimiters.
The source tag is stamped on every imported observation's source field.
It tells one import from another, for example ore.reference for a named ORE
example vintage. An empty tag keeps the untagged behaviour that existed
before the field was added.
2.2. What the import does with a key
The ORE key codec is the authority on what a key means.
datum::ore_key_codec::read is asked to read each key, and a key the codec
refuses is not imported at all. The key is then written back in canonical
form, and the datum URI and the series URI are derived from it through
oresmd_uri_codec.
For each named key the import finds or creates the market series catalog
entry. A new series is classified through the series classification rules,
which give it its series_subclass and its asset class junction rows, and
its change reason is system.external_data_import. The observations are
then written in bulk.
The fixings path is parallel and separate. A fixing's series is the index it
fixes, so the import reads the qualifier with datum::ore_index_codec::read
and writes the index's fixing URI as the series identity. A fixing name the
codec refuses is reported and dropped, the same way a quote key the codec
refuses is dropped. Fixings land in their own table through
market_fixing_repository.
An observation's key is not stored. It is written from the datum URI, so the series carries the only durable name.
2.3. The reversed-key correction
Some vendored ORE example files store an FX spot value under a reversed
currency pair. fx_quote_convention_checker, in
projects/ores.ore/core/include/ores.ore.core/market/fx_quote_convention_checker.hpp,
compares a quote's currency order against the canonical pairs that
ores.refdata holds. When the reversed pair is the one actually present, it
swaps the qualifier's two currencies and returns key_swapped.
The checker never touches the quoted value, so it cannot introduce a floating point error, and an unrecognised pair is left alone rather than guessed at. When a swap happens, the observation's change commentary records that the key was reversed relative to refdata's canonical pair.
The correction is best effort. If the refdata pair lookup fails, the import disables the correction for the whole batch and logs that fact, and the import still runs. A missing side check never fails an import.
2.4. The export
export_market_data_request takes no arguments, and the request comment
gives the reason. An ORE market file is a snapshot of everything a run
needs, not a slice of one series, so an export that could name a subset
would produce a file that does not reproduce anything.
The service returns the file bodies rather than writing them, because the
caller owns the file system. market_data_content holds one
DATE<TAB>KEY<TAB>VALUE line per observation and fixings_content holds one
DATE<TAB>INDEX<TAB>VALUE line per fixing. The response also carries the
series, observation and fixing counts.
Both requests declare requires_session = true.
2.5. Facts the code shape does not show
- The import converges on the same catalog shape an ingest write produces. A series it creates gets the same classification, subclass and asset class junction rows, so a reader cannot tell an imported series from an ingested one by its shape.
- Every observation the import writes names the source
ore-import, a source of the providerorewith the kindreplay, because the import replays recorded values and no live session produced them. The series key is (item,ore, party). - The export's scope is the tenant and the import's scope is the tenant. Neither takes a series, a party or a date range.
- The import reports parse warnings and errors in the response while
importing what it could read, so a partial vintage is visible rather than
rejected whole. The request's
duplicates_are_errorsflag chooses how a repeateddate, keypair is handled. The default keeps the later row and reports a warning, and the strict mode reports the repeat as an error and persists none of the affected content.
3. See also
- The market data path: a public fixing, a curve, a report — the structure note that orders this cluster, and where to read this page in it.
- Market Data Architecture — the structure note that orders this cluster, and where to read this page in it.
- The source kind, the
replaykind of the import's source. - Series and observation, the catalog the import writes into.
- The import service is
projects/ores.marketdata/core/src/service/import_service.cpp. - The checker is
fx_quote_convention_checkerinprojects/ores.ore/core/include/ores.ore.core/market/fx_quote_convention_checker.hpp.