Custom Measure not working


#1

I’m trying to extend FxSingleTrade to add my own custom measure by following this guide: Adding a New Measure

So far I’ve created an ExtendedMeasures class, implemented FxSingleTradeForwardPointsFunction and registered with:

CalculationFunctions functions = StandardComponents.calculationFunctions().composedWith(CalculationFunctions
.of(new FxFlexibleForwardTradeCalculationFunction(), new FxSingleTradeForwardPointsFunction()));

The error I’m getting is: Unable to get a value from a failure result: Measure ‘FxSwapRate’ is not supported by function 'FxSingleTradeCalculationFunction’

My code is in Github here: Strata Extensions and there is a JUnit test FxForwardTest that demonstrates this issue.

Am I doing this correctly?


#2

You need to extend AbstractDerivedCalculationFunction instead of implementing CalculationFunction. You set up similar things, but typically depend on Measures.RESOLVED_TARGET. I’ve updated the docs with more info: http://strata.opengamma.io/add_measure/


#3

It worked but then broke other stuff such as NDF and FxSwap. In your example the constructor is private, so for mine I made the constructor public and registered it this way:

		CalculationFunctions functions = StandardComponents.calculationFunctions()
				.composedWith(CalculationFunctions.of(new FxFlexibleForwardTradeCalculationFunction()))
				.composedWith(new FxSingleTradeForwardPointsFunction());

This worked for my test case but now other FX types are broken with a NPE thrown in DerivedCalculationFunctions.wrap.

I added a test for FxNdf to demonstrate the NPE an pushed it to github: Strata Extensions

To fix, it’s sufficient to use getOrDefault as opposed to get (or check for null):

  @SuppressWarnings("unchecked")
  private <T extends CalculationTarget, R> CalculationFunction<? super T> wrap(CalculationFunction<? super T> fn, T target) {
    List<DerivedCalculationFunction<?, ?>> derivedFunctions =
        functionsByTargetType.getOrDefault(target.getClass(), ImmutableList.of());
    CalculationFunction<? super T> wrappedFn = fn;

    for (DerivedCalculationFunction<?, ?> derivedFn : derivedFunctions) {
      // These casts are necessary because the type information is lost when the functions are stored in the map.
      // They are safe because T is the target type which is is the map key and R isn't actually used
      CalculationFunction<T> wrappedFnCast = (CalculationFunction<T>) wrappedFn;
      DerivedCalculationFunction<T, R> derivedFnCast = (DerivedCalculationFunction<T, R>) derivedFn;
      wrappedFn = new DerivedCalculationFunctionWrapper<>(derivedFnCast, wrappedFnCast);
    }

    return wrappedFn;
  }

#4

Thanks: https://github.com/OpenGamma/Strata/pull/1856


#5

Is there a snapshot repo I can pull this from? Otherwise I can refer to my local repo copy.


#6

We don’t have a formal snapshot repo I’m afraid, nor do we guarantee particular timelines for releases. So I think building it locally is best for now.


#7

OK, thanks. At the moment I’m grafting Quantlib underneath Strata to allow me to price things that are missing such as: Callable/Cancellable swaps, Bermudan Swaptions etc. As a consequence I will be creating a lot of CalculationFunctions. It would be convenient if they could be automatically registered either through a Spring like reflection mechanism, or by specifying them in an .ini file that can be read in (as opposed to doing this in code). Is there already a way to extend CalculationFunctions dynamically?


#8

Interesting idea. There is no current dynamic mechanism, but you could implement CalculationFunctions yourself.