private void doUpdateHistoricalQuotes(IProgressMonitor monitor, List<IStatus> errors) { for (Security security : securities) { monitor.subTask(MessageFormat.format(Messages.JobMsgUpdatingQuotesFor, security.getName())); try { QuoteFeed feed = Factory.getQuoteFeedProvider(security.getFeed()); if (feed != null) { ArrayList<Exception> exceptions = new ArrayList<Exception>(); feed.updateHistoricalQuotes(security, exceptions); if (!exceptions.isEmpty()) addToErrors(security.getName(), exceptions, errors); } } catch (IOException e) { errors.add( new Status( IStatus.ERROR, PortfolioPlugin.PLUGIN_ID, security.getName() + ": " //$NON-NLS-1$ + e.getMessage(), e)); } monitor.worked(1); } }
@Override public void beforePage() { Security security = model.getSecurity(); List<TransactionPair<?>> transactions = security.getTransactions(model.getClient()); Collections.sort(transactions, new TransactionPair.ByDate()); tableViewer.setInput(transactions); }
@Test public void testWhenQuotesAreOnlyAvailableFromTheMiddleOfTheReportInterval() { DateMidnight startDate = new DateMidnight(2012, 12, 31); DateMidnight middleDate = new DateMidnight(2013, 2, 18); DateMidnight endDate = new DateMidnight(2013, 4, 1); // create model Client client = new Client(); new AccountBuilder() // .deposit_(startDate, 100 * Values.Amount.factor()) // .interest(startDate.plusDays(10), 10 * Values.Amount.factor()) // .addTo(client); Security security = new SecurityBuilder() // .generatePrices(50 * Values.Amount.factor(), middleDate, endDate) // .addTo(client); // calculate performance indices List<Exception> warnings = new ArrayList<Exception>(); ReportingPeriod reportInterval = new ReportingPeriod.FromXtoY(startDate.toDate(), endDate.toDate()); ClientIndex clientIndex = PerformanceIndex.forClient(client, reportInterval, warnings); PerformanceIndex securityIndex = PerformanceIndex.forSecurity(clientIndex, security, warnings); // asserts assertTrue(warnings.isEmpty()); Date[] clientDates = clientIndex.getDates(); Date[] securityDates = securityIndex.getDates(); assertThat(securityDates[0], is(middleDate.toDate())); assertThat(securityDates[securityDates.length - 1], is(endDate.toDate())); assertThat( new DateMidnight(clientDates[clientDates.length - 1]), is(new DateMidnight(securityDates[securityDates.length - 1]))); double[] clientAccumulated = clientIndex.getAccumulatedPercentage(); double[] securityAccumulated = securityIndex.getAccumulatedPercentage(); int index = Days.daysBetween(startDate, middleDate).getDays(); assertThat(new DateMidnight(clientDates[index]), is(middleDate)); assertThat(securityAccumulated[0], IsCloseTo.closeTo(clientAccumulated[index], 0.000001d)); long middlePrice = security.getSecurityPrice(middleDate.toDate()).getValue(); long lastPrice = security.getSecurityPrice(endDate.toDate()).getValue(); // 10% is interest of the deposit double performance = (double) (lastPrice - middlePrice) / (double) middlePrice + 0.1d; assertThat( securityAccumulated[securityAccumulated.length - 1], IsCloseTo.closeTo(performance, 0.000001d)); }
private Security assertSecurity(List<Item> results) { Optional<Item> item = results.stream().filter(i -> i instanceof SecurityItem).findFirst(); assertThat(item.isPresent(), is(true)); Security security = ((SecurityItem) item.get()).getSecurity(); assertThat(security.getIsin(), is("DE000BASF111")); assertThat(security.getWkn(), is("BASF11")); assertThat(security.getName(), is("BASF SE")); assertThat(security.getCurrencyCode(), is(CurrencyUnit.EUR)); return security; }
private void onSecurityChanged(Security security) { prices.setData(Security.class.toString(), security); prices.setInput(security != null ? security.getPrices() : new ArrayList<SecurityPrice>(0)); prices.refresh(); latest.setInput(security); transactions.setInput( security != null ? security.getTransactions(getClient()) : new ArrayList<Transaction>(0)); updateChart(security); }
private void addSecurityPerformance( DataSeries item, Security security, List<Exception> warnings) { PerformanceIndex securityIndex = dataCache.get(security.getUUID()); if (securityIndex == null) { securityIndex = PerformanceIndex.forInvestment(getClient(), security, getReportingPeriod(), warnings); dataCache.put(security.getUUID(), securityIndex); } addScatterSeries(item, securityIndex); }
@Test public void testErtragsgutschrift2() throws IOException { DeutscheBankPDFExctractor extractor = new DeutscheBankPDFExctractor(new Client()) { @Override String strip(File file) throws IOException { return from(file.getName()); } }; List<Exception> errors = new ArrayList<Exception>(); List<Item> results = extractor.extract(Arrays.asList(new File("DeutscheBankErtragsgutschrift2.txt")), errors); assertThat(errors, empty()); assertThat(results.size(), is(2)); new AssertImportActions().check(results, CurrencyUnit.EUR); // check security Security security = results.stream().filter(i -> i instanceof SecurityItem).findFirst().get().getSecurity(); assertThat(security.getName(), is("ISHS-MSCI N. AMERIC.UCITS ETF BE.SH.(DT.ZT.)")); assertThat(security.getIsin(), is("DE000A0J2060")); assertThat(security.getWkn(), is("A0J206")); assertThat(security.getCurrencyCode(), is("USD")); // check transaction Optional<Item> item = results.stream().filter(i -> i instanceof TransactionItem).findFirst(); assertThat(item.isPresent(), is(true)); assertThat(item.get().getSubject(), instanceOf(AccountTransaction.class)); AccountTransaction transaction = (AccountTransaction) item.get().getSubject(); assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getSecurity(), is(security)); assertThat(transaction.getDate(), is(LocalDate.parse("2015-03-24"))); assertThat(transaction.getMonetaryAmount(), is(Money.of(CurrencyUnit.EUR, 16_17L))); assertThat(transaction.getShares(), is(Values.Share.factorize(123))); Optional<Unit> grossValue = transaction.getUnit(Unit.Type.GROSS_VALUE); assertThat(grossValue.isPresent(), is(true)); assertThat(grossValue.get().getAmount(), is(Money.of("EUR", 16_17L))); assertThat(grossValue.get().getForex(), is(Money.of("USD", 17_38L))); assertThat( grossValue.get().getExchangeRate().doubleValue(), IsCloseTo.closeTo(0.930578, 0.000001)); }
@Test public void testThatSecurityIndexIsCalculated() { DateMidnight startDate = new DateMidnight(2012, 12, 31); DateMidnight endDate = new DateMidnight(2013, 4, 1); long startPrice = 100 * Values.Amount.factor(); // create model Client client = new Client(); new AccountBuilder() // .deposit_(startDate, startPrice) // .addTo(client); Security security = new SecurityBuilder() // .generatePrices(startPrice, startDate, endDate) // .addTo(client); // calculate performance indices List<Exception> warnings = new ArrayList<Exception>(); ReportingPeriod reportInterval = new ReportingPeriod.FromXtoY(startDate.toDate(), endDate.toDate()); ClientIndex clientIndex = PerformanceIndex.forClient(client, reportInterval, warnings); PerformanceIndex securityIndex = PerformanceIndex.forSecurity(clientIndex, security, warnings); // asserts assertTrue(warnings.isEmpty()); Date[] dates = securityIndex.getDates(); assertThat(dates[0], is(startDate.toDate())); assertThat(dates[dates.length - 1], is(endDate.toDate())); long lastPrice = security.getSecurityPrice(endDate.toDate()).getValue(); double performance = (double) (lastPrice - startPrice) / (double) startPrice; double[] accumulated = securityIndex.getAccumulatedPercentage(); assertThat(accumulated[0], is(0d)); assertThat(accumulated[accumulated.length - 1], IsCloseTo.closeTo(performance, 0.000001d)); }
@Test public void testThatPerformanceOfAnInvestmentIntoAnIndexIsIdenticalToIndex() { LocalDate startDate = LocalDate.of(2012, 1, 1); LocalDate endDate = LocalDate.of(2012, 4, 29); // a weekend long startPrice = Values.Quote.factorize(100); Client client = new Client(); Security security = new SecurityBuilder() // .generatePrices(startPrice, startDate, endDate) // .addTo(client); PortfolioBuilder portfolio = new PortfolioBuilder(new Account()); // add some buy transactions LocalDate date = startDate; while (date.isBefore(endDate)) { long p = security.getSecurityPrice(date).getValue(); portfolio.inbound_delivery(security, date, Values.Share.factorize(100), p); date = date.plusDays(20); } portfolio.addTo(client); ReportingPeriod.FromXtoY period = new ReportingPeriod.FromXtoY(startDate, endDate); List<Exception> warnings = new ArrayList<Exception>(); CurrencyConverter converter = new TestCurrencyConverter(); ClientIndex index = PerformanceIndex.forClient(client, converter, period, warnings); assertTrue(warnings.isEmpty()); double[] accumulated = index.getAccumulatedPercentage(); long lastPrice = security.getSecurityPrice(endDate).getValue(); assertThat( (double) (lastPrice - startPrice) / (double) startPrice, IsCloseTo.closeTo(accumulated[accumulated.length - 1], PRECISION)); PerformanceIndex benchmark = PerformanceIndex.forSecurity(index, security); assertThat( benchmark.getFinalAccumulatedPercentage(), is(index.getFinalAccumulatedPercentage())); }
@Test public void testErtragsgutschrift7_USD_Freibetrag_nicht_ausgeschoepft() throws IOException { ConsorsbankPDFExctractor extractor = new ConsorsbankPDFExctractor(new Client()); List<Exception> errors = new ArrayList<Exception>(); URL url = FileLocator.resolve( getClass() .getResource( "ConsorsbankErtragsgutschrift7_USD_Freibetrag_nicht_ausgeschoepft.pdf")); List<Item> results = extractor.extract(Arrays.asList(new File(url.getPath())), errors); assertThat(errors, empty()); assertThat(results.size(), is(2)); // check security Security security = results.stream().filter(i -> i instanceof SecurityItem).findFirst().get().getSecurity(); assertThat(security.getWkn(), is("200417")); assertThat(security.getName(), is("ALTRIA GROUP INC.")); // check dividend transaction AccountTransaction t = (AccountTransaction) results .stream() .filter(i -> i instanceof TransactionItem) .filter( i -> ((AccountTransaction) i.getSubject()).getType() == AccountTransaction.Type.DIVIDENDS) .findFirst() .get() .getSubject(); assertThat(t.getDate(), is(LocalDate.parse("2016-01-11"))); assertThat(t.getShares(), is(Values.Share.factorize(650))); assertThat(t.getMonetaryAmount(), is(Money.of("EUR", 285_60))); assertThat(t.getUnit(Unit.Type.GROSS_VALUE).get().getForex(), is(Money.of("USD", 367_25))); // check tax assertThat(t.getUnitSum(Type.TAX), is(Money.of("EUR", 50_40))); // QUEST }
@Override public List<Item> extract( int skipLines, List<String[]> rawValues, Map<String, Column> field2column, List<Exception> errors) { Security dummy = new Security(); for (String[] line : rawValues) { try { SecurityPrice p = extract(line, field2column); if (p != null) dummy.addPrice(p); } catch (ParseException e) { errors.add(e); } } List<Item> result = new ArrayList<>(); if (!dummy.getPrices().isEmpty()) result.add(new SecurityItem(dummy)); return result; }
private void doUpdateLatestQuotes(IProgressMonitor monitor, List<IStatus> errors) { Map<String, List<Security>> byFeeds = new HashMap<String, List<Security>>(); for (Security s : securities) { List<Security> l = byFeeds.get(s.getFeed()); if (l == null) byFeeds.put(s.getFeed(), l = new ArrayList<Security>()); l.add(s); } for (Map.Entry<String, List<Security>> entry : byFeeds.entrySet()) { if (monitor.isCanceled()) return; try { QuoteFeed feed = Factory.getQuoteFeedProvider(entry.getKey()); if (feed != null) { ArrayList<Exception> exceptions = new ArrayList<Exception>(); feed.updateLatestQuotes(entry.getValue(), exceptions); if (!exceptions.isEmpty()) addToErrors(feed.getName(), exceptions, errors); } } catch (IOException e) { errors.add(new Status(IStatus.ERROR, PortfolioPlugin.PLUGIN_ID, e.getMessage(), e)); } } }
private void updateChart(Security security) { ISeries series = chart.getSeriesSet().getSeries(Messages.ColumnQuote); if (series != null) chart.getSeriesSet().deleteSeries(Messages.ColumnQuote); chart.clearMarkerLines(); if (security == null || security.getPrices().isEmpty()) { chart.getTitle().setText(security == null ? "..." : security.getName()); // $NON-NLS-1$ chart.redraw(); return; } chart.getTitle().setText(security.getName()); List<SecurityPrice> prices = security.getPrices(); int index; Date[] dates; double[] values; if (chartPeriod == null) { index = 0; dates = new Date[prices.size()]; values = new double[prices.size()]; } else { index = Math.abs( Collections.binarySearch( prices, new SecurityPrice(chartPeriod, 0), new SecurityPrice.ByDate())); if (index >= prices.size()) { // no data available chart.redraw(); return; } dates = new Date[prices.size() - index]; values = new double[prices.size() - index]; } for (int ii = 0; index < prices.size(); index++, ii++) { SecurityPrice p = prices.get(index); dates[ii] = p.getTime(); values[ii] = p.getValue() / Values.Quote.divider(); } ILineSeries lineSeries = (ILineSeries) chart.getSeriesSet().createSeries(SeriesType.LINE, Messages.ColumnQuote); lineSeries.setXDateSeries(dates); lineSeries.setLineWidth(2); lineSeries.enableArea(true); lineSeries.setSymbolType(PlotSymbolType.NONE); lineSeries.setYSeries(values); lineSeries.setAntialias(SWT.ON); chart.getAxisSet().adjustRange(); for (Portfolio portfolio : getClient().getPortfolios()) { for (PortfolioTransaction t : portfolio.getTransactions()) { if (t.getSecurity() == security && (chartPeriod == null || chartPeriod.before(t.getDate()))) { String label = Values.Share.format(t.getShares()); switch (t.getType()) { case BUY: case TRANSFER_IN: case DELIVERY_INBOUND: chart.addMarkerLine(t.getDate(), new RGB(0, 128, 0), label); break; case SELL: case TRANSFER_OUT: case DELIVERY_OUTBOUND: chart.addMarkerLine(t.getDate(), new RGB(128, 0, 0), "-" + label); // $NON-NLS-1$ break; default: throw new UnsupportedOperationException(); } } } } chart.redraw(); }
@Test public void testWhenQuotesAreOnlyAvailableUntilTheMiddleOfTheReportInterval() { DateMidnight startDate = new DateMidnight(2012, 12, 31); DateMidnight middleDate = new DateMidnight(2013, 2, 18); DateMidnight endDate = new DateMidnight(2013, 3, 31); // create model Client client = new Client(); Account account = new Account(); client.addAccount(account); addT( account, startDate.toCalendar(Locale.getDefault()), Type.DEPOSIT, 100 * Values.Amount.factor()); addT( account, startDate.plusDays(10).toCalendar(Locale.getDefault()), Type.INTEREST, 10 * Values.Amount.factor()); Security security = new Security(); client.addSecurity(security); int startPrice = 50 * Values.Amount.factor(); generatePrices(security, startPrice, startDate, middleDate); // calculate performance indices List<Exception> warnings = new ArrayList<Exception>(); ReportingPeriod reportInterval = new ReportingPeriod.FromXtoY(startDate.toDate(), endDate.toDate()); ClientIndex clientIndex = PerformanceIndex.forClient(client, reportInterval, warnings); PerformanceIndex securityIndex = PerformanceIndex.forSecurity(clientIndex, security, warnings); // asserts assertTrue(warnings.isEmpty()); Date[] clientDates = clientIndex.getDates(); Date[] securityDates = securityIndex.getDates(); assertThat(securityDates[0], is(startDate.toDate())); assertThat(securityDates[securityDates.length - 1], is(middleDate.toDate())); assertThat(new DateMidnight(clientDates[0]), is(new DateMidnight(securityDates[0]))); double[] securityAccumulated = securityIndex.getAccumulatedPercentage(); int index = Days.daysBetween(startDate, middleDate).getDays(); assertThat(new DateMidnight(clientDates[index]), is(middleDate)); assertThat(securityAccumulated[0], IsCloseTo.closeTo(0d, 0.000001d)); long middlePrice = security.getSecurityPrice(middleDate.toDate()).getValue(); double performance = (double) (middlePrice - startPrice) / (double) startPrice; assertThat( securityAccumulated[securityAccumulated.length - 1], IsCloseTo.closeTo(performance, 0.000001d)); }