Package com.opengamma.financial.aggregation

Source Code of com.opengamma.financial.aggregation.PortfolioMultiAggregator

/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.aggregation;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.TreeMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Lists;
import com.opengamma.core.position.Portfolio;
import com.opengamma.core.position.PortfolioNode;
import com.opengamma.core.position.Position;
import com.opengamma.core.position.impl.SimplePortfolio;
import com.opengamma.core.position.impl.SimplePortfolioNode;
import com.opengamma.util.ArgumentChecker;

/**
* An aggregator of portfolios.
*/
public class PortfolioMultiAggregator {
 
  private static final Logger s_logger = LoggerFactory.getLogger(PortfolioMultiAggregator.class);

  private final List<List<AggregationFunction<?>>> _aggregationFunctionsList;

  public PortfolioMultiAggregator(List<List<AggregationFunction<?>>> aggregationFunctions) {
    _aggregationFunctionsList = aggregationFunctions;
  }
 
  public Portfolio aggregate(Portfolio inputPortfolio) {
    return aggregate(inputPortfolio, inputPortfolio.getName() + " multi-aggregated");
  }

  public Portfolio aggregate(Portfolio inputPortfolio, String portfolioName) {
    ArgumentChecker.notEmpty(portfolioName, "portfolioName");
    List<Position> flattenedPortfolio = Lists.newArrayList();
    flatten(inputPortfolio.getRootNode(), flattenedPortfolio);
    final SimplePortfolioNode root = new SimplePortfolioNode(portfolioName);
    for (List<AggregationFunction<?>> aggregationFunctions : _aggregationFunctionsList) {
      final SimplePortfolioNode aggregateRoot = new SimplePortfolioNode(buildPortfolioNodeName(aggregationFunctions));
      aggregate(aggregateRoot, flattenedPortfolio, new ArrayDeque<>(aggregationFunctions));
      root.addChildNode(aggregateRoot);
    }
    return new SimplePortfolio(portfolioName, root);
  }
 
  protected void flatten(PortfolioNode portfolioNode, List<Position> flattenedPortfolio) {
    flattenedPortfolio.addAll(portfolioNode.getPositions());   
    for (PortfolioNode subNode : portfolioNode.getChildNodes()) {
      flatten(subNode, flattenedPortfolio);
    }
  }
 
  protected void aggregate(SimplePortfolioNode inputNode, List<Position> flattenedPortfolio, Queue<AggregationFunction<?>> functionList) {
    AggregationFunction<?> nextFunction = functionList.remove();
    s_logger.debug("Aggregating {} positions by {}", flattenedPortfolio, nextFunction);
    @SuppressWarnings("unchecked")
    Map<String, List<Position>> buckets = new TreeMap<>((Comparator<? super String>) nextFunction);
    for (Object entry : nextFunction.getRequiredEntries()) {
      buckets.put(entry.toString(), new ArrayList<Position>());
    }
    // drop into buckets - could drop straight into tree but this is easier because we can use faster lookups as we're going.
    for (Position position : flattenedPortfolio) {
      Object obj = nextFunction.classifyPosition(position);
      if (obj != null) {
        String name = obj.toString();
        if (buckets.containsKey(name)) {
          buckets.get(name).add(position);
        } else {
          ArrayList<Position> list = Lists.newArrayList();
          list.add(position);
          buckets.put(name, list);
        }
      }
    }
    for (String bucketName : buckets.keySet()) {
      SimplePortfolioNode newNode = new SimplePortfolioNode();
      newNode.setParentNodeId(inputNode.getUniqueId());
      newNode.setName(bucketName);
      inputNode.addChildNode(newNode);
      List<Position> bucket = buckets.get(bucketName);
      Collections.sort(bucket, nextFunction.getPositionComparator());
      if (functionList.isEmpty() || bucket.isEmpty()) { //IGN-138 - don't build huge empty portfolios
        for (Position position : bucket) {
          newNode.addPosition(position);
        }
      } else {
        aggregate(newNode, bucket, new ArrayDeque<>(functionList)); // make a copy for each bucket.
      }
    }
  }
 
  protected String buildPortfolioNodeName(List<AggregationFunction<?>> aggregationFunctions) {
    StringBuilder aggregatedPortfolioName = new StringBuilder();
    for (AggregationFunction<?> aggFunction : aggregationFunctions) {
      aggregatedPortfolioName.append(aggFunction.getName());
      aggregatedPortfolioName.append(", ");
    }
    if (aggregationFunctions.size() > 0) {
      aggregatedPortfolioName.delete(aggregatedPortfolioName.length() - 2, aggregatedPortfolioName.length()); // remember it's end index _exclusive_
    }
    return aggregatedPortfolioName.toString();
  }
}
TOP

Related Classes of com.opengamma.financial.aggregation.PortfolioMultiAggregator

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.