Skip to main content

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.

This page describes the mechanism introduced in MR 3.1.0 that allows you to customize the measure configuration through Spring Beans. It also provides an example of adding customization using the new mechanism.

Concept

Measures in Atoti Market Risk are now configured as replaceable qualified Spring Beans, with the Atoti Server post-processing chain being composed through the use of qualified parameters in the bean creation methods.

Bean annotations

All measure beans in Atoti Market Risk have custom annotations, per cube. These annotations attach a Copper context to the bean and make instantiation conditional on the cube being enabled.

Available annotations

AnnotationConditionCube
SensitivitiesCopperContextBeanBeanEnabledSensitivitiesCubeSensitivity Cube
SensitivitiesSummaryCopperContextBeanBeanEnabledSensitivitiesSummaryCubeSensitivity Summary Cube
VarCopperContextBeanBeanEnabledVaRCubeVaR-ES Cube
VarSummaryCopperContextBeanBeanEnabledVaRSummaryCubeVaR-ES Summary Cube
PnLCopperContextBeanBeanEnabledPnLCubePLCube
PnLSummaryCopperContextBeanBeanEnabledPnLSummaryCubePL Summary Cube
MarketDataCopperContextBeanBeanEnabledMarketDataCubeMarket Data Cube

The Resolver objects

Each cube in Atoti Market Risk uses an implementation of the IMeasureResolver interface that defines the annotation to use for the measures intended for that cube.
    @Bean
    @Qualifier(SP_QUALIFIER__VAR_MEASURES_RESOLVER)
    @Conditional(BeanEnabledVaRCube.class)
    public IMeasureResolver varResolver(ICopperContextScopeManager scopeManager, ConfigurableListableBeanFactory beanFactory) {
        return new MeasureResolver(scopeManager, beanFactory, VarCopperContextBean.class);
    }
The IMeasureResolver interface performs the following actions:
  • Collects all annotated beans.
  • Groups them by @Qualifier.
  • Selects the @Primary bean for each individual @Qualifier.
  • Publishes the beans on the Copper context, ordered by dependency relationship.

Available Resolvers

QualifierConditionAnnotation
SP_QUALIFIER__SENSITIVITY_MEASURES_RESOLVERBeanEnabledSensitivitiesCubeSensitivitiesCopperContextBean
SP_QUALIFIER__SENSITIVITY_SUMMARY_MEASURES_RESOLVERBeanEnabledSensitivitiesSummaryCubeSensitivitiesSummaryCopperContextBean
SP_QUALIFIER__VAR_MEASURES_RESOLVERBeanEnabledVaRCubeVarCopperContextBean
SP_QUALIFIER__VAR_SUMMARY_MEASURES_RESOLVERBeanEnabledVaRSummaryCubeVarSummaryCopperContextBean
SP_QUALIFIER__PNL_MEASURES_RESOLVERBeanEnabledPnLCubePnLCopperContextBean
SP_QUALIFIER__PNL_SUMMARY_MEASURES_RESOLVERBeanEnabledPnLSummaryCubePnLSummaryCopperContextBean
SP_QUALIFIER__MARKET_DATA_MEASURES_RESOLVERBeanEnabledMarketDataCubeMarketDataCopperContextBean

The MeasurePublisher beans

