Package com.opengamma.analytics.financial.credit.portfoliolosssimulationmodel

Source Code of com.opengamma.analytics.financial.credit.portfoliolosssimulationmodel.ScenarioGenerator

/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.credit.portfoliolosssimulationmodel;

import com.opengamma.analytics.financial.credit.recoveryratemodel.RecoveryRateModel;
import com.opengamma.analytics.financial.credit.underlyingpool.definition.UnderlyingPool;
import com.opengamma.analytics.math.random.NormalRandomNumberGenerator;
import com.opengamma.analytics.math.statistics.distribution.NormalDistribution;
import com.opengamma.util.ArgumentChecker;

/**
* Class to generate a set of simulated default/recovery rate scenarios for a specified universe of obligors
*/
public class ScenarioGenerator {

  // ----------------------------------------------------------------------------------------------------------------------------------------

  // TODO : Do we need to do any arg checks on the simulation seed?
  // TODO : Remember to check if an obligor is already tagged as having defaulted
  // TODO : Check range of rho more carefully
  // TODO : Sort out the simulation seeds to make sure they are correctly used
  // TODO : Sort out the public/private access

  // ----------------------------------------------------------------------------------------------------------------------------------------

  // The universe of obligors to simulate scenarios for (treat as a very large 'UnderlyingPool' object)
  private final UnderlyingPool _obligorUniverse;

  // The recovery rate models (constant or stochastic) for each obligor in the universe of obligors
  private final RecoveryRateModel[] _recoveryRateModels;

  // The number of simulations
  private final int _numberOfSimulations;

  // The default simulation random number seed
  private final int _defaultSimulationSeed;

  // The simulation seed for sampling stochastic recoveries
  private final int _recoveryRateSimulationSeed;

  // The time horizon for the simulation (usually an integer, but need not be)
  private final double _simulationTimeHorizon;

  // The correlation of the defaults with the systemic factor
  private final double[] _rho;

  // The correlation of the sampled recovery rates with the systemic factor
  private final double[] _beta;

  // The default probability of the obligors
  private final double[] _defaultProbability;

  // ----------------------------------------------------------------------------------------------------------------------------------------

  public ScenarioGenerator(
      final UnderlyingPool obligorUniverse,
      final RecoveryRateModel[] recoveryRateModels,
      final int numberOfSimulations,
      final int defaultSimulationSeed,
      final int recoveryRateSimulationSeed,
      final double simulationTimeHorizon,
      final double[] rho,
      final double[] beta,
      final double[] defaultProbability) {

    // ----------------------------------------------------------------------------------------------------------------------------------------

    ArgumentChecker.notNull(obligorUniverse, "Obligor universe");
    ArgumentChecker.notNull(recoveryRateModels, "Recovery rate models");

    ArgumentChecker.isTrue(recoveryRateModels.length == obligorUniverse.getNumberOfObligors(), "The number of obligors must equal the number of input recovery rate models");
    ArgumentChecker.isTrue(rho.length == obligorUniverse.getNumberOfObligors(), "The number of obligors must equal the number of input correlations");
    ArgumentChecker.isTrue(beta.length == obligorUniverse.getNumberOfObligors(), "The number of obligors must equal the number of input correlations");
    ArgumentChecker.isTrue(defaultProbability.length == obligorUniverse.getNumberOfObligors(), "The number of obligors must equal the number of input default probabilities");

    ArgumentChecker.notNegative(numberOfSimulations, "Number of simulations");
    ArgumentChecker.notNegative(simulationTimeHorizon, "Simulation time horizon");

    for (int i = 0; i < obligorUniverse.getNumberOfObligors(); i++) {
      ArgumentChecker.isInRangeInclusive(-1.0, 1.0, rho[i]);
      ArgumentChecker.isInRangeInclusive(-1.0, 1.0, beta[i]);
    }

    // ----------------------------------------------------------------------------------------------------------------------------------------

    _obligorUniverse = obligorUniverse;
    _recoveryRateModels = recoveryRateModels;

    _numberOfSimulations = numberOfSimulations;
    _defaultSimulationSeed = defaultSimulationSeed;
    _recoveryRateSimulationSeed = recoveryRateSimulationSeed;

    _simulationTimeHorizon = simulationTimeHorizon;

    _rho = rho;
    _beta = beta;
    _defaultProbability = defaultProbability;

    // ----------------------------------------------------------------------------------------------------------------------------------------
  }

