Java tutorial
/* * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you 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 org.wso2.extension.siddhi.execution.var.models.parametric; import com.google.common.collect.HashBasedTable; import com.google.common.collect.Table; import org.apache.commons.math3.distribution.NormalDistribution; import org.apache.commons.math3.linear.Array2DRowRealMatrix; import org.apache.commons.math3.linear.RealMatrix; import org.wso2.extension.siddhi.execution.var.models.util.asset.Asset; import org.wso2.extension.siddhi.execution.var.models.util.asset.ParametricAsset; import org.wso2.extension.siddhi.execution.var.models.util.portfolio.ParametricPortfolio; import org.wso2.extension.siddhi.execution.var.models.util.portfolio.Portfolio; import org.wso2.extension.siddhi.execution.var.models.VaRCalculator; import org.wso2.extension.siddhi.execution.var.models.util.Event; import java.util.Map; import java.util.Set; public class ParametricVaRCalculator extends VaRCalculator { private final Table<String, String, Double> covarianceTable; /** * @param batchSize * @param confidenceInterval */ public ParametricVaRCalculator(int batchSize, double confidenceInterval) { super(batchSize, confidenceInterval); covarianceTable = HashBasedTable.create(); } /** * @return the var of the portfolio Calculate var for the given portfolio using updated covariances and means */ @Override public Double processData(Portfolio portfolio, Event event) { Asset asset = getAssetPool().get(event.getSymbol()); if (asset.getNumberOfReturnValues() > 1) { RealMatrix varCovarMatrix = new Array2DRowRealMatrix(getVarCovarMatrix(portfolio)); RealMatrix weightageMatrix = new Array2DRowRealMatrix(getWeightageMatrix(portfolio)); RealMatrix meanMatrix = new Array2DRowRealMatrix(getMeanMatrix(portfolio)); RealMatrix portfolioVarianceMatrix = weightageMatrix.multiply(varCovarMatrix) .multiply(weightageMatrix.transpose()); RealMatrix portfolioMeanMatrix = weightageMatrix.multiply(meanMatrix.transpose()); double portfolioVariance = portfolioVarianceMatrix.getData()[0][0]; double portfolioMean = portfolioMeanMatrix.getData()[0][0]; if (portfolioVariance == 0) { // a normal distribution cannot be defined when sd = 0 return null; } double portfolioStandardDeviation = Math.sqrt(portfolioVariance); NormalDistribution normalDistribution = new NormalDistribution(portfolioMean, portfolioStandardDeviation); double zValue = normalDistribution.inverseCumulativeProbability(1 - getConfidenceInterval()); double var = zValue * portfolio.getTotalPortfolioValue(); return var; } return null; } /** * @param portfolio * @return Get VarCovar matrix for a given portfolio */ private double[][] getVarCovarMatrix(Portfolio portfolio) { Set<String> keys = portfolio.getAssetListKeySet(); int numberOfAssets = keys.size(); String symbols[] = keys.toArray(new String[numberOfAssets]); double[][] varCovarMatrix = new double[numberOfAssets][numberOfAssets]; double covariance; for (int i = 0; i < symbols.length; i++) { for (int j = i; j < symbols.length; j++) { covariance = covarianceTable.get(symbols[i], symbols[j]); varCovarMatrix[i][j] = covariance; if (i != j) { varCovarMatrix[j][i] = covariance; } } } return varCovarMatrix; } /** * @param portfolio * @return Get weightage matrix for a given portfolio */ private double[][] getWeightageMatrix(Portfolio portfolio) { Set<String> keys = portfolio.getAssetListKeySet(); int numberOfAssets = keys.size(); double[][] weightageMatrix = new double[1][numberOfAssets]; final int[] i = { 0 }; keys.forEach((symbol) -> { Asset asset = getAssetPool().get(symbol); weightageMatrix[0][i[0]] = asset.getCurrentStockPrice() * portfolio.getCurrentAssetQuantities(symbol) / portfolio.getTotalPortfolioValue(); i[0]++; }); return weightageMatrix; } /** * @param portfolio * @return Get mean matrix for a given portfolio */ private double[][] getMeanMatrix(Portfolio portfolio) { Set<String> keys = portfolio.getAssetListKeySet(); double[][] meanMatrix = new double[1][keys.size()]; final int[] i = { 0 }; keys.forEach((symbol) -> { meanMatrix[0][i[0]] = getAssetPool().get(symbol).getMean(); i[0]++; }); return meanMatrix; } /** * @param symbol Update excess returns based on latest event */ private void updateExcessReturnList(String symbol) { ParametricAsset asset = (ParametricAsset) getAssetPool().get(symbol); double[] returnValues = asset.getReturnValues(); double mean = getAssetPool().get(symbol).getMean(); double[] excessReturns = new double[returnValues.length]; for (int i = 0; i < returnValues.length; i++) { excessReturns[i] = returnValues[i] - mean; } asset.setExcessReturns(excessReturns); } /** * @param symbol Update global co-variance table based on latest event */ private void updateCovarianceTable(String symbol) { Set<String> keys = getAssetPool().keySet(); double[] excessReturns = ((ParametricAsset) getAssetPool().get(symbol)).getExcessReturns(); keys.forEach((iterateSymbol) -> { double[] iterateExcessReturns = ((ParametricAsset) getAssetPool().get(iterateSymbol)) .getExcessReturns(); int min; double covariance = 0.0; if (excessReturns.length > iterateExcessReturns.length) { min = iterateExcessReturns.length; } else { min = excessReturns.length; } for (int j = 0; j < min; j++) { covariance += excessReturns[j] * iterateExcessReturns[j]; } covariance /= (getBatchSize() - 2); covarianceTable.put(symbol, iterateSymbol, covariance); covarianceTable.put(iterateSymbol, symbol, covariance); }); } /** * @param symbol Update covariance table and excess returns based on latest event */ @Override public void simulateChangedAsset(String symbol) { updateExcessReturnList(symbol); updateCovarianceTable(symbol); } @Override public Portfolio createPortfolio(String id, Map<String, Integer> assets) { return new ParametricPortfolio(id, assets); } @Override public Asset createAsset(int windowSize) { return new ParametricAsset(windowSize); } }