@Override public FxSwapTrade trade(double quantity, MarketData marketData, ReferenceData refData) { FxRate fxRate = marketData.getValue(fxRateId); double rate = fxRate.fxRate(template.getCurrencyPair()); double fxPts = marketData.getValue(farForwardPointsId); BuySell buySell = quantity > 0 ? BuySell.BUY : BuySell.SELL; return template.createTrade(marketData.getValuationDate(), buySell, Math.abs(quantity), rate, fxPts, refData); }
public void test_of_far() { FxSwapTemplate test = FxSwapTemplate.of(FAR_PERIOD, CONVENTION); assertEquals(test.getPeriodToNear(), Period.ZERO); assertEquals(test.getPeriodToFar(), FAR_PERIOD); assertEquals(test.getConvention(), CONVENTION); assertEquals(test.getCurrencyPair(), EUR_USD); }
@Override public FxSwapTemplate build() { return new FxSwapTemplate( periodToNear, periodToFar, convention); }
/** * Restricted copy constructor. * @param beanToCopy the bean to copy from, not null */ private Builder(FxSwapTemplate beanToCopy) { this.periodToNear = beanToCopy.getPeriodToNear(); this.periodToFar = beanToCopy.getPeriodToFar(); this.convention = beanToCopy.getConvention(); }
public void test_createTrade() { FxSwapTemplate base = FxSwapTemplate.of(NEAR_PERIOD, FAR_PERIOD, CONVENTION); LocalDate tradeDate = LocalDate.of(2015, 10, 29); FxSwapTrade test = base.createTrade(tradeDate, BUY, NOTIONAL_EUR, FX_RATE_NEAR, FX_RATE_PTS, REF_DATA); LocalDate spotDate = PLUS_TWO_DAYS.adjust(tradeDate, REF_DATA); LocalDate nearDate = spotDate.plus(NEAR_PERIOD); LocalDate farDate = spotDate.plus(FAR_PERIOD); BusinessDayAdjustment bda = CONVENTION.getBusinessDayAdjustment(); FxSwap expected = FxSwap.ofForwardPoints( CurrencyAmount.of(EUR, NOTIONAL_EUR), FxRate.of(EUR, USD, FX_RATE_NEAR), FX_RATE_PTS, nearDate, farDate, bda); assertEquals(test.getInfo().getTradeDate(), Optional.of(tradeDate)); assertEquals(test.getProduct(), expected); }
public void test_serialization() { FxSwapTemplate test = FxSwapTemplate.of(NEAR_PERIOD, FAR_PERIOD, CONVENTION); assertSerialization(test); }
@ImmutablePreBuild private static void preBuild(Builder builder) { if (builder.template != null) { if (builder.label == null) { builder.label = Tenor.of(builder.template.getPeriodToFar()).toString(); } if (builder.fxRateId == null) { builder.fxRateId = FxRateId.of(builder.template.getCurrencyPair()); } else { ArgChecker.isTrue( builder.fxRateId.getPair().toConventional().equals(builder.template.getCurrencyPair().toConventional()), "FxRateId currency pair '{}' must match that of the template '{}'", builder.fxRateId.getPair(), builder.template.getCurrencyPair()); } } }
private LocalDate calculateEnd(LocalDate valuationDate, ReferenceData refData) { FxSwapTrade trade = template.createTrade(valuationDate, BuySell.BUY, 1, 1, 0, refData); return trade.getProduct().getFarLeg().resolve(refData).getPaymentDate(); }
/** * Obtains a template based on the specified periods and convention. * <p> * Both the period from the spot date to the near date and far date are specified. * <p> * For example, a '3M x 6M' FX swap has a period from spot to the start date of 3 months and * a period from spot to the far date of 6 months * * @param periodToNear the period between the spot date and the near date * @param periodToFar the period between the spot date and the far date * @param convention the market convention * @return the template */ public static FxSwapTemplate of(Period periodToNear, Period periodToFar, FxSwapConvention convention) { return FxSwapTemplate.builder() .periodToNear(periodToNear) .periodToFar(periodToFar) .convention(convention).build(); }
@Override public DatedParameterMetadata metadata(LocalDate valuationDate, ReferenceData refData) { LocalDate nodeDate = date(valuationDate, refData); if (date.isFixed()) { return LabelDateParameterMetadata.of(nodeDate, label); } Tenor tenor = Tenor.of(template.getPeriodToFar()); return TenorDateParameterMetadata.of(nodeDate, tenor, label); }
private FxSwapTemplate( Period periodToNear, Period periodToFar, FxSwapConvention convention) { JodaBeanUtils.notNull(periodToNear, "periodToNear"); JodaBeanUtils.notNull(periodToFar, "periodToFar"); JodaBeanUtils.notNull(convention, "convention"); this.periodToNear = periodToNear; this.periodToFar = periodToFar; this.convention = convention; validate(); }
@Override protected Object propertyGet(Bean bean, String propertyName, boolean quiet) { switch (propertyName.hashCode()) { case -18701724: // periodToNear return ((FxSwapTemplate) bean).getPeriodToNear(); case -970442405: // periodToFar return ((FxSwapTemplate) bean).getPeriodToFar(); case 2039569265: // convention return ((FxSwapTemplate) bean).getConvention(); } return super.propertyGet(bean, propertyName, quiet); }
public void test_trade() { FxSwapCurveNode node = FxSwapCurveNode.of(TEMPLATE, QUOTE_ID_PTS); FxSwapTrade trade = node.trade(1d, MARKET_DATA, REF_DATA); double rate = FX_RATE_NEAR.fxRate(EUR_USD); FxSwapTrade expected = TEMPLATE.createTrade(VAL_DATE, BuySell.BUY, 1.0, rate, FX_RATE_PTS, REF_DATA); assertEquals(trade, expected); assertEquals(node.resolvedTrade(1d, MARKET_DATA, REF_DATA), trade.resolve(REF_DATA)); }
/** * Obtains a template based on the specified period and convention. * <p> * The near date is equal to the spot date. * The period from the spot date to the far date is specified * <p> * For example, a '6M' FX swap has a near leg on the spot date and a period from spot to the far date of 6 months * * @param periodToFar the period between the spot date and the far date * @param convention the market convention * @return the template */ public static FxSwapTemplate of(Period periodToFar, FxSwapConvention convention) { return FxSwapTemplate.builder() .periodToNear(Period.ZERO) .periodToFar(periodToFar) .convention(convention).build(); }
public void test_of_near_far() { FxSwapTemplate test = FxSwapTemplate.of(NEAR_PERIOD, FAR_PERIOD, CONVENTION); assertEquals(test.getPeriodToNear(), NEAR_PERIOD); assertEquals(test.getPeriodToFar(), FAR_PERIOD); assertEquals(test.getConvention(), CONVENTION); assertEquals(test.getCurrencyPair(), EUR_USD); }
private static CurveNode curveFxSwapCurveNode( String conventionStr, String timeStr, String label, QuoteId quoteId, double spread, CurveNodeDate date, CurveNodeDateOrder order) { if (!DoubleMath.fuzzyEquals(spread, 0d, 1e-10d)) { throw new IllegalArgumentException("Additional spread must be zero for FX swaps"); } Matcher matcher = SIMPLE_YMD_TIME_REGEX.matcher(timeStr.toUpperCase(Locale.ENGLISH)); if (!matcher.matches()) { throw new IllegalArgumentException(Messages.format("Invalid time format for FX swap: {}", timeStr)); } Period periodToEnd = Period.parse("P" + matcher.group(1)); FxSwapConvention convention = FxSwapConvention.of(conventionStr); FxSwapTemplate template = FxSwapTemplate.of(periodToEnd, convention); return FxSwapCurveNode.builder() .template(template) .farForwardPointsId(quoteId) .label(label) .date(date) .dateOrder(order) .build(); }
public void test_builder_insufficientInfo() { assertThrowsIllegalArg(() -> FxSwapTemplate.builder().convention(CONVENTION).build()); assertThrowsIllegalArg(() -> FxSwapTemplate.builder().periodToNear(NEAR_PERIOD).build()); assertThrowsIllegalArg(() -> FxSwapTemplate.builder().periodToFar(FAR_PERIOD).build()); }
public void coverage() { FxSwapCurveNode test = FxSwapCurveNode.of(TEMPLATE, QUOTE_ID_PTS); coverImmutableBean(test); FxSwapCurveNode test2 = FxSwapCurveNode.builder() .label(LABEL) .template(FxSwapTemplate.of(Period.ZERO, FAR_PERIOD, CONVENTION)) .fxRateId(FX_RATE_ID2) .farForwardPointsId(QUOTE_ID_PTS2) .date(CurveNodeDate.LAST_FIXING) .build(); coverBeanEquals(test, test2); }