Beispiel #1
0
  @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);
    }
  }
Beispiel #2
0
 @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;
 }
Beispiel #3
0
 @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;
 }
Beispiel #4
0
 @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;
 }
Beispiel #5
0
  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);
  }
Beispiel #6
0
  @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);
    }
  }
Beispiel #7
0
 @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();
 }
Beispiel #8
0
  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;
    }
  }