  // ----------------------------------------------------------------------------------------------------------------------------------------

  // Method to compute the recovery rates for each obligor for each simulated scenario
  public double[][] generateRecoveryRateScenarios(final ScenarioGenerator scenarioGenerator, final SimulatedObligorDefaultState[][] simulatedDefaultScenarios) {

    // Determine the number of simulations and number of obligors in the universe
    int numberOfSimulations = scenarioGenerator.getNumberofSimulations();
    int numberOfObligors = scenarioGenerator.getObligorUniverse().getNumberOfObligors();

    // The matrix of simulated recovery rates per simulation to output
    double[][] simulatedRecoveryRateScenarios = new double[numberOfSimulations][numberOfObligors];

    // Construct a N(0, 1) random number generator
    NormalRandomNumberGenerator normRand = new NormalRandomNumberGenerator(0.0, 1.0);

    // Construct a N(0, 1) distribution object (for calculating the default barrier level)
    NormalDistribution normDist = new NormalDistribution(0.0, 1.0);

    // Compute the vector of systemic factors
    final double[] systemicFactor = normRand.getVector(numberOfSimulations);

    // Main loop of simulation
    for (int alpha = 0; alpha < numberOfSimulations; alpha++) {

      // Loop over each of the obligors
      for (int i = 0; i < numberOfObligors; i++) {

        // Did obligor i default on scenario alpha ...
        if (simulatedDefaultScenarios[alpha][i] == SimulatedObligorDefaultState.DEFAULTED) {

          // ... yes, then calculate the stochastic recovery rate

          // Calculate an idiosyncratic N(0, 1) deviate
          final double[] eta = normRand.getVector(1);

          // Get the correlation (coupling) of the sampled recovery rate with the systemic factor
          final double beta = scenarioGenerator.getBeta()[i];

          // Compute the recovery rate latent variable for this obligor for this simulation
          final double recoveryRateLatentVariable = beta * systemicFactor[i] + Math.sqrt(1 - beta * beta) * eta[0];

          // Calculate the recovery rate

          // FIXME :
          simulatedRecoveryRateScenarios[alpha][i] = 0.0;

        } else {

          // ... no, in which case the recovery rate is just the user input recovery rate

          simulatedRecoveryRateScenarios[alpha][i] = scenarioGenerator.getRecoveryRateModels()[i].getRecoveryRate();
        }

      }
    }

    return simulatedRecoveryRateScenarios;
  }

  // ----------------------------------------------------------------------------------------------------------------------------------------

  // Method to generate a vector of N(0, 1) deviates corresponding to the systemic factor for each simulation
  private double[] generateSystemicFactors(final int numberOfSimulations, final int defaultSimulationSeed) {

    // Construct a N(0, 1) random number generator
    NormalRandomNumberGenerator normRand = new NormalRandomNumberGenerator(0.0, 1.0);

    // Compute the vector of systemic factors
    final double[] systemicFactor = normRand.getVector(numberOfSimulations);

    return systemicFactor;
  }

  // ----------------------------------------------------------------------------------------------------------------------------------------

