/* * ------------------------------------------------------------------------- * $Id: EfficientFrontier.java,v 1.3 2003/04/03 21:31:09 trudisch Exp $ * ------------------------------------------------------------------------- * Copyright (c) 1999 Visual Numerics Inc. All Rights Reserved. * * This software is confidential information which is proprietary to * and a trade secret of Visual Numerics, Inc. Use, duplication or * disclosure is subject to the terms of an appropriate license * agreement. * * VISUAL NUMERICS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. VISUAL * NUMERICS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR * ITS DERIVATIVES. *-------------------------------------------------------------------------- */ package com.imsl.demo.risk; import com.imsl.math.*; import com.imsl.chart.*; /** * * @author brophy * @created February 7, 2002 */ public class EfficientFrontier extends JFrameChart { /** Creates new EfficientFrontier */ public EfficientFrontier() throws QuadraticProgramming.InconsistentSystemException { double h[][] = { {1.134E-4, 4.376E-5, 5.242E-5, 5.173E-8, 1.128E-7}, {4.376E-5, 2.271E-4, 2.108E-5, 1.109E-5, 3.632E-5}, {5.242E-5, 2.108E-5, 1.159E-4, -8.052E-6, -4.459E-7}, {5.173E-8, 1.109E-5, -8.052E-6, 1.168E-4, 1.112E-5}, {1.128E-7, 3.632E-5, -4.459E-7, 1.112E-5, 6.373E-4} }; double meanReturns[] = {0.054, 0.046, 0.024, 0.073, 0.065}; int n = h.length; double g[] = new double[n]; /* * Constraints * 1) Portfolio's value must be 100% * sum(x[k]) = 1 ==> aeq[k] = 1 for all k beq[0] = 1 * 2) Meet target * sum(returns[k]*x[k]) >= expectedReturn * 3) No shorting allowed * x[k] >= 0 for all k ==> ane[i][j] = (i==j ? 1 : 0) bne[k] = 0 */ double aeq[][] = new double[1][n]; double beq[] = {1}; double ane[][] = new double[n+1][n]; double bne[] = new double[n+1]; for (int i = 0; i < n; i++) { aeq[0][i] = 1.0; ane[i+1][i] = 1.0; } ane[0] = meanReturns; double x[] = new double[20]; double y[] = new double[x.length]; for (int k = 0; k < x.length; k++) { y[k] = 2*0.073*k/x.length; bne[0] = y[k]; try { QuadraticProgramming qp = new QuadraticProgramming(h, g, aeq, beq, ane, bne); double p[] = qp.getSolution(); double sum = 0.0; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { sum += p[i]*h[i][j]*p[j]; } } x[k] = Math.sqrt(sum); System.out.println(x[k]+" "+y[k]); } catch (Exception e) { System.out.println("fail y="+y[k]); x[k] = y[k] = Double.NaN; } } // Print the solution and its dual //new PrintMatrix("x").print(qp.getSolution()); //new PrintMatrix("dual").print(qp.getDual()); Chart chart = getChart(); chart.setTextColor("blue"); AxisXY axis = new AxisXY(chart); axis.getAxisX().getAxisTitle().setTitle("standard deviation"); axis.getAxisY().getAxisTitle().setTitle("return"); axis.getAxisX().getAxisLabel().setTextFormat("0.00%");///java.text.NumberFormat.getPercentInstance()); Data data = new Data(axis, x, y); data.setDataType(Data.DATA_TYPE_LINE | Data.DATA_TYPE_MARKER); data.setLineColor("green"); data.setMarkerColor("green"); data.setMarkerType(Data.MARKER_TYPE_FILLED_SQUARE); y = (double[])meanReturns.clone(); x = new double[n]; for (int k = 0; k < n; k++) { //x[k] *= 100; x[k] = Math.sqrt(h[k][k]); } data = new Data(axis, x, y); data.setDataType(Data.DATA_TYPE_MARKER); data.setMarkerColor("red"); data.setMarkerType(Data.MARKER_TYPE_HOLLOW_SQUARE); } public static void main(String args[]) throws Exception { new EfficientFrontier().show(); } }