For each cube, a MeasurePublisher bean is created, which is responsible for calling the measure creation objects in the correct order. The possible measure creation objects are:
ObjectMethodDescription
CopperCubePublisher copperCubeCopperCubePublisher::acceptOptional publisher responsible for setting up Copper-defined hierarchies.
IMeasureResolver measureResolverIMeasureResolver::measuresIMeasureResolver object responsible for beans defined using the mechanism described on this page.
List<MeasurePublisher> additionalMeasuresMeasurePublisher::acceptOptional List of publishers for additional measures.
The optional objects are not available on the Summary cubes. To replace the default copperCube and additionalMeasures publishers, the following qualifiers are available:
QualifierCube
SP_QUALIFIER__SENSITIVITY_COPPER_CUBESensitivity Cube
SP_QUALIFIER__ADDITIONAL_SENSITIVITY_MEASURESSensitivity Cube
SP_QUALIFIER__VAR_COPPER_CUBEVaR-ES Cube
SP_QUALIFIER__ADDITIONAL_VAR_MEASURESVaR-ES Cube
SP_QUALIFIER__PNL_COPPER_CUBEPLCube
SP_QUALIFIER__ADDITIONAL_PNL_MEASURESPLCube
SP_QUALIFIER__MARKET_DATA_COPPER_CUBEMarket Data Cube
SP_QUALIFIER__ADDITIONAL_MARKET_DATA_MEASURESMarket Data Cube
The MeasurePublisher beans used by the cube configuration classes use the following qualifiers:
QualifierCubeCondition
SP_QUALIFIER__SENSITIVITY_MEASURESSensitivity CubeBeanEnabledSensitivitiesCube
SP_QUALIFIER__SENSITIVITY_SUMMARY_MEASURESSensitivity Summary CubeBeanEnabledSensitivitiesSummaryCube
SP_QUALIFIER__VAR_MEASURESVaR-ES CubeBeanEnabledVaRCube
SP_QUALIFIER__VAR_SUMMARY_MEASURESVaR-ES Summary CubeBeanEnabledVaRSummaryCube
SP_QUALIFIER__PNL_MEASURESPLCubeBeanEnabledPnLCube
SP_QUALIFIER__PNL_SUMMARY_MEASURESPL Summary CubeBeanEnabledPnLSummaryCube
SP_QUALIFIER__MARKET_DATA_MEASURESMarket Data CubeBeanEnabledMarketDataCube
SP_QUALIFIER__COMMON_MEASURESCombined CubeBeanEnabledCommonCube

Parameter objects

The cube-specific measure chains rely on parameter objects that contain:
  • Configuration properties (usually cube levels, members, formatters)
  • Parameters required for creating measures (e.g. formula providers, the market data retrieval service, the number of axes for a sensitivity)
  • Constants for use in @Qualifier annotations
  • Methods for naming measures