  // Method to compute the default barrier levels for the obligors
  private double[] generateDefaultBarrierLevels(ScenarioGenerator scenarioGenerator) {

    final int numberOfObligors = scenarioGenerator.getObligorUniverse().getNumberOfObligors();

    // Vector to hold the default barrier level for each obligor
    double[] defaultBarrierLevel = new double[numberOfObligors];

    // Construct a N(0, 1) distribution object (for calculating the default barrier level)
    NormalDistribution normDist = new NormalDistribution(0.0, 1.0);

    // Compute the default barrier level for each obligor
    for (int i = 0; i < numberOfObligors; i++) {

      final double defaultProbability = scenarioGenerator.getDefaultProbability()[i];
      defaultBarrierLevel[i] = normDist.getInverseCDF(defaultProbability);
    }

    return defaultBarrierLevel;
  }

  // ----------------------------------------------------------------------------------------------------------------------------------------

  // Method to compute the simulated defaults for each simulation
  public SimulatedObligorDefaultState[][] generateDefaultScenarios(final ScenarioGenerator scenarioGenerator) {

    // Determine the number of simulations and number of obligors in the universe
    int numberOfSimulations = scenarioGenerator.getNumberofSimulations();
    int numberOfObligors = scenarioGenerator.getObligorUniverse().getNumberOfObligors();

    // Construct a N(0, 1) random number generator
    NormalRandomNumberGenerator normRand = new NormalRandomNumberGenerator(0.0, 1.0);

    // The matrix of simulated defaults per simulation to output
    SimulatedObligorDefaultState[][] simulatedDefaultScenarios = new SimulatedObligorDefaultState[numberOfSimulations][numberOfObligors];

    // Compute the default barrier level for each obligor
    final double[] defaultBarrierLevel = generateDefaultBarrierLevels(scenarioGenerator);

    // Compute the vector of systemic factors (one sample for each simulation)
    final double[] systemicFactor = generateSystemicFactors(numberOfSimulations, scenarioGenerator.getDefaultSimulationSeed());

    // Main loop of simulation
    for (int alpha = 0; alpha < numberOfSimulations; alpha++) {

      // Construct a vector of idiosyncratic N(0, 1) deviates for this simulation
      final double[] epsilon = normRand.getVector(numberOfObligors);

      // Loop over each of the obligors
      for (int i = 0; i < numberOfObligors; i++) {

        // Get the correlation (coupling) of the default of this obligor with the systemic factor
        final double rho = scenarioGenerator.getRho()[i];

        // Compute the default latent variable for this obligor for this simulation
        final double defaultLatentVariable = rho * systemicFactor[0] + Math.sqrt(1 - rho * rho) * epsilon[i];

        // Did the obligor i default in simulation alpha ...
        if (defaultLatentVariable < defaultBarrierLevel[i]) {
          // ... yes
          simulatedDefaultScenarios[alpha][i] = SimulatedObligorDefaultState.DEFAULTED;
        } else {
          // ... no
          simulatedDefaultScenarios[alpha][i] = SimulatedObligorDefaultState.NOTDEFAULTED;
        }

      }
    }

    return simulatedDefaultScenarios;
  }

  // ----------------------------------------------------------------------------------------------------------------------------------------

  public UnderlyingPool getObligorUniverse() {
    return _obligorUniverse;
  }

  public RecoveryRateModel[] getRecoveryRateModels() {
    return _recoveryRateModels;
  }

  public int getNumberofSimulations() {
    return _numberOfSimulations;
  }

  public int getDefaultSimulationSeed() {
    return _defaultSimulationSeed;
  }

  public int getRecoveryRateSimulationSeed() {
    return _recoveryRateSimulationSeed;
  }

  public double getSimulationTimeHorizon() {
    return _simulationTimeHorizon;
  }

  public double[] getRho() {
    return _rho;
  }

  public double[] getBeta() {
    return _beta;
  }

  public double[] getDefaultProbability() {
    return _defaultProbability;
  }

  // ----------------------------------------------------------------------------------------------------------------------------------------
}
TOP

Related Classes of com.opengamma.analytics.financial.credit.portfoliolosssimulationmodel.ScenarioGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.