Post-processors
The Atoti Market Data Library provides several post-processors for the retrieval of market data:
- a single market data corresponding to a key defining the market data
- all the market data corresponding to a curve, surface, or cube
Market data post-processors
Interfaces for market data retrieval are defined in the packages com.activeviam.marketdata.lib.retrievers.intf
and com.activeviam.marketdata.lib.retrievers.contextual.intf
.
Post-processor | Description |
---|---|
AMarketDataPostProcessor<C, V, T extends IContextualMarketDataRetriever<C, V>> |
Abstract class that handles: - required levels - default value for market data - the MarketDataDateShift used for the retrieval of market data |
ADefaultMarketDataPostProcessor<R extends IContextualMarketDataRetriever<List<Object>, Double>> |
Abstract class extending AMarketDataPostProcessor that handles coordinates of type List<Object> and market data of type Double . That class also offers the possibility to override the coordinates coming from the location in the buildCoordinates(ILocation location) method. |
SingleMarketDataPostProcessor |
Handles the retrieval of a single piece of market data without any interpolation. |
CurveMarketDataPostProcessor |
Handles the retrieval of curve market data with interpolation. Uses the maturity converter for the computation of the interpolation input data. |
SurfaceMarketDataPostProcessor |
Handles the retrieval of surface market data with interpolation. Uses the maturity converter for the computation of the interpolation input data. |
CubeMarketDataPostProcessor |
Handles the retrieval of cube market data with interpolation. Uses the maturity converter for the computation of the interpolation input data. |
FxMarketDataPostProcessor |
Handles the retrieval of FX rates with inversion and pivoting functionality. It instantiates an FxContextualMarketDataRetriever inside the post-processor. |
FactoryFxRateMarketDataPostProcessor |
Handles the retrieval of FX rates with inversion and pivoting functionality. It uses the FxMarketDataRetrieverFactory to instantiate an FxContextualMarketDataRetriever . |
AMarketDataPostProcessor
This post-processor extends ABasicPostProcessor
.
It uses the following generic types:
C
: type of the coordinates used to retrieve market data (e.g.List<Object>
).V
: type of the retrieved market data (e.g.Double
).T extends IContextualMarketDataRetriever<C, V>
: type of theIContextualMarketDataRetriever
used in the post-processor.
This post-processor has the following properties:
LEVELS_PROPERTY
: aILevelInfo[]
representing the levels required for retrieving market data.MARKET_DATA_DATE_SHIFT_PROPERTY
: aMarketDataDateShift
object.DEFAULT_VALUE_PROPERTY
: an object of typeV
that represents the default value to return.
The logic of the post-processor is as follows:
- Check if the point location for which the post-processor is invoked is at the required levels. If it is not, the default value is returned.
- If the point location is at the required levels, invoke the abstract method
C buildCoordinates(ILocation location)
for the point location to build the coordinates from the location. - Invoke the abstract method
T getMarketDataRetriever(ILocation location)
for the point location to get the retriever that will be used. - Invoke the retriever for the extracted coordinates and the
MarketDataDateShift
specified in the configuration of the post-processor.
ADefaultMarketDataPostProcessor
This post-processor extends AMarketDataPostProcessor<List<Object>, Double, R>
.
It handles the retrieval of market data with coordinates of type List<Object>
and values Double
.
This post-processor has one property on top of the properties from AMarketDataPostProcessor
:
OVERRIDDEN_STORE_VALUES_PROPERTY
: aList<Object>
representing the overridden values used to build the coordinates from the point location. To use overridden values, aList<Object>
of a length bigger than the number of required levels needs to be provided. The post-processor iterates over that list and for eachnull
value found in that list, it takes the coordinate of the corresponding index in the required levels. Otherwise, it takes the value specified in the overridden values list (see example below).
Optionally, the method List<Object> overrideCoordinates(List<Object> coordinates)
can be implemented in a class extending that post-processor to further
override the coordinates after the execution of that logic.
APropertyMarketDataPostProcessor
This post-processor extends ADefaultMarketDataPostProcessor<IDefaultContextualMarketDataRetriever>
This post-processor has one property on top of the properties from ADefaultMarketDataPostProcessor
:
RETRIEVER_PROPERTY
: the name of theIMarketDataRetrievalContainer<IDefaultMarketDataRetriever>
object to use to retrieve market data.
SingleMarketDataPostProcessor
This post-processor extends APropertyMarketDataPostProcessor
.
This post-processor creates a SingleContextualMarketDataRetriever
from the IMarketDataRetrievalContainer
defined in the properties to retrieve market data.
CurveMarketDataPostProcessor
This post-processor extends ADefaultMarketDataPostProcessor<InterpolatingCurveContextualMarketDataRetriever>
.
This post-processor has one property on top of the properties from ADefaultMarketDataPostProcessor
:
INTERPOLATION_MODE_PROPERTY
: specifies theInterpolationMode
to use.
The post-processor uses the IMaturityConverter
and the CurveMarketDataRetrieverFactory
that are injected via the interfaces IMaturityConverterAware
and
ICurveMarketDataRetrieverFactoryAware
respectively.
The maturity converter is used to convert the tenors into double values so that they can be used as inputs of the interpolator.
The CurveMarketDataRetrieverFactory
instantiates an InterpolatingCurveContextualMarketDataRetriever
, used to handle curve market data retrieval and
interpolation.
SurfaceMarketDataPostProcessor
This post-processor extends ADefaultMarketDataPostProcessor<InterpolatingSurfaceContextualMarketDataRetriever>
.
This post-processor has one property on top of the properties from ADefaultMarketDataPostProcessor
:
INTERPOLATION_MODE_PROPERTY
: specifies theInterpolationMode
to use.
The post-processor uses the IMaturityConverter
and the SurfaceMarketDataRetrieverFactory
that are injected via the interfaces IMaturityConverterAware
and
ISurfaceMarketDataRetrieverFactoryAware
respectively.
The maturity converter is used to convert the tenors and moneyness into double values so that they can be used as inputs of the interpolator.
The SurfaceMarketDataRetrieverFactory
instantiates an InterpolatingSurfaceContextualMarketDataRetriever
, used to handle surface market data retrieval
and interpolation.
CubeMarketDataPostProcessor
This post-processor extends ADefaultMarketDataPostProcessor<InterpolatingCubeContextualMarketDataRetriever>
.
This post-processor has one property on top of the properties from ADefaultMarketDataPostProcessor
:
INTERPOLATION_MODE_PROPERTY
: specifies theInterpolationMode
to use.
The post-processor uses the IMaturityConverter
and the CubeMarketDataRetrieverFactory
that are injected via the interfaces IMaturityConverterAware
and
ICubeMarketDataRetrieverFactoryAware
respectively.
The maturity converter is used to convert the tenors, moneyness and maturities into double values so that they can be used as inputs of the interpolator.
The CubeMarketDataRetrieverFactory
instantiates an InterpolatingCubeContextualMarketDataRetriever
that is used to handle cube market data retrieval
and interpolation.
FxRateMarketDataPostProcessor
This post-processor extends ADefaultMarketDataPostProcessor<FxContextualMarketDataRetriever>
.
This post-processor has one property on top of the properties from ADefaultMarketDataPostProcessor
:
PIVOT_CURRENCY_PROPERTY
: specifies the currency to use as a pivot when a rate isn’t found for the currency pair.
The post-processor uses the IMarketDataRetrievalContainerService
injected via the IMarketDataRetrievalContainerServiceAware
interface to instantiate an FxContextualMarketDataRetriever
internally.
FactoryFxRateMarketDataPostProcessor
This post-processor extends ADefaultMarketDataPostProcessor<FxContextualMarketDataRetriever>
.
The post-processor uses the FxMarketDataRetrieverFactory
injected via the IFxMarketDataRetrieverFactoryAware
interface to instantiate an FxContextualMarketDataRetriever
.
For this post-processor, the pivot currency should be defined in the FxMarketDataRetrieverFactory
.
Configuration
To instantiate market data post-processors, builders are provided in the APropertyMarketDataPostProcessor
, CurveMarketDataPostProcessor
,
SurfaceMarketDataPostProcessor
, CubeMarketDataPostProcessor
, FxRateMarketDataPostProcessor
and FactoryFxRateMarketDataPostProcessor
classes.
APropertyMarketDataPostProcessor
The builder of the APropertyMarketDataPostProcessor
has the following methods:
withRequiredLevels
: list ofLevelIdentifier
objects to define the required levels.withRetriever
: the String corresponding to the name of theIMarketDataRetrievalContainer
to use.
Optionally, the following methods can be used:
withMarketDataDateShift
: specifies theMarketDataDateShift
value to use (by default, theMarketDataDateShift.CURRENT_DAY
value is used as market data shift).withDefaultValue
: specifies the value to return.withOverriddenValues
: specifies the overridden values to use when the coordinates are built (see below). By default, no overridden values are used.
The SingleMarketDataPostProcessor
returns the PropertyMarketDataPostProcessorBuilder
, in order to allow extensions.
FxRateMarketDataPostProcessor
The builder of the FxRateMarketDataPostProcessor
provides an extra method:
withPivotCurrency
: the currency to use as a pivot when searching for an FX rate, as a String (e.g. ifEUR
is selected as a pivot currency, a rate forUSD/GBP
will be retrieved asUSD/EUR
multiplied byEUR/GBP
).
FxMarketDataRetrieverFactory
The FxMarketDataRetrieverFactory
provided in the Atoti Market Data Spring Boot Starter will use the market-data.fx.pivot-currency
property to set the pivot currency.
CurveMarketDataPostProcessor
The builder of the CurveMarketDataPostProcessor
provides an extra method:
withTenorMapperFactory
: the mapper factory used to create the tenor mapper based on the coordinates.
SurfaceMarketDataPostProcessor
The builder of the SurfaceMarketDataPostProcessor
provides two extra method:
withTenorMapperFactory
: the mapper factory used to create the tenor mapper based on the coordinates.withMoneynessMapperFactory
: the mapper factory used to create the moneyness mapper based on the coordinates.
CubeMarketDataPostProcessor
The builder of the CubeMarketDataPostProcessor
provides three extra method:
withTenorMapperFactory
: the mapper factory used to create the tenor mapper based on the coordinates.withMoneynessMapperFactory
: the mapper factory used to create the moneyness mapper based on the coordinates.withMaturityMapperFactory
: the mapper factory used to create the maturity mapper based on the coordinates.
Example
Here’s an example of creating a measure using the SingleMarketDataPostProcessor
:
LevelIdentifier asOfDateLevel = new LevelIdentifier("Dates", "Date", "AsOfDate");
LevelIdentifier marketDataSetLevel = new LevelIdentifier("MarketData", "MarketDataSets", "MarketDataSet");
LevelIdentifier riskFactorIdLevel = new LevelIdentifier("RiskFactorId", "RiskFactorId", "RiskFactorId");
CopperMeasure instrumentMeasure = SingleMarketDataPostProcessor.measure()
.withRetriever(SPOT_MARKET_DATA_STORE)
.withRequiredLevels(asOfDateLevel, marketDataSetLevel, riskFactorIdLevel)
.as("InstrumentMeasure");
To use overridden values, we provide a List<Object>
of a length bigger than the number of required levels.
The post-processor iterates over that list, and for each null
value found in that list, it takes the coordinate of the corresponding index in the required
levels. Otherwise it takes the value specified in the overridden values list.
For instance, with the following configuration:
LevelIdentifier asOfDateLevel = new LevelIdentifier("Dates", "Date", "AsOfDate");
LevelIdentifier marketDataSetLevel = new LevelIdentifier("MarketData", "MarketDataSets", "MarketDataSet");
CopperMeasure instrumentMeasureWithOverride = SingleMarketDataPostProcessor.measure()
.withRetriever(SPOT_MARKET_DATA_STORE)
.withRequiredLevels(asOfDateLevel, marketDataSetLevel)
.withOverriddenValues(null, null, "Instrument2")
.as("InstrumentMeasureWithOverride");
the post-processor retrieves data for coordinates equal to:
- the as-of-date and the market data set that are extracted from the location at which the post-processor is invoked
- the instrument ID “Instrument2”
In addition to the methods present in the SingleMarketDataPostProcessor
builder, the CurvePostProcessor
, SurfacePostProcessor
and CubePostProcessor
builders also have a withInterpolationMode
to specify which interpolation mode to use.
Those three post-processors use the maturity retriever to convert tenors, moneyness, and maturities for the inputs of the interpolator.
Example - CurvePostProcessor
builder
LevelIdentifier asOfDateLevel = new LevelIdentifier("Dates", "Date", "AsOfDate");
LevelIdentifier marketDataSetLevel = new LevelIdentifier("MarketData", "MarketDataSets", "MarketDataSet");
LevelIdentifier curveIdLevel = new LevelIdentifier("CurveId", "CurveId", "CurveId");
LevelIdentifier tenorsLevel = new LevelIdentifier("Tenor", "Tenor", "Tenor");
CopperMeasure copperMeasure = CurveMarketDataPostProcessor.measure()
.withInterpolationMode(InterpolationMode.LINEAR)
.withRequiredLevels(asOfDateLevel, marketDataSetLevel, curveIdLevel, tenorsLevel)
.withTenorMapperFactory(this::mapTenor)
.as("CurveMeasure");
public CoordinateMapper<String> mapTenor(List<Object> coordinates) {
return tenorOrMaturity -> switch (tenorOrMaturity) {
case "1Y":
yield 360.0;
case "5Y":
yield 1800.0;
case "10Y":
yield 3600.0;
default:
yield 0.0;
};
}
Example - SurfacePostProcessor
builder
LevelIdentifier asOfDateLevel = new LevelIdentifier("Dates", "Date", "AsOfDate");
LevelIdentifier marketDataSetLevel = new LevelIdentifier("MarketData", "MarketDataSets", "MarketDataSet");
LevelIdentifier surfaceIdLevel = new LevelIdentifier("SurfaceId", "SurfaceId", "SurfaceId");
LevelIdentifier tenorsLevel = new LevelIdentifier("Tenor", "Tenor", "Tenor");
LevelIdentifier moneynessesLevel = new LevelIdentifier("Moneyness", "Moneyness", "Moneyness");
CopperMeasure copperMeasure = SurfaceMarketDataPostProcessor.measure()
.withInterpolationMode(InterpolationMode.LINEAR)
.withRequiredLevels(asOfDateLevel, marketDataSetLevel, surfaceIdLevel, tenorsLevel, moneynessesLevel)
.withTenorMapperFactory(this::mapTenor)
.withMoneynessMapperFactory(this::mapMoneyness)
.as("SurfaceMeasure");
public CoordinateMapper<String> mapTenor(List<Object> coordinates) {
return tenorOrMaturity -> switch (tenorOrMaturity) {
case "1Y":
yield 360.0;
case "5Y":
yield 1800.0;
case "10Y":
yield 3600.0;
default:
yield 0.0;
};
}
public CoordinateMapper<String> mapMoneyness(List<Object> coordinates) {
return moneyness -> switch (moneyness) {
case "ATM":
yield 1.0;
case "+2.5%":
yield 1.025;
case "+5%":
yield 1.05;
default:
yield 0.0;
};
}
Example - CubePostProcessor
builder
LevelIdentifier asOfDateLevel = new LevelIdentifier("Dates", "Date", "AsOfDate");
LevelIdentifier marketDataSetLevel = new LevelIdentifier("MarketData", "MarketDataSets", "MarketDataSet");
LevelIdentifier cubeIdLevel = new LevelIdentifier("CubeId", "CubeId", "CubeId");
LevelIdentifier tenorsLevel = new LevelIdentifier("Tenor", "Tenor", "Tenor");
LevelIdentifier moneynessesLevel = new LevelIdentifier("Moneyness", "Moneyness", "Moneyness");
LevelIdentifier maturitiesLevel = new LevelIdentifier("UnderlyingMaturity", "UnderlyingMaturity", "UnderlyingMaturity");
CopperMeasure copperMeasure = CubeMarketDataPostProcessor.measure()
.withInterpolationMode(InterpolationMode.LINEAR)
.withRequiredLevels(asOfDateLevel, marketDataSetLevel, cubeIdLevel, tenorsLevel, moneynessesLevel, maturitiesLevel)
.withTenorMapperFactory(this::mapTenorOrMaturity)
.withMaturityMapperFactory(this::mapTenorOrMaturity)
.withMoneynessMapperFactory(this::mapMoneyness)
.as("CubeMeasure");
public CoordinateMapper<String> mapTenorOrMaturity(List<Object> coordinates) {
return tenorOrMaturity -> switch (tenorOrMaturity) {
case "1Y":
yield 360.0;
case "5Y":
yield 1800.0;
case "10Y":
yield 3600.0;
default:
yield 0.0;
};
}
public CoordinateMapper<String> mapMoneyness(List<Object> coordinates) {
return moneyness -> switch (moneyness) {
case "ATM":
yield 1.0;
case "+2.5%":
yield 1.025;
case "+5%":
yield 1.05;
default:
yield 0.0;
};
}
Example - FxRateMarketDataPostProcessor
builder
LevelIdentifier asOfDateLevel = new LevelIdentifier("Dates", "Date", "AsOfDate");
LevelIdentifier marketDataSetLevel = new LevelIdentifier("MarketData", "MarketDataSets", "MarketDataSet");
LevelIdentifier currencyLevel = new LevelIdentifier("Currency", "Currency", "Currency");
LevelIdentifier displayCurrencyLevel = new LevelIdentifier("DisplayCurrency", "DisplayCurrency", "DisplayCurrency");
String pivotCurrency = "EUR";
CopperMeasure copperMeasure = FxRateMarketDataPostProcessor.measure()
.withRequiredLevels(asOfDateLevel, marketDataSetLevel, currencyLevel, displayCurrencyLevel)
.withPivotCurrency(pivotCurrency)
.as("FX Rate");
Example - FactoryFxRateMarketDataPostProcessor
builder
LevelIdentifier asOfDateLevel = new LevelIdentifier("Dates", "Date", "AsOfDate");
LevelIdentifier marketDataSetLevel = new LevelIdentifier("MarketData", "MarketDataSets", "MarketDataSet");
LevelIdentifier currencyLevel = new LevelIdentifier("Currency", "Currency", "Currency");
LevelIdentifier displayCurrencyLevel = new LevelIdentifier("DisplayCurrency", "DisplayCurrency", "DisplayCurrency");
String pivotCurrency = "EUR";
CopperMeasure copperMeasure = FxRateMarketDataPostProcessor.measure()
.withRequiredLevels(asOfDateLevel, marketDataSetLevel, currencyLevel, displayCurrencyLevel)
.as("FX Rate");