CreditCurvePointShift implements Perturbation, ImmutableBean { public static CreditCurvePointShift relative(Map<Tenor, Double> shifts) { return new CreditCurvePointShift(ShiftType.RELATIVE, shifts); } private  CreditCurvePointShift(
      ShiftType shiftType,
      Map<Tenor, Double> shifts); static CreditCurvePointShift absolute(Map<Tenor, Double> shifts); static CreditCurvePointShift relative(Map<Tenor, Double> shifts); @Override CreditCurveData apply(Object marketData, MatchDetails matchDetails); @Override Class<?> getMarketDataType(); @Override Class<? extends MatchDetails> getMatchDetailsType(); @Override PerturbationTarget getTargetType(); static CreditCurvePointShift.Meta meta(); static CreditCurvePointShift.Builder builder(); @Override CreditCurvePointShift.Meta metaBean(); @Override Property<R> property(String propertyName); @Override Set<String> propertyNames(); Builder toBuilder(); @Override boolean equals(Object obj); @Override int hashCode(); @Override String toString();  }
@Test public void relative() { ImmutableMap<Tenor, Double> shifts = ImmutableMap.of(Tenor.ONE_YEAR, 0.01, Tenor.THREE_YEARS, 0.02, Tenor.TEN_YEARS, 0.10); CreditCurvePointShift relative = CreditCurvePointShift.relative(shifts); CreditCurveData shifted = relative.apply(CreditPricingSampleData.createSingleNameCreditCurveData(), StandardMatchDetails.MATCH); ImmutableSortedMap<Tenor, CdsQuote> cdsQuotes = shifted.getCdsQuotes(); for (Map.Entry<Tenor, CdsQuote> entry : cdsQuotes.entrySet()) { ParSpreadQuote quote = (ParSpreadQuote) entry.getValue(); double expected = 0.0028; Tenor tenor = entry.getKey(); if (tenor== Tenor.ONE_YEAR) { expected = 0.002828; } else if (tenor == Tenor.THREE_YEARS) { expected = 0.002856; } else if (tenor == Tenor.TEN_YEARS) { expected = 0.00308; } assertEquals(expected, quote.getParSpread(), DELTA); } }