/* * ------------------------------------------------------------------------- * $Id: Simulate.java,v 1.6 2004/05/26 19:03:12 estewart 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.chart.*; import com.imsl.math.Cholesky; import com.imsl.stat.*; import com.imsl.IMSLException; import java.text.*; import java.awt.GridBagConstraints; import javax.swing.*; /** * * @author brophy * @created January 31, 2002 */ public class Simulate extends JFrameChart { private Database db; private AxisXY axis; private Bar bar; private Statistics statistics; private int nSamples = 100000; private double portfolioValues[] = {1000, 500, 1000, 0, 0}; private Cholesky chol; private double bins[]; private Summary summary; private EditPortfolio editPortfolio; private MonteCarloProgress progress; private boolean cancelMonteCarlo; private PortfolioPie portfolioPie; /** Creates new ChartReturns */ public Simulate(Database db, double covar[][]) throws IMSLException { this.db = db; setTitle("Risk Analysis"); Object l[] = getListeners(java.awt.event.WindowListener.class); for (int k = 0; k < l.length; k++) { removeWindowListener((java.awt.event.WindowListener)l[k]); } Chart chart = getChart(); chart.setTextColor("purple"); //chart.getBackground().setFillColor(new java.awt.Color(240,240,240)); axis = new AxisXY(chart); axis.getAxisX().getAxisTitle().setTitle("Daily Returns"); axis.getAxisY().getAxisTitle().setTitle("Probability"); axis.getAxisX().getAxisLabel().setTextFormat(new java.text.DecimalFormat("0.0%")); axis.getAxisY().getAxisLabel().setTextFormat(new java.text.DecimalFormat("0%")); axis.getAxisX().getGrid().setPaint(true); axis.getAxisY().getGrid().setPaint(true); axis.getAxisX().getGrid().setLineColor("lightGray"); axis.getAxisY().getGrid().setLineColor("lightGray"); statistics = new Statistics(); statistics.setLocation(25,500); statistics.show(); chol = new Cholesky(covar); compute(); editPortfolio = new EditPortfolio(db.getTickers()); editPortfolio.setLocation(25,100); //editPortfolio.show(); portfolioPie = new PortfolioPie(this); portfolioPie.update(db.getTickers(), portfolioValues); //com.imsl.math.PrintMatrixFormat pmf = new com.imsl.math.PrintMatrixFormat(); //pmf.setNumberFormat(new java.text.DecimalFormat("0.000E0")); //new com.imsl.math.PrintMatrix().printHTML(pmf,covar,covar.length,covar.length); } public void setVisible(boolean vis) { super.setVisible(vis); if (vis) { java.awt.Point chartLoc = getLocationOnScreen(); java.awt.Dimension statSize = statistics.getSize(); statistics.setLocation(chartLoc.x-statSize.width,chartLoc.y); java.awt.Dimension portSize = editPortfolio.getSize(); editPortfolio.setLocation(chartLoc.x,chartLoc.y-portSize.height); //java.awt.Dimension pieSize = portfolioPie.getSize(); //portfolioPie.setLocation(chartLoc.x-pieSize.width,chartLoc.y-pieSize.height); portfolioPie.setSize(225,225); portfolioPie.setLocation(chartLoc.x-225,chartLoc.y-225); } statistics.setVisible(vis); editPortfolio.setVisible(vis); portfolioPie.setVisible(vis); } public void cancelMonteCarlo() { cancelMonteCarlo = true; } private void compute() { cancelMonteCarlo = false; progress = new MonteCarloProgress(this, 0, nSamples); progress.setLocationRelativeTo(this); progress.setVisible(true); new Thread(new Runnable() { public void run() { runMonteCarlo(); } }).start(); } public void runMonteCarlo() { int nVariables = portfolioValues.length; int nBins = 50; double max = 0.05; summary = new Summary(); com.imsl.stat.Random random = new com.imsl.stat.Random(); double center = portfolio(new double[nVariables]); // Setup the bins bins = new double[nBins]; final double dx = 2.*max/nBins; double x[] = new double[nBins]; for (int k = 0; k < nBins; k++) { x[k] = -max + (k+0.5)*dx; } for (int p = 0; p < nSamples; p++) { double r[] = random.nextMultivariateNormal(nVariables, chol); double value = portfolio(r); double t = (value-center)/center; summary.update(t); if (p%10000 == 0) progress.setValue(p); if (cancelMonteCarlo) { progress.setVisible(false); return; } int j = (int)Math.round((t+max-0.5*dx)/dx); if (j >= 0 && j < nBins) bins[j]++; } final double xx[] = x; SwingUtilities.invokeLater(new Runnable() { public void run() { updateChart(xx, dx); } }); } private void updateChart(final double x[], double dx) { progress.setVisible(false); //getChart().getChartTitle().setTitle(); if (bar != null) bar.remove(); for (int k = 0; k < bins.length; k++) bins[k] /= nSamples; bar = new Bar(axis, x, bins); bar.setBarType(Bar.BAR_TYPE_VERTICAL); bar.setFillColor("green"); bar.setBarWidth(0.5*dx); axis.getAxisY().setWindow(0, 0.10); axis.getAxisY().setAutoscaleInput(AxisXY.AUTOSCALE_OFF); repaint(); StringBuffer sb = new StringBuffer(2048); sb.append("<html><body>"); sb.append("<p align='center'><b>Returns</b></p>"); sb.append("<table>"); appendRow(sb, "Samples", nSamples); appendRow(sb, "Minimum", summary.getMinimum()); appendRow(sb, "Maximum", summary.getMaximum()); appendRow(sb, "Mean", summary.getMean()); appendRow(sb, "Standard Deviation", summary.getStandardDeviation()); appendRow(sb, "Variance", summary.getVariance()); appendRow(sb, "Skewness", summary.getSkewness()); appendRow(sb, "Kurtosis", summary.getKurtosis()); sb.append("</table></body></html>"); statistics.setText(sb.toString()); statistics.repaint(); } static final DecimalFormat formatStat = new DecimalFormat("0.00000E0"); private void appendRow(StringBuffer sb, String title, double value) { sb.append("<tr><td align='right'><i>"); sb.append(title); sb.append("</i></td><td align='left'>"); sb.append(formatStat.format(value)); sb.append("</td><tr>"); } double portfolio(double returns[]) { double sum = 0.0; for (int k = 0; k < returns.length; k++) { sum += portfolioValues[k] * (1.0+returns[k]); } return sum; } private class Statistics extends JDialog { private JEditorPane jEditorPane; public Statistics() { super(Simulate.this, false); setTitle("Summary Statistics"); jEditorPane = new JEditorPane(); jEditorPane.setContentType("text/html"); jEditorPane.setPreferredSize(new java.awt.Dimension(250,375)); getContentPane().add(jEditorPane); pack(); } void setText(String text) { jEditorPane.setText(text); } } private class EditPortfolio extends JDialog { private JTextField jTextFieldSamples; private JTextField jTextField[]; EditPortfolio(String tickers[]) { setTitle("Edit"); getContentPane().setLayout(new java.awt.GridBagLayout()); GridBagConstraints gridBagConstraints = new GridBagConstraints(); JLabel jLabel = new JLabel("Samples"); jLabel.setHorizontalAlignment(SwingConstants.RIGHT); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; getContentPane().add(jLabel, gridBagConstraints); jTextFieldSamples = new JTextField(Integer.toString(nSamples)); jTextFieldSamples.setHorizontalAlignment(JTextField.RIGHT); jTextFieldSamples.setPreferredSize(new java.awt.Dimension(100,30)); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; getContentPane().add(jTextFieldSamples, gridBagConstraints); jTextField = new JTextField[tickers.length]; for (int k = 0; k < tickers.length; k++) { jLabel = new JLabel(tickers[k]); jLabel.setHorizontalAlignment(SwingConstants.RIGHT); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; getContentPane().add(jLabel, gridBagConstraints); jTextField[k] = new JTextField(Double.toString(portfolioValues[k])); jTextField[k].setHorizontalAlignment(JTextField.RIGHT); jTextField[k].setPreferredSize(new java.awt.Dimension(100,30)); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; getContentPane().add(jTextField[k], gridBagConstraints); } JButton jButton = new JButton("Update"); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; getContentPane().add(jButton, gridBagConstraints); jButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { update(); } }); pack(); } private void update() { nSamples = Integer.valueOf(jTextFieldSamples.getText()).intValue(); for (int k = 0; k < jTextField.length; k++) { portfolioValues[k] = Double.valueOf(jTextField[k].getText()).doubleValue(); } portfolioPie.update(db.getTickers(), portfolioValues); Simulate.this.compute(); Simulate.this.repaint(); } } }