/*
* -------------------------------------------------------------------------
* $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();
}
}