ores.marketdata.market_observation

Table of Contents

A single market data observation: the value of a series at a given observation_datetime and point_id (tenor/surface coordinate). observation_datetime is the financial valid-time (UTC); valid_from=/=valid_to is the transaction time. Corrections replace the previous value via the soft-update trigger.

TimescaleDB hypertable partitioned by observation_datetime with 30-day chunks; GIST exclusion and DELETE RULEs are incompatible with hypertables — uniqueness is enforced via partial unique index and the soft-update/soft-delete trigger pair.

No audit trail columns (version, modified_by, performed_by, change_reason_code, change_commentary) — tick-level data volumes make these impractical.

1. Flags

2. Columns

2.1. id

Surrogate UUID uniquely identifying this observation row.

2.2. party_id

Party that owns this observation.

Set server-side from the authenticated session. Enforced by RLS.

ctx.generate_uuid()

2.3. series_id

Reference to ores_marketdata_market_series_tbl(id) — identifies what was observed.

2.4. observation_datetime

Financial valid-time: when the market value was observed (UTC). Also the hypertable partition column.

ctx.past_timepoint()

2.5. point_id

Tenor or compound surface identifier (e.g. 1Y, 5Y/2Y/ATM, 0.03/10Y/2Y).

Every observation carries one. A series whose keys have no coordinate of their own has a single point and names it explicitly – SPOT for an FX rate, an equity or a commodity price, the empty string for a series with no coordinate at all, such as a recovery rate. The value comes from series_key_registry::default_point_for(), so it is a property of the series type rather than something each producer decides.

2.6. value

Serialised market value (numeric string; format is series-type-specific).

std::to_string(faker::number::decimal<double>(0.0, 100.0))

2.7. source

Source tag identifying the producer channel that published this observation (e.g. synthetic.v1.tick.fx_spot.eur-usd).

3. SQL

3.1. Flags

3.2. Checks

expression
"value" <> ''

3.3. Bitemporal natural keys

column nullable
series_id false
observation_datetime false
point_id false

3.4. Indexes

name columns unique current_only where_extra
observations_current_uniq tenant_id, party_id, series_id, observation_datetime, point_id true true  
observations_series_datetime tenant_id, party_id, series_id, observation_datetime desc false false  
observations_tenant_datetime tenant_id, party_id, observation_datetime desc false false  
observations_source tenant_id, party_id, source, observation_datetime desc false false source is not null
observations_series_point_datetime tenant_id, series_id, point_id, observation_datetime desc false false  

4. Foreign keys

4.1. series_id

Every real caller lists observations scoped to one series (tick-level volumes make an unfiltered list impractical) — generates a dedicated, paginated list_by_series_id endpoint (protocol/repository/service/ registrar) instead of an optional filter bolted onto the generic .list endpoint. Default page size is 1000 (vs the usual 100): market data is high-volume tick data, not user-managed reference rows. Ordered by observation_datetime desc (not the facet's usual primary-key order): a fully random UUID id has no correlation to time, so the default order would silently return an arbitrary subset rather than the most recent observations whenever a series exceeds the page limit — exactly the "most recent N" behaviour the hand-written override this facet replaces used to provide, and the observations_series_datetime index below exists specifically to serve this ordering.

5. C++

5.1. Flags

5.2. Repository

5.3. Domain includes

#include <boost/uuid/uuid.hpp>
#include <chrono>
#include <optional>
#include <string>

5.4. Entity includes

#include <optional>
#include <string>

5.5. Conventions

Emacs 29.3 (Org mode 9.6.15)