> ## 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.

# Replacing the FX rates bean

export const productName = "Atoti FRTB";

The FX Rates service controls how currency conversion is performed across all cubes.
By default, {productName} creates a `ScenarioFxRates` bean that reads rates from the
`FXRates` datastore table and supports scenario-specific FX vectors for IMA Expected Shortfall
and Stress Calibration.

## Default configuration

The bean is defined in `FxRatesServiceConfig`:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@Bean
@Qualifier("fxRates")
public IScenarioFxRates fxRates(
        @Qualifier(ES_SCENARIO_TYPE) ScenarioFxRates.IDirectScenarioFxRates esScenarioFxRates,
        @Qualifier(STRESS_CALIBRATION_SCENARIO_TYPE) ScenarioFxRates.IDirectScenarioFxRates stressCalibrationScenarioFxRates
) {
    return new ScenarioFxRates(commonCcy, Map.of(
            ES_SCENARIO_TYPE, esScenarioFxRates,
            STRESS_CALIBRATION_SCENARIO_TYPE, stressCalibrationScenarioFxRates
    ));
}
```

This bean is then injected into every FX post-processor and FX analysis hierarchy by
`FRTBPostProcessorConfig.apManagerInitPrerequisitePluginInjections()`:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
injectAll(IFXRatesAware.class, fxRates);
injectAll(IScenarioFxRates.Aware.class, fxRates);
```

No changes to `FRTBPostProcessorConfig` are needed when replacing the bean — the injection
calls automatically pick up whichever `IScenarioFxRates` bean Spring resolves.

## Replacing the FX Rates bean

To provide a custom FX rates implementation (for example, parameter-set-specific rates),
create a new `@Configuration` class that extends `FxRatesServiceConfig` and override the
`fxRates()` bean method:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@Configuration
public class CustomFxRatesConfig extends FxRatesServiceConfig {

    @Override
    @Bean
    @Qualifier("fxRates")
    public IScenarioFxRates fxRates(
            @Qualifier(ES_SCENARIO_TYPE) ScenarioFxRates.IDirectScenarioFxRates esScenarioFxRates,
            @Qualifier(STRESS_CALIBRATION_SCENARIO_TYPE) ScenarioFxRates.IDirectScenarioFxRates stressCalibrationScenarioFxRates
    ) {
        return new MyCustomScenarioFxRates(commonCcy, Map.of(
                ES_SCENARIO_TYPE, esScenarioFxRates,
                STRESS_CALIBRATION_SCENARIO_TYPE, stressCalibrationScenarioFxRates
        ));
    }
}
```

The custom implementation must implement `IScenarioFxRates` (or extend `ScenarioFxRates`).
The two key methods to implement or override are:

| Method                               | Purpose                                                                                                                                                                                                                                     |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `getFxRate(...)`                     | Returns the FX rate for a given currency pair. The `leafCoordinates` parameter carries any extra coordinates registered by `updateLeafCoordinatesFunction` (e.g. the parameter set).                                                        |
| `updateLeafCoordinatesFunction(...)` | Registers extra leaf levels that the FX post-processor should resolve at query time. Return a `LocationFunction` whose `getRequiredLevels()` declares the extra levels and whose `apply()` extracts the coordinate from the query location. |

### Example: parameter-set-specific FX rates

To return different FX rates depending on the Parameter Set dimension, the custom
implementation should:

1. Override `updateLeafCoordinatesFunction` to register the Parameter Set level as an extra
   leaf level using a `LocationFunction`:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@Override
public LocationFunction updateLeafCoordinatesFunction(
        IActivePivot pivot, Properties properties,
        String ppPluginKey, LocationFunction userFunction) {

    ILevelInfo parameterSetLevel = HierarchiesUtil.getLevel(pivot,
            new LevelIdentifier(PARAMETERS_SET_DIM, PARAMETER_SET_HIERARCHY, PARAMETER_SET_LVL));

    return new LocationFunction() {
        @Override
        public @NonNull List<Object> apply(
                @NonNull ILocation location, @NonNull IQueryCache cache) {
            return List.of(
                    LocationUtil.isAtOrBelowLevel(location, parameterSetLevel)
                            ? LocationUtil.getCoordinate(location, parameterSetLevel)
                            : "BCBS");
        }

        @Override
        public @NonNull Collection<ILevelInfo> getRequiredLevels() {
            return List.of(parameterSetLevel);
        }
    };
}
```

2. Override `getFxRate` to read the parameter set from `leafCoordinates` and return the
   appropriate rate:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@Override
public Double getFxRate(
        IDatabaseVersion datastore, LocalDate asOfDate,
        String baseCcy, String counterCcy, int maxFallbackDays,
        IDateShift dateInfo, IActivePivot activePivot,
        List<Object> leafCoordinates) {

    String parameterSet = leafCoordinates.isEmpty()
            ? "BCBS"
            : leafCoordinates.getFirst().toString();

    // Look up parameter-set-specific rate, falling back to default
    return lookupRate(parameterSet, baseCcy, counterCcy, asOfDate);
}
```

## Related classes

| Class                     | Module                     | Description                                 |
| ------------------------- | -------------------------- | ------------------------------------------- |
| `FxRatesServiceConfig`    | frtb-activepivot           | Default bean definition                     |
| `FRTBPostProcessorConfig` | frtb-activepivot           | Injection into post-processors              |
| `ScenarioFxRates`         | frtb-core                  | Default implementation (extends `FxRates`)  |
| `IScenarioFxRates`        | frtb-core                  | Interface adding scenario FX vector support |
| `IFxRates`                | common-accelerator-library | Base interface for FX rate retrieval        |
| `LocationFunction`        | common-accelerator-library | Interface for registering extra leaf levels |
