コード例 #1
0
        //-------------------------------------------------------------------------
        public Trade parseTrade(FpmlDocument document, XmlElement tradeEl)
        {
            // supported elements:
            //  'generalTerms/effectiveDate'
            //  'generalTerms/scheduledTerminationDate'
            //  'generalTerms/buyerSellerModel'
            //  'generalTerms/dateAdjustments'
            //  'generalTerms/referenceInformation'
            //  'generalTerms/indexReferenceInformation'
            //  'feeLeg/initialPayment'
            //  'feeLeg/periodicPayment'
            //  'protectionTerms/calculationAmount'
            // ignored elements:
            //  'generalTerms/additionalTerm'
            //  'generalTerms/substitution'
            //  'generalTerms/modifiedEquityDelivery'
            //  'feeLeg/periodicPayment/adjustedPaymentDates'
            //  'feeLeg/marketFixedRate'
            //  'feeLeg/paymentDelay'
            //  'feeLeg/initialPoints'
            //  'feeLeg/marketPrice'
            //  'feeLeg/quotationStyle'
            //  'protectionTerms/*'
            //  'cashSettlementTerms'
            //  'physicalSettlementTerms'
            // rejected elements:
            //  'generalTerms/basketReferenceInformation'
            //  'feeLeg/singlePayment'
            TradeInfoBuilder tradeInfoBuilder = document.parseTradeInfo(tradeEl);

            return(parseCds(document, tradeEl, tradeInfoBuilder));
        }
コード例 #2
0
        //-------------------------------------------------------------------------
        public Trade parseTrade(FpmlDocument document, XmlElement tradeEl)
        {
            // supported elements:
            // 'payment/payerPartyReference'
            // 'payment/receiverPartyReference'
            // 'payment/paymentAmount'
            // 'payment/paymentDate?'
            // ignored elements:
            // 'payment/payerAccountReference?'
            // 'payment/receiverAccountReference?'
            // 'payment/paymentType?'
            // 'payment/settlementInformation?'
            // 'payment/discountFactor?'
            // 'payment/presentValueAmount?'
            TradeInfoBuilder tradeInfoBuilder = document.parseTradeInfo(tradeEl);
            XmlElement       bulletEl         = tradeEl.getChild("bulletPayment");
            XmlElement       paymentEl        = bulletEl.getChild("payment");

            BulletPayment.Builder bulletBuilder = BulletPayment.builder();
            // pay/receive and counterparty
            bulletBuilder.payReceive(document.parsePayerReceiver(paymentEl, tradeInfoBuilder));
            // payment date
            bulletBuilder.date(document.parseAdjustableDate(paymentEl.getChild("paymentDate")));
            // amount
            bulletBuilder.value(document.parseCurrencyAmount(paymentEl.getChild("paymentAmount")));

            return(BulletPaymentTrade.builder().info(tradeInfoBuilder.build()).product(bulletBuilder.build()).build());
        }
