> ## Documentation Index
> Fetch the complete documentation index at: https://docs.activeviam.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 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:<br />- required levels<br />- default value for market data<br />- the `MarketDataDateShift` used for the retrieval of market data                                                                                                         |
| `ADefaultMarketDataPostProcessor<R extends IContextualMarketDataRetriever<Object[], Double>>`                                                                                     | Abstract class extending `AMarketDataPostProcessor` that handles coordinates of type `Object[]` and market data of type `Double`. This class also allows you to override the coordinates coming from the location in the `buildCoordinates(ILocation location)` method. |
| `APropertyMarketDataPostProcessor<T extends IDefaultMarketDataRetriever> extends ADefaultMarketDataPostProcessor<IDefaultContextualMarketDataRetriever>`                          | Abstract class extending `ADefaultMarketDataPostProcessor` that allows you to define an `IMarketDataRetrievalContainer<T>` market data retriever using the `RETRIEVER_PROPERTY` property.                                                                               |
| `ADirectQueryCachingMarketDataPostProcessor<T extends IDefaultMarketDataRetriever> extends APropertyMarketDataPostProcessor<T> implements IDatabaseCachePrefetchingPostProcessor` | Abstract class extending `APropertyMarketDataPostProcessor` that caches market data in a DirectQuery application to improve query performance.                                                                                                                          |
| `SingleMarketDataPostProcessor`                                                                                                                                                   | Handles the retrieval of a single piece of market data without any interpolation.                                                                                                                                                                                       |
| `CurveMarketDataPostProcessor`                                                                                                                                                    | Handles curve market data retrieval with interpolation.                                                                                                                                                                                                                 |
| `SurfaceMarketDataPostProcessor`                                                                                                                                                  | Handles surface market data retrieval with interpolation.                                                                                                                                                                                                               |
| `CubeMarketDataPostProcessor`                                                                                                                                                     | Handles the retrieval of a single point in a cube market data.                                                                                                                                                                                                          |
| `FxRateMarketDataPostProcessor`                                                                                                                                                   | Handles FX rates retrieval with inversion and pivoting functionality.                                                                                                                                                                                                   |

## AMarketDataPostProcessor

This post-processor extends `ABasicPostProcessor`.

It uses the following generic types:

* `C`: type of the coordinates used to retrieve market data (e.g. `Object[]`).
* `V`: type of the retrieved market data (e.g. `Double`).
* `T extends IContextualMarketDataRetriever<C, V>`: type of the `IContextualMarketDataRetriever` used in the post-processor.

This post-processor has the following properties:

* `LEVELS_PROPERTY`: a `ILevelInfo[]` representing the levels required for retrieving market data.
* `MARKET_DATA_DATE_SHIFT_PROPERTY`: a `MarketDataDateShift` object.
* `DEFAULT_VALUE_PROPERTY`: an object of type `V` that represents the default value to return.

The logic of the post-processor is as follows:

1. 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.
2. 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.
3. Invoke the abstract method `T getMarketDataRetriever(ILocation location)` for the point location to get the retriever that will be used.
4. Invoke the retriever for the extracted coordinates and the `MarketDataDateShift` specified in the configuration of the post-processor.

## ADefaultMarketDataPostProcessor

This post-processor extends `AMarketDataPostProcessor<Object[], Double, R>`.
It handles the retrieval of market data with coordinates of type `Object[]` and values `Double`.

This post-processor has one property on top of the properties from `AMarketDataPostProcessor`:

* `OVERRIDDEN_STORE_VALUES_PROPERTY`: an `Object[]` representing the overridden values used to build the coordinates from the point location.
  To use overridden values, an `Object[]` of a length equal or bigger than the number of required levels needs to be provided.
  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 (see example below).

Optionally, the method `Object[] overrideCoordinates(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>` and has one generic type:
`<T extends IDefaultMarketDataRetriever>`, which is used to define the type of the retriever used.