The following object types are available:
ObjectCubeDescription
MarketDataMeasureParametersMarket Data CubeMeasure parameters for the Market Data cube, containing cube levels, members and formatters.
MarketDataMeasureNamesMarket Data CubeConstants and naming methods for the Market Data cube.
PnLMeasureParametersPLCube, PL Summary CubeMeasure parameters for the PL and PL Summary cubes, containing cube levels and formatters.
PnLMeasureNamesPLCube, PL Summary CubeConstants and naming methods for the PL and PL Summary cubes.
SensiMeasureParametersSensitivity Cube, Sensitivity Summary CubeMeasure parameters for the Sensitivity and Sensitivity Summary cubes, containing cube levels, members, formatters, formula providers, the number of axes for a sensitivity, the maturity converter and the market data retrieval service together with custom parameters for the service.
SensiMeasureNamesSensitivity Cube, Sensitivity Summary CubeConstants and naming methods for the Sensitivity and Sensitivity Summary cubes.
DividendMeasureNamesSensitivity Cube, Sensitivity Summary CubeConstants and naming methods specific to the Dividend measures in the Sensitivity and Sensitivity Summary cubes.
VaRMeasureParametersVaR-ES Cube, VaR-ES Summary CubeMeasure parameters for the VaR-ES and VaR-ES Summary cubes, containing cube levels, members and formatters, as well as configurable confidence levels and risk classes.
VaRMetricParametersAndNamesVaR-ES Cube, VaR-ES Summary CubeConstants and naming methods for the VaR-ES and VaR-ES Summary cubes, together with the postprocessor object specific to each VaR metric (VaR, Harrel-Davis VaR, VaE, ES, ETG, Weighted VaR, Weighted VaE, Weighted ES, and Weighted ETG).
The [...]MeasureParameters and VaR-ES Cube metric-specific [...]Names objects are exposed as beans. For the other cubes, the [...]Names objects are created using the parameter beans. To replace the beans, the following qualifiers are available:
QualifierTypeDescription
SP_QUALIFIER__MARKET_DATA_MEASURE_PARAMETERSMarketDataMeasureParametersMeasure parameters for the Market Data cube.
SP_QUALIFIER__PNL_MEASURE_PARAMETERSPnLMeasureParametersMeasure parameters for the PL and PL Summary cubes.
SP_QUALIFIER__VAR_CUBE_MEASURE_PARAMETERSVaRMeasureParametersMeasure parameters for the VaR-ES and VaR-ES Summary cubes.
SP_QUALIFIER__ES_PARAMETERSVaRMetricParametersAndNamesThe constants, naming methods, and postprocessor for the ES metric.
SP_QUALIFIER__ETG_PARAMETERSVaRMetricParametersAndNamesThe constants, naming methods, and postprocessor for the ETG metric.
SP_QUALIFIER__HD_PARAMETERSVaRMetricParametersAndNamesThe constants, naming methods, and postprocessor for the Harrel-Davis VaR metric.
SP_QUALIFIER__VAE_PARAMETERSVaRMetricParametersAndNamesThe constants, naming methods, and postprocessor for the VaE metric.
SP_QUALIFIER__VAR_PARAMETERSVaRMetricParametersAndNamesThe constants, naming methods, and postprocessor for the VaR metric.
SP_QUALIFIER__WES_PARAMETERSVaRMetricParametersAndNamesThe constants, naming methods, and postprocessor for the Weighted ES metric.
SP_QUALIFIER__WETG_PARAMETERSVaRMetricParametersAndNamesThe constants, naming methods, and postprocessor for the Weighted ETG metric.
SP_QUALIFIER__WVAE_PARAMETERSVaRMetricParametersAndNamesThe constants, naming methods, and postprocessor for the Weighted VaE metric.
SP_QUALIFIER__WVAR_PARAMETERSVaRMetricParametersAndNamesThe constants, naming methods, and postprocessor for the Weighted VaR metric.
SP_QUALIFIER__BASE_MEASURE_PARAMETERSSensiMeasureParametersRequired measure parameters for the common and aggregated Sensitivity measure chains.
SP_QUALIFIER__DELTA_MEASURE_PARAMETERSSensiMeasureParametersRequired measure parameters for the Delta measure chains.
SP_QUALIFIER__GAMMA_MEASURE_PARAMETERSSensiMeasureParametersRequired measure parameters for the Gamma measure chains.
SP_QUALIFIER__VEGA_MEASURE_PARAMETERSSensiMeasureParametersRequired measure parameters for the Vega measure chains.
SP_QUALIFIER__VANNA_MEASURE_PARAMETERSSensiMeasureParametersRequired measure parameters for the Vanna measure chains.
SP_QUALIFIER__VOLGA_MEASURE_PARAMETERSSensiMeasureParametersRequired measure parameters for the Volga measure chains.
SP_QUALIFIER__THETA_MEASURE_PARAMETERSSensiMeasureParametersRequired measure parameters for the Theta measure chains.
SP_QUALIFIER__CROSS_GAMMA_MEASURE_PARAMETERSSensiMeasureParametersRequired measure parameters for the Cross Gamma measure chains.
SP_QUALIFIER__CORRELATION_MEASURE_PARAMETERSSensiMeasureParametersRequired measure parameters for the Correlation measure chains.
SP_QUALIFIER__DIVIDEND_MEASURE_PARAMETERSSensiMeasureParametersRequired measure parameters for the Dividend measure chains.

Factories

The logic for creating Copper-based measures is contained within collections of interfaces split by logical measure sub-chain (e.g. ILadderExpansionMeasures, IRiskClassFixedConfidenceMeasures). For each cube, an abstract factory class implements the specific interfaces and stores the Parameters and Names objects required. Concrete classes extend the abstract class and define common helper methods. The methods contained within the factory interfaces are mostly of the type MeasureCreator, an interface alias for Function<CopperMeasure[], CopperMeasure>. The function takes an array of underlying measures and returns a single resulting measure. The alias also defines two additional methods:
  • MeasureCreator#on(CopperMeasure... measures) - an alias for Function#apply(measures) that allows the usage of varargs
  • MeasureCreator#noUnderlying() - an alias for Function#apply(null)
