Table4Reconciler.java
package org.drip.sample.helitterman;
import org.drip.measure.bayesian.R1MultivariateConvolutionMetrics;
import org.drip.measure.continuous.MultivariateMeta;
import org.drip.measure.gaussian.*;
import org.drip.measure.statistics.MultivariateMoments;
import org.drip.numerical.common.FormatUtil;
import org.drip.portfolioconstruction.allocator.*;
import org.drip.portfolioconstruction.asset.*;
import org.drip.portfolioconstruction.bayesian.*;
import org.drip.portfolioconstruction.params.AssetUniverseStatisticalProperties;
import org.drip.service.env.EnvManager;
/*
* -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*/
/*!
* Copyright (C) 2019 Lakshmi Krishnamurthy
* Copyright (C) 2018 Lakshmi Krishnamurthy
* Copyright (C) 2017 Lakshmi Krishnamurthy
* Copyright (C) 2016 Lakshmi Krishnamurthy
*
* This file is part of DROP, an open-source library targeting risk, transaction costs, exposure, margin
* calculations, valuation adjustment, and portfolio construction within and across fixed income,
* credit, commodity, equity, FX, and structured products.
*
* https://lakshmidrip.github.io/DROP/
*
* DROP is composed of three modules:
*
* - DROP Analytics Core - https://lakshmidrip.github.io/DROP-Analytics-Core/
* - DROP Portfolio Core - https://lakshmidrip.github.io/DROP-Portfolio-Core/
* - DROP Numerical Core - https://lakshmidrip.github.io/DROP-Numerical-Core/
*
* DROP Analytics Core implements libraries for the following:
* - Fixed Income Analytics
* - Asset Backed Analytics
* - XVA Analytics
* - Exposure and Margin Analytics
*
* DROP Portfolio Core implements libraries for the following:
* - Asset Allocation Analytics
* - Transaction Cost Analytics
*
* DROP Numerical Core implements libraries for the following:
* - Statistical Learning
* - Numerical Optimizer
* - Spline Builder
* - Algorithm Support
*
* Documentation for DROP is Spread Over:
*
* - Main => https://lakshmidrip.github.io/DROP/
* - Wiki => https://github.com/lakshmiDRIP/DROP/wiki
* - GitHub => https://github.com/lakshmiDRIP/DROP
* - Repo Layout Taxonomy => https://github.com/lakshmiDRIP/DROP/blob/master/Taxonomy.md
* - Javadoc => https://lakshmidrip.github.io/DROP/Javadoc/index.html
* - Technical Specifications => https://github.com/lakshmiDRIP/DROP/tree/master/Docs/Internal
* - Release Versions => https://lakshmidrip.github.io/DROP/version.html
* - Community Credits => https://lakshmidrip.github.io/DROP/credits.html
* - Issues Catalog => https://github.com/lakshmiDRIP/DROP/issues
* - JUnit => https://lakshmidrip.github.io/DROP/junit/index.html
* - Jacoco => https://lakshmidrip.github.io/DROP/jacoco/index.html
*
* 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.
*/
/**
* <i>Table4Reconciler</i> reconciles the First Set of Outputs (Table #4) of the Black-Litterman Model
* Process as illustrated in the Following Paper:
*
* <br><br>
* <ul>
* <li>
* He. G., and R. Litterman (1999): The Intuition behind the Black-Litterman Model Portfolios,
* Goldman Sachs Asset Management
* </li>
* </ul>
*
* <br><br>
* <ul>
* <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/PortfolioCore.md">Portfolio Core Module</a></li>
* <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/AssetAllocationAnalyticsLibrary.md">Asset Allocation Analytics Library</a></li>
* <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/README.md">Sample</a></li>
* <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/sample/helitterman/README.md">He and Litterman (1999) Reconcilers</a></li>
* </ul>
* <br><br>
*
* @author Lakshmi Krishnamurthy
*/
public class Table4Reconciler
{
public static final void main (
final String[] argumentArray)
throws Exception
{
EnvManager.InitEnv ("");
String[] assetIDArray = new String[]
{
"AUS",
"CAD",
"FRA",
"GER",
"JPN",
"UK ",
"USA"
};
double[] assetEquilibriumWeightArray = new double[]
{
0.016,
0.022,
0.052,
0.055,
0.116,
0.124,
0.615
};
double[][] assetExcessReturnsCorrelationMatrix = new double[][]
{
{1.000, 0.488, 0.478, 0.515, 0.439, 0.512, 0.491},
{0.488, 1.000, 0.664, 0.655, 0.310, 0.608, 0.779},
{0.478, 0.664, 1.000, 0.861, 0.355, 0.783, 0.668},
{0.515, 0.655, 0.861, 1.000, 0.354, 0.777, 0.653},
{0.439, 0.310, 0.355, 0.354, 1.000, 0.405, 0.306},
{0.512, 0.608, 0.783, 0.777, 0.405, 1.000, 0.652},
{0.491, 0.779, 0.668, 0.653, 0.306, 0.652, 1.000}
};
double[] assetExcessReturnsVolatilityArray = new double[]
{
0.160,
0.203,
0.248,
0.271,
0.210,
0.200,
0.187
};
double[][] assetSpaceViewProjectionMatrix = new double[][]
{
{0.000, 0.000, -0.295, 1.000, 0.000, -0.705, 0.000}
};
double tau = 0.05;
double riskAversion = 2.5;
double riskFreeRate = 0.0;
double[] projectionExpectedExcessReturnsArray = new double[]
{
0.05
};
double[][] projectionExcessReturnsCovarianceMatrix = new double[][]
{
{0.021 * tau}
};
double[] assetSpaceJointReturnsReconcilerArray = new double[]
{
0.043,
0.076,
0.093,
0.110,
0.045,
0.070,
0.081
};
double[] posteriorOptimalWeightsReconcilerArray = new double[]
{
0.015,
0.021,
-0.040,
0.354,
0.110,
-0.095,
0.586
};
double[] posteriorOptimalDeviationReconcilerArray = new double[]
{
0.000,
0.000,
-0.089,
0.302,
0.000,
-0.213,
0.000
};
double[] bayesPELoadingsReconcilerArray = new double[]
{
0.302
};
R1MultivariateNormal viewDistribution = R1MultivariateNormal.Standard (
new MultivariateMeta (
new String[] {
"TABLE 4"
}
),
projectionExpectedExcessReturnsArray,
projectionExcessReturnsCovarianceMatrix
);
double[][] assetExcessReturnsCovarianceMatrix = new double[assetIDArray.length][assetIDArray.length];
for (int assetID1 = 0; assetID1 < assetIDArray.length; ++assetID1)
{
for (int assetID2 = 0; assetID2 < assetIDArray.length; ++assetID2)
{
assetExcessReturnsCovarianceMatrix[assetID1][assetID2] =
assetExcessReturnsCorrelationMatrix[assetID1][assetID2] *
assetExcessReturnsVolatilityArray[assetID1] * assetExcessReturnsVolatilityArray[assetID2];
}
}
BlackLittermanCombinationEngine blackLittermanCombinationEngine =
new BlackLittermanCombinationEngine (
ForwardReverseHoldingsAllocation.Reverse (
Portfolio.Standard (
assetIDArray,
assetEquilibriumWeightArray
),
assetExcessReturnsCovarianceMatrix,
riskAversion
),
new PriorControlSpecification (
false,
riskFreeRate,
tau
),
new ProjectionSpecification (
viewDistribution,
assetSpaceViewProjectionMatrix
)
);
R1MultivariateConvolutionMetrics jointPosteriorMetrics =
blackLittermanCombinationEngine.customConfidenceRun().jointPosteriorMetrics();
R1MultivariateNormal jointDistribution = (R1MultivariateNormal) jointPosteriorMetrics.joint();
R1MultivariateNormal posteriorDistribution =
(R1MultivariateNormal) jointPosteriorMetrics.posterior();
double[] assetSpaceJointReturnsArray = jointDistribution.mean();
double[][] assetSpaceJointCovarianceMatrix = jointDistribution.covariance().covarianceMatrix();
double[][] assetSpacePosteriorCovarianceMatrix =
posteriorDistribution.covariance().covarianceMatrix();
HoldingsAllocation optimizationOutput = new QuadraticMeanVarianceOptimizer().allocate (
new HoldingsAllocationControl (
assetIDArray,
CustomRiskUtilitySettings.RiskAversion (
riskAversion
),
EqualityConstraintSettings.Unconstrained()
),
AssetUniverseStatisticalProperties.FromMultivariateMetrics (
MultivariateMoments.Standard (
assetIDArray,
posteriorDistribution.mean(),
assetSpacePosteriorCovarianceMatrix
)
)
);
AssetComponent[] assetComponentArray = optimizationOutput.optimalPortfolio().assetComponentArray();
ProjectionExposure projectionExposure =
blackLittermanCombinationEngine.projectionExposureAttribution();
double[] interViewComponentArray = projectionExposure.interViewComponentArray();
double[] intraViewComponentArray = projectionExposure.intraViewComponentArray();
double[] priorViewComponentArray = projectionExposure.priorViewComponentArray();
double[] cumulativeViewComponentLoadingArray = projectionExposure.cumulativeViewComponentLoadingArray();
System.out.println ("\n\t|------------------------||");
System.out.println ("\t| TAU => " + FormatUtil.FormatDouble (tau, 1, 8, 1.) + " ||");
System.out.println ("\t| DELTA => " + FormatUtil.FormatDouble (riskFreeRate, 1, 8, 1.) + " ||");
System.out.println ("\t|------------------------||");
System.out.println ("\n\t|------------------------||");
System.out.println ("\t| ASSET EXCESS RETURNS ||");
System.out.println ("\t|------------------------||");
System.out.println ("\t| ID => EQ WT | VOL ||");
System.out.println ("\t|------------------------||");
for (int assetID = 0; assetID < assetSpaceJointReturnsReconcilerArray.length; ++assetID)
{
System.out.println (
"\t| [" + assetIDArray[assetID] + "] =>" +
FormatUtil.FormatDouble (assetEquilibriumWeightArray[assetID], 2, 1, 100.) + "% |" +
FormatUtil.FormatDouble (assetExcessReturnsVolatilityArray[assetID], 2, 1, 100.) + "% ||"
);
}
System.out.println ("\t|------------------------||");
System.out.println ("\n\t|------------------------------------------------------------------------------------------------||");
System.out.println ("\t| PRIOR CROSS ASSET CORRELATION MATRIX ||");
System.out.println ("\t|------------------------------------------------------------------------------------------------||");
String header = "\t| |";
for (int assetID = 0; assetID < assetIDArray.length; ++assetID)
{
header += " " + assetIDArray[assetID] + " |";
}
System.out.println (header + "|");
System.out.println ("\t|------------------------------------------------------------------------------------------------||");
for (int assetIDI = 0; assetIDI < assetIDArray.length; ++assetIDI)
{
String dump = "\t| " + assetIDArray[assetIDI] + " ";
for (int j = 0; j < assetIDArray.length; ++j)
{
dump += "|" + FormatUtil.FormatDouble (assetExcessReturnsCorrelationMatrix[assetIDI][j], 1, 8, 1.) + " ";
}
System.out.println (dump + "||");
}
System.out.println ("\t|------------------------------------------------------------------------------------------------||");
System.out.println ("\n\t|------------------------------------------------------------------------------------------------||");
System.out.println ("\t| PRIOR CROSS ASSET COVARIANCE MATRIX ||");
System.out.println ("\t|------------------------------------------------------------------------------------------------||");
header = "\t| |";
for (int assetID = 0; assetID < assetIDArray.length; ++assetID)
{
header += " " + assetIDArray[assetID] + " |";
}
System.out.println (header + "|");
System.out.println ("\t|------------------------------------------------------------------------------------------------||");
for (int assetIDI = 0; assetIDI < assetIDArray.length; ++assetIDI)
{
String dump = "\t| " + assetIDArray[assetIDI] + " ";
for (int assetIDJ = 0; assetIDJ < assetIDArray.length; ++assetIDJ)
{
dump += "|" + FormatUtil.FormatDouble (
assetExcessReturnsCovarianceMatrix[assetIDI][assetIDJ], 1, 8, 1.
) + " ";
}
System.out.println (dump + "||");
}
System.out.println ("\t|------------------------------------------------------------------------------------------------||");
System.out.println ("\n\t|------------------------------------------------------------------------------------------------||");
System.out.println ("\t| VIEW SCOPING ASSET PROJECTION LOADING ||");
System.out.println ("\t|------------------------------------------------------------------------------------------------||");
header = "\t| |";
for (int assetID = 0; assetID < assetIDArray.length; ++assetID)
{
header += " " + assetIDArray[assetID] + " |";
}
System.out.println (header + "|");
System.out.println ("\t|------------------------------------------------------------------------------------------------||");
for (int viewIndex = 0; viewIndex < assetSpaceViewProjectionMatrix.length; ++viewIndex)
{
String dump = "\t| #" + viewIndex + " ";
for (int assetID = 0; assetID < assetIDArray.length; ++assetID)
{
dump += "|" + FormatUtil.FormatDouble (assetSpaceViewProjectionMatrix[viewIndex][assetID], 1, 8, 1.) + " ";
}
System.out.println (dump + "||");
}
System.out.println ("\t|------------------------------------------------------------------------------------------------||");
System.out.println ("\n\t|------------------------------------------------------------------------------------------------||");
System.out.println ("\t|------------------------------------------------------------------------------------------------||");
for (int viewIndexI = 0; viewIndexI < assetSpaceViewProjectionMatrix.length; ++viewIndexI)
{
String dump = "\t| #" + viewIndexI + " ";
for (int viewIndexJ = 0; viewIndexJ < assetSpaceViewProjectionMatrix.length; ++viewIndexJ)
{
dump += "|" + FormatUtil.FormatDouble (projectionExcessReturnsCovarianceMatrix[viewIndexI][viewIndexJ], 1, 8, 1.) + " ";
}
System.out.println (dump + "|" + FormatUtil.FormatDouble (projectionExpectedExcessReturnsArray[viewIndexI], 1, 2, 100.) + "%");
}
System.out.println ("\t|------------------------------------------------------------------------------------------------||");
System.out.println ("\t|------------------------------------------------------------------------------------------------||");
System.out.println ("\n\t|------------------------------------------------------------------------------------------------||");
System.out.println ("\t| JOINT CROSS ASSET COVARIANCE MATRIX ||");
System.out.println ("\t|------------------------------------------------------------------------------------------------||");
header = "\t| |";
for (int assetID = 0; assetID < assetIDArray.length; ++assetID)
{
header += " " + assetIDArray[assetID] + " |";
}
System.out.println (header + "|");
System.out.println ("\t|------------------------------------------------------------------------------------------------||");
for (int assetIDI = 0; assetIDI < assetIDArray.length; ++assetIDI)
{
String dump = "\t| " + assetIDArray[assetIDI] + " ";
for (int assetIDJ = 0; assetIDJ < assetIDArray.length; ++assetIDJ)
{
dump += "|" + FormatUtil.FormatDouble (
assetSpaceJointCovarianceMatrix[assetIDI][assetIDJ], 1, 8, 1.
) + " ";
}
System.out.println (dump + "||");
}
System.out.println ("\t|------------------------------------------------------------------------------------------------||");
System.out.println ("\n\t|------------------------------------------------------------------------------------------------||");
System.out.println ("\t| POSTERIOR CROSS ASSET COVARIANCE MATRIX ||");
System.out.println ("\t|------------------------------------------------------------------------------------------------||");
header = "\t| |";
for (int assetID = 0; assetID < assetIDArray.length; ++assetID)
{
header += " " + assetIDArray[assetID] + " |";
}
System.out.println (header + "|");
System.out.println ("\t|------------------------------------------------------------------------------------------------||");
for (int assetIDI = 0; assetIDI < assetIDArray.length; ++assetIDI)
{
String dump = "\t| " + assetIDArray[assetIDI] + " ";
for (int assetIDJ = 0; assetIDJ < assetIDArray.length; ++assetIDJ)
{
dump += "|" + FormatUtil.FormatDouble (
assetSpacePosteriorCovarianceMatrix[assetIDI][assetIDJ], 1, 8, 1.
) + " ";
}
System.out.println (dump + "||");
}
System.out.println ("\t|------------------------------------------------------------------------------------------------||\n");
System.out.println ("\t|------------------------||");
System.out.println ("\t| JOINT/POSTERIOR RETURN ||");
System.out.println ("\t|------------------------||");
System.out.println ("\t| ID => RIOC | HL99 ||");
System.out.println ("\t|------------------------||");
for (int assetID = 0; assetID < assetSpaceJointReturnsReconcilerArray.length; ++assetID)
{
System.out.println (
"\t| [" + assetIDArray[assetID] + "] =>" +
FormatUtil.FormatDouble (assetSpaceJointReturnsArray[assetID], 2, 1, 100.) + "% |" +
FormatUtil.FormatDouble (assetSpaceJointReturnsReconcilerArray[assetID], 2, 1, 100.) + "% ||"
);
}
System.out.println ("\t|------------------------||");
System.out.println ("\n\t|------------------------||");
System.out.println ("\t| OPTIMAL POSTERIOR WTS. ||");
System.out.println ("\t|------------------------||");
System.out.println ("\t| ID => RIOC | HL99 ||");
System.out.println ("\t|------------------------||");
for (int assetID = 0; assetID < assetComponentArray.length; ++assetID)
{
System.out.println (
"\t| [" + assetIDArray[assetID] + "] =>" +
FormatUtil.FormatDouble (assetComponentArray[assetID].amount(), 2, 1, 100.) + "% |" +
FormatUtil.FormatDouble (posteriorOptimalWeightsReconcilerArray[assetID], 2, 1, 100.) + "% ||"
);
}
System.out.println ("\t|------------------------||");
System.out.println ("\n\t|------------------------||");
System.out.println ("\t| POSTERIOR DEVIATION ||");
System.out.println ("\t|------------------------||");
System.out.println ("\t| ID => RIOC | HL99 ||");
System.out.println ("\t|------------------------||");
for (int assetID = 0; assetID < assetComponentArray.length; ++assetID)
{
System.out.println (
"\t| [" + assetIDArray[assetID] + "] =>" +
FormatUtil.FormatDouble (assetComponentArray[assetID].amount() - (assetEquilibriumWeightArray[assetID]) / (1. + tau), 2, 1, 100.) + "% |" +
FormatUtil.FormatDouble (posteriorOptimalDeviationReconcilerArray[assetID], 2, 1, 100.) + "% ||"
);
}
System.out.println ("\t|------------------------||\n");
System.out.println ("\t|-----------------------------------------------------------------||");
System.out.println ("\t| POSTERIOR DEVIATION WEIGHTS ATTRIBUTION ||");
System.out.println ("\t|-----------------------------------------------------------------||");
System.out.println ("\t| VIEW NUM => INTRA | INTER | PRIOR | CUMUL | BAYES | RECON ||");
System.out.println ("\t|-----------------------------------------------------------------||");
for (int viewIndex = 0; viewIndex < interViewComponentArray.length; ++viewIndex)
{
System.out.println (
"\t| VIEW #" + (viewIndex + 1) + " => " +
FormatUtil.FormatDouble (interViewComponentArray[viewIndex], 1, 3, 1.) + " | " +
FormatUtil.FormatDouble (intraViewComponentArray[viewIndex], 1, 3, 1.) + " | " +
FormatUtil.FormatDouble (priorViewComponentArray[viewIndex], 1, 3, 1.) + " | " +
FormatUtil.FormatDouble (cumulativeViewComponentLoadingArray[viewIndex], 1, 3, 1.) + " | " +
FormatUtil.FormatDouble (cumulativeViewComponentLoadingArray[viewIndex] / (1. + tau), 1, 3, 1.) + " | " +
FormatUtil.FormatDouble (bayesPELoadingsReconcilerArray[viewIndex], 1, 3, 1.) + " ||"
);
}
System.out.println ("\t|-----------------------------------------------------------------||\n");
EnvManager.TerminateEnv();
}
}