use of name.abuchen.portfolio.snapshot.filter.ClientSecurityFilter in project portfolio by buchen.
the class SecurityTaxAndFeeAccountTransactionsTestCase method testAdidas.
@Test
public void testAdidas() {
SecurityPerformanceSnapshot snapshot = SecurityPerformanceSnapshot.create(client, converter, interval);
SecurityPerformanceRecord record = snapshot.getRecords().stream().filter(r -> r.getSecurity().equals(adidas)).findAny().orElseThrow(IllegalArgumentException::new);
assertThat(record.getTransactions().size(), is(6));
// fees and taxes from the buy transaction + separate transactions
assertThat(record.getFees(), is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(10d + 10d - 5d))));
assertThat(record.getTaxes(), is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(10d + 25d - 5d))));
// delta is end value - starting value including all fees and taxes
assertThat(record.getDelta(), is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(1456.5 - 1533 - 10 + 5 - 25 + 5))));
// IRR as calculated in Excel
// @formatter:off
// date w/ tax w/o tax
// 02.01.17 -1533 -1523
// 09.01.17 -10 -10
// 10.01.17 5 5
// 11.01.17 -25 0
// 12.01.17 5 0
// 31.01.17 1456,5 1456,5
// XIRR -0,573350433 -0,453151944
// @formatter:on
assertThat(record.getIrr(), closeTo(-0.453151944d, 1.0e-8));
// check filtering - ClientSecurityFilter
Client filteredClient = new ClientSecurityFilter(adidas).filter(client);
checkFilteredClientAdidas(filteredClient, 1.0);
// check filtering - ClientClassificationFilter
Taxonomy case1 = client.getTaxonomies().stream().filter(t -> "case_full_classification_adidas".equals(t.getName())).findAny().orElseThrow(IllegalArgumentException::new);
Classification classification = case1.getAllClassifications().stream().filter(c -> "category_security".equals(c.getName())).findAny().orElseThrow(IllegalArgumentException::new);
filteredClient = new ClientClassificationFilter(classification).filter(client);
checkFilteredClientAdidas(filteredClient, 1.0);
// TTWROR must be identical to one calculated via ClientSecurityFilter
// (implicitly used by the SecurityPeformanceSnapshot)
PerformanceIndex index = PerformanceIndex.forClassification(client, converter, classification, interval, new ArrayList<>());
assertThat(index.getFinalAccumulatedPercentage(), is(record.getTrueTimeWeightedRateOfReturn()));
// a partial assignment of the security should be identical to the full
// assignment - only the weight differs
Taxonomy case2 = client.getTaxonomies().stream().filter(t -> "case_partial_classification_adidas".equals(t.getName())).findAny().orElseThrow(IllegalArgumentException::new);
classification = case2.getAllClassifications().stream().filter(c -> "category_security".equals(c.getName())).findAny().orElseThrow(IllegalArgumentException::new);
filteredClient = new ClientClassificationFilter(classification).filter(client);
checkFilteredClientAdidas(filteredClient, 0.5);
}
use of name.abuchen.portfolio.snapshot.filter.ClientSecurityFilter in project portfolio by buchen.
the class SecuritiesChart method addMovingAveragePurchasePrice.
private void addMovingAveragePurchasePrice() {
// no purchase price
if (security.getCurrencyCode() == null)
return;
// create a list of dates that are relevant for floating avg purchase price
// changes (i.e. all purchase and sell events)
Client filteredClient = new ClientSecurityFilter(security).filter(client);
CurrencyConverter securityCurrency = converter.with(security.getCurrencyCode());
LocalDate today = LocalDate.now();
List<LocalDate> candidates = //
client.getPortfolios().stream().flatMap(//
p -> p.getTransactions().stream()).filter(t -> t.getSecurity().equals(security)).filter(t -> !(t.getType() == PortfolioTransaction.Type.TRANSFER_IN || t.getType() == PortfolioTransaction.Type.TRANSFER_OUT)).filter(t -> t.getDateTime().toLocalDate().isBefore(today)).map(t -> (chartPeriod == null || t.getDateTime().toLocalDate().isAfter(chartPeriod)) ? t.getDateTime().toLocalDate() : chartPeriod).distinct().sorted().collect(Collectors.toList());
// calculate floating avg purchase price for each event - separate lineSeries
// per holding period
List<Double> values = new ArrayList<>();
List<LocalDate> dates = new ArrayList<>();
int seriesCounter = 0;
for (LocalDate eventDate : candidates) {
Optional<Double> purchasePrice = getMovingAveragePurchasePrice(filteredClient, securityCurrency, eventDate);
if (purchasePrice.isPresent()) {
dates.add(eventDate);
values.add(purchasePrice.get());
} else {
if (!dates.isEmpty()) {
// add previous value if the data series ends here (no more
// future events)
dates.add(eventDate);
values.add(values.get(values.size() - 1));
createMovingAveragePurchaseLineSeries(values, dates, seriesCounter++);
values.clear();
dates.clear();
} else if (dates.isEmpty()) {
// if no holding period exists, then do not add the event at
// all
}
}
}
// add today if needed
getMovingAveragePurchasePrice(filteredClient, securityCurrency, today).ifPresent(price -> {
dates.add(today);
values.add(price);
});
if (!dates.isEmpty())
createMovingAveragePurchaseLineSeries(values, dates, seriesCounter);
}
use of name.abuchen.portfolio.snapshot.filter.ClientSecurityFilter in project portfolio by buchen.
the class SecuritiesChart method addFIFOPurchasePrice.
private void addFIFOPurchasePrice() {
// no purchase price
if (security.getCurrencyCode() == null)
return;
// create a list of dates that are relevant for FIFO purchase price
// changes (i.e. all purchase and sell events)
Client filteredClient = new ClientSecurityFilter(security).filter(client);
CurrencyConverter securityCurrency = converter.with(security.getCurrencyCode());
LocalDate today = LocalDate.now();
List<LocalDate> candidates = //
client.getPortfolios().stream().flatMap(//
p -> p.getTransactions().stream()).filter(t -> t.getSecurity().equals(security)).filter(t -> !(t.getType() == PortfolioTransaction.Type.TRANSFER_IN || t.getType() == PortfolioTransaction.Type.TRANSFER_OUT)).filter(t -> t.getDateTime().toLocalDate().isBefore(today)).map(t -> (chartPeriod == null || t.getDateTime().toLocalDate().isAfter(chartPeriod)) ? t.getDateTime().toLocalDate() : chartPeriod).distinct().sorted().collect(Collectors.toList());
// calculate FIFO purchase price for each event - separate lineSeries
// per holding period
List<Double> values = new ArrayList<>();
List<LocalDate> dates = new ArrayList<>();
int seriesCounter = 0;
for (LocalDate eventDate : candidates) {
Optional<Double> purchasePrice = getPurchasePrice(filteredClient, securityCurrency, eventDate);
if (purchasePrice.isPresent()) {
dates.add(eventDate);
values.add(purchasePrice.get());
} else {
if (!dates.isEmpty()) {
// add previous value if the data series ends here (no more
// future events)
dates.add(eventDate);
values.add(values.get(values.size() - 1));
createFIFOPurchaseLineSeries(values, dates, seriesCounter++);
values.clear();
dates.clear();
} else if (dates.isEmpty()) {
// if no holding period exists, then do not add the event at
// all
}
}
}
// add today if needed
getPurchasePrice(filteredClient, securityCurrency, today).ifPresent(price -> {
dates.add(today);
values.add(price);
});
if (!dates.isEmpty())
createFIFOPurchaseLineSeries(values, dates, seriesCounter);
}
Aggregations