/** * Loads one or more CSV format position 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 positions, position-level errors are captured in the result */ public ValueWithFailures<List<Position>> load(ResourceLocator... resources) { return load(Arrays.asList(resources)); }
/** * Parses one or more CSV format position files, returning ETD futures and * options by identifier without using reference data. * <p> * When an ETD row is found, {@link EtdIdUtils} is used to create an identifier. * The identifier is used to create a {@link SecurityPosition}, with no call to reference data. * <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 positions, all errors are captured in the result */ public ValueWithFailures<List<SecurityPosition>> parseLightweight(Collection<CharSource> charSources) { return parse(charSources, SecurityPosition.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 PositionCsvLoader of(PositionCsvInfoResolver resolver) { return new PositionCsvLoader(resolver); }
public void test_parseFiltering() { PositionCsvLoader test = PositionCsvLoader.standard(); assertEquals(test.parse(ImmutableList.of(FILE.getCharSource())).getValue().size(), 3); // 7 errors assertEquals(test.parse(ImmutableList.of(FILE.getCharSource()), SecurityPosition.class).getValue().size(), 10); assertEquals(test.parse(ImmutableList.of(FILE.getCharSource()), ResolvableSecurityPosition.class).getValue().size(), 3); assertEquals(test.parse(ImmutableList.of(FILE.getCharSource()), GenericSecurityPosition.class).getValue().size(), 1); }
public void test_load_invalidNoQuantity() { EtdContractSpecId specId = EtdContractSpecId.of("OG-ETD", "F-ECAG-FGBL"); EtdContractSpec contract = EtdContractSpec.builder() .id(specId) .type(EtdType.FUTURE) .exchangeId(ExchangeIds.ECAG) .contractCode(FGBL) .description("Dummy") .priceInfo(SecurityPriceInfo.of(Currency.GBP, 100)) .build(); ReferenceData refData = ImmutableReferenceData.of(specId, contract); PositionCsvLoader test = PositionCsvLoader.of(refData); ValueWithFailures<List<Position>> trades = test.parse( ImmutableList.of(CharSource.wrap("Strata Position Type,Exchange,Contract Code,Expiry\nFUT,ECAG,FGBL,2017-06"))); assertEquals(trades.getFailures().size(), 1); FailureItem failure = trades.getFailures().get(0); assertEquals(failure.getReason(), FailureReason.PARSING); assertEquals(failure.getMessage(), "CSV file position could not be parsed at line 2: " + "Security must contain a quantity column, either 'Quantity' or 'Long Quantity' and 'Short Quantity'"); }
public void test_load_genericSecurity() { PositionCsvLoader test = PositionCsvLoader.standard(); ValueWithFailures<List<Position>> trades = test.load(FILE); List<GenericSecurityPosition> filtered = trades.getValue().stream() .flatMap(filtering(GenericSecurityPosition.class)) .collect(toImmutableList()); assertEquals(filtered.size(), 1); assertBeanEquals(SECURITY3FULL, filtered.get(0)); }
public void test_isKnownFormat() { PositionCsvLoader test = PositionCsvLoader.standard(); assertEquals(test.isKnownFormat(FILE.getCharSource()), true); }
public void test_parseLightweight() { PositionCsvLoader test = PositionCsvLoader.standard(); ValueWithFailures<List<SecurityPosition>> trades = test.parseLightweight(ImmutableList.of(FILE.getCharSource())); List<SecurityPosition> filtered = trades.getValue(); assertEquals(filtered.size(), 10);
private <T extends Position> ValueWithFailures<List<T>> parseFile(CharSource charSource, Class<T> positionType) { 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, positionType); } catch (RuntimeException ex) { return ValueWithFailures.of( ImmutableList.of(), FailureItem.of( FailureReason.PARSING, ex, "CSV file could not be parsed: {exceptionMessage}: {}", ex.getMessage(), charSource)); } }
for (CsvRow row : (Iterable<CsvRow>) () -> csv) { try { PositionInfo info = parsePositionInfo(row); Optional<String> typeRawOpt = row.findValue(TYPE_FIELD); if (typeRawOpt.isPresent()) {
public void test_load_invalidNoHeader() { PositionCsvLoader test = PositionCsvLoader.standard(); ValueWithFailures<List<Position>> 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); }
public void test_load_security() { PositionCsvLoader test = PositionCsvLoader.standard(); ValueWithFailures<List<Position>> trades = test.load(FILE); List<SecurityPosition> filtered = trades.getValue().stream() .flatMap(filtering(SecurityPosition.class)) .collect(toImmutableList()); assertEquals(filtered.size(), 2); assertBeanEquals(SECURITY1, filtered.get(0)); assertBeanEquals(SECURITY2, filtered.get(1)); }
/** * Parses one or more CSV format position files. * <p> * A type is specified to filter the positions. * If the type is {@link SecurityPosition}, then ETD parsing will proceed as per {@link #parseLightweight(Collection)}. * Otherwise, ETD parsing will proceed as per {@link #parse(Collection)}. * <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 position type * @param charSources the CSV character sources * @param positionType the position type to return * @return the loaded positions, all errors are captured in the result */ public <T extends Position> ValueWithFailures<List<T>> parse(Collection<CharSource> charSources, Class<T> positionType) { try { ValueWithFailures<List<T>> result = ValueWithFailures.of(ImmutableList.of()); for (CharSource charSource : charSources) { ValueWithFailures<List<T>> singleResult = parseFile(charSource, positionType); result = result.combinedWith(singleResult, Guavate::concatToList); } return result; } catch (RuntimeException ex) { return ValueWithFailures.of(ImmutableList.of(), FailureItem.of(FailureReason.ERROR, ex)); } }
public void test_load_invalidNoType() { PositionCsvLoader test = PositionCsvLoader.standard(); ValueWithFailures<List<Position>> 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 Position Type' header"), true); }
.build(); ReferenceData refData = ImmutableReferenceData.of(specId, contract); PositionCsvLoader test = PositionCsvLoader.of(refData); ValueWithFailures<List<EtdFuturePosition>> trades = test.parse(ImmutableList.of(FILE.getCharSource()), EtdFuturePosition.class); List<EtdFuturePosition> filtered = trades.getValue(); assertEquals(filtered.size(), 4);
/** * Parses one or more CSV format position files, returning ETD futures and * options using information from reference data. * <p> * When an ETD row is found, reference data is used to find the correct security. * This uses {@link EtdContractSpec} by default, although this can be overridden in the resolver. * Futures and options will be returned as {@link EtdFuturePosition} and {@link EtdOptionPosition}. * <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 positions, all errors are captured in the result */ public ValueWithFailures<List<Position>> parse(Collection<CharSource> charSources) { return parse(charSources, Position.class); }
/** * Obtains an instance that uses the specified set of reference data. * * @param refData the reference data * @return the loader */ public static PositionCsvLoader of(ReferenceData refData) { return new PositionCsvLoader(PositionCsvInfoResolver.of(refData)); }
public void test_load_invalidUnknownType() { PositionCsvLoader test = PositionCsvLoader.standard(); ValueWithFailures<List<Position>> trades = test.parse(ImmutableList.of(CharSource.wrap("Strata Position Type\nFoo"))); assertEquals(trades.getFailures().size(), 1); FailureItem failure = trades.getFailures().get(0); assertEquals(failure.getReason(), FailureReason.PARSING); assertEquals(failure.getMessage(), "CSV file position type 'Foo' is not known at line 2"); }
/** * Loads one or more CSV format position 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 positions, all errors are captured in the result */ public ValueWithFailures<List<Position>> load(Collection<ResourceLocator> resources) { Collection<CharSource> charSources = resources.stream() .map(r -> UnicodeBom.toCharSource(r.getByteSource())) .collect(toList()); return parse(charSources); }