The following factory classes are available:
CubeFactoryAbstract classInterfaceDescription
Market Data CubeMarketDataFactoryAMarketDataFactoryIMarketDataMeasuresAll MeasureCreator objects used in creating measures for the Market Data cube.
PLCube, PL Summary CubePnLFactoryAPnLFactoryIPnLMeasuresAll MeasureCreator objects used in creating measures for the PL and PL Summary cubes.
Sensitivity Cube, Sensitivity Summary CubeSensiFactoryASensiFactoryIBaseMeasuresMeasureCreator objects for creating measures not split by sensitivity type.
IBucketedMeasuresMeasureCreator objects for measures that can be bucketed on time pillars.
IDayToDayMeasuresMeasureCreator objects for creating day-to-day difference measures.
ILadderExpansionMeasuresMeasureCreator objects for creating ladder measures.
INamedDayToDayMeasuresMeasureCreator objects for day-to-day measures.
INativeCurrencyMeasuresMeasureCreator objects for creating sensitivity measures in the native currency.
ISensitivityMeasuresMeasureCreator objects for creating the top-level, post-FX sensitivity measures.
ISplitMeasuresMeasureCreator objects for creating corporate split measures.
Sensitivity CubePnLExplainFactoryAPnLExplainFactoryIAggregateMeasuresMeasureCreator objects for creating aggregated top level measures (e.g. with a plus operation).
IBasePnLExplainMeasuresMeasureCreator objects for creating measures not split by sensitivity type.
IBucketedMeasuresSee above.
IFilteredMeasuresSee above.
INamedDayToDayMeasuresSee above.
IPnLExplainMeasuresMeasureCreator objects for creating PnL Explain measures, by sensitivity and aggregated.
ISensitivityMarketDataMeasuresSee above.
ISplitMeasuresSee above.
Sensitivity CubeTaylorFactoryATaylorFactoryIAggregateMeasuresSee above.
IBucketedMeasuresSee above.
IContextualMeasuresMeasureCreator objects for creating measures with the confidence level controlled through a context value.
IFilteredMeasuresSee above.
IFixedConfidenceMeasuresMeasureCreator objects for creating measures per configurable confidence levels.
IIncrementalMeasuresMeasureCreator objects for creating Incremental, LEstimator, Component VaR and Component VaR Delta measures.
INamedDayToDayMeasuresSee above.
IShiftMeasuresMeasureCreator objects for creating market shift measures.
ISplitMeasuresSee above.
IStatisticalMeasuresMeasureCreator for measures that perform statistical operations on vectors (e.g. min, max, mean).
ITaylorVaRMeasuresMeasureCreator objects for creating Taylor VaR measures, by sensitivity and aggregated.
IVaRESMeasuresMeasureCreator objects for creating measures not split by metric type.
VaR-ES Cube, VaR-ES Summary CubeVaRFactoryAVaRFactoryIContextualMeasuresSee above.
IContextualRiskClassMeasuresMeasureCreator objects for creating measures with the confidence level controlled through a context value, split by configurable risk class.
IFixedConfidenceMeasuresSee above.
IIncrementalMeasuresSee above.
IRiskClassFixedConfidenceMeasuresMeasureCreator objects for creating measures per configurable confidence level, split by configurable risk class.
IVaRESMeasuresSee above.

Chains

Chain classes are configuration classes that leverage measure factories to define a measure chain as a collection of beans. A typical measure definition consists of:
  • The cube-specific bean annotation (see Bean annotations)
  • A @Qualifier annotation specific to the measure.
  • (OPTIONAL) A @MeasureGroup annotation marking the measure to be part of a group.
  • (OPTIONAL) A @Conditional annotation to enable/disable creating the measure depending on the project configuration.
  • The type of the bean (CopperMeasure and CopperMeasure[] are currently supported).
  • Underlying measures as qualified parameters of the method.
  • The logic for creating the measure, within the method body.

Examples

