Package name.abuchen.portfolio.snapshot

Source Code of name.abuchen.portfolio.snapshot.GroupByTaxonomy$Item

package name.abuchen.portfolio.snapshot;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import name.abuchen.portfolio.Messages;
import name.abuchen.portfolio.model.Classification;
import name.abuchen.portfolio.model.Classification.Assignment;
import name.abuchen.portfolio.model.InvestmentVehicle;
import name.abuchen.portfolio.model.SecurityPrice;
import name.abuchen.portfolio.model.Taxonomy;
import name.abuchen.portfolio.model.Values;

public final class GroupByTaxonomy
{
    private static final class Item
    {
        private SecurityPosition position;
        private int weight;

        private Item(SecurityPosition position)
        {
            this.position = position;
        }
    }

    private final Taxonomy taxonomy;
    private final long valuation;
    private final List<AssetCategory> categories = new ArrayList<AssetCategory>();

    private GroupByTaxonomy(Taxonomy taxonomy, long valuation)
    {
        this.taxonomy = taxonomy;
        this.valuation = valuation;
    }

    /* package */GroupByTaxonomy(Taxonomy taxonomy, ClientSnapshot snapshot)
    {
        this(taxonomy, snapshot.getAssets());

        Map<InvestmentVehicle, Item> vehicle2position = new HashMap<InvestmentVehicle, Item>();

        // cash
        for (AccountSnapshot a : snapshot.getAccounts())
        {
            if (a.getFunds() == 0)
                continue;

            SecurityPosition sp = new SecurityPosition(null);
            sp.setShares(Values.Share.factor());
            sp.setPrice(new SecurityPrice(snapshot.getTime(), a.getFunds()));
            vehicle2position.put(a.getAccount(), new Item(sp));
        }

        // portfolio
        if (snapshot.getJointPortfolio() != null)
        {
            for (SecurityPosition pos : snapshot.getJointPortfolio().getPositions())
                vehicle2position.put(pos.getSecurity(), new Item(pos));
        }

        doGrouping(vehicle2position);
    }

    /* package */public GroupByTaxonomy(Taxonomy taxonomy, PortfolioSnapshot snapshot)
    {
        this(taxonomy, snapshot.getValue());

        Map<InvestmentVehicle, Item> vehicle2position = new HashMap<InvestmentVehicle, Item>();

        for (SecurityPosition pos : snapshot.getPositions())
            vehicle2position.put(pos.getSecurity(), new Item(pos));

        doGrouping(vehicle2position);
    }

    private void doGrouping(final Map<InvestmentVehicle, Item> vehicle2position)
    {
        if (taxonomy != null)
        {
            createCategoriesAndAllocate(vehicle2position);
            sortCategoriesByRank();
        }

        allocateLeftOvers(vehicle2position);
    }

    private void createCategoriesAndAllocate(final Map<InvestmentVehicle, Item> vehicle2position)
    {
        for (Classification classification : taxonomy.getRoot().getChildren())
        {
            final Map<InvestmentVehicle, Item> vehicle2item = new HashMap<InvestmentVehicle, Item>();

            // first: assign items to categories

            // item.weight records both the weight
            // (a) already assigned to any category
            // (b) assigned to this category

            classification.accept(new Taxonomy.Visitor()
            {
                @Override
                public void visit(Classification classification, Assignment assignment)
                {
                    Item item = vehicle2position.get(assignment.getInvestmentVehicle());
                    if (item != null)
                    {
                        item.weight += assignment.getWeight(); // record (a)

                        SecurityPosition position = item.position;
                        if (assignment.getWeight() == Classification.ONE_HUNDRED_PERCENT)
                        {
                            vehicle2item.put(assignment.getInvestmentVehicle(), item);
                        }
                        else
                        {
                            Item other = vehicle2item.get(assignment.getInvestmentVehicle());
                            if (other == null)
                            {
                                other = new Item(position);
                                vehicle2item.put(assignment.getInvestmentVehicle(), other);
                            }

                            // record (b) into the copy
                            other.weight += assignment.getWeight();
                        }
                    }
                }
            });

            // second: create asset category and positions

            if (!vehicle2item.isEmpty())
            {
                AssetCategory category = new AssetCategory(classification, valuation);
                categories.add(category);

                for (Entry<InvestmentVehicle, Item> entry : vehicle2item.entrySet())
                {
                    Item item = entry.getValue();
                    SecurityPosition position = item.position;
                    if (item.weight != Classification.ONE_HUNDRED_PERCENT)
                        position = SecurityPosition.split(position, item.weight);

                    category.addPosition(new AssetPosition(entry.getKey(), position, getValuation()));
                }

                // sort positions by name
                Collections.sort(category.getPositions(), new AssetPosition.ByDescription());
            }
        }
    }

    private void sortCategoriesByRank()
    {
        Collections.sort(categories, new Comparator<AssetCategory>()
        {
            @Override
            public int compare(AssetCategory o1, AssetCategory o2)
            {
                int rank1 = o1.getClassification().getRank();
                int rank2 = o2.getClassification().getRank();
                return rank1 < rank2 ? -1 : rank1 == rank2 ? 0 : 1;
            }
        });
    }

    private void allocateLeftOvers(final Map<InvestmentVehicle, Item> vehicle2position)
    {
        Classification classification = new Classification(null, Classification.UNASSIGNED_ID,
                        Messages.LabelWithoutClassification);
        AssetCategory unassigned = new AssetCategory(classification, getValuation());

        for (Entry<InvestmentVehicle, Item> entry : vehicle2position.entrySet())
        {
            Item item = entry.getValue();

            if (item.weight < Classification.ONE_HUNDRED_PERCENT)
            {
                SecurityPosition position = item.position;
                if (item.weight != 0)
                    position = SecurityPosition.split(position, Classification.ONE_HUNDRED_PERCENT - item.weight);

                unassigned.addPosition(new AssetPosition(entry.getKey(), position, getValuation()));
            }
        }

        if (!unassigned.getPositions().isEmpty())
            categories.add(unassigned);
    }

    public long getValuation()
    {
        return valuation;
    }

    public long getFIFOPurchaseValue()
    {
        long purchaseValue = 0;
        for (AssetCategory category : categories)
            purchaseValue += category.getFIFOPurchaseValue();
        return purchaseValue;
    }

    public long getProfitLoss()
    {
        long profitLoss = 0;
        for (AssetCategory category : categories)
            profitLoss += category.getProfitLoss();
        return profitLoss;
    }

    public List<AssetCategory> asList()
    {
        return categories;
    }

    /* package */AssetCategory byClassification(Classification classification)
    {
        for (AssetCategory category : categories)
        {
            if (category.getClassification().equals(classification))
                return category;
        }

        return null;
    }
}
TOP

Related Classes of name.abuchen.portfolio.snapshot.GroupByTaxonomy$Item

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.