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.backtest; import org.apache.commons.math3.distribution.BinomialDistribution; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; import org.json.JSONObject; import org.wso2.extension.siddhi.execution.var.models.VaRCalculator; import org.wso2.extension.siddhi.execution.var.models.historical.HistoricalVaRCalculator; import org.wso2.extension.siddhi.execution.var.models.montecarlo.MonteCarloVarCalculator; import org.wso2.extension.siddhi.execution.var.models.parametric.ParametricVaRCalculator; import org.wso2.extension.siddhi.execution.var.models.util.Event; import org.wso2.extension.siddhi.execution.var.models.util.asset.Asset; import org.wso2.extension.siddhi.execution.var.models.util.portfolio.Portfolio; import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Formatter; import java.util.HashMap; import java.util.Map; import java.util.Scanner; import java.util.Set; public class BacktestIncrementalTest { private static final int BATCH_SIZE = 251; /** * set parameters before run **/ private static final double VAR_CI = 0.99; private static final String DATA_SET = "set-3"; // private static final String METHOD = "historical"; // private static final String METHOD = "parametric"; private static final String METHOD = "montecarlo"; /** * end **/ private static final double BACKTEST_CI = 0.05; private static int NUMBER_OF_SAMPLES; private static final int VAR_PER_SAMPLE = 500; private static final String PORTFOLIO_KEY = "Portfolio 1"; private ArrayList<Double> varList; private ArrayList<Double> lossList; // private double previousPortfolioValue; // private double currentPortfolioValue; public BacktestIncrementalTest() { varList = new ArrayList(); lossList = new ArrayList(); } public static void main(String[] args) throws FileNotFoundException { new BacktestIncrementalTest().runTest(); } public void runTest() throws FileNotFoundException { VaRCalculator varCalculator = null; if (METHOD.equalsIgnoreCase("historical")) { varCalculator = new HistoricalVaRCalculator(BATCH_SIZE, VAR_CI); } else if (METHOD.equalsIgnoreCase("parametric")) { varCalculator = new ParametricVaRCalculator(BATCH_SIZE, VAR_CI); } else if (METHOD.equalsIgnoreCase("montecarlo")) { varCalculator = new MonteCarloVarCalculator(BATCH_SIZE, VAR_CI, 2500, 100, 0.01); } else { System.exit(0); } ArrayList<Event> list = readBacktestData(); Map<String, Integer> assets = initPortfolio(); Portfolio portfolio = varCalculator.createPortfolio("1", assets); varCalculator.addPortfolio("1", portfolio); for (int i = 0; i < 216; i++) { varCalculator.calculateValueAtRisk(list.get(i)); } for (int i = 216; i < list.size(); i++) { //System.out.print("Event " + (i) + " : "); String jsonString = (String) varCalculator.calculateValueAtRisk(list.get(i)); //currentPortfolioValue = portfolio.getTotalPortfolioValue(); if (jsonString != null) { JSONObject jsonObject = new JSONObject(jsonString); Double calculatedVar = (Double) jsonObject.get(PORTFOLIO_KEY); // hardcoded for portfolio ID 1 //System.out.printf("Var : %.3f", calculatedVar); varList.add(calculatedVar); // should filter double actualLoss = getPortfolioValuation(portfolio, varCalculator.getAssetPool()) - getPreviousPortfolioValuation(portfolio, varCalculator.getAssetPool()); lossList.add(actualLoss); //System.out.printf(" Loss : %.3f", actualLoss); } //previousPortfolioValue = currentPortfolioValue; //System.out.println(); } //runStandardCoverageTest(); runViolationTest(); } private void runStandardCoverageTest() { BinomialDistribution dist = new BinomialDistribution(VAR_PER_SAMPLE, 1 - VAR_CI); double leftEnd = dist.inverseCumulativeProbability(BACKTEST_CI / 2); double rightEnd = dist.inverseCumulativeProbability(1 - (BACKTEST_CI / 2)); System.out.println("Left End :" + leftEnd); System.out.println("Right End :" + rightEnd); NUMBER_OF_SAMPLES = lossList.size() / VAR_PER_SAMPLE; int numberOfExceptions; int failCount = 0; for (int j = 0; j < NUMBER_OF_SAMPLES; j++) { numberOfExceptions = 0; for (int i = j * VAR_PER_SAMPLE; i < (j + 1) * VAR_PER_SAMPLE; i++) { if (lossList.get(i + 1) < 0) { if (lossList.get(i + 1) < varList.get(i)) { numberOfExceptions++; } } } System.out.println("Sample Set : " + (j + 1) + " Exceptions : " + numberOfExceptions); if (numberOfExceptions < leftEnd || rightEnd < numberOfExceptions) { failCount++; } } System.out.println( "Success Rate : " + (((double) NUMBER_OF_SAMPLES - failCount) / (NUMBER_OF_SAMPLES)) * 100 + " %"); } private void runViolationTest() { Formatter formatter = null; try { formatter = new Formatter(new File(METHOD + "-" + DATA_SET + "-" + VAR_CI + ".csv")); formatter.format("%s,%s%n", "VaR", "Loss"); } catch (FileNotFoundException e) { e.printStackTrace(); } DescriptiveStatistics lossStat = new DescriptiveStatistics( lossList.stream().mapToDouble(Double::doubleValue).toArray()); DescriptiveStatistics varStat = new DescriptiveStatistics( varList.stream().mapToDouble(Double::doubleValue).toArray()); DescriptiveStatistics violationStat = new DescriptiveStatistics(); int failCount = 0; int numberOfData = varList.size(); for (int i = 0; i < numberOfData - 1; i++) { formatter.format("%.3f,%.3f%n", varList.get(i), lossList.get(i + 1)); if (lossList.get(i + 1) < varList.get(i)) { violationStat.addValue(varList.get(i)); failCount++; } } formatter.close(); System.out.println("Number of data : " + numberOfData); System.out.printf("Loss Mean : %.2f\n", lossStat.getMean()); System.out.printf("Var Mean : %.2f\n", varStat.getMean()); System.out.printf("Number of violations : %d\n", failCount); System.out.printf("Mean Violation : %.2f\n", violationStat.getMean()); System.out.printf("Violation Rate : %.2f%%\n", ((double) failCount) / (numberOfData - 1) * 100); } private double getPortfolioValuation(Portfolio portfolio, Map<String, Asset> assetMap) { double currentPortfolioValue = 0; Set<String> keys = portfolio.getAssetListKeySet(); for (String symbol : keys) { try { Asset asset = assetMap.get(symbol); currentPortfolioValue += asset.getCurrentStockPrice() * portfolio.getCurrentAssetQuantities(symbol); } catch (Exception e) { System.out.println(symbol); } } return currentPortfolioValue; } private double getPreviousPortfolioValuation(Portfolio portfolio, Map<String, Asset> assetMap) { double prevPortfolioValue = 0; Set<String> keys = portfolio.getAssetListKeySet(); for (String symbol : keys) { Asset asset = assetMap.get(symbol); prevPortfolioValue += asset.getPreviousStockPrice() * portfolio.getPreviousAssetQuantities(symbol); } return prevPortfolioValue; } public ArrayList<Event> readBacktestData() throws FileNotFoundException { ClassLoader classLoader = getClass().getClassLoader(); Scanner scan = new Scanner( new File(classLoader.getResource("backtest-data-aio-" + DATA_SET + ".csv").getFile())); ArrayList<Event> list = new ArrayList(); Event event; String[] split; while (scan.hasNext()) { event = new Event(); split = scan.nextLine().split(","); event.setSymbol(split[2]); event.setPrice(Double.parseDouble(split[1])); list.add(event); } return list; } private Map<String, Integer> initPortfolio() throws FileNotFoundException { ClassLoader classLoader = getClass().getClassLoader(); Scanner scanner = new Scanner(new File(classLoader.getResource("portfolio-init.csv").getFile())); HashMap<String, Integer> assets = new HashMap<>(); String split[]; while (scanner.hasNextLine()) { split = scanner.nextLine().split(","); assets.put(split[0], Integer.parseInt(split[1])); } return assets; } }