A measure defined as part of the PNL_EXPLAIN_NEXT_DATE group:
    @SensitivitiesCopperContextBean
    @Qualifier(SENSI + PNL_EXPLAIN_NEXT_DATE)
    @MeasureGroup(PNL_EXPLAIN_NEXT_DATE)
    public CopperMeasure correlationPnlExplainNextDate(@Qualifier(SENSI + PNL_EXPLAIN_NATIVE_NEXT_DATE) CopperMeasure pnlExplainNativeNextDate) {
        return getFactory().pnlExplainNextDate().on(pnlExplainNativeNextDate);
    }
A measure operating on all measures part of the PNL_EXPLAIN_NEXT_DATE group:
    @SensitivitiesCopperContextBean
    @Qualifier(AGGREGATE_PNL_EXPLAIN_NATIVE_NEXT_DATE)
    public CopperMeasure pnlExplainNativeNextDate(@MeasureGroup(PNL_EXPLAIN_NATIVE_NEXT_DATE) CopperMeasure[] sensitivitiesPnlExplainNativeNextDate) {
        return getFactory().aggregateMeasures(SensiMeasureNames::getAggregatePnlExplainNativeNextDate).on(sensitivitiesPnlExplainNativeNextDate);
    }
A measure bean generating multiple measures based on project configuration:
    @VarCopperContextBean
    @Qualifier(METRIC + CONFIDENCE)
    public CopperMeasure[] esMetricConfidence(@Qualifier(VAR_FX_VECTOR) CopperMeasure varEsVarFxVector) {
        CopperMeasure[] returnArray = new CopperMeasure[getConfidenceLevels().size()];
        for (int i = 0; i < getConfidenceLevels().size(); i++) {
            returnArray[i] = getFactory().metricConfidence(getConfidenceLevels().get(i)).on(varEsVarFxVector);
        }
        return returnArray;
    }
The following packages contain [...]Chain classes implementing the relevant interfaces:
PackageFactory
com.activeviam.mr.marketdata.measures.chainsA single MarketDataFactory.
com.activeviam.mr.pnl.measures.chains.completeThe common PnLFactory.
com.activeviam.mr.pnl.measures.chains.summaryThe common PnLFactory.
com.activeviam.mr.productcontrol.measures.chainsThe common PnLFactory.
com.activeviam.mr.sensi.measures.chains.completeA SensiFactory instance per sensitivity type, providing the correct Parameters and Names.
A PnLExplainFactory instance per sensitivity type, providing the correct Parameters and Names.
A TaylorFactory instance per sensitivity type, providing the correct Parameters and Names.
com.activeviam.mr.sensi.measures.chains.summaryA SensiFactory instance per sensitivity type, providing the correct Parameters and Names.
com.activeviam.mr.var.measures.chains.completeA VaRFactory instance per metric type, providing the correct Parameters and Names.
com.activeviam.mr.var.measures.chains.summaryA VaRFactory instance per metric type, providing the correct Parameters and Names.
Each package contains one or more [...]Chain classes, split by logical measure sub-chain. As multiple measures can make use of the same factory MeasureCreator method, a single factory interface can result in multiple [...]Chain classes. The Sensitivity and VaR-ES measures are further duplicated by sensitivity type and VaR metric, respectively. Each sensitivity type and VaR metric has a base abstract class that defines specific Parameters objects to be used in creating the relevant Factory. Summary cubes also have a (sometimes smaller) set of [...]Chain classes, with potentially missing measures.

Customization mechanism and examples

The internal configuration described in the Concept section enables the customization of measures through standalone bean definitions anywhere in the project configuration. To customize a measure chain, you can replace individually qualified measures by defining a bean with the same annotations, marked as @Primary. Making the configuration class extend one of the A[...]Chain abstract classes gives access to the factory, names and parameters objects specific to that chain, through getFactory(), getFactory().getNames() and getParameters(). While all internally defined measures make use of the factories, this is not a requirement.

Replacing the PnLVectorExpand measure

@Configuration
public class CustomMeasuresConfig extends AVaRESChain {

    private static final int[] MULTIPLIERS = new int[]{2, 3, 5};

