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.

allows developers to implement their own maturity converters based on the IMaturityConverter interface. This page will walk you through the process of implementing a converter than can be configured in a properties file.

The IMaturityConverter interface and the MaturityConverterConfig class

Any implementation of a maturity converter implements the IMaturityConverter interface. These implementations must be autowirable through Spring, as well as usable as an extended plugin. The interface defines two methods:
  • toDate() to convert a String tenor to a LocalDate object
  • toYearFraction() to return the year fraction between a LocalDate as-of-date and a String maturity
The MaturityConverterConfig class is used to expose (as a bean) the implementation of the interface that is used throughout the project. The default implementation is Actual360MaturityConverter , based on the Actual/360 day count convention. The example implementation below does not use the leafCoordinates or pivot parameters defined in the interface, as currently all conversion is handled in the ETL.

Implementing a custom configurable converter

Although the default converter is hard-coded to the Actual/360 convention, you can easily implement a converter that uses the Spring environment to define the day counts. The static class constants must cover:
  • Defaults for the week, month and year day counts
  • Keys for the Spring environment properties
  • A Map<String, Integer> to allow repeated retrieval of day values after initialisation
public ConfigurableMaturityConverter(Environment env) {
   DAY_VALUES.put(DAY_KEY, 1);
   DAY_VALUES.put(WEEK_KEY, Integer.parseInt(env.getProperty(WEEK_PROPERTY, WEEK_DEFAULT)));
   DAY_VALUES.put(MONTH_KEY, Integer.parseInt(env.getProperty(MONTH_PROPERTY, MONTH_DEFAULT)));
   DAY_VALUES.put(YEAR_KEY, Integer.parseInt(env.getProperty(YEAR_PROPERTY, YEAR_DEFAULT)));
}
Then add the week, month and year values to the application.properties file, which is loaded by default into the Spring environment:
# The number of days in a week, for maturity conversion purposes.
maturity-conversion.days.week=7

# The number of days in a month, for maturity conversion purposes.
maturity-conversion.days.month=30

# The number of days in a year, for maturity conversion purposes.
maturity-conversion.days.year=365
To take advantage of the LocalDate API, the toYearFraction() method converts the String maturity into a LocalDate using the toDate() method, and retrieves the year count directly from the Map initialised above:
@Override
public double toYearFraction(IActivePivot pivot, IDatastoreVersion datastoreVersion, LocalDate asOfDate, String maturity, List<Object> leafCoordinates) {
   LocalDate maturityDate = toDate(pivot, datastoreVersion, asOfDate, maturity, new LocalDateParser(), leafCoordinates);
   Double daysFromAsOfDate = (double)(maturityDate.toEpochDay() - asOfDate.toEpochDay());
   return daysFromAsOfDate / DAY_VALUES.get(YEAR_KEY);
}
The toDate() method has to handle both String representations of dates, as well as tenors. One of the parameters of the method is a LocalDateParser, which can be initialised to use any date format (with the default being yyyy-MM-dd).
@Override
public LocalDate toDate(IActivePivot pivot, IDatastoreVersion datastoreVersion, LocalDate asOfDate, String tenorOrDate, LocalDateParser parser, List<Object> leafCoordinates) {
   LocalDate sensitivityDate;
   try {
      sensitivityDate = parser.parse(tenorOrDate);
   } catch (DateTimeParseException e) {
      // Not a date, mostly a tenor
      sensitivityDate = asOfDate.plusDays(daysInTenor(tenorOrDate));
   }
   return sensitivityDate;
}
In this example, the conversion of the tenor into a number of days is handled in the static daysInTenor method. The example covers the Tomorrow Next tenor, and any combination of a number and one of D,W,M,Y in both uppercase and lowercase. In the FRTB project, tenors expressed as numbers without a period string are assumed to be fractions of a year. Any special cases and error handling must be incorporated in this conversion.
private static int daysInTenor(String tenor) {

   if(tenor.equalsIgnoreCase("TN")) {
      return 2;
   }

   double number = Double.parseDouble(tenor.replaceAll("[^0-9.]", ""));
   String tenorPeriod = String.valueOf(tenor.charAt(tenor.length() - 1));
   tenorPeriod = tenorPeriod.replaceAll("[0-9]", "");
   int days = 0;
   String tenorLowerCase = tenorPeriod.toLowerCase();
   if(!tenorLowerCase.isEmpty() && DAY_VALUES.containsKey(tenorLowerCase)) {
      days = (int) number * DAY_VALUES.get(tenorLowerCase);
   } else {
      //assume it's an frtb vertex expressed in years
      double vertex = Double.parseDouble(tenor);
      days = (int) (vertex * DAY_VALUES.get(YEAR_KEY));
   }
   return days;
}
To use the ConfigurableMaturityConverter, the MaturityConverterConfig class must autowire the environment and initialise the converter, exposing it as a bean:
@Configuration
public class MaturityConverterConfig implements IMaturityConverterConfig {

   @Autowired
   private Environment env;

   /**
    * Returns the maturity converter to be used in the project, as a Spring bean.
    * Default maturity converter is a {@link com.activeviam.frtb.core.dates.impl.Actual360MaturityConverter}.
    * This should be replaced by any custom maturity converter required by the project.
    * @return The required maturity converter.
    */
   @Bean
   public IMaturityConverter maturityConverter() {
      return new ConfigurableMaturityConverter(env);
   }

}