/** * Loads one or more CSV format trade files. * <p> * CSV files sometimes contain a Unicode Byte Order Mark. * This method uses {@link UnicodeBom} to interpret it. * * @param resources the CSV resources * @return the loaded trades, trade-level errors are captured in the result */ public ValueWithFailures<List<Trade>> load(ResourceLocator... resources) { return load(Arrays.asList(resources)); }
/** * Parses one or more CSV format trade files. * <p> * CSV files sometimes contain a Unicode Byte Order Mark. * Callers are responsible for handling this, such as by using {@link UnicodeBom}. * * @param charSources the CSV character sources * @return the loaded trades, all errors are captured in the result */ public ValueWithFailures<List<Trade>> parse(Collection<CharSource> charSources) { return parse(charSources, Trade.class); }
/** * Obtains an instance that uses the specified resolver for additional information. * * @param resolver the resolver used to parse additional information * @return the loader */ public static TradeCsvLoader of(TradeCsvInfoResolver resolver) { return new TradeCsvLoader(resolver); }
public void test_isKnownFormat() { TradeCsvLoader test = TradeCsvLoader.standard(); assertEquals(test.isKnownFormat(FILE.getCharSource()), true); }
public void test_load_filtered() { TradeCsvLoader test = TradeCsvLoader.standard(); ValueWithFailures<List<Trade>> trades = test.parse( ImmutableList.of(FILE.getCharSource()), ImmutableList.of(FraTrade.class, TermDepositTrade.class)); assertEquals(trades.getValue().size(), 6); assertEquals(trades.getFailures().size(), 10); assertEquals(trades.getFailures().get(0).getMessage(), "Trade type not allowed " + SwapTrade.class.getName() + ", only these types are supported: FraTrade, TermDepositTrade"); }
public void test_load_resolver() { AtomicInteger fraCount = new AtomicInteger(); AtomicInteger termCount = new AtomicInteger(); TradeCsvInfoResolver resolver = new TradeCsvInfoResolver() { @Override public FraTrade completeTrade(CsvRow row, FraTrade trade) { fraCount.incrementAndGet(); return trade; } @Override public TermDepositTrade completeTrade(CsvRow row, TermDepositTrade trade) { termCount.incrementAndGet(); return trade; } @Override public ReferenceData getReferenceData() { return ReferenceData.standard(); } }; TradeCsvLoader test = TradeCsvLoader.of(resolver); test.parse(ImmutableList.of(FILE.getCharSource())); assertEquals(fraCount.get(), 3); assertEquals(termCount.get(), 3); }
/** * Parses one or more CSV format trade files with a quiet type filter. * <p> * A type is specified to filter the trades. * Trades that do not match the type are silently dropped. * <p> * CSV files sometimes contain a Unicode Byte Order Mark. * Callers are responsible for handling this, such as by using {@link UnicodeBom}. * * @param <T> the trade type * @param charSources the CSV character sources * @param tradeType the trade type to return * @return the loaded trades, all errors are captured in the result */ public <T extends Trade> ValueWithFailures<List<T>> parse(Collection<CharSource> charSources, Class<T> tradeType) { try { ValueWithFailures<List<T>> result = ValueWithFailures.of(ImmutableList.of()); for (CharSource charSource : charSources) { ValueWithFailures<List<T>> singleResult = parseFile(charSource, tradeType); result = result.combinedWith(singleResult, Guavate::concatToList); } return result; } catch (RuntimeException ex) { return ValueWithFailures.of(ImmutableList.of(), FailureItem.of(FailureReason.ERROR, ex)); } }
try { String typeRaw = row.getField(TYPE_FIELD); TradeInfo info = parseTradeInfo(row); switch (typeRaw.toUpperCase(Locale.ENGLISH)) { case "FRA":
public void test_load_invalidNoHeader() { TradeCsvLoader test = TradeCsvLoader.standard(); ValueWithFailures<List<Trade>> trades = test.parse(ImmutableList.of(CharSource.wrap(""))); assertEquals(trades.getFailures().size(), 1); FailureItem failure = trades.getFailures().get(0); assertEquals(failure.getReason(), FailureReason.PARSING); assertEquals(failure.getMessage().contains("CSV file could not be parsed"), true); }
@Test public void test_load_fx_forwards_with_legs_in_same_direction() throws Exception { TradeCsvLoader standard = TradeCsvLoader.standard(); ResourceLocator locator = ResourceLocator.of("classpath:com/opengamma/strata/loader/csv/fxtrades_legs_same_direction.csv"); ValueWithFailures<List<Trade>> loadedData = standard.load(locator); assertEquals(loadedData.getFailures().size(), 1, loadedData.getFailures().toString()); FailureItem failureItem = loadedData.getFailures().get(0); assertEquals(failureItem.getReason().toString(), "PARSING"); assertEquals( failureItem.getMessage(), "CSV file trade could not be parsed at line 2: FxSingle legs must not have the same direction: Pay, Pay"); List<Trade> loadedTrades = loadedData.getValue(); assertEquals(loadedTrades.size(), 0); }
private <T extends Trade> ValueWithFailures<List<T>> parseFile(CharSource charSource, Class<T> tradeType) { try (CsvIterator csv = CsvIterator.of(charSource, true)) { if (!csv.headers().contains(TYPE_FIELD)) { return ValueWithFailures.of( ImmutableList.of(), FailureItem.of(FailureReason.PARSING, "CSV file does not contain '{header}' header: {}", TYPE_FIELD, charSource)); } return parseFile(csv, tradeType); } catch (RuntimeException ex) { return ValueWithFailures.of( ImmutableList.of(), FailureItem.of( FailureReason.PARSING, ex, "CSV file could not be parsed: {exceptionMessage}: {}", ex.getMessage(), charSource)); } }
public void test_load_invalidNoType() { TradeCsvLoader test = TradeCsvLoader.standard(); ValueWithFailures<List<Trade>> trades = test.parse(ImmutableList.of(CharSource.wrap("Id"))); assertEquals(trades.getFailures().size(), 1); FailureItem failure = trades.getFailures().get(0); assertEquals(failure.getReason(), FailureReason.PARSING); assertEquals(failure.getMessage().contains("CSV file does not contain 'Strata Trade Type' header"), true); }
public void test_load_genericSecurity() { TradeCsvLoader test = TradeCsvLoader.standard(); ValueWithFailures<List<Trade>> trades = test.load(FILE); List<GenericSecurityTrade> filtered = trades.getValue().stream() .flatMap(filtering(GenericSecurityTrade.class)) .collect(toImmutableList()); assertEquals(filtered.size(), 1); GenericSecurityTrade expected1 = GenericSecurityTrade.builder() .info(TradeInfo.builder() .id(StandardId.of("OG", "123433")) .tradeDate(date(2017, 6, 1)) .settlementDate(date(2017, 6, 3)) .build()) .security( GenericSecurity.of( SecurityInfo.of( SecurityId.of("OG-Security", "AAPL"), SecurityPriceInfo.of(5, CurrencyAmount.of(USD, 0.01), 10)))) .quantity(12) .price(14.5) .build(); assertBeanEquals(expected1, filtered.get(0)); }
/** * Loads one or more CSV format trade files. * <p> * CSV files sometimes contain a Unicode Byte Order Mark. * This method uses {@link UnicodeBom} to interpret it. * * @param resources the CSV resources * @return the loaded trades, all errors are captured in the result */ public ValueWithFailures<List<Trade>> load(Collection<ResourceLocator> resources) { Collection<CharSource> charSources = resources.stream() .map(r -> UnicodeBom.toCharSource(r.getByteSource())) .collect(toList()); return parse(charSources); }
/** * Obtains an instance that uses the specified set of reference data. * * @param refData the reference data * @return the loader */ public static TradeCsvLoader of(ReferenceData refData) { return new TradeCsvLoader(TradeCsvInfoResolver.of(refData)); }
public void test_load_invalidFra() { TradeCsvLoader test = TradeCsvLoader.standard(); ValueWithFailures<List<Trade>> trades = test.parse(ImmutableList.of(CharSource.wrap("Strata Trade Type,Buy Sell\nFra,Buy"))); assertEquals(trades.getFailures().size(), 1); FailureItem failure = trades.getFailures().get(0); assertEquals(failure.getReason(), FailureReason.PARSING); assertEquals(failure.getMessage(), "CSV file trade could not be parsed at line 2: Header not found: 'Notional'"); }
public void test_load_security() { TradeCsvLoader test = TradeCsvLoader.standard(); ValueWithFailures<List<Trade>> trades = test.load(FILE); List<SecurityTrade> filtered = trades.getValue().stream() .flatMap(filtering(SecurityTrade.class)) .collect(toImmutableList()); assertEquals(filtered.size(), 2); SecurityTrade expected1 = SecurityTrade.builder() .info(TradeInfo.builder() .id(StandardId.of("OG", "123431")) .tradeDate(date(2017, 6, 1)) .settlementDate(date(2017, 6, 3)) .build()) .securityId(SecurityId.of("OG-Security", "AAPL")) .quantity(12) .price(14.5) .build(); assertBeanEquals(expected1, filtered.get(0)); SecurityTrade expected2 = SecurityTrade.builder() .info(TradeInfo.builder() .id(StandardId.of("OG", "123432")) .tradeDate(date(2017, 6, 1)) .settlementDate(date(2017, 6, 3)) .build()) .securityId(SecurityId.of("BBG", "MSFT")) .quantity(-20) .price(17.8) .build(); assertBeanEquals(expected2, filtered.get(1)); }
List<Class<? extends Trade>> tradeTypes) { ValueWithFailures<List<Trade>> parsed = parse(charSources, Trade.class); List<Trade> valid = new ArrayList<>(); List<FailureItem> failures = new ArrayList<>(parsed.getFailures());
/** * Obtains an instance that uses the standard set of reference data. * * @return the loader */ public static TradeCsvLoader standard() { return new TradeCsvLoader(TradeCsvInfoResolver.standard()); }