    @VarCopperContextBean
    @Qualifier(PNL_VECTOR_EXPAND)
    @Primary
    public CopperMeasure expandRename(@Qualifier(PNL_VECTOR_EXPAND) CopperMeasure pnlVectorExpand) {
        return pnlVectorExpand.as("PnLVectorExpandOld");
    }

    @VarCopperContextBean
    @Qualifier("MultiplePnLVectorExpand")
    @Primary
    public CopperMeasure[] multiply(@Qualifier(PNL_VECTOR_EXPAND) CopperMeasure pnlVectorExpand) {
        CopperMeasure[] returnArray = new CopperMeasure[MULTIPLIERS.length];
        for (int i = 0; i < MULTIPLIERS.length; i++) {
            returnArray[i] = pnlVectorExpand.multiply(Copper.constant(MULTIPLIERS[i])).as("PnLVectorExpand x " + MULTIPLIERS[i]);
        }
        return returnArray;
    }

    @VarCopperContextBean
    @Qualifier("Aggregate PnL Vector Expand")
    @Primary
    public CopperMeasure aggregatePnLVectorExpand(@Qualifier("MultiplePnLVectorExpand") CopperMeasure[] multipliedPnLVectorExpand) {
        return Arrays.stream(multipliedPnLVectorExpand).reduce(CopperMeasure::plus).get().as(PNL_VECTOR_EXPAND);
    }

    @VarCopperContextBean
    @Qualifier(PNL_VECTOR_EXPAND_NEIGHBOUR_VALUE)
    @Primary
    public CopperMeasure customVarEsPnlVectorExpandNeighbourValue(@Qualifier("Aggregate PnL Vector Expand") CopperMeasure varEsPnlVectorExpand) {
        return getFactory().pnlVectorExpandNeighbour().on(varEsPnlVectorExpand);
    }
}
In this example we’re renaming the initial PnLVectorExpand measure to PnLVectorExpandOld, creating PnLVectorExpand x 2, PnLVectorExpand x 3 and PnLVectorExpand x 5 measures and summing them up to replace the initial PnLVectorExpand measure. Finally, to ensure our new bean is in the correct position in the chain, we replace the PNL_VECTOR_EXPAND_NEIGHBOUR_VALUE bean and use Aggregate PnL Vector Expand instead of PNL_VECTOR_EXPAND as the underlier.

Replacing a subchain

If the use-case requires replacing a longer part of a measure chain (e.g. skipping several intermediate steps), the intermediate beans also have to be explicitly replaced. Two options are available:
  • Replacing the bean and returning null:
    @SensitivitiesCopperContextBean
    @Qualifier(SENSI + NATIVE_INTERMEDIATE)
    @Primary
    public CopperMeasure deltaSensiNativeIntermediate() {
        return null;
    }
  • Replacing the bean and returning the underlier:
    @SensitivitiesCopperContextBean
    @Qualifier(SENSI + NATIVE_VECTOR_EXPAND)
    public CopperMeasure deltaSkipVectorNativeExpand(@Qualifier(SENSI + NATIVE_SUM_TECHNICAL_FILTERED) CopperMeasure sumTechnicalFiltered) {
        return sumTechnicalFiltered;
    }
If the intermediate measures are likely to be used as underliers in other parts of the chain, return the underlier to avoid NullPointerException issues.

Suggested Further Reading

Custom Measures Warning

Atoti Market Risk cubes and their summary variants (for example the VaR-ES Cube and the VaR-ES Summary Cube) are created as a horizontal distribution. This enables Atoti Market Risk to show a single measure (for example VaR) with some dates coming from the full cube and other date contributions from the summary cube. This is a useful feature, but it comes with a warning. Atoti Server expects that all cubes in a horizontal distribution have exactly identical measure chains. If they do not, this can lead to errors or incorrect results when queries are executed on a query cube with both cubes. The measure chains in Atoti Market Risk are not identical between main and summary cubes, but we have taken care to avoid these failure scenarios. We strongly recommend that, if you are using summary cubes, you add any new measures both to the main and summary cubes.
Measure chain differences between main and summary cubes may lead to runtime errors or incorrect query results.