コード例 #3
0
        //-------------------------------------------------------------------------
        public Trade parseTrade(FpmlDocument document, XmlElement tradeEl)
        {
            // supported elements:
            // 'exchangedCurrency1/paymentAmount'
            // 'exchangedCurrency2/paymentAmount'
            // 'valueDate'
            // 'currency1ValueDate'
            // 'currency2ValueDate'
            // 'nonDeliverableSettlement?'
            // ignored elements:
            // 'dealtCurrency?'
            // 'exchangeRate'
            XmlElement fxEl = tradeEl.getChild("fxSingleLeg");
            // amounts
            TradeInfoBuilder tradeInfoBuilder = document.parseTradeInfo(tradeEl);
            XmlElement       curr1El          = fxEl.getChild("exchangedCurrency1");
            XmlElement       curr2El          = fxEl.getChild("exchangedCurrency2");
            // pay/receive and counterparty
            PayReceive curr1PayReceive = document.parsePayerReceiver(curr1El, tradeInfoBuilder);
            PayReceive curr2PayReceive = document.parsePayerReceiver(curr2El, tradeInfoBuilder);

            if (curr1PayReceive == curr2PayReceive)
            {
                throw new FpmlParseException("FX single leg currencies must not have same Pay/Receive direction");
            }
            // amount
            CurrencyAmount curr1Amount = document.parseCurrencyAmount(curr1El.getChild("paymentAmount"));
            CurrencyAmount curr2Amount = document.parseCurrencyAmount(curr2El.getChild("paymentAmount"));

            if (curr1PayReceive == PayReceive.PAY)
            {
                curr1Amount = curr1Amount.negative();
                curr2Amount = curr2Amount.positive();
            }
            else
            {
                curr1Amount = curr1Amount.positive();
                curr2Amount = curr2Amount.negative();
            }
            // payment date
            LocalDate currency1Date = document.parseDate(fxEl.findChild("currency1ValueDate").orElseGet(() => fxEl.getChild("valueDate")));
            LocalDate currency2Date = document.parseDate(fxEl.findChild("currency2ValueDate").orElseGet(() => fxEl.getChild("valueDate")));
            // FxSingle or NDF
            Optional <XmlElement> ndfEl = fxEl.findChild("nonDeliverableSettlement");

            if (!ndfEl.Present)
            {
                return(FxSingleTrade.builder().info(tradeInfoBuilder.build()).product(FxSingle.of(Payment.of(curr1Amount, currency1Date), Payment.of(curr2Amount, currency2Date))).build());
            }
            if (!currency1Date.Equals(currency2Date))
            {
                throw new FpmlParseException("FxNdf only supports a single payment date");
            }
            return(parseNdf(document, fxEl, ndfEl.get(), curr1Amount, curr2Amount, currency1Date, tradeInfoBuilder));
        }
コード例 #4
0
        //-------------------------------------------------------------------------
        public Trade parseTrade(FpmlDocument document, XmlElement tradeEl)
        {
            // supported elements:
            // 'nearLeg'
            // 'farLeg'
            TradeInfoBuilder tradeInfoBuilder = document.parseTradeInfo(tradeEl);
            XmlElement       fxEl             = tradeEl.getChild("fxSwap");
            FxSingle         nearLeg          = parseLeg(fxEl.getChild("nearLeg"), document, tradeInfoBuilder);
            FxSingle         farLeg           = parseLeg(fxEl.getChild("farLeg"), document, tradeInfoBuilder);

            return(FxSwapTrade.builder().info(tradeInfoBuilder.build()).product(FxSwap.of(nearLeg, farLeg)).build());
        }
コード例 #5
0
        //-------------------------------------------------------------------------
        public Trade parseTrade(FpmlDocument document, XmlElement tradeEl)
        {
            // supported elements:
            //  'swaption'
            //  'swaption/buyerPartyReference'
            //  'swaption/sellerPartyReference'
            //  'swaption/premium/payerPartyReference'
            //  'swaption/premium/receiverPartyReference'
            //  'swaption/premium/paymentAmount'
            //  'swaption/premium/paymentDate'
            //  'swaption/europeanExercise'
            //  'swaption/europeanExercise/expirationDate'
            //  'swaption/europeanExercise/expirationDate/adjustableDate'
            //  'swaption/europeanExercise/expirationDate/adjustableDate/unadjustedDate'
            //  'swaption/europeanExercise/expirationDate/adjustableDate/dateAdjustments'
            //  'swaption/europeanExercise/expirationTime
            //  'swaption/swap'
            // ignored elements:
            //  'Product.model?'
            //  'swaption/calculationAgent'
            //  'swaption/assetClass'
            //  'swaption/primaryAssestClass'
            //  'swaption/productId'
            //  'swaption/productType'
            //  'swaption/secondaryAssetClass'
            //  'swaption/sellerAccountReference'
            //  'swaption/sellerPartyReference'
            //  'swaption/swaptionAdjustedDates'
            //  'swaption/swaptionStraddle'
            TradeInfoBuilder tradeInfoBuilder = document.parseTradeInfo(tradeEl);

            XmlElement swaptionEl         = tradeEl.getChild("swaption");
            XmlElement europeanExerciseEl = swaptionEl.getChild("europeanExercise");
            XmlElement expirationTimeEl   = europeanExerciseEl.getChild("expirationTime");

            // Parse the premium, expiry date, expiry time and expiry zone, longShort and swaption settlement.
            AdjustablePayment  premium            = parsePremium(swaptionEl, document, tradeInfoBuilder);
            AdjustableDate     expiryDate         = parseExpiryDate(europeanExerciseEl, document);
            LocalTime          expiryTime         = parseExpiryTime(expirationTimeEl, document);
            ZoneId             expiryZone         = parseExpiryZone(expirationTimeEl, document);
            LongShort          longShort          = parseLongShort(swaptionEl, document, tradeInfoBuilder);
            SwaptionSettlement swaptionSettlement = parseSettlement(swaptionEl, document);

            //Re use the Swap FpML parser to parse the underlying swap on this swaption.
            SwapFpmlParserPlugin swapParser = SwapFpmlParserPlugin.INSTANCE;
            Swap swap = swapParser.parseSwap(document, swaptionEl, tradeInfoBuilder);

            Swaption swaption = Swaption.builder().expiryDate(expiryDate).expiryZone(expiryZone).expiryTime(expiryTime).longShort(longShort).swaptionSettlement(swaptionSettlement).underlying(swap).build();

            return(SwaptionTrade.builder().info(tradeInfoBuilder.build()).product(swaption).premium(premium).build());
        }
コード例 #6
0
        private FxSingle parseLeg(XmlElement legEl, FpmlDocument document, TradeInfoBuilder tradeInfoBuilder)
        {
            // supported elements:
            // 'exchangedCurrency1/paymentAmount'
            // 'exchangedCurrency2/paymentAmount'
            // 'valueDate'
            // ignored elements:
            // 'dealtCurrency?'
            // 'exchangeRate'
            // rejected elements:
            // 'nonDeliverableSettlement?'
            // 'currency1ValueDate'
            // 'currency2ValueDate'
            document.validateNotPresent(legEl, "currency1ValueDate");
            document.validateNotPresent(legEl, "currency2ValueDate");
            document.validateNotPresent(legEl, "nonDeliverableSettlement");
            XmlElement curr1El = legEl.getChild("exchangedCurrency1");
            XmlElement curr2El = legEl.getChild("exchangedCurrency2");
            // pay/receive and counterparty
            PayReceive curr1PayReceive = document.parsePayerReceiver(curr1El, tradeInfoBuilder);
            PayReceive curr2PayReceive = document.parsePayerReceiver(curr2El, tradeInfoBuilder);

            if (curr1PayReceive == curr2PayReceive)
            {
                throw new FpmlParseException("FX single leg currencies must not have same Pay/Receive direction");
            }
            // amount
            CurrencyAmount curr1Amount = document.parseCurrencyAmount(curr1El.getChild("paymentAmount"));
            CurrencyAmount curr2Amount = document.parseCurrencyAmount(curr2El.getChild("paymentAmount"));

            if (curr1PayReceive == PayReceive.PAY)
            {
                curr1Amount = curr1Amount.negative();
                curr2Amount = curr2Amount.positive();
            }
            else
            {
                curr1Amount = curr1Amount.positive();
                curr2Amount = curr2Amount.negative();
            }
            // payment date
            LocalDate valueDate = document.parseDate(legEl.getChild("valueDate"));

            // result
            return(FxSingle.of(curr1Amount, curr2Amount, valueDate));
        }
コード例 #7
0
        //-------------------------------------------------------------------------
        public Trade parseTrade(FpmlDocument document, XmlElement tradeEl)
        {
            // supported elements:
            // 'payerPartyReference'
            // 'receiverPartyReference'
            // 'startDate'
            // 'maturityDate'
            // 'principal'
            // 'fixedRate'
            // 'dayCountFraction'
            // ignored elements:
            // 'payerAccountReference?'
            // 'receiverAccountReference?'
            // 'interest?'
            // rejected elements:
            // 'features?'
            // 'payment*'
            TradeInfoBuilder tradeInfoBuilder = document.parseTradeInfo(tradeEl);
            XmlElement       termEl           = tradeEl.getChild("termDeposit");

            document.validateNotPresent(termEl, "features");
            document.validateNotPresent(termEl, "payment");
            TermDeposit.Builder termBuilder = TermDeposit.builder();
            // pay/receive and counterparty
            PayReceive payReceive = document.parsePayerReceiver(termEl, tradeInfoBuilder);

            termBuilder.buySell(BuySell.ofBuy(payReceive.Pay));
            // start date
            termBuilder.startDate(document.parseDate(termEl.getChild("startDate")));
            // maturity date
            termBuilder.endDate(document.parseDate(termEl.getChild("maturityDate")));
            // principal
            CurrencyAmount principal = document.parseCurrencyAmount(termEl.getChild("principal"));

            termBuilder.currency(principal.Currency);
            termBuilder.notional(principal.Amount);
            // fixed rate
            termBuilder.rate(document.parseDecimal(termEl.getChild("fixedRate")));
            // day count
            termBuilder.dayCount(document.parseDayCountFraction(termEl.getChild("dayCountFraction")));

            return(TermDepositTrade.builder().info(tradeInfoBuilder.build()).product(termBuilder.build()).build());
        }
コード例 #8
0
        private LongShort parseLongShort(XmlElement swaptionEl, FpmlDocument document, TradeInfoBuilder tradeInfoBuilder)
        {
            BuySell buySell = document.parseBuyerSeller(swaptionEl, tradeInfoBuilder);

            return(buySell.Buy ? LongShort.LONG : LongShort.SHORT);
        }
コード例 #9
0
        private AdjustablePayment parsePremium(XmlElement swaptionEl, FpmlDocument document, TradeInfoBuilder tradeInfoBuilder)
        {
            XmlElement     premiumEl       = swaptionEl.getChild("premium");
            PayReceive     payReceive      = document.parsePayerReceiver(premiumEl, tradeInfoBuilder);
            XmlElement     paymentAmountEl = premiumEl.getChild("paymentAmount");
            CurrencyAmount ccyAmount       = document.parseCurrencyAmount(paymentAmountEl);

            ccyAmount = payReceive.Pay ? ccyAmount.negated() : ccyAmount;
            AdjustableDate paymentDate = premiumEl.findChild("paymentDate").map(el => document.parseAdjustableDate(el)).get();

            return(AdjustablePayment.of(ccyAmount, paymentDate));
        }
コード例 #10
0
        private Trade parseNdf(FpmlDocument document, XmlElement fxEl, XmlElement ndfEl, CurrencyAmount curr1Amount, CurrencyAmount curr2Amount, LocalDate valueDate, TradeInfoBuilder tradeInfoBuilder)
        {
            // rate
            XmlElement rateEl = fxEl.getChild("exchangeRate");
            double     rate   = document.parseDecimal(rateEl.getChild("rate"));
            XmlElement pairEl = rateEl.getChild("quotedCurrencyPair");
            Currency   curr1  = document.parseCurrency(pairEl.getChild("currency1"));
            Currency   curr2  = document.parseCurrency(pairEl.getChild("currency2"));
            string     basis  = pairEl.getChild("quoteBasis").Content;
            FxRate     fxRate;

            if ("Currency2PerCurrency1".Equals(basis))
            {
                fxRate = FxRate.of(curr1, curr2, rate);
            }
            else if ("Currency1PerCurrency2".Equals(basis))
            {
                fxRate = FxRate.of(curr2, curr1, rate);
            }
            else
            {
                throw new FpmlParseException("Unknown quote basis: " + basis);
            }
            // settlement currency
            Currency       settleCurr       = document.parseCurrency(ndfEl.getChild("settlementCurrency"));
            CurrencyAmount settleCurrAmount = curr1Amount.Currency.Equals(settleCurr) ? curr1Amount : curr2Amount;
            // index
            XmlElement        fixingEl        = ndfEl.getChild("fixing"); // only support one of these in pricing model
            LocalDate         fixingDate      = document.parseDate(fixingEl.getChild("fixingDate"));
            DaysAdjustment    offset          = DaysAdjustment.ofCalendarDays(Math.toIntExact(valueDate.until(fixingDate, DAYS)));
            XmlElement        sourceEl        = fixingEl.getChild("fxSpotRateSource"); // required for our model
            XmlElement        primarySourceEl = sourceEl.getChild("primaryRateSource");
            string            primarySource   = primarySourceEl.getChild("rateSource").Content;
            string            primaryPage     = primarySourceEl.findChild("rateSourcePage").map(e => e.Content).orElse("");
            LocalTime         time            = document.parseTime(sourceEl.getChild("fixingTime").getChild("hourMinuteTime")); // required for our model
            HolidayCalendarId calendar        = document.parseBusinessCenter(sourceEl.getChild("fixingTime").getChild("businessCenter"));
            FxIndex           index           = ImmutableFxIndex.builder().name(primarySource + "/" + primaryPage + "/" + time).currencyPair(CurrencyPair.of(curr1, curr2)).fixingCalendar(calendar).maturityDateOffset(offset).build();

            return(FxNdfTrade.builder().info(tradeInfoBuilder.build()).product(FxNdf.builder().settlementCurrencyNotional(settleCurrAmount).agreedFxRate(fxRate).index(index).paymentDate(valueDate).build()).build());
        }
コード例 #11
0
        // parses the CDS
        internal Trade parseCds(FpmlDocument document, XmlElement tradeEl, TradeInfoBuilder tradeInfoBuilder)
        {
            XmlElement cdsEl          = tradeEl.getChild("creditDefaultSwap");
            XmlElement generalTermsEl = cdsEl.getChild("generalTerms");
            XmlElement feeLegEl       = cdsEl.getChild("feeLeg");

            document.validateNotPresent(generalTermsEl, "basketReferenceInformation");
            document.validateNotPresent(feeLegEl, "singlePayment");
            BuySell buySell = document.parseBuyerSeller(generalTermsEl, tradeInfoBuilder);

            // effective and termination date are optional in FpML but mandatory for Strata
            AdjustableDate        effectiveDate   = document.parseAdjustableDate(generalTermsEl.getChild("effectiveDate"));
            AdjustableDate        terminationDate = document.parseAdjustableDate(generalTermsEl.getChild("scheduledTerminationDate"));
            BusinessDayAdjustment bda             = generalTermsEl.findChild("dateAdjustments").map(el => document.parseBusinessDayAdjustments(el)).orElse(BusinessDayAdjustment.NONE);

            PeriodicSchedule.Builder scheduleBuilder = PeriodicSchedule.builder().startDate(effectiveDate.Unadjusted).startDateBusinessDayAdjustment(effectiveDate.Adjustment).endDate(terminationDate.Unadjusted).endDateBusinessDayAdjustment(terminationDate.Adjustment).businessDayAdjustment(bda);

            // an upfront fee
            Optional <XmlElement> initialPaymentOptEl = feeLegEl.findChild("initialPayment");
            AdjustablePayment     upfrontFee          = null;

            if (initialPaymentOptEl.Present)
            {
                XmlElement     initialPaymentEl = initialPaymentOptEl.get();
                PayReceive     payRec           = document.parsePayerReceiver(initialPaymentEl, tradeInfoBuilder);
                CurrencyAmount amount           = document.parseCurrencyAmount(initialPaymentEl.getChild("paymentAmount"));
                LocalDate      date             = initialPaymentEl.findChild("adjustablePaymentDate").map(el => document.parseDate(el)).orElse(effectiveDate.Unadjusted);
                AdjustableDate adjDate          = AdjustableDate.of(date, bda);
                upfrontFee = payRec.Pay ? AdjustablePayment.ofPay(amount, adjDate) : AdjustablePayment.ofReceive(amount, adjDate);
            }

            // we require a periodicPayment and fixedAmountCalculation
            XmlElement periodicPaymentEl = feeLegEl.getChild("periodicPayment");

            scheduleBuilder.frequency(periodicPaymentEl.findChild("paymentFrequency").map(el => document.parseFrequency(el)).orElse(Frequency.P3M));
            periodicPaymentEl.findChild("firstPaymentDate").ifPresent(el => scheduleBuilder.firstRegularStartDate(document.parseDate(el)));
            periodicPaymentEl.findChild("firstPeriodStartDate").ifPresent(el => scheduleBuilder.overrideStartDate(AdjustableDate.of(document.parseDate(el))));
            periodicPaymentEl.findChild("lastRegularPaymentDate").ifPresent(el => scheduleBuilder.lastRegularEndDate(document.parseDate(el)));
            scheduleBuilder.rollConvention(periodicPaymentEl.findChild("rollConvention").map(el => document.convertRollConvention(el.Content)).orElse(null));
            XmlElement fixedAmountCalcEl = periodicPaymentEl.getChild("fixedAmountCalculation");
            double     fixedRate         = document.parseDecimal(fixedAmountCalcEl.getChild("fixedRate"));
            DayCount   dayCount          = fixedAmountCalcEl.findChild("dayCountFraction").map(el => document.parseDayCountFraction(el)).orElse(DayCounts.ACT_360);

            // handle a single protectionTerms element
            XmlElement     protectionTermEl = cdsEl.getChild("protectionTerms");
            CurrencyAmount notional         = document.parseCurrencyAmount(protectionTermEl.getChild("calculationAmount"));

            // single name CDS
            Optional <XmlElement> singleOptEl = generalTermsEl.findChild("referenceInformation");

            if (singleOptEl.Present)
            {
                // we require a single entityId
                XmlElement referenceEntityEl = singleOptEl.get().getChild("referenceEntity");
                XmlElement entityIdEl        = referenceEntityEl.getChild("entityId");
                string     scheme            = entityIdEl.findAttribute("entityIdScheme").orElse("http://www.fpml.org/coding-scheme/external/entity-id-RED-1-0");
                string     value             = entityIdEl.Content;
                StandardId entityId          = StandardId.of(scheme, value);
                Cds        cds = Cds.builder().buySell(buySell).legalEntityId(entityId).currency(notional.Currency).notional(notional.Amount).paymentSchedule(scheduleBuilder.build()).fixedRate(fixedRate).dayCount(dayCount).build();
                return(CdsTrade.builder().info(tradeInfoBuilder.build()).product(cds).upfrontFee(upfrontFee).build());
            }

            // CDS index
            Optional <XmlElement> indexOptEl = generalTermsEl.findChild("indexReferenceInformation");

            if (indexOptEl.Present)
            {
                string   indexName = indexOptEl.get().getChild("indexName").Content;
                CdsIndex cdsIndex  = CdsIndex.builder().buySell(buySell).cdsIndexId(StandardId.of("CDX-Name", indexName)).currency(notional.Currency).notional(notional.Amount).paymentSchedule(scheduleBuilder.build()).fixedRate(fixedRate).dayCount(dayCount).build();
                return(CdsIndexTrade.builder().info(tradeInfoBuilder.build()).product(cdsIndex).upfrontFee(upfrontFee).build());
            }

            // unknown type
            throw new FpmlParseException("FpML CDS must be single name or index");
        }