org.pau.assetmanager.viewmodel.stocks.HistoricalStockBalanceState.java Source code

Java tutorial

Introduction

Here is the source code for org.pau.assetmanager.viewmodel.stocks.HistoricalStockBalanceState.java

Source

/**
 * This file is part of Pau's Asset Manager Project.
 *
 * Pau's Asset Manager Project is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Pau's Asset Manager Project is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Pau's Asset Manager Project.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.pau.assetmanager.viewmodel.stocks;

import java.util.Calendar;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.pau.assetmanager.entities.Annotation;
import org.pau.assetmanager.entities.StockExpensesAnnotation;
import org.pau.assetmanager.entities.StockIncomeAnnotation;
import org.pau.assetmanager.utils.AssetManagerRuntimeException;
import org.pau.assetmanager.viewmodel.StocksYearlyReportViewModel;
import org.pau.assetmanager.viewmodel.utils.BookSelection;

import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.collect.Table;

public class HistoricalStockBalanceState {

    public static Table<Integer, Integer, Set<StockState>> getConiniousHistoricalStockBalanceStateTable(
            BookSelection bookSelection, Integer lastYear, Optional<String> optionalStockLabel) {
        Table<Integer, Integer, Set<StockState>> uncontiniousHistoricalStockBalanceStateTable = getDiscontiniousHistoricalStockBalanceStateTable(
                bookSelection, lastYear, optionalStockLabel);
        Table<Integer, Integer, Set<StockState>> continiousHistoricalStockBalanceStateTable = HashBasedTable
                .<Integer, Integer, Set<StockState>>create();
        List<Integer> yearsWithHistoricalValues = Lists
                .newArrayList(uncontiniousHistoricalStockBalanceStateTable.rowMap().keySet());
        Map<String, StockState> stockToStockState = new HashMap<String, StockState>();
        if (yearsWithHistoricalValues.size() > 0) {
            Collections.sort(yearsWithHistoricalValues);
            for (Integer currentYear = yearsWithHistoricalValues.get(0); currentYear <= lastYear; currentYear++) {
                Map<Integer, Set<StockState>> yearHistoricalStockBalanceStateTable = uncontiniousHistoricalStockBalanceStateTable
                        .rowMap().get(currentYear);
                for (Integer currentMonth = 0; currentMonth <= 11; currentMonth++) {
                    Set<StockState> stockStateSet = new HashSet<StockState>();
                    if (yearHistoricalStockBalanceStateTable != null
                            && yearHistoricalStockBalanceStateTable.get(currentMonth) != null) {
                        stockStateSet = yearHistoricalStockBalanceStateTable.get(currentMonth);
                    }
                    Map<String, StockState> currentStockToStockState = Maps.uniqueIndex(stockStateSet,
                            new Function<StockState, String>() {
                                @Override
                                public String apply(StockState input) {
                                    return input.getSymbol();
                                }
                            });
                    stockToStockState.putAll(currentStockToStockState);
                    continiousHistoricalStockBalanceStateTable.put(currentYear, currentMonth,
                            Sets.newHashSet(stockToStockState.values()));
                }
            }
        }
        return continiousHistoricalStockBalanceStateTable;
    }

    private static Table<Integer, Integer, Set<StockState>> getDiscontiniousHistoricalStockBalanceStateTable(
            BookSelection bookSelection, Integer lastYear, Optional<String> optionalStockLabel) {
        // year --> month --> symbol
        Table<Integer, Integer, Set<StockState>> historicalStockBalanceStateTable = HashBasedTable
                .<Integer, Integer, Set<StockState>>create();
        Calendar calendar = GregorianCalendar.getInstance();
        List<Annotation> annotations = StocksYearlyReportViewModel.getStocksAnnotationsUntilYear(bookSelection,
                lastYear);
        if (optionalStockLabel.isPresent()) {
            final String stockLabel = optionalStockLabel.get();
            annotations = Lists.newArrayList(Collections2.filter(annotations, new Predicate<Annotation>() {
                @Override
                public boolean apply(Annotation annotation) {
                    if (annotation instanceof StockIncomeAnnotation
                            || annotation instanceof StockExpensesAnnotation) {
                        return annotation.getConcept().equals(stockLabel);
                    } else {
                        return false;
                    }
                }
            }));
        }
        Map<String, StockState> symbolToCurrentStockState = new HashMap<String, StockState>();
        for (Annotation annotation : annotations) {
            calendar.setTime(annotation.getDate());
            Integer currentYear = calendar.get(Calendar.YEAR);
            Integer currentMonth = calendar.get(Calendar.MONTH);
            updateCurrentSymbolToCurrentStockState(symbolToCurrentStockState, annotation, currentMonth,
                    currentYear);
            StockState stockState = symbolToCurrentStockState.get(annotation.getConcept());
            Set<StockState> setOfStockStates = null;
            if (historicalStockBalanceStateTable.rowMap().get(currentYear) == null
                    || historicalStockBalanceStateTable.rowMap().get(currentYear).get(currentMonth) == null) {
                setOfStockStates = new HashSet<StockState>();
            } else {
                setOfStockStates = historicalStockBalanceStateTable.rowMap().get(currentYear).get(currentMonth);
            }
            if (setOfStockStates.contains(stockState)) {
                setOfStockStates.remove(stockState);
            }
            setOfStockStates.add(stockState);
            historicalStockBalanceStateTable.put(currentYear, currentMonth, setOfStockStates);
        }
        return historicalStockBalanceStateTable;
    }

    private static void updateCurrentSymbolToCurrentStockState(Map<String, StockState> symbolToCurrentStockState,
            Annotation annotation, Integer month, Integer year) {
        if (!symbolToCurrentStockState.keySet().contains(annotation.getConcept())) {
            if (annotation instanceof StockExpensesAnnotation) {
                StockExpensesAnnotation stockExpensesAnnotation = (StockExpensesAnnotation) annotation;
                StockState stockState = new StockState(stockExpensesAnnotation.getConcept(),
                        -stockExpensesAnnotation.getAmount(), stockExpensesAnnotation.getNumberOfStocks(), month,
                        year);
                symbolToCurrentStockState.put(annotation.getConcept(), stockState);
            } else {
                throw new AssetManagerRuntimeException("the first transaction should be buy stocks");
                // TODO: error, the first transaction should be buy stocks
            }
        } else {
            StockState stockState = symbolToCurrentStockState.get(annotation.getConcept());
            if (annotation instanceof StockExpensesAnnotation) {
                StockExpensesAnnotation stockExpensesAnnotation = (StockExpensesAnnotation) annotation;
                stockState = new StockState(stockState.getSymbol(),
                        stockState.getBalance() - stockExpensesAnnotation.getAmount(),
                        stockState.getNumberOfPurchasedStocks() + stockExpensesAnnotation.getNumberOfStocks(),
                        month, year);
            } else if (annotation instanceof StockIncomeAnnotation) {
                StockIncomeAnnotation stockIncomeAnnotation = (StockIncomeAnnotation) annotation;
                stockState = new StockState(stockState.getSymbol(),
                        stockState.getBalance() + stockIncomeAnnotation.getAmount(),
                        stockState.getNumberOfPurchasedStocks() - stockIncomeAnnotation.getNumberOfStocks(), month,
                        year);
            }
            symbolToCurrentStockState.put(annotation.getConcept(), stockState);
        }

    }

}