Market Data and Registration
If you only remember one thing from this section, remember this: the instruments library is intentionally explicit.
It does not silently register conventions at import time. It does not guess how a rate index should be built. It does not assume where curves or fixings live.
That design is a good thing. It keeps pricing behavior controlled and auditable. It also means your connector or bootstrap code must wire the pieces together on purpose.
1. Platform prerequisites
Before pricing can load anything, the platform needs to know where curves and fixings are stored.
That configuration lives in InstrumentsConfiguration.
The two important fields are:
discount_curves_storage_nodereference_rates_fixings_storage_node
These are table ids, not human-readable table names. The pricing runtime uses them to build APIDataNode readers behind the scenes.
If these are missing or misconfigured, pricing cannot fetch market data even if the tables already exist.
2. The storage contracts
The runtime expects two specific storage shapes.
Discount curves
Table identifier:
discount_curves
Index:
time_indexunique_identifier
Columns:
curveas a compressed string payload
That payload expands into a simple curve dictionary:
- key: days to maturity
- value: zero rate
Reference-rate fixings
Table identifier:
fixing_rates_1d
Index:
time_indexunique_identifier
Columns:
rateas a decimal float
3. Constant names vs UID values
This distinction matters a lot.
- A constant name is the symbolic name, such as
ZERO_CURVE__VALMER_TIIE_28. - A UID value is the resolved identifier string returned by
Constant.get_value(...).
The ETL layer and the pricing layer do not use them the same way.
ETL registration
ETL registries are keyed by constant name.
That means DiscountCurvesNode and FixingRatesNode stay environment-agnostic. They resolve the actual UID later, at runtime.
Pricing registration
Pricing registration is keyed by UID value.
That is the identifier you later pass into:
get_index(...)build_zero_curve(...)FloatingRateBond(floating_rate_index_name=...)InterestRateSwap(float_leg_index_name=...)
4. The bootstrap sequence
The clean mental model is:
- Register ETL builders.
- Run ETL nodes to populate storage.
- Register pricing indices.
- Validate the runtime by loading a curve or an index once.
If you skip step 3, pricing usually fails with a missing IndexSpec error.
5. ETL builders
Two registries drive ETL:
DISCOUNT_CURVE_BUILDERSFIXING_RATE_BUILDERS
These registries map constant names to builder functions.
Discount-curve builder contract
A discount-curve builder receives:
update_statisticscurve_unique_identifierbase_node_curve_pointswhen applicable
It should return a DataFrame indexed by:
time_indexunique_identifier
And it should provide one column:
curve
The curve column should contain a dictionary before compression. The node handles compression for storage.
Fixing-rate builder contract
A fixing-rate builder receives:
update_statisticsunique_identifier
It returns a DataFrame indexed by:
time_indexunique_identifier
With one value column:
rate
6. The built-in ETL nodes
Two SDK nodes matter most here:
DiscountCurvesNodeFixingRatesNode
They are standard DataNodes. Their job is not to price instruments. Their job is to keep the pricing inputs fresh in storage.
If you need a refresher on the producer side, see Data Nodes.
7. Pricing registration with IndexSpec
Once curves and fixings exist in storage, the runtime still needs a pricing interpretation for each index UID.
That interpretation lives in IndexSpec.
An IndexSpec tells the runtime:
- which curve UID to load,
- which fixing UID to load,
- which calendar, day counter, tenor, currency, and settlement rules to use.
That is why pricing registration is connector-owned. The base library stays clean, and your connector owns the business conventions.
8. Common failure modes
- Curves were stored, but no
IndexSpecwas registered for the index UID. - An
IndexSpecexists, butInstrumentsConfigurationpoints to the wrong storage node ids. - A builder writes percent values where the runtime expects decimals.
- Teams mix constant names and resolved UID values in the wrong registry.
9. Operational advice
- Keep registration explicit in a single
register_all()style bootstrap. - Make that bootstrap idempotent.
- Validate registration early by calling
build_zero_curve(...)once during startup.