MoneyWiseAnalysisPortfolioBucket.java
/*
* MoneyWise: Finance Application
* Copyright 2012-2026. Tony Washer
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data;
import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
import io.github.tonywasher.joceanus.oceanus.date.OceanusDate;
import io.github.tonywasher.joceanus.oceanus.date.OceanusDateRange;
import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
import io.github.tonywasher.joceanus.metis.data.MetisDataDifference;
import io.github.tonywasher.joceanus.metis.data.MetisDataFieldValue;
import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataList;
import io.github.tonywasher.joceanus.metis.field.MetisFieldItem;
import io.github.tonywasher.joceanus.metis.field.MetisFieldItem.MetisFieldTableItem;
import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
import io.github.tonywasher.joceanus.metis.list.MetisListIndexed;
import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicDataType;
import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePortfolio;
import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseSecurity;
import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseSecurityHolding;
import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCurrency;
import io.github.tonywasher.joceanus.moneywise.exc.MoneyWiseDataException;
import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisSecurityBucket.MoneyWiseAnalysisSecurityBucketList;
import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.values.MoneyWiseAnalysisAccountAttr;
import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.values.MoneyWiseAnalysisAccountValues;
import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.values.MoneyWiseAnalysisSecurityAttr;
import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.values.MoneyWiseAnalysisSecurityValues;
import java.util.Currency;
import java.util.Iterator;
import java.util.List;
/**
* Portfolio Bucket.
*/
public final class MoneyWiseAnalysisPortfolioBucket
implements MetisFieldTableItem {
/**
* Local Report fields.
*/
private static final MetisFieldSet<MoneyWiseAnalysisPortfolioBucket> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseAnalysisPortfolioBucket.class);
/*
* Declare Fields.
*/
static {
FIELD_DEFS.declareLocalField(MoneyWiseBasicDataType.PORTFOLIO, MoneyWiseAnalysisPortfolioBucket::getPortfolio);
FIELD_DEFS.declareLocalField(MoneyWiseAnalysisDataResource.BUCKET_BASEVALUES, MoneyWiseAnalysisPortfolioBucket::getPortfolioCash);
FIELD_DEFS.declareLocalField(MoneyWiseBasicDataType.CASH, MoneyWiseAnalysisPortfolioBucket::getBaseValues);
FIELD_DEFS.declareLocalField(MoneyWiseBasicDataType.SECURITY.getListId(), MoneyWiseAnalysisPortfolioBucket::getSecurities);
FIELD_DEFS.declareLocalFieldsForEnum(MoneyWiseAnalysisSecurityAttr.class, MoneyWiseAnalysisPortfolioBucket::getAttributeValue);
}
/**
* Totals bucket name.
*/
private static final MetisDataFieldId NAME_TOTALS = MoneyWiseAnalysisDataResource.ANALYSIS_TOTALS;
/**
* The portfolio.
*/
private final MoneyWisePortfolio thePortfolio;
/**
* The reporting currency.
*/
private final MoneyWiseCurrency theCurrency;
/**
* The cash bucket.
*/
private final MoneyWiseAnalysisPortfolioCashBucket theCash;
/**
* The security bucket list.
*/
private final MoneyWiseAnalysisSecurityBucketList theSecurities;
/**
* Values.
*/
private final MoneyWiseAnalysisSecurityValues theValues;
/**
* The base values.
*/
private final MoneyWiseAnalysisSecurityValues theBaseValues;
/**
* Is this a foreign currency?
*/
private final Boolean isForeignCurrency;
/**
* Does this portfolio have foreign currency values?
*/
private boolean hasForeignCurrency;
/**
* Constructor.
*
* @param pAnalysis the analysis
* @param pPortfolio the portfolio account
*/
private MoneyWiseAnalysisPortfolioBucket(final MoneyWiseAnalysis pAnalysis,
final MoneyWisePortfolio pPortfolio) {
/* Store the portfolio */
thePortfolio = pPortfolio;
theCurrency = pAnalysis.getCurrency();
/* Create the cash bucket */
theCash = new MoneyWiseAnalysisPortfolioCashBucket(pAnalysis, pPortfolio);
/* Create the securities list */
theSecurities = pPortfolio != null
? new MoneyWiseAnalysisSecurityBucketList(pAnalysis)
: null;
/* Create the value maps and initialise them */
final Currency myCurrency = theCurrency == null
? MoneyWiseAnalysisAccountBucket.DEFAULT_CURRENCY
: theCurrency.getCurrency();
theValues = new MoneyWiseAnalysisSecurityValues(myCurrency);
theBaseValues = new MoneyWiseAnalysisSecurityValues(myCurrency);
initValues();
/* Determine whether the portfolio is a foreign currency */
isForeignCurrency = !MetisDataDifference.isEqual(pAnalysis.getCurrency(), theCurrency);
hasForeignCurrency = isForeignCurrency;
}
/**
* Constructor.
*
* @param pAnalysis the analysis
* @param pBase the underlying bucket
*/
private MoneyWiseAnalysisPortfolioBucket(final MoneyWiseAnalysis pAnalysis,
final MoneyWiseAnalysisPortfolioBucket pBase) {
/* Copy details from base */
thePortfolio = pBase.getPortfolio();
theCurrency = pBase.getCurrency();
isForeignCurrency = pBase.isForeignCurrency();
hasForeignCurrency = pBase.hasForeignCurrency();
/* Create the cash bucket */
theCash = new MoneyWiseAnalysisPortfolioCashBucket(pAnalysis, pBase.getPortfolioCash());
/* Create the securities list */
theSecurities = thePortfolio != null
? new MoneyWiseAnalysisSecurityBucketList(pAnalysis, pBase.getSecurities())
: null;
/* Create the value maps and initialise them */
final Currency myCurrency = theCurrency.getCurrency();
theValues = new MoneyWiseAnalysisSecurityValues(myCurrency);
theBaseValues = new MoneyWiseAnalysisSecurityValues(myCurrency);
initValues();
}
/**
* Constructor.
*
* @param pAnalysis the analysis
* @param pBase the underlying bucket
* @param pDate the date for the bucket
*/
private MoneyWiseAnalysisPortfolioBucket(final MoneyWiseAnalysis pAnalysis,
final MoneyWiseAnalysisPortfolioBucket pBase,
final OceanusDate pDate) {
/* Copy details from base */
thePortfolio = pBase.getPortfolio();
theCurrency = pBase.getCurrency();
isForeignCurrency = pBase.isForeignCurrency();
/* Create the cash bucket */
theCash = new MoneyWiseAnalysisPortfolioCashBucket(pAnalysis, pBase.getPortfolioCash(), pDate);
/* Create the securities list */
theSecurities = thePortfolio != null
? new MoneyWiseAnalysisSecurityBucketList(pAnalysis, pBase.getSecurities(), pDate)
: null;
/* Create the value maps and initialise them */
final Currency myCurrency = theCurrency.getCurrency();
theValues = new MoneyWiseAnalysisSecurityValues(myCurrency);
theBaseValues = new MoneyWiseAnalysisSecurityValues(myCurrency);
initValues();
}
/**
* Constructor.
*
* @param pAnalysis the analysis
* @param pBase the underlying bucket
* @param pRange the date range for the bucket
*/
private MoneyWiseAnalysisPortfolioBucket(final MoneyWiseAnalysis pAnalysis,
final MoneyWiseAnalysisPortfolioBucket pBase,
final OceanusDateRange pRange) {
/* Copy details from base */
thePortfolio = pBase.getPortfolio();
theCurrency = pBase.getCurrency();
isForeignCurrency = pBase.isForeignCurrency();
/* Create the cash bucket */
theCash = new MoneyWiseAnalysisPortfolioCashBucket(pAnalysis, pBase.getPortfolioCash(), pRange);
/* Create the securities list */
theSecurities = thePortfolio != null
? new MoneyWiseAnalysisSecurityBucketList(pAnalysis, pBase.getSecurities(), pRange)
: null;
/* Create the value maps and initialise them */
final Currency myCurrency = theCurrency.getCurrency();
theValues = new MoneyWiseAnalysisSecurityValues(myCurrency);
theBaseValues = new MoneyWiseAnalysisSecurityValues(myCurrency);
initValues();
}
@Override
public MetisFieldSet<MoneyWiseAnalysisPortfolioBucket> getDataFieldSet() {
return FIELD_DEFS;
}
@Override
public String formatObject(final OceanusDataFormatter pFormatter) {
return toString();
}
@Override
public String toString() {
return getName();
}
/**
* Is this a foreign currency?
*
* @return true/false
*/
public Boolean isForeignCurrency() {
return isForeignCurrency;
}
/**
* Does this portfolio hold foreign currency accounts/securities?
*
* @return true/false
*/
public Boolean hasForeignCurrency() {
return hasForeignCurrency;
}
/**
* Obtain the name.
*
* @return the name
*/
public String getName() {
return thePortfolio == null
? NAME_TOTALS.getId()
: thePortfolio.getName();
}
@Override
public Integer getIndexedId() {
return thePortfolio.getIndexedId();
}
/**
* Obtain the portfolio.
*
* @return the portfolio
*/
public MoneyWisePortfolio getPortfolio() {
return thePortfolio;
}
/**
* Obtain the currency.
*
* @return the currency
*/
public MoneyWiseCurrency getCurrency() {
return theCurrency;
}
/**
* Obtain the portfolio cash bucket.
*
* @return the bucket
*/
public MoneyWiseAnalysisPortfolioCashBucket getPortfolioCash() {
return theCash;
}
/**
* Obtain the security buckets.
*
* @return the buckets
*/
public MoneyWiseAnalysisSecurityBucketList getSecurities() {
return theSecurities;
}
/**
* Obtain the security bucket iterator.
*
* @return the iterator
*/
public Iterator<MoneyWiseAnalysisSecurityBucket> securityIterator() {
return theSecurities.iterator();
}
/**
* Obtain the values.
*
* @return the values
*/
public MoneyWiseAnalysisSecurityValues getValues() {
return theValues;
}
/**
* Obtain the base values.
*
* @return the base values
*/
public MoneyWiseAnalysisSecurityValues getBaseValues() {
return theBaseValues;
}
/**
* Set Value.
*
* @param pAttr the attribute
* @param pValue the value of the attribute
*/
void setValue(final MoneyWiseAnalysisSecurityAttr pAttr,
final OceanusMoney pValue) {
/* Set the value into the list */
theValues.setValue(pAttr, pValue);
}
/**
* Get an attribute value.
*
* @param pAttr the attribute
* @return the value to set
*/
private Object getAttributeValue(final MoneyWiseAnalysisSecurityAttr pAttr) {
/* Access value of object */
final Object myValue = getValue(pAttr);
/* Return the value */
return myValue != null
? myValue
: MetisDataFieldValue.SKIP;
}
/**
* Obtain an attribute value.
*
* @param pAttr the attribute
* @return the value of the attribute or null
*/
private Object getValue(final MoneyWiseAnalysisSecurityAttr pAttr) {
/* Obtain the attribute */
return theValues.getValue(pAttr);
}
/**
* InitialiseValues.
*/
private void initValues() {
/* Determine currency */
final Currency myCurrency = theCurrency == null
? MoneyWiseAnalysisAccountBucket.DEFAULT_CURRENCY
: theCurrency.getCurrency();
/* Create valuation fields for the portfolio */
theValues.setValue(MoneyWiseAnalysisSecurityAttr.VALUATION, new OceanusMoney(myCurrency));
theBaseValues.setValue(MoneyWiseAnalysisSecurityAttr.VALUATION, new OceanusMoney(myCurrency));
/* Create profit fields for the portfolio */
theValues.setValue(MoneyWiseAnalysisSecurityAttr.PROFIT, new OceanusMoney(myCurrency));
theBaseValues.setValue(MoneyWiseAnalysisSecurityAttr.PROFIT, new OceanusMoney(myCurrency));
/* Create market fields for the portfolio */
theValues.setValue(MoneyWiseAnalysisSecurityAttr.MARKETGROWTH, new OceanusMoney(myCurrency));
theValues.setValue(MoneyWiseAnalysisSecurityAttr.CURRENCYFLUCT, new OceanusMoney(myCurrency));
theValues.setValue(MoneyWiseAnalysisSecurityAttr.MARKETPROFIT, new OceanusMoney(myCurrency));
}
/**
* Obtain the SecurityBucket from this portfolio for a security holding.
*
* @param pHolding the security holding
* @return the bucket
*/
public MoneyWiseAnalysisSecurityBucket getSecurityBucket(final MoneyWiseSecurityHolding pHolding) {
/* Return the security bucket for the portfolio's list */
return theSecurities.getBucket(pHolding);
}
/**
* Obtain the SecurityBucket from this portfolio for a security.
*
* @param pSecurity the security
* @return the bucket
*/
public MoneyWiseAnalysisSecurityBucket findSecurityBucket(final MoneyWiseSecurity pSecurity) {
/* Return the security bucket for the portfolio's list */
return theSecurities.findItemById(pSecurity.getIndexedId());
}
@Override
public boolean equals(final Object pThat) {
/* Handle the trivial cases */
if (this == pThat) {
return true;
}
if (pThat == null) {
return false;
}
if (!(pThat instanceof MoneyWiseAnalysisPortfolioBucket)) {
return false;
}
/* Compare the Portfolios */
final MoneyWiseAnalysisPortfolioBucket myThat = (MoneyWiseAnalysisPortfolioBucket) pThat;
return getPortfolio().equals(myThat.getPortfolio());
}
@Override
public int hashCode() {
return getPortfolio().hashCode();
}
/**
* Calculate delta.
*/
void calculateDelta() {
/* Obtain a copy of the value */
OceanusMoney myValue = theValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.VALUATION);
myValue = new OceanusMoney(myValue);
/* Subtract any base value */
final OceanusMoney myBase = theBaseValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.VALUATION);
myValue.subtractAmount(myBase);
/* Set the delta */
setValue(MoneyWiseAnalysisSecurityAttr.VALUEDELTA, myValue);
}
/**
* Add bucket to totals.
*
* @param pBucket the underlying bucket
*/
void addValues(final MoneyWiseAnalysisSecurityBucket pBucket) {
/* Add values */
addValues(theValues, pBucket.getValues());
/* Add base values */
addValues(theBaseValues, pBucket.getBaseValues());
/* Adjust foreign currency indication */
hasForeignCurrency |= pBucket.isForeignCurrency();
}
/**
* Add bucket to totals.
*
* @param pBucket the underlying bucket
*/
void addValues(final MoneyWiseAnalysisPortfolioCashBucket pBucket) {
/* Add values */
addValues(theValues, pBucket.getValues());
/* Add base values */
addValues(theBaseValues, pBucket.getBaseValues());
}
/**
* Add bucket to totals.
*
* @param pTotals the totals
* @param pSource the values to add
*/
private static void addValues(final MoneyWiseAnalysisSecurityValues pTotals,
final MoneyWiseAnalysisAccountValues pSource) {
/* Add valuation values */
final OceanusMoney myValue = pTotals.getMoneyValue(MoneyWiseAnalysisSecurityAttr.VALUATION);
final OceanusMoney mySrcValue = pSource.getMoneyValue(MoneyWiseAnalysisAccountAttr.VALUATION);
myValue.addAmount(mySrcValue);
}
/**
* Add bucket to totals.
*
* @param pTotals the totals
* @param pSource the values to add
*/
private static void addValues(final MoneyWiseAnalysisSecurityValues pTotals,
final MoneyWiseAnalysisSecurityValues pSource) {
/* Add valuation values */
OceanusMoney myValue = pTotals.getMoneyValue(MoneyWiseAnalysisSecurityAttr.VALUATION);
OceanusMoney mySrcValue = pSource.getMoneyValue(MoneyWiseAnalysisSecurityAttr.VALUATION);
myValue.addAmount(mySrcValue);
/* Add invested values */
myValue = pTotals.getMoneyValue(MoneyWiseAnalysisSecurityAttr.INVESTED);
mySrcValue = pSource.getMoneyValue(MoneyWiseAnalysisSecurityAttr.INVESTED);
myValue.addAmount(mySrcValue);
/* Add cost values */
myValue = pTotals.getMoneyValue(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST);
mySrcValue = pSource.getMoneyValue(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST);
myValue.addAmount(mySrcValue);
/* Add gains values */
myValue = pTotals.getMoneyValue(MoneyWiseAnalysisSecurityAttr.REALISEDGAINS);
mySrcValue = pSource.getMoneyValue(MoneyWiseAnalysisSecurityAttr.REALISEDGAINS);
myValue.addAmount(mySrcValue);
/* Add profit adjustment values */
myValue = pTotals.getMoneyValue(MoneyWiseAnalysisSecurityAttr.GROWTHADJUST);
mySrcValue = pSource.getMoneyValue(MoneyWiseAnalysisSecurityAttr.GROWTHADJUST);
myValue.addAmount(mySrcValue);
/* Add dividends values */
myValue = pTotals.getMoneyValue(MoneyWiseAnalysisSecurityAttr.DIVIDEND);
mySrcValue = pSource.getMoneyValue(MoneyWiseAnalysisSecurityAttr.DIVIDEND);
myValue.addAmount(mySrcValue);
/* Add market values */
myValue = pTotals.getMoneyValue(MoneyWiseAnalysisSecurityAttr.MARKETGROWTH);
mySrcValue = pSource.getMoneyValue(MoneyWiseAnalysisSecurityAttr.MARKETGROWTH);
if (mySrcValue != null) {
myValue.addAmount(mySrcValue);
}
/* Add currency values */
myValue = pTotals.getMoneyValue(MoneyWiseAnalysisSecurityAttr.CURRENCYFLUCT);
mySrcValue = pSource.getMoneyValue(MoneyWiseAnalysisSecurityAttr.CURRENCYFLUCT);
if (mySrcValue != null) {
myValue.addAmount(mySrcValue);
}
/* Add market profit values */
myValue = pTotals.getMoneyValue(MoneyWiseAnalysisSecurityAttr.MARKETPROFIT);
mySrcValue = pSource.getMoneyValue(MoneyWiseAnalysisSecurityAttr.MARKETPROFIT);
if (mySrcValue != null) {
myValue.addAmount(mySrcValue);
}
/* Add profit values */
myValue = pTotals.getMoneyValue(MoneyWiseAnalysisSecurityAttr.PROFIT);
mySrcValue = pSource.getMoneyValue(MoneyWiseAnalysisSecurityAttr.PROFIT);
if (mySrcValue != null) {
myValue.addAmount(mySrcValue);
}
}
/**
* Is the portfolio bucket active?
*
* @return true/false
*/
public boolean isActive() {
/* Look for active cash */
if (theCash.isActive()) {
return true;
}
/* Loop through securities */
final Iterator<MoneyWiseAnalysisSecurityBucket> myIterator = securityIterator();
while (myIterator.hasNext()) {
final MoneyWiseAnalysisSecurityBucket mySecurity = myIterator.next();
/* Look for active security */
if (mySecurity.isActive()) {
return true;
}
}
/* Inactive */
return false;
}
/**
* Is the portfolio bucket idle?
*
* @return true/false
*/
public boolean isIdle() {
/* Look for non-idle cash */
if (Boolean.FALSE.equals(theCash.isIdle())) {
return false;
}
/* Loop through securities */
final Iterator<MoneyWiseAnalysisSecurityBucket> myIterator = securityIterator();
while (myIterator.hasNext()) {
final MoneyWiseAnalysisSecurityBucket mySecurity = myIterator.next();
/* Look for active security */
if (Boolean.FALSE.equals(mySecurity.isIdle())) {
return false;
}
}
/* Idle */
return true;
}
/**
* Obtain cash valuation.
*
* @param pBase get base valuation - true/false
* @return the valuation minus the cash value
*/
public OceanusMoney getCashValue(final boolean pBase) {
/* Obtain the cash valuation */
final MoneyWiseAnalysisAccountValues myCashValues = pBase
? theCash.getBaseValues()
: theCash.getValues();
return new OceanusMoney(myCashValues.getMoneyValue(MoneyWiseAnalysisAccountAttr.VALUATION));
}
/**
* Obtain non-cash valuation.
*
* @param pBase get base valuation - true/false
* @return the valuation minus the cash value
*/
public OceanusMoney getNonCashValue(final boolean pBase) {
/* Handle valuation by subtracting the cash valuation */
final MoneyWiseAnalysisSecurityValues myValues = pBase
? theBaseValues
: theValues;
final OceanusMoney myValue = new OceanusMoney(myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.VALUATION));
myValue.subtractAmount(getCashValue(pBase));
return myValue;
}
/**
* PortfolioBucket list class.
*/
public static final class MoneyWiseAnalysisPortfolioBucketList
implements MetisFieldItem, MetisDataList<MoneyWiseAnalysisPortfolioBucket> {
/**
* Local Report fields.
*/
private static final MetisFieldSet<MoneyWiseAnalysisPortfolioBucketList> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseAnalysisPortfolioBucketList.class);
/*
* Declare Fields.
*/
static {
FIELD_DEFS.declareLocalField(MoneyWiseAnalysisDataResource.ANALYSIS_NAME, MoneyWiseAnalysisPortfolioBucketList::getAnalysis);
FIELD_DEFS.declareLocalField(MoneyWiseAnalysisDataResource.ANALYSIS_TOTALS, MoneyWiseAnalysisPortfolioBucketList::getTotals);
}
/**
* The analysis.
*/
private final MoneyWiseAnalysis theAnalysis;
/**
* The list.
*/
private final MetisListIndexed<MoneyWiseAnalysisPortfolioBucket> theList;
/**
* The totals.
*/
private final MoneyWiseAnalysisPortfolioBucket theTotals;
/**
* Do we have a foreign portfolio account?
*/
private Boolean haveForeignCurrency = Boolean.FALSE;
/**
* Do we have active securities?
*/
private Boolean haveActiveSecurities = Boolean.FALSE;
/**
* Construct a top-level List.
*
* @param pAnalysis the analysis
*/
MoneyWiseAnalysisPortfolioBucketList(final MoneyWiseAnalysis pAnalysis) {
/* Initialise class */
theAnalysis = pAnalysis;
theTotals = allocateTotalsBucket();
theList = new MetisListIndexed<>();
theList.setComparator((l, r) -> l.getPortfolio().compareTo(r.getPortfolio()));
}
/**
* Construct a dated List.
*
* @param pAnalysis the analysis
* @param pBase the base list
*/
MoneyWiseAnalysisPortfolioBucketList(final MoneyWiseAnalysis pAnalysis,
final MoneyWiseAnalysisPortfolioBucketList pBase) {
/* Initialise class */
this(pAnalysis);
/* Loop through the buckets */
final Iterator<MoneyWiseAnalysisPortfolioBucket> myIterator = pBase.iterator();
while (myIterator.hasNext()) {
final MoneyWiseAnalysisPortfolioBucket myCurr = myIterator.next();
/* Access the bucket */
final MoneyWiseAnalysisPortfolioBucket myBucket = new MoneyWiseAnalysisPortfolioBucket(pAnalysis, myCurr);
/* Ignore if portfolio is idle */
if (!myBucket.isIdle()) {
/* Add to the list */
theList.add(myBucket);
}
}
}
/**
* Construct a dated List.
*
* @param pAnalysis the analysis
* @param pBase the base list
* @param pDate the Date
*/
MoneyWiseAnalysisPortfolioBucketList(final MoneyWiseAnalysis pAnalysis,
final MoneyWiseAnalysisPortfolioBucketList pBase,
final OceanusDate pDate) {
/* Initialise class */
this(pAnalysis);
/* Loop through the buckets */
final Iterator<MoneyWiseAnalysisPortfolioBucket> myIterator = pBase.iterator();
while (myIterator.hasNext()) {
final MoneyWiseAnalysisPortfolioBucket myCurr = myIterator.next();
/* Access the bucket for this date */
final MoneyWiseAnalysisPortfolioBucket myBucket = new MoneyWiseAnalysisPortfolioBucket(pAnalysis, myCurr, pDate);
/* Ignore if portfolio is idle */
if (!myBucket.isIdle()) {
/* Add to the list */
theList.add(myBucket);
}
}
}
/**
* Construct a ranged List.
*
* @param pAnalysis the analysis
* @param pBase the base list
* @param pRange the Date Range
*/
MoneyWiseAnalysisPortfolioBucketList(final MoneyWiseAnalysis pAnalysis,
final MoneyWiseAnalysisPortfolioBucketList pBase,
final OceanusDateRange pRange) {
/* Initialise class */
this(pAnalysis);
/* Loop through the buckets */
final Iterator<MoneyWiseAnalysisPortfolioBucket> myIterator = pBase.iterator();
while (myIterator.hasNext()) {
final MoneyWiseAnalysisPortfolioBucket myCurr = myIterator.next();
/* Access the bucket for this range */
final MoneyWiseAnalysisPortfolioBucket myBucket = new MoneyWiseAnalysisPortfolioBucket(pAnalysis, myCurr, pRange);
/* If the bucket is non-idle or active */
if (myBucket.isActive() || !myBucket.isIdle()) {
/* Add to the list */
theList.add(myBucket);
}
}
}
@Override
public MetisFieldSet<MoneyWiseAnalysisPortfolioBucketList> getDataFieldSet() {
return FIELD_DEFS;
}
@Override
public List<MoneyWiseAnalysisPortfolioBucket> getUnderlyingList() {
return theList.getUnderlyingList();
}
@Override
public String formatObject(final OceanusDataFormatter pFormatter) {
return getDataFieldSet().getName();
}
/**
* Obtain the analysis.
*
* @return the analysis
*/
MoneyWiseAnalysis getAnalysis() {
return theAnalysis;
}
/**
* Obtain the Totals.
*
* @return the totals
*/
public MoneyWiseAnalysisPortfolioBucket getTotals() {
return theTotals;
}
/**
* Do we have a foreign currency?
*
* @return true/false
*/
public Boolean haveForeignCurrency() {
return haveForeignCurrency;
}
/**
* Do we have active securities?
*
* @return true/false
*/
public Boolean haveActiveSecurities() {
return haveActiveSecurities;
}
/**
* Obtain item by id.
*
* @param pId the id to lookup
* @return the item (or null if not present)
*/
public MoneyWiseAnalysisPortfolioBucket findItemById(final Integer pId) {
/* Return results */
return theList.getItemById(pId);
}
/**
* Obtain the PortfolioBucket for a given portfolio.
*
* @param pPortfolio the portfolio
* @return the bucket
*/
public MoneyWiseAnalysisPortfolioBucket getBucket(final MoneyWisePortfolio pPortfolio) {
/* Locate the bucket in the list */
MoneyWiseAnalysisPortfolioBucket myItem = findItemById(pPortfolio.getIndexedId());
/* If the item does not yet exist */
if (myItem == null) {
/* Create the new bucket */
myItem = new MoneyWiseAnalysisPortfolioBucket(theAnalysis, pPortfolio);
/* Add to the list */
theList.add(myItem);
}
/* Return the bucket */
return myItem;
}
/**
* Obtain the PortfolioBucket for a given portfolio.
*
* @param pPortfolio the portfolio
* @return the bucket
*/
public MoneyWiseAnalysisPortfolioCashBucket getCashBucket(final MoneyWisePortfolio pPortfolio) {
/* Locate the bucket in the list */
final MoneyWiseAnalysisPortfolioBucket myItem = getBucket(pPortfolio);
/* Return the bucket */
return myItem.getPortfolioCash();
}
/**
* Obtain the SecurityBucket for a given security holding.
*
* @param pHolding the holding
* @return the bucket
*/
public MoneyWiseAnalysisSecurityBucket getBucket(final MoneyWiseSecurityHolding pHolding) {
/* Locate the portfolio bucket in the list */
final MoneyWisePortfolio myPortfolio = pHolding.getPortfolio();
final MoneyWiseAnalysisPortfolioBucket myBucket = getBucket(myPortfolio);
/* Return the security bucket for the portfolio's list */
return myBucket.getSecurityBucket(pHolding);
}
/**
* Obtain the matching PortfolioBucket.
*
* @param pPortfolio the portfolio
* @return the matching bucket
*/
public MoneyWiseAnalysisPortfolioBucket getMatchingPortfolio(final MoneyWisePortfolio pPortfolio) {
/* Return the matching portfolio if it exists else an orphan bucket */
final MoneyWiseAnalysisPortfolioBucket myPortfolio = findItemById(pPortfolio.getIndexedId());
return myPortfolio != null
? myPortfolio
: new MoneyWiseAnalysisPortfolioBucket(theAnalysis, pPortfolio);
}
/**
* Obtain the matching SecurityBucket.
*
* @param pSecurity the security
* @return the matching bucket
*/
public MoneyWiseAnalysisSecurityBucket getMatchingSecurityHolding(final MoneyWiseSecurityHolding pSecurity) {
/* Find the portfolio and holding */
final MoneyWiseAnalysisPortfolioBucket myPortfolio = findItemById(pSecurity.getPortfolio().getIndexedId());
final MoneyWiseAnalysisSecurityBucket mySecurity = myPortfolio == null
? null
: myPortfolio.findSecurityBucket(pSecurity.getSecurity());
return mySecurity != null
? mySecurity
: new MoneyWiseAnalysisSecurityBucket(theAnalysis, pSecurity);
}
/**
* Obtain the default PortfolioBucket.
*
* @return the default bucket
*/
public MoneyWiseAnalysisPortfolioBucket getDefaultPortfolio() {
/* Return the first portfolio in the list if it exists */
return isEmpty()
? null
: theList.getUnderlyingList().get(0);
}
/**
* Obtain the default SecurityBucket.
*
* @return the default bucket
*/
public MoneyWiseAnalysisSecurityBucket getDefaultSecurityHolding() {
/* Loop through the portfolio buckets */
final Iterator<MoneyWiseAnalysisPortfolioBucket> myIterator = iterator();
while (myIterator.hasNext()) {
final MoneyWiseAnalysisPortfolioBucket myPortfolio = myIterator.next();
/* Loop through the security buckets */
final Iterator<MoneyWiseAnalysisSecurityBucket> mySecIterator = myPortfolio.securityIterator();
if (mySecIterator.hasNext()) {
/* Access bucket and category */
return mySecIterator.next();
}
}
/* No security bucket found */
return null;
}
/**
* Allocate the Totals PortfolioBucket.
*
* @return the bucket
*/
private MoneyWiseAnalysisPortfolioBucket allocateTotalsBucket() {
/* Obtain the totals portfolio */
return new MoneyWiseAnalysisPortfolioBucket(theAnalysis, (MoneyWisePortfolio) null);
}
/**
* Analyse securities.
*
* @param pMarket the market analysis
*/
void analyseSecurities(final MoneyWiseAnalysisMarket pMarket) {
/* Access details */
final OceanusDateRange myRange = theAnalysis.getDateRange();
final MoneyWiseAnalysisPortfolioCashBucket myCashTotals = theTotals.getPortfolioCash();
/* Loop through the portfolio buckets */
final Iterator<MoneyWiseAnalysisPortfolioBucket> myIterator = iterator();
while (myIterator.hasNext()) {
final MoneyWiseAnalysisPortfolioBucket myPortfolio = myIterator.next();
/* Access the cash bucket */
final MoneyWiseAnalysisPortfolioCashBucket myCash = myPortfolio.getPortfolioCash();
/* Handle foreign asset */
if (Boolean.TRUE.equals(myCash.isForeignCurrency())) {
myCash.calculateFluctuations(myRange);
pMarket.processAccount(myCash);
haveForeignCurrency = Boolean.TRUE;
}
/* Calculate the delta */
myCash.calculateDelta();
myPortfolio.addValues(myCash);
theTotals.addValues(myCash);
myCashTotals.addValues(myCash);
/* Loop through the buckets */
final Iterator<MoneyWiseAnalysisSecurityBucket> mySecIterator = myPortfolio.securityIterator();
while (mySecIterator.hasNext()) {
/* Access bucket and category */
final MoneyWiseAnalysisSecurityBucket myCurr = mySecIterator.next();
/* Analyse the security bucket */
myCurr.analyseBucket(myRange);
/* Process market movements */
pMarket.processSecurity(myCurr);
/* Add to the portfolio bucket and add values */
myPortfolio.addValues(myCurr);
theTotals.addValues(myCurr);
/* Note active security */
haveActiveSecurities = Boolean.TRUE;
/* Handle foreign asset */
if (Boolean.TRUE.equals(myCurr.isForeignCurrency())) {
haveForeignCurrency = Boolean.TRUE;
}
}
/* Sort the list */
myPortfolio.getSecurities().sortBuckets();
/* Calculate delta for the portfolio */
myPortfolio.calculateDelta();
}
/* Sort the list */
theList.sortList();
/* Calculate delta for the totals */
theTotals.calculateDelta();
}
/**
* Mark active securities.
*
* @throws OceanusException on error
*/
public void markActiveSecurities() throws OceanusException {
/* Loop through the portfolio buckets */
final Iterator<MoneyWiseAnalysisPortfolioBucket> myIterator = iterator();
while (myIterator.hasNext()) {
final MoneyWiseAnalysisPortfolioBucket myCurr = myIterator.next();
/* Mark active securities */
final MoneyWiseAnalysisSecurityBucketList mySecurities = myCurr.getSecurities();
if (mySecurities.markActiveSecurities()) {
/* Check closed state */
final MoneyWisePortfolio myPortfolio = myCurr.getPortfolio();
if (Boolean.TRUE.equals(myPortfolio.isClosed())
&& theAnalysis.getData().checkClosedAccounts()) {
/* throw exception */
throw new MoneyWiseDataException(myCurr, "Illegally closed portfolio");
}
/* Note that the portfolio is relevant as it has relevant securities */
myPortfolio.setRelevant();
}
}
}
}
}