This post-processor has one property on top of the properties from `ADefaultMarketDataPostProcessor`:

* `RETRIEVER_PROPERTY`: the name of the `IMarketDataRetrievalContainer<IDefaultMarketDataRetriever>` object used to retrieve market data.

## ADirectQueryCachingMarketDataPostProcessor

This post-processor extends `ADefaultMarketDataPostProcessor<IDefaultContextualMarketDataRetriever>` and has one generic type: `<T extends IDefaultMarketDataRetriever>`, which is used to define the type of the retriever used.

This post-processor implements the `IDatabaseCachePrefetchingPostProcessor` interface and all of its methods.
When injected with an `IDatabaseCacheManager` (available in a DirectQuery application), this post-processor will cache market data during
the prefetch phase of a query to improve the performance of market data retrievals during the later compute phase.
This uses the [DirectQuery Local Cache](https://docs.activeviam.com/products/atoti/server/6.1.9/docs/directquery/directquery_local_cache/)
and requires some [initial configuration](./directquery).

## SingleMarketDataPostProcessor

This post-processor extends `ADirectQueryCachingMarketDataPostProcessor<IDefaultMarketDataRetriever>`.

This post-processor creates a `SingleContextualMarketDataRetriever` from the `IMarketDataRetrievalContainer` defined in the properties to retrieve market data.

## CurveMarketDataPostProcessor

This post-processor extends `ADirectQueryCachingMarketDataPostProcessor<ICurveMarketDataRetriever<String>>`.

This post-processor has two properties on top of the properties from `APropertyMarketDataPostProcessor`:

* `INTERPOLATION_MODE_PROPERTY`: specifies the `InterpolationMode` to use.
* `TENOR_MAPPER_PROPERTY`: specifies the `ITenorMapper<String, Double>` object used to convert the tenors into double values used as inputs for the interpolator.

## SurfaceMarketDataPostProcessor

This post-processor extends `ADirectQueryCachingMarketDataPostProcessor<ISurfaceMarketDataRetriever<String, String>>`.

This post-processor has three properties on top of the properties from `APropertyMarketDataPostProcessor`:

* `INTERPOLATION_MODE_PROPERTY`: specifies the `InterpolationMode` to use.
* `TENOR_MAPPER_PROPERTY`: specifies the `ITenorMapper<String, Double>` object used to convert the tenors into double values used as inputs for the interpolator.
* `MONEYNESS_MAPPER_FACTORY_PROPERTY`: specifies the `IMoneynessMapper<String, Double>` object used to convert moneyness values into double values used as inputs for the interpolator.

## CubeMarketDataPostProcessor

This post-processor extends `ADirectQueryCachingMarketDataPostProcessor<ICubeMarketDataRetriever<String, String, String>>`.
It does not let you perform interpolation on the cubic market data.

## FxRateMarketDataPostProcessor

This post-processor extends `ADirectQueryCachingMarketDataPostProcessor<IFxMarketDataRetriever>`.

It uses a pivot currency when searching for an FX rate, as a string. For example, if `EUR` is selected as a pivot currency, a
rate for `USD/GBP` will be retrieved as `USD/EUR` multiplied by `EUR/GBP`.

<Note>
  Important note: The pivot currency is defined as an attribute, `pivotCurrency`, which needs to be injected using the extended plugin injection mechanism.
</Note>

## Configuration

To instantiate market data post-processors, a builder helper class `MarketDataMeasureBuilderHelper` is provided, as well as the following builders:

* `SpotMarketDataMeasureBuilder`
* `FxRateMarketDataMeasureBuilder`
* `CurveMarketDataMeasureBuilder`
* `SurfaceMarketDataMeasureBuilder`
* `CubeMarketDataMeasureBuilder`

### `MarketDataMeasureBuilderHelper`

Use this helper class with post-processors that extend the class `APropertyMarketDataPostProcessor`.
It has a constructor with the following arguments:

* `pluginKey`: the plugin key of the market data post-processor to use.
* `retrievalContainerName` the name of the `IMarketDataRetrievalContainer` to use in the market data post-processor.

In the `startBuilding`method, the following parameters are provided:

* `requiredLevels`: list of `LevelIdentifier` objects to define the required levels.
* `marketDataDateShift`: the `MarketDataDateShift` value to use.

Optionally, you can use the following methods before invoking the `startBuilding` method:

* `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.
* `withType`: specifies the output type of the market data post-processor. By default, `double` is used.

### `SpotMarketDataMeasureBuilder`

The `SpotMarketDataMeasureBuilder` lets you define a measure retrieving spot market data using the `SingleMarketDataPostProcessor`and the
`SPOT_MARKET_DATA_RETRIEVER` retriever.

It has a constructor with the following arguments:

* `asOfDate`: the level from which to resolve the asOfDate used to retrieve spot market data.
* `marketDataSet`: the level from which to resolve the market data set used to retrieve spot market data.
* `instrumentId`: the level from which to resolve the instrument id used to retrieve spot market data.
* `marketDataDateShift`: the market data date shift used to retrieve spot market data.

The `build()` method is used to instantiate a `CopperPostProcessor` that corresponds to the provided configuration parameters.

### `FxRateMarketDataMeasureBuilder`

The `FxRateMarketDataMeasureBuilder` lets you define a measure retrieving FX rate market data using the `FxRateMarketDataPostProcessor`and the
`FX_RATE_MARKET_DATA_RETRIEVER` retriever.

It has a constructor with the following arguments:

* `asOfDate`: the level from which to resolve the asOfDate used to retrieve spot market data.
* `marketDataSet`: the level from which to resolve the market data set used to retrieve spot market data.
* `baseCcy`: the level from which to resolve the base currency used to retrieve the FX rate.
* `counterCcy`: the counter currency used to retrieve the FX rate.
* `marketDataDateShift`: the market data date shift used to retrieve spot market data.

<Note>
  The `FxRateMarketDataPostProcessor` uses a pivot currency when searching for an FX rate, as a string. For example, if `EUR` is selected as a pivot currency, a
  rate for `USD/GBP` will be retrieved as `USD/EUR` multiplied by `EUR/GBP`. The pivot currency needs to be injected using the post-processor’s `setPivotCurrency` method.
</Note>

The `build()` method is used to instantiate a `CopperPostProcessor` that corresponds to the provided configuration parameters.

### `CurveMarketDataMeasureBuilder`

The `CurveMarketDataMeasureBuilder` lets you define a measure retrieving curve market data using the `CurveMarketDataPostProcessor`and the
`CURVE_MARKET_DATA_RETRIEVER` retriever.

It has a constructor with the following arguments:

* `asOfDate`: the level from which to resolve the asOfDate used to retrieve curve market data.
* `marketDataSet`: the level from which to resolve the market data set used to retrieve curve market data.
* `curveId`: the level from which to resolve the curve id used to retrieve curve market data.
* `tenor`: the level from which to resolve the tenor used to retrieve curve market data.
* `marketDataDateShift`: the market data date shift used to retrieve spot market data.

`CurveMarketDataMeasureBuilder` provides two builder methods:

* `withInterpolationMode`: the interpolation mode used by the `CurveMarketDataPostProcessor`
* `withTenorMapper`: the tenor mapper used to convert the tenors into double values used as inputs for the interpolator. If this is not called, the interpolation will use the `StringToDoubleTenorMapper`.

The `build()` method is used to instantiate a `CopperPostProcessor` that corresponds to the provided configuration parameters.

### `SurfaceMarketDataMeasureBuilder`

The `SurfaceMarketDataMeasureBuilder` lets you define a measure retrieving curve market data using the `SurfaceMarketDataPostProcessor`and the
`SURFACE_MARKET_DATA_RETRIEVER` retriever.

It has a constructor with the following arguments:

* `asOfDate`: the level from which to resolve the asOfDate used to retrieve the surface market data.
* `marketDataSet`: the level from which to resolve the market data set used to retrieve the surface market data.
* `surfaceId`: the level from which to resolve the surface id used to retrieve the surface market data.
* `tenor`: the level from which to resolve the tenor used to retrieve the surface market data.
* `moneyness`: the level from which to resolve the moneyness used to retrieve the surface market data.
* `marketDataDateShift`: the market data date shift used to retrieve the surface market data.

`SurfaceMarketDataMeasureBuilder` provides three builder methods:

* `withInterpolationMode`: the interpolation mode used by the `SurfaceMarketDataPostProcessor`.
* `withTenorMapper`: the tenor mapper used to convert the tenors into double values used as inputs for the interpolator. If this is not called, the interpolation will use the `DefaultStringToDoubleTenorMapper`.
* `withMoneynessMapper`: the moneyness mapper used to convert the moneyness values into double values used as inputs for the interpolator. If this is not called, the interpolation will use the `DefaultStringToDoubleMoneynessMapper`.

The `build()` method is used to instantiate a `CopperPostProcessor` that corresponds to the provided configuration parameters.

### `CubeMarketDataMeasureBuilder`

The `CubeMarketDataMeasureBuilder` lets you define a measure retrieving curve market data using the `CubeMarketDataPostProcessor`and the
`CUBE_MARKET_DATA_RETRIEVER` retriever.

It has a constructor with the following arguments:

* `asOfDate`: the level from which to resolve the asOfDate used to retrieve the cubic market data.
* `marketDataSet`: the level from which to resolve the market data set used to retrieve the cubic market data.
* `cubeId`: the level from which to resolve the cube id used to retrieve the cubic market data.
* `tenor`: the level from which to resolve the tenor used to retrieve the cubic market data.
* `moneyness`: the level from which to resolve the moneyness used to retrieve the cubic market data.
* `maturity`: the level from which to resolve the maturity used to retrieve the cubic market data.
* `marketDataDateShift`: the market data date shift used to retrieve the cubic market data.

### Example

Here’s an example of creating a measure using the `MarketDataMeasureBuilderHelper`:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
LevelIdentifier asOfDateLevel = new LevelIdentifier("Dates", "Date", "AsOfDate");
LevelIdentifier marketDataSetLevel = new LevelIdentifier("MarketData", "MarketDataSets", "MarketDataSet");
LevelIdentifier instrumentIdLevel = new LevelIdentifier("InstrumentId", "InstrumentId", "InstrumentId");

CopperPostProcessor instrumentMeasure = new MarketDataMeasureBuilderHelper<>(
        SingleMarketDataPostProcessor.PLUGIN_KEY,
        SPOT_MARKET_DATA_RETRIEVER)
        .startBuilding(List.of(asOfDateLevel, marketDataSetLevel, instrumentIdLevel), MarketDataDateShift.CURRENT_DAY)
        .as("InstrumentMeasure");
```

To use overridden values, we provide an `Object[]` (or `Object...`) of a length equal to or 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:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
LevelIdentifier asOfDateLevel = new LevelIdentifier("Dates", "Date", "AsOfDate");
LevelIdentifier marketDataSetLevel = new LevelIdentifier("MarketData", "MarketDataSets", "MarketDataSet");
LevelIdentifier instrumentIdLevel = new LevelIdentifier("InstrumentId", "InstrumentId", "InstrumentId");

CopperPostProcessor instrumentMeasureWithOverrideKey = new MarketDataMeasureBuilderHelper<>(
        SingleMarketDataPostProcessor.PLUGIN_KEY,
        SPOT_MARKET_DATA_RETRIEVER)
        .withOverriddenValues(LocalDate.MIN, "RT", null)
        .startBuilding(List.of(asOfDateLevel, marketDataSetLevel, instrumentIdLevel), MarketDataDateShift.CURRENT_DAY)
        .as("InstrumentMeasureWithOverrideKey");
```

the post-processor retrieves data for coordinates equal to:

* the asOfDate `LocalDate.MIN` and the market data set `"RT"`
* the instrument ID that is extracted from the location at which the post-processor is invoked

#### Example - `SpotMarketDataMeasureBuilder` builder

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
LevelIdentifier asOfDateLevel = new LevelIdentifier("Dates", "Date", "AsOfDate");
LevelIdentifier marketDataSetLevel = new LevelIdentifier("MarketData", "MarketDataSets", "MarketDataSet");
LevelIdentifier instrumentIdLevel = new LevelIdentifier("InstrumentId", "InstrumentId", "InstrumentId");

CopperPostProcessor instrumentWithSpotBuilderMeasure = new SpotMarketDataMeasureBuilder(
        asOfDateLevel, marketDataSetLevel, instrumentIdLevel, MarketDataDateShift.CURRENT_DAY)
        .build()
        .as("InstrumentWithSpotBuilderMeasure");
}
```

#### Example - `CurveMarketDataMeasureBuilder` builder

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
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");

CopperPostProcessor curveMeasure = new CurveMarketDataMeasureBuilder(asOfDateLevel, marketDataSetLevel, curveIdLevel, tenorsLevel,
        MarketDataDateShift.CURRENT_DAY)
        .withTenorMapper(new TestTenorMapper())
        .withInterpolationMode(LINEAR)
        .build()
        .as("CurveMeasure");

private static class TestTenorMapper implements ITenorMapper<String, Double> {
    @Override
    public Double map(String tenor) {
    return switch (tenor) {
        case "1Y":
            yield 360.0;
        case "5Y":
            yield 1800.0;
        case "10Y":
            yield 3600.0;
        default:
            yield 0.0;
    };
}
```

#### Example - `SurfaceMarketDataMeasureBuilder` builder

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
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");

CopperPostProcessor surfaceMeasure = new SurfaceMarketDataMeasureBuilder(asOfDateLevel, marketDataSetLevel, surfaceIdLevel, tenorsLevel, moneynessesLevel,
        MarketDataDateShift.CURRENT_DAY)
        .withTenorMapper(new TestTenorMapper())
        .withMoneynessMapper(new TestMoneynessMapper())
        .withInterpolationMode(InterpolationMode.LINEAR)
        .build()
        .as("SurfaceMeasure");

private static class TestTenorMapper implements ITenorMapper<String, Double> {
    @Override
    public Double map(String tenor) {
    return switch (tenor) {
        case "1Y":
            yield 360.0;
        case "5Y":
            yield 1800.0;
        case "10Y":
            yield 3600.0;
        default:
            yield 0.0;
    };
}

private static class TestMoneynessMapper implements IMoneynessMapper<String, Double> {
    @Override
    public Double map(String moneyness) {
    return switch (moneyness) {
        case "ATM":
            yield 1.0;
        case "+2.5%":
            yield 1.025;
        case "+5%":
            yield 1.05;
        default:
            yield 0.0;
    };
}
```

#### Example - `CubeMarketDataMeasureBuilder` builder

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
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");

CopperPostProcessor cubeMeasure = new CubeMarketDataMeasureBuilder(asOfDateLevel, marketDataSetLevel, cubeIdLevel, tenorsLevel,
        moneynessesLevel, maturitiesLevel, MarketDataDateShift.CURRENT_DAY)
        .build()
        .as("CubeMeasure");
```

#### Example - `FxRateMarketDataMeasureBuilder` builder

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
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");

CopperPostProcessor fxMeasure = new FxRateMarketDataMeasureBuilder(asOfDateLevel, marketDataSetLevel, currencyLevel, displayCurrencyLevel,
        MarketDataDateShift.CURRENT_DAY)
        .build()
        .as("FX Rate");
```
