Dashboard > GridGain User Guide > CreditRiskManager.java - GigaSpaces
CreditRiskManager.java - GigaSpaces
Added by Nikita Ivanov, last edited by Nikita Ivanov on Jul 22, 2007
Labels: 
(None)


This class abstracts out the calculation of risk for a credit portfolio. This class abstracts out the calculation of risk for a credit portfolio. It contains calculateCreditRiskMonteCarlo(...) method annotated with @Gridify(...) annotation which means that execution will be split across multiple nodes.

Full Source Code

CreditRiskManager.java
package org.gridgain.examples.montecarlo.gigaspaces;

import java.util.*;
import org.gridgain.grid.gridify.*;
import com.j_spaces.core.client.*;
import com.j_spaces.map.*;

public class CreditRiskManager {
    /**
     * Default randomizer with normal distribution.
     * Note that since every JVM on the grid will have its own random
     * generator (independently initialized) the Monte-Carlo simulation
     * will be slightly skewed when performed on the grid due to skewed
     * normal distribution of the sub-jobs comparing to execution on the
     * local node only with single random generator. Real-life applications
     * may want to provide its own implementation of distributed random
     * generator.
     */
    private static Random rndGen = new Random();

    /**
     * Calculates credit risk for a given credit portfolio. This calculation uses
     * Monte-Carlo Simulation to produce risk value.
     * <p>
     * Note that this class generally represents a business logic and the entire
     * grid enabling occurs in one line of annotation added to this method:
     * <pre>
     *      Gridify(taskClass = CreditRiskGridTask.class)
     * </pre>
     * Note also that this annotation could have been added externally via XML
     * file leaving this file completely untouched - yet still fully grid enabled.
     *
     * @param spaceMapName Name of the GigaSpaces map.
     * @param mapKey Portfolio key inside the GigaSpaces map.
     * @param horizon Forecast horizon (in days).
     * @param iters Number of Monte-Carlo iterations.
     * @param percentile Cutoff level.
     * @return Credit risk value, i.e. the minimal amount that creditor has to
     *      have available to cover possible defaults.
     * @throws FinderException Thrown in case of any error with GigaSpaces.
     */
    @Gridify(taskClass = CreditRiskGridTask.class)
    public double calculateCreditRiskMonteCarlo(String spaceMapName, String mapKey, int horizon,
        int iters, double percentile) throws FinderException {
        IMap mapSpace = (IMap)CacheFinder.find(spaceMapName);

        Credit[] portfolio = (Credit[]) mapSpace.get(mapKey);

        System.out.println(">>> Calculating credit risk for portfolio [size=" + portfolio.length + ", horizon=" +
            horizon + ", percentile=" + percentile + ", iterations=" + iters + "] <<<");

        double[] losses = calculateLosses(portfolio, horizon, iters);

        Arrays.sort(losses);

        double[] lossProbs = new double[losses.length];

        // Count variational numbers.
        // Every next one either has the same value or previous one plus probability of loss.
        for (int i = 0; i < losses.length; i++) {
            if (i == 0) {
                // First time it's just a probability of first value.
                lossProbs[i] = getLossProbability(losses, i);
            }
            else if (losses[i] != losses[i - 1]) {
                // Probability of this loss plus previous one.
                lossProbs[i] = getLossProbability(losses, i) + lossProbs[i - 1];
            }
            else {
                // The same loss the same probability.
                lossProbs[i] = lossProbs[i - 1];
            }
        }

        // Count percentile.
        double crdRisk = 0;

        for (int i = 0; i < lossProbs.length; i++) {
            if (lossProbs[i] > percentile) {
                crdRisk = losses[i - 1];

                break;
            }
        }

        return crdRisk;
    }

    /**
     * Calculates losses for the given credit portfolio using Monte-Carlo Simulation.
     * Simulates probability of default only.
     *
     * @param portfolio Credit portfolio.
     * @param horizon Forecast horizon.
     * @param iters Number of Monte-Carlo iterations.
     * @return Losses array simulated by Monte Carlo method.
     */
    private double[] calculateLosses(Credit[] portfolio, int horizon, int iters) {
        double[] losses = new double[iters];

        // Count losses using Monte-Carlo method. We generate random probability of default,
        // if it exceeds certain credit default value we count losses - otherwise count income.
        for (int i = 0; i < iters; i++) {
            for (Credit crd : portfolio) {
                int remDays = Math.min(crd.getRemainingTerm(), horizon);

                if (rndGen.nextDouble() >= 1 - crd.getDefaultProbability(remDays)) {
                    // (1 + 'r' * min(H, W) / 365) * S.
                    // Where W is a horizon, H is a remaining crediting term, 'r' is an annual credit rate,
                    // S is a remaining credit amount.
                    losses[i] += (1 + crd.getAnnualRate() * Math.min(horizon, crd.getRemainingTerm()) / 365)
                        * crd.getRemainingAmount();
                }
                else {
                    // - 'r' * min(H,W) / 365 * S
                    // Where W is a horizon, H is a remaining crediting term, 'r' is a annual credit rate,
                    // S is a remaining credit amount.
                    losses[i] -= crd.getAnnualRate() * Math.min(horizon, crd.getRemainingTerm()) / 365 *
                        crd.getRemainingAmount();
                }
            }
        }

        return losses;
    }

    /**
     * Calculates probability of certain loss in array of losses.
     *
     * @param losses Array of losses.
     * @param i Index of certain loss in array.
     * @return Probability of loss with given index.
     */
    private double getLossProbability(double[] losses, int i) {
        double count = 0;
        double loss = losses[i];

        for (double tmp : losses) {
            if (loss == tmp) {
                count++;
            }
        }

        return count / losses.length;
    }
}

Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.2.10 Build:#528 Nov 29, 2006) - Bug/feature request - Contact Administrators