如何构建迭代器以在列表中获取所有可能的组合



我正在尝试计算股票投资组合的方差。为了实现这一点,我需要计算资产之间的加权协方差。我有一个类,包括一个用于存储投资组合中每种资产权重的字段和一个用于存储计算股票回报列表的字段。到目前为止,我已经构建了一个辅助函数来遍历资产列表并使用 apache.commons.math3 库执行一部分计算(请参阅下面的代码(。但是,这显然是错误的,因为他没有包括资产的所有可能组合。我已经研究了apache.commons组合迭代器,但我不确定如何实现它。任何帮助将不胜感激。

private double getPortfolioVariance(double portfolioVariance, List<AssetDto> assets, int historyLength) {
    for (int i = 0; i < assets.size() - 1; i++) {
        double weight = assets.get(i).getWeight() / 100;
        double weightOther = assets.get(i + 1).getWeight() / 100;
        if (assets.get(i).getStockReturns() != null && assets.get(i + 1) != null) {
            List<Double> returns = assets.get(i).getStockReturns().stream().limit(historyLength).collect(Collectors.toList());
            List<Double> returnsOther = assets.get(i).getStockReturns().stream().limit(historyLength).collect(Collectors.toList());
            Covariance covariance = new Covariance();
            double assetsCovariance = covariance.
                    covariance(returns.stream().mapToDouble(Double::doubleValue).toArray(),
                            returnsOther.stream().mapToDouble(Double::doubleValue).toArray());
            portfolioVariance += 2 * weight * weightOther * assetsCovariance;
        }
    }
    return portfolioVariance;
}

你可以使用 commons-math3 项目中的 CombinatoricsUtils 类。实用程序方法组合迭代器创建一个迭代器,它生成 n 到 k 的所有组合,没有重复。下面的示例:

private double getPortfolioVariance(double portfolioVariance, List<AssetDto> assets, int historyLength) {
    Iterator<int[]> iterator = CombinatoricsUtils.combinationsIterator(assets.size(), 2);
    while (iterator.hasNext()) {
        final int[] combination = iterator.next();
        AssetDto firstAsset = assets.get(combination[0]);
        AssetDto otherAsset = assets.get(combination[1]);
        double weight = firstAsset.getWeight() / 100;
        double weightOther = otherAsset.getWeight() / 100;
        if (firstAsset.getStockReturns() != null && otherAsset != null) {
            List<Double> returns = firstAsset.getStockReturns().stream().limit(historyLength).collect(Collectors.toList());
            List<Double> returnsOther = otherAsset.getStockReturns().stream().limit(historyLength).collect(Collectors.toList());
            Covariance covariance = new Covariance();
            double assetsCovariance = covariance.
                    covariance(returns.stream().mapToDouble(Double::doubleValue).toArray(),
                            returnsOther.stream().mapToDouble(Double::doubleValue).toArray());
            portfolioVariance += 2 * weight * weightOther * assetsCovariance;
        }
    }
    return portfolioVariance;
}

最新更新