// parses a SecurityTrade from the CSV row private static SecurityTrade parseSecurityTrade(CsvRow row, TradeInfo info, TradeCsvInfoResolver resolver) { string securityIdScheme = row.findValue(SECURITY_ID_SCHEME_FIELD).orElse(DEFAULT_SECURITY_SCHEME); string securityIdValue = row.getValue(SECURITY_ID_FIELD); SecurityId securityId = SecurityId.of(securityIdScheme, securityIdValue); double price = LoaderUtils.parseDouble(row.getValue(PRICE_FIELD)); double quantity = parseTradeQuantity(row); return(SecurityTrade.of(info, securityId, quantity, price)); }
// parses a trade from the CSV row internal static SecurityQuantityTrade parseTrade(CsvRow row, TradeInfo info, TradeCsvInfoResolver resolver) { SecurityTrade trade = parseSecurityTrade(row, info, resolver); SecurityTrade @base = resolver.completeTrade(row, trade); double?tickSizeOpt = row.findValue(TICK_SIZE).map(str => LoaderUtils.parseDouble(str)); Optional <Currency> currencyOpt = row.findValue(CURRENCY).map(str => Currency.of(str)); double?tickValueOpt = row.findValue(TICK_VALUE).map(str => LoaderUtils.parseDouble(str)); double contractSize = row.findValue(CONTRACT_SIZE).map(str => LoaderUtils.parseDouble(str)).orElse(1d); if (tickSizeOpt.HasValue && currencyOpt.Present && tickValueOpt.HasValue) { SecurityPriceInfo priceInfo = SecurityPriceInfo.of(tickSizeOpt.Value, CurrencyAmount.of(currencyOpt.get(), tickValueOpt.Value), contractSize); GenericSecurity sec = GenericSecurity.of(SecurityInfo.of(@base.SecurityId, priceInfo)); return(GenericSecurityTrade.of(@base.Info, sec, @base.Quantity, @base.Price)); } return(@base); }
// parse the row to a trade private static SwapTrade parseRow(CsvRow row, TradeInfo info, TradeCsvInfoResolver resolver) { Optional <string> conventionOpt = row.findValue(CONVENTION_FIELD); if (conventionOpt.Present) { return(parseWithConvention(row, info, resolver, conventionOpt.get())); } else { Optional <string> payReceive = row.findValue("Leg 1 " + DIRECTION_FIELD); if (payReceive.Present) { return(FullSwapTradeCsvLoader.parse(row, info)); } throw new System.ArgumentException("Swap trade had invalid combination of fields. Must include either '" + CONVENTION_FIELD + "' or '" + "Leg 1 " + DIRECTION_FIELD + "'"); } }
/// <summary> /// Parses the data from a CSV row. /// </summary> /// <param name="row"> the CSV row object </param> /// <param name="info"> the trade info object </param> /// <param name="resolver"> the resolver used to parse additional information. This is not currently used in this method. </param> /// <returns> the parsed trade, as an instance of <seealso cref="FxSingleTrade"/> </returns> internal static FxSingleTrade parse(CsvRow row, TradeInfo info, TradeCsvInfoResolver resolver) { FxSingleTrade trade = parseRow(row, info); return(resolver.completeTrade(row, trade)); }
// restricted constructor private TradeCsvLoader(TradeCsvInfoResolver resolver) { this.resolver = ArgChecker.notNull(resolver, "resolver"); }
/// <summary> /// Obtains an instance that uses the specified resolver for additional information. /// </summary> /// <param name="resolver"> the resolver used to parse additional information </param> /// <returns> the loader </returns> public static TradeCsvLoader of(TradeCsvInfoResolver resolver) { return(new TradeCsvLoader(resolver)); }
/// <summary> /// Obtains an instance that uses the specified set of reference data. /// </summary> /// <param name="refData"> the reference data </param> /// <returns> the loader </returns> public static TradeCsvLoader of(ReferenceData refData) { return(new TradeCsvLoader(TradeCsvInfoResolver.of(refData))); }
//------------------------------------------------------------------------- /// <summary> /// Obtains an instance that uses the standard set of reference data. /// </summary> /// <returns> the loader </returns> public static TradeCsvLoader standard() { return(new TradeCsvLoader(TradeCsvInfoResolver.standard())); }
// parse the row to a trade private static TermDepositTrade parseRow(CsvRow row, TradeInfo info, TradeCsvInfoResolver resolver) { BuySell buySell = LoaderUtils.parseBuySell(row.getValue(BUY_SELL_FIELD)); double notional = LoaderUtils.parseDouble(row.getValue(NOTIONAL_FIELD)); double fixedRate = LoaderUtils.parseDoublePercent(row.getValue(FIXED_RATE_FIELD)); Optional <TermDepositConvention> conventionOpt = row.findValue(CONVENTION_FIELD).map(s => TermDepositConvention.of(s)); Optional <Period> tenorOpt = row.findValue(TENOR_FIELD).map(s => LoaderUtils.parseTenor(s).Period); Optional <LocalDate> startDateOpt = row.findValue(START_DATE_FIELD).map(s => LoaderUtils.parseDate(s)); Optional <LocalDate> endDateOpt = row.findValue(END_DATE_FIELD).map(s => LoaderUtils.parseDate(s)); Optional <Currency> currencyOpt = row.findValue(CURRENCY_FIELD).map(s => Currency.parse(s)); Optional <DayCount> dayCountOpt = row.findValue(DAY_COUNT_FIELD).map(s => LoaderUtils.parseDayCount(s)); BusinessDayConvention dateCnv = row.findValue(DATE_ADJ_CNV_FIELD).map(s => LoaderUtils.parseBusinessDayConvention(s)).orElse(BusinessDayConventions.MODIFIED_FOLLOWING); Optional <HolidayCalendarId> dateCalOpt = row.findValue(DATE_ADJ_CAL_FIELD).map(s => HolidayCalendarId.of(s)); // use convention if available if (conventionOpt.Present) { if (currencyOpt.Present || dayCountOpt.Present) { throw new System.ArgumentException("TermDeposit trade had invalid combination of fields. When '" + CONVENTION_FIELD + "' is present these fields must not be present: " + ImmutableList.of(CURRENCY_FIELD, DAY_COUNT_FIELD)); } TermDepositConvention convention = conventionOpt.get(); // explicit dates take precedence over relative ones if (startDateOpt.Present && endDateOpt.Present) { if (tenorOpt.Present) { throw new System.ArgumentException("TermDeposit trade had invalid combination of fields. When these fields are found " + ImmutableList.of(CONVENTION_FIELD, START_DATE_FIELD, END_DATE_FIELD) + " then these fields must not be present " + ImmutableList.of(TENOR_FIELD)); } LocalDate startDate = startDateOpt.get(); LocalDate endDate = endDateOpt.get(); TermDepositTrade trade = convention.toTrade(info, startDate, endDate, buySell, notional, fixedRate); return(adjustTrade(trade, dateCnv, dateCalOpt)); } // relative dates if (tenorOpt.Present && info.TradeDate.Present) { if (startDateOpt.Present || endDateOpt.Present) { throw new System.ArgumentException("TermDeposit trade had invalid combination of fields. When these fields are found " + ImmutableList.of(CONVENTION_FIELD, TENOR_FIELD, TRADE_DATE_FIELD) + " then these fields must not be present " + ImmutableList.of(START_DATE_FIELD, END_DATE_FIELD)); } LocalDate tradeDate = info.TradeDate.get(); Period periodToStart = tenorOpt.get(); TermDepositTrade trade = convention.createTrade(tradeDate, periodToStart, buySell, notional, fixedRate, resolver.ReferenceData); trade = trade.toBuilder().info(info).build(); return(adjustTrade(trade, dateCnv, dateCalOpt)); } } else if (startDateOpt.Present && endDateOpt.Present && currencyOpt.Present && dayCountOpt.Present) { LocalDate startDate = startDateOpt.get(); LocalDate endDate = endDateOpt.get(); Currency currency = currencyOpt.get(); DayCount dayCount = dayCountOpt.get(); TermDeposit.Builder builder = TermDeposit.builder().buySell(buySell).currency(currency).notional(notional).startDate(startDate).endDate(endDate).dayCount(dayCount).rate(fixedRate); TermDepositTrade trade = TermDepositTrade.of(info, builder.build()); return(adjustTrade(trade, dateCnv, dateCalOpt)); } // no match throw new System.ArgumentException("TermDeposit trade had invalid combination of fields. These fields are mandatory:" + ImmutableList.of(BUY_SELL_FIELD, NOTIONAL_FIELD, FIXED_RATE_FIELD) + " and one of these combinations is mandatory: " + ImmutableList.of(CONVENTION_FIELD, TRADE_DATE_FIELD, TENOR_FIELD) + " or " + ImmutableList.of(CONVENTION_FIELD, START_DATE_FIELD, END_DATE_FIELD) + " or " + ImmutableList.of(START_DATE_FIELD, END_DATE_FIELD, CURRENCY_FIELD, DAY_COUNT_FIELD)); }
/// <summary> /// Parses from the CSV row. /// </summary> /// <param name="row"> the CSV row </param> /// <param name="info"> the trade info </param> /// <param name="resolver"> the resolver used to parse additional information </param> /// <returns> the parsed trade </returns> internal static TermDepositTrade parse(CsvRow row, TradeInfo info, TradeCsvInfoResolver resolver) { TermDepositTrade trade = parseRow(row, info, resolver); return(resolver.completeTrade(row, trade)); }
// parse the row to a trade private static FraTrade parseRow(CsvRow row, TradeInfo info, TradeCsvInfoResolver resolver) { BuySell buySell = LoaderUtils.parseBuySell(row.getValue(BUY_SELL_FIELD)); double notional = LoaderUtils.parseDouble(row.getValue(NOTIONAL_FIELD)); double fixedRate = LoaderUtils.parseDoublePercent(row.getValue(FIXED_RATE_FIELD)); Optional <FraConvention> conventionOpt = row.findValue(CONVENTION_FIELD).map(s => FraConvention.of(s)); Optional <Period> periodToStartOpt = row.findValue(PERIOD_TO_START_FIELD).map(s => LoaderUtils.parsePeriod(s)); Optional <LocalDate> startDateOpt = row.findValue(START_DATE_FIELD).map(s => LoaderUtils.parseDate(s)); Optional <LocalDate> endDateOpt = row.findValue(END_DATE_FIELD).map(s => LoaderUtils.parseDate(s)); Optional <IborIndex> indexOpt = row.findValue(INDEX_FIELD).map(s => IborIndex.of(s)); Optional <IborIndex> interpolatedOpt = row.findValue(INTERPOLATED_INDEX_FIELD).map(s => IborIndex.of(s)); Optional <DayCount> dayCountOpt = row.findValue(DAY_COUNT_FIELD).map(s => LoaderUtils.parseDayCount(s)); BusinessDayConvention dateCnv = row.findValue(DATE_ADJ_CNV_FIELD).map(s => LoaderUtils.parseBusinessDayConvention(s)).orElse(BusinessDayConventions.MODIFIED_FOLLOWING); Optional <HolidayCalendarId> dateCalOpt = row.findValue(DATE_ADJ_CAL_FIELD).map(s => HolidayCalendarId.of(s)); // not parsing paymentDate, fixingDateOffset, discounting // use convention if available if (conventionOpt.Present) { if (indexOpt.Present || interpolatedOpt.Present || dayCountOpt.Present) { throw new System.ArgumentException("Fra trade had invalid combination of fields. When '" + CONVENTION_FIELD + "' is present these fields must not be present: " + ImmutableList.of(INDEX_FIELD, INTERPOLATED_INDEX_FIELD, DAY_COUNT_FIELD)); } FraConvention convention = conventionOpt.get(); // explicit dates take precedence over relative ones if (startDateOpt.Present && endDateOpt.Present) { if (periodToStartOpt.Present) { throw new System.ArgumentException("Fra trade had invalid combination of fields. When these fields are found " + ImmutableList.of(CONVENTION_FIELD, START_DATE_FIELD, END_DATE_FIELD) + " then these fields must not be present " + ImmutableList.of(PERIOD_TO_START_FIELD)); } LocalDate startDate = startDateOpt.get(); LocalDate endDate = endDateOpt.get(); // NOTE: payment date assumed to be the start date FraTrade trade = convention.toTrade(info, startDate, endDate, startDate, buySell, notional, fixedRate); return(adjustTrade(trade, dateCnv, dateCalOpt)); } // relative dates if (periodToStartOpt.Present && info.TradeDate.Present) { if (startDateOpt.Present || endDateOpt.Present) { throw new System.ArgumentException("Fra trade had invalid combination of fields. When these fields are found " + ImmutableList.of(CONVENTION_FIELD, PERIOD_TO_START_FIELD, TRADE_DATE_FIELD) + " then these fields must not be present " + ImmutableList.of(START_DATE_FIELD, END_DATE_FIELD)); } LocalDate tradeDate = info.TradeDate.get(); Period periodToStart = periodToStartOpt.get(); FraTrade trade = convention.createTrade(tradeDate, periodToStart, buySell, notional, fixedRate, resolver.ReferenceData); trade = trade.toBuilder().info(info).build(); return(adjustTrade(trade, dateCnv, dateCalOpt)); } } else if (startDateOpt.Present && endDateOpt.Present && indexOpt.Present) { LocalDate startDate = startDateOpt.get(); LocalDate endDate = endDateOpt.get(); IborIndex index = indexOpt.get(); Fra.Builder builder = Fra.builder().buySell(buySell).notional(notional).startDate(startDate).endDate(endDate).fixedRate(fixedRate).index(index); interpolatedOpt.ifPresent(interpolated => builder.indexInterpolated(interpolated)); dayCountOpt.ifPresent(dayCount => builder.dayCount(dayCount)); return(adjustTrade(FraTrade.of(info, builder.build()), dateCnv, dateCalOpt)); } // no match throw new System.ArgumentException("Fra trade had invalid combination of fields. These fields are mandatory:" + ImmutableList.of(BUY_SELL_FIELD, NOTIONAL_FIELD, FIXED_RATE_FIELD) + " and one of these combinations is mandatory: " + ImmutableList.of(CONVENTION_FIELD, TRADE_DATE_FIELD, PERIOD_TO_START_FIELD) + " or " + ImmutableList.of(CONVENTION_FIELD, START_DATE_FIELD, END_DATE_FIELD) + " or " + ImmutableList.of(START_DATE_FIELD, END_DATE_FIELD, INDEX_FIELD)); }
/// <summary> /// Parses from the CSV row. /// </summary> /// <param name="row"> the CSV row </param> /// <param name="info"> the trade info </param> /// <param name="resolver"> the resolver used to parse additional information </param> /// <returns> the parsed trade </returns> internal static SwapTrade parse(CsvRow row, IList <CsvRow> variableRows, TradeInfo info, TradeCsvInfoResolver resolver) { SwapTrade trade = parseRow(row, info, resolver); trade = parseVariableNotional(trade, variableRows); trade = parseVariableRates(trade, variableRows); return(resolver.completeTrade(row, trade)); }
// parse a trade based on a convention internal static SwapTrade parseWithConvention(CsvRow row, TradeInfo info, TradeCsvInfoResolver resolver, string conventionStr) { BuySell buySell = LoaderUtils.parseBuySell(row.getValue(BUY_SELL_FIELD)); double notional = LoaderUtils.parseDouble(row.getValue(NOTIONAL_FIELD)); double fixedRate = LoaderUtils.parseDoublePercent(row.getValue(FIXED_RATE_FIELD)); Optional <Period> periodToStartOpt = row.findValue(PERIOD_TO_START_FIELD).map(s => LoaderUtils.parsePeriod(s)); Optional <Tenor> tenorOpt = row.findValue(TENOR_FIELD).map(s => LoaderUtils.parseTenor(s)); Optional <LocalDate> startDateOpt = row.findValue(START_DATE_FIELD).map(s => LoaderUtils.parseDate(s)); Optional <LocalDate> endDateOpt = row.findValue(END_DATE_FIELD).map(s => LoaderUtils.parseDate(s)); Optional <RollConvention> rollCnvOpt = row.findValue(ROLL_CONVENTION_FIELD).map(s => LoaderUtils.parseRollConvention(s)); Optional <StubConvention> stubCnvOpt = row.findValue(STUB_CONVENTION_FIELD).map(s => StubConvention.of(s)); Optional <LocalDate> firstRegStartDateOpt = row.findValue(FIRST_REGULAR_START_DATE_FIELD).map(s => LoaderUtils.parseDate(s)); Optional <LocalDate> lastRegEndDateOpt = row.findValue(LAST_REGULAR_END_DATE_FIELD).map(s => LoaderUtils.parseDate(s)); BusinessDayConvention dateCnv = row.findValue(DATE_ADJ_CNV_FIELD).map(s => LoaderUtils.parseBusinessDayConvention(s)).orElse(BusinessDayConventions.MODIFIED_FOLLOWING); Optional <HolidayCalendarId> dateCalOpt = row.findValue(DATE_ADJ_CAL_FIELD).map(s => HolidayCalendarId.of(s)); double? fxRateOpt = row.findValue(FX_RATE_FIELD).map(str => LoaderUtils.parseDouble(str)); // explicit dates take precedence over relative ones if (startDateOpt.Present && endDateOpt.Present) { if (periodToStartOpt.Present || tenorOpt.Present) { throw new System.ArgumentException("Swap trade had invalid combination of fields. When these fields are found " + ImmutableList.of(CONVENTION_FIELD, START_DATE_FIELD, END_DATE_FIELD) + " then these fields must not be present " + ImmutableList.of(PERIOD_TO_START_FIELD, TENOR_FIELD)); } LocalDate startDate = startDateOpt.get(); LocalDate endDate = endDateOpt.get(); SwapTrade trade = createSwap(info, conventionStr, startDate, endDate, buySell, notional, fixedRate, fxRateOpt); return(adjustTrade(trade, rollCnvOpt, stubCnvOpt, firstRegStartDateOpt, lastRegEndDateOpt, dateCnv, dateCalOpt)); } // start date + tenor if (startDateOpt.Present && tenorOpt.Present) { if (periodToStartOpt.Present || endDateOpt.Present) { throw new System.ArgumentException("Swap trade had invalid combination of fields. When these fields are found " + ImmutableList.of(CONVENTION_FIELD, START_DATE_FIELD, TENOR_FIELD) + " then these fields must not be present " + ImmutableList.of(PERIOD_TO_START_FIELD, END_DATE_FIELD)); } LocalDate startDate = startDateOpt.get(); Tenor tenor = tenorOpt.get(); LocalDate endDate = startDate.plus(tenor); SwapTrade trade = createSwap(info, conventionStr, startDate, endDate, buySell, notional, fixedRate, fxRateOpt); return(adjustTrade(trade, rollCnvOpt, stubCnvOpt, firstRegStartDateOpt, lastRegEndDateOpt, dateCnv, dateCalOpt)); } // relative dates if (periodToStartOpt.Present && tenorOpt.Present && info.TradeDate.Present) { if (startDateOpt.Present || endDateOpt.Present) { throw new System.ArgumentException("Swap trade had invalid combination of fields. When these fields are found " + ImmutableList.of(CONVENTION_FIELD, PERIOD_TO_START_FIELD, TENOR_FIELD, TRADE_DATE_FIELD) + " then these fields must not be present " + ImmutableList.of(START_DATE_FIELD, END_DATE_FIELD)); } LocalDate tradeDate = info.TradeDate.get(); Period periodToStart = periodToStartOpt.get(); Tenor tenor = tenorOpt.get(); if (fxRateOpt.HasValue) { XCcyIborIborSwapConvention convention = XCcyIborIborSwapConvention.of(conventionStr); double notionalFlat = notional * fxRateOpt.Value; SwapTrade trade = convention.createTrade(tradeDate, periodToStart, tenor, buySell, notional, notionalFlat, fixedRate, resolver.ReferenceData); trade = trade.toBuilder().info(info).build(); return(adjustTrade(trade, rollCnvOpt, stubCnvOpt, firstRegStartDateOpt, lastRegEndDateOpt, dateCnv, dateCalOpt)); } else { SingleCurrencySwapConvention convention = SingleCurrencySwapConvention.of(conventionStr); SwapTrade trade = convention.createTrade(tradeDate, periodToStart, tenor, buySell, notional, fixedRate, resolver.ReferenceData); trade = trade.toBuilder().info(info).build(); return(adjustTrade(trade, rollCnvOpt, stubCnvOpt, firstRegStartDateOpt, lastRegEndDateOpt, dateCnv, dateCalOpt)); } } // no match throw new System.ArgumentException("Swap trade had invalid combination of fields. These fields are mandatory:" + ImmutableList.of(BUY_SELL_FIELD, NOTIONAL_FIELD, FIXED_RATE_FIELD) + " and one of these combinations is mandatory: " + ImmutableList.of(CONVENTION_FIELD, TRADE_DATE_FIELD, PERIOD_TO_START_FIELD, TENOR_FIELD) + " or " + ImmutableList.of(CONVENTION_FIELD, START_DATE_FIELD, TENOR_FIELD) + " or " + ImmutableList.of(CONVENTION_FIELD, START_DATE_FIELD, END_DATE_FIELD)); }