action portfoliooptimizer_post_portfolio_optimization_hierarchical_risk_parity_clustering { label: "Hierarchical Clustering-Based Risk Parity Portfolio" description: "Compute the asset weights of the hierarchical clustering-based risk parity portfolio, optionally subject to: \n* Minimum and maximum weights constraints\n* Minimum and maximum portfolio exposure constraints\n\nReferences\n * [Machine Learning for Asset Management: New Developments and Financial Applications, Emmanuel Jurczenko, Chapter 9, Harald Lohre,Carsten Rother,Kilian Axel Schäfer, Hierarchical Risk Parity: Accounting for Tail Dependencies in Multi-asset Multi-factor Allocations](https://onlinelibrary.wiley.com/doi/10.1002/9781119751182.ch9)\n * [Thomas Raffinot, Hierarchical Clustering-Based Asset Allocation, The Journal of Portfolio Management Multi-Asset Special Issue 2018, 44 (2) 89-99](https://jpm.pm-research.com/content/44/2/89.abstract)\n * [Raffinot, Thomas, The Hierarchical Equal Risk Contribution Portfolio](https://ssrn.com/abstract=3237540)\n * [Johann Pfitzinger & Nico Katzke, 2019. A constrained hierarchical risk parity algorithm with cluster-based capital allocation. Working Papers 14/2019, Stellenbosch University, Department of Economics](https://ideas.repec.org/p/sza/wpaper/wpapers328.html)\n" provider: portfoliooptimizer method: POST path: "/portfolio/optimization/hierarchical-risk-parity/clustering-based" encoding: json input: { type: "object" required: ["assets", "assetsCovarianceMatrix"] properties: { acrossClusterAllocationMethod: { type: "string" description: "The allocation method to use across clusters" enum: ["equalWeighting", "inverseVolatility", "inverseVariance"] } assets: { type: "integer" description: "The number of assets" } assetsCovarianceMatrix: { type: "array" description: "assetsCovarianceMatrix[i][j] is the covariance between the asset i and the asset j" items: { type: "array" items: { type: "number" } } } clusteringMethod: { type: "string" description: "The hierarchical clustering method to use" enum: ["singleLinkage", "averageLinkage", "completeLinkage", "wardLinkage"] } clusteringOrdering: { type: "string" description: "The order to impose on the hierarchical clustering tree leaves" enum: ["r-hclust", "optimal"] } clusters: { type: "integer" description: "The number of clusters to use in the hierarchical clustering tree; if not provided, the number of clusters to use is computed using the gap statistic method, as described in the first reference" } constraints: { type: "object" properties: { maximumAssetsWeights: { type: "array" description: "maximumAssetsWeights[i] is the maximum weight of the asset i in the portfolio, in percentage" items: { type: "number" } } maximumPortfolioExposure: { type: "number" description: "The maximum portfolio exposure; must be higher than or equal to minimumPortfolioExposure" } minimumAssetsWeights: { type: "array" description: "minimumAssetsWeights[i] is the minimum weight of the asset i in the portfolio, in percentage" items: { type: "number" } } minimumPortfolioExposure: { type: "number" description: "The minimum portfolio exposure; must be lower than or equal to maximumPortfolioExposure" } } } withinClusterAllocationMethod: { type: "string" description: "The allocation method to use within clusters" enum: ["equalWeighting", "inverseVolatility", "inverseVariance"] } } } output: { type: "object" required: ["assetsWeights"] properties: { assetsWeights: { type: "array" description: "assetsWeights[i] is the weight of the asset i in the portfolio, in percentage" items: { type: "number" } } } } }