@Override public BigDecimal getPriceAvgBuyFor( PortfolioShare portfolioShare, Date currentStartDate, Date currentEndDate, Currency targetCurrency) { BigDecimal totalMoneyInvested = BigDecimal.ZERO; BigDecimal totalQuantityBought = BigDecimal.ZERO; for (TransactionElement te : headTransactionsTo(currentStartDate, currentEndDate)) { if (te.transactionType().equals(TransactionType.AIN) && te.getStock().equals(portfolioShare.getStock())) { BigDecimal convertedPrice = getCurrencyConverter() .convert(te.getCurrency(), targetCurrency, te.getPrice(), te.getDate()); totalMoneyInvested = totalMoneyInvested.add( convertedPrice.multiply(te.getQuantity()).setScale(10, BigDecimal.ROUND_HALF_EVEN)); totalQuantityBought = totalQuantityBought.add(te.getQuantity()); } } if (totalQuantityBought.compareTo(BigDecimal.ZERO) == 0) { LOGGER.warn("getPriceAvgBuyFor : Bought Transaction sum to zero for " + portfolioShare); return BigDecimal.ZERO; } else { return totalMoneyInvested.divide(totalQuantityBought, 10, BigDecimal.ROUND_HALF_EVEN); } }
@Override public BigDecimal getQuantityFor( PortfolioShare portfolioShare, Date currentStartDate, Date currentEndDate) { BigDecimal ret = BigDecimal.ZERO; for (TransactionElement te : headTransactionsTo(currentStartDate, currentEndDate)) { if (te.getStock().equals(portfolioShare.getStock())) { ret = ret.add(te.getQuantity()); } } return ret; }
@Transient public SortedSet<TransactionElement> getTransactionsFor( PortfolioShare portfolioShare, Date currentStartDate, Date currentEndDate) { SortedSet<TransactionElement> ret = new TreeSet<TransactionElement>(); for (TransactionElement te : headTransactionsTo(currentStartDate, currentEndDate)) { if (te.getStock().equals(portfolioShare.getStock())) { ret.add(te); } } return ret; }
@Transient public Date getLastTransactionFor( PortfolioShare portfolioShare, Date currentStartDate, Date currentEndDate) { // return transactions.last().getDate(); Date ret = new Date(0); for (TransactionElement te : headTransactionsTo(currentStartDate, currentEndDate)) { if (te.getStock().equals(portfolioShare.getStock())) { ret = te.getDate(); } } return ret; }
public void rawRemoveShare(PortfolioShare portfolioShare) { removeShareFromList(portfolioShare); Set<TransactionElement> toRemove = new HashSet<TransactionElement>(); for (TransactionElement transaction : transactions) { if (transaction.getStock().equals(portfolioShare.getStock())) { toRemove.add(transaction); } } transactions.removeAll(toRemove); }
@Override public InOutWeighted getWeightedInvestedFor( PortfolioShare portfolioShare, Date currentEndDate, Currency currency) { try { SortedSet<TransactionElement> transactionsForStock = new TreeSet<TransactionElement>(); for (TransactionElement te : headTransactionsTo(null, currentEndDate)) { if (te.getStock().equals(portfolioShare.getStock())) { transactionsForStock.add(te); } } return portfolioShare.calculateInflationAndExpectationWeightedInvestedCash( currentEndDate, transactionsForStock, currency); } catch (InvalidAlgorithmParameterException e) { BigDecimal cashin = portfolioShare.getCashin(null, currentEndDate, currency); BigDecimal cashout = portfolioShare.getCashout(null, currentEndDate, currency); return new InOutWeighted(cashin, cashout, currentEndDate); } }
@Override public BigDecimal getCashOutFor( PortfolioShare portfolioShare, Date currentStartDate, Date currentEndDate, Currency targetCurrency) { BigDecimal ret = BigDecimal.ZERO; for (TransactionElement te : headTransactionsTo(currentStartDate, currentEndDate)) { if (te.transactionType().equals(TransactionType.AOUT) && te.getStock().equals(portfolioShare.getStock())) { BigDecimal convertedPrice = getCurrencyConverter() .convert(te.getCurrency(), targetCurrency, te.getPrice(), te.getDate()); ret = ret.add( convertedPrice.multiply(te.getQuantity()).setScale(10, BigDecimal.ROUND_HALF_EVEN)); } } return ret.abs(); }
private String extractTransactionLog( Date startDate, Date endDate, Currency targetCurrency, Date cpgPeriodStart, Date cpgPeriodEnd, BigDecimal transactionFee, BigDecimal exchangeFee) throws Throwable { try { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); SortedSet<TransactionElement> sortedByStock = transactionsSortedByStock(startDate, endDate); CurrencyConverter currencyConverter = PortfolioMgr.getInstance().getCurrencyConverter(); String messagePortCurrency = "Transactions (" + targetCurrency + " - " + dateFormat.format(cpgPeriodStart) + " -> " + dateFormat.format(cpgPeriodEnd) + " - transaction fee " + transactionFee + " - exchange fee " + exchangeFee + ") in " + getName() + " :\n" + "stock, date, transaction price, quantity in, amount in, quantity out, amount out, realised capital gain, currency, close price"; String messageNoConvertion = "Transactions (Original currencies - " + dateFormat.format(cpgPeriodStart) + " -> " + dateFormat.format(cpgPeriodEnd) + " - transaction fee " + transactionFee + ") in " + getName() + " :\n" + "stock, date, transaction price, quantity in, amount in, quantity out, amount out, realised capital gain, currency, close price, exchange rate"; Stock currentStock = null; // Transactions Map<Stock, BigDecimal[]> pss = new HashMap<Stock, BigDecimal[]>(); for (TransactionElement te : sortedByStock) { if (currentStock == null || !currentStock.equals(te.getStock())) { // init stock currentStock = te.getStock(); // pss.add(getShareForStock(currentStock)); pss.put(currentStock, new BigDecimal[] {BigDecimal.ZERO, BigDecimal.ZERO}); } BigDecimal closePrice = BigDecimal.ZERO; BigDecimal convertedClosePrice = BigDecimal.ZERO; BigDecimal convertionRate = BigDecimal.ONE; try { Quotations quotations = QuotationsFactories.getFactory() .getQuotationsInstance( currentStock, te.getDate(), true, currentStock.getMarketValuation().getCurrency(), ValidityFilter.CLOSE); closePrice = quotations.getClosestCloseForDate(te.getDate()); Quotations convertedQuotations = QuotationsFactories.getFactory() .getQuotationsInstance( currentStock, te.getDate(), true, targetCurrency, ValidityFilter.CLOSE); convertedClosePrice = convertedQuotations.getClosestCloseForDate(te.getDate()); convertionRate = currencyConverter.convert( currentStock.getMarketValuation(), targetCurrency, BigDecimal.ONE, te.getDate()); } catch (Exception e) { LOGGER.warn("Error loading stock prices for " + currentStock + " : " + e); } boolean buy = te.getQuantity().compareTo(BigDecimal.ZERO) > 0; BigDecimal transPrice = applyFee(buy, te.getPrice(), transactionFee); BigDecimal convertedTransPrice = applyFee( buy, currencyConverter.convert( te.getCurrency(), targetCurrency, transPrice, te.getDate()), exchangeFee); BigDecimal transAmount = transPrice.multiply(te.getQuantity()).setScale(2, BigDecimal.ROUND_HALF_EVEN); BigDecimal convertedTransAmount = convertedTransPrice.multiply(te.getQuantity()).setScale(2, BigDecimal.ROUND_HALF_EVEN); if (buy) { messagePortCurrency = messagePortCurrency + "\n" + currentStock.getFriendlyName() + "," + dateFormat.format(te.getDate()) + "," + convertedTransPrice + "," + te.getQuantity() + "," + convertedTransAmount + ",,,0.00," + targetCurrency + "," + convertedClosePrice; messageNoConvertion = messageNoConvertion + "\n" + currentStock.getFriendlyName() + "," + dateFormat.format(te.getDate()) + "," + transPrice + "," + te.getQuantity() + "," + transAmount + ",,,0.00," + te.getCurrency() + "," + closePrice + "," + convertionRate; } else { // sell Boolean isSellWithinCpgPeriod = te.getDate().compareTo(cpgPeriodStart) >= 0 && te.getDate().compareTo(cpgPeriodEnd) <= 0; BigDecimal cpgPortCurrency = BigDecimal.ZERO; if (isSellWithinCpgPeriod) { BigDecimal priceAvgBuyPortCur = applyFee( true, applyFee( true, this.getShareForStock(currentStock) .getPriceAvgBuy(startDate, te.getDate(), targetCurrency), transactionFee), exchangeFee); cpgPortCurrency = te.getQuantity() .multiply(priceAvgBuyPortCur) .setScale(2, BigDecimal.ROUND_HALF_EVEN) .subtract(convertedTransAmount); pss.get(currentStock)[0] = pss.get(currentStock)[0].add(cpgPortCurrency); } messagePortCurrency = messagePortCurrency + "\n" + currentStock.getFriendlyName() + "," + dateFormat.format(te.getDate()) + "," + convertedTransPrice + ",,," + te.getQuantity() + "," + convertedTransAmount + "," + cpgPortCurrency + "," + targetCurrency + "," + convertedClosePrice; BigDecimal cpgNoConv = BigDecimal.ZERO; if (isSellWithinCpgPeriod) { BigDecimal priceAvgBuyNoConv = applyFee( true, this.getShareForStock(currentStock) .getPriceAvgBuy( startDate, te.getDate(), currentStock.getMarketValuation().getCurrency()), transactionFee); cpgNoConv = te.getQuantity() .multiply(priceAvgBuyNoConv) .setScale(2, BigDecimal.ROUND_HALF_EVEN) .subtract(transAmount); pss.get(currentStock)[1] = pss.get(currentStock)[1].add(cpgNoConv); } messageNoConvertion = messageNoConvertion + "\n" + currentStock.getFriendlyName() + "," + dateFormat.format(te.getDate()) + "," + transPrice + ",,," + te.getQuantity() + "," + transAmount + "," + cpgNoConv + "," + te.getCurrency() + "," + closePrice + "," + convertionRate; } } messagePortCurrency = messagePortCurrency + "\n\n" + "Totals (" + targetCurrency + " - " + dateFormat.format(cpgPeriodStart) + " -> " + dateFormat.format(cpgPeriodEnd) + " - transaction fee " + transactionFee + " - exchange fee " + exchangeFee + ") in " + getName() + " :\n" + "stock, on the, average price, quantity, invested (in-out), value, realised capital gain, potential capital gain, currency, last close"; messageNoConvertion = messageNoConvertion + "\n\n" + "Totals (Original currencies - " + dateFormat.format(cpgPeriodStart) + " -> " + dateFormat.format(cpgPeriodEnd) + " - transaction fee " + transactionFee + ") in " + getName() + " :\n" + "stock, on the, average price, quantity, invested (in-out), value, realised capital gain, potential capital gain, currency, last close, last exchange rate"; // Totals for (Stock stock : pss.keySet()) { PortfolioShare ps = getShareForStock(stock); try { Quotations quotations = QuotationsFactories.getFactory() .getQuotationsInstance( stock, endDate, true, stock.getMarketValuation().getCurrency(), ValidityFilter.CLOSE); BigDecimal lastClosePrice = quotations.getClosestCloseForDate(endDate); Quotations convertedQuotations = QuotationsFactories.getFactory() .getQuotationsInstance( stock, endDate, true, targetCurrency, ValidityFilter.CLOSE); BigDecimal lastConvertedClosePrice = convertedQuotations.getClosestCloseForDate(endDate); BigDecimal lastConvertionRate = currencyConverter.convert( stock.getMarketValuation(), targetCurrency, BigDecimal.ONE, endDate); BigDecimal quantity = getQuantityFor(ps, startDate, endDate); boolean isQuantityPositiveAtEndPeriod = ps.getQuantity(startDate, cpgPeriodEnd).compareTo(BigDecimal.ZERO) > 0; BigDecimal invPortCur = applyFee( true, applyFee( true, ps.getCashin(startDate, endDate, targetCurrency), transactionFee), exchangeFee) .subtract( applyFee( false, applyFee( false, ps.getCashout(startDate, endDate, targetCurrency), transactionFee), exchangeFee)); BigDecimal valuePortCur = applyFee( false, applyFee(false, ps.getValue(startDate, endDate, targetCurrency), transactionFee), exchangeFee); messagePortCurrency = messagePortCurrency + "\n" + ps.getStock().getFriendlyName() + ", " + dateFormat.format(endDate) + ", " + applyFee( true, applyFee( true, ps.getPriceAvgBuy(startDate, endDate, targetCurrency), transactionFee), exchangeFee) + ", " + quantity + "," + invPortCur + ", " + valuePortCur + ", " + pss.get(stock)[0] + "," + (isQuantityPositiveAtEndPeriod ? valuePortCur.subtract(invPortCur) : BigDecimal.ZERO) + ", " + targetCurrency + ", " + lastConvertedClosePrice; BigDecimal invNoConv = applyFee( true, ps.getCashin(startDate, endDate, stock.getMarketValuation().getCurrency()), transactionFee) .subtract( applyFee( false, ps.getCashout( startDate, endDate, stock.getMarketValuation().getCurrency()), transactionFee)); BigDecimal valueNoConv = applyFee( false, ps.getValue(startDate, endDate, stock.getMarketValuation().getCurrency()), transactionFee); messageNoConvertion = messageNoConvertion + "\n" + ps.getStock().getFriendlyName() + ", " + dateFormat.format(endDate) + ", " + applyFee( true, ps.getPriceAvgBuy( startDate, endDate, stock.getMarketValuation().getCurrency()), transactionFee) + ", " + quantity + "," + invNoConv + ", " + valueNoConv + ", " + pss.get(stock)[1] + "," + (isQuantityPositiveAtEndPeriod ? valueNoConv.subtract(invNoConv) : BigDecimal.ZERO) + ", " + stock.getMarketValuation().getCurrency() + ", " + lastClosePrice + ", " + lastConvertionRate; } catch (Exception e) { LOGGER.warn("Error loading last stock prices for " + stock + " : " + e); } } return messagePortCurrency + "\n\n" + messageNoConvertion; } catch (Throwable e) { throw e; } }