com.opengamma.analytics.financial.model.finitedifference.MarkovChainSmallTimeApprox.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.analytics.financial.model.finitedifference.MarkovChainSmallTimeApprox.java

Source

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

import org.apache.commons.lang.Validate;

import com.opengamma.analytics.financial.model.option.pricing.analytic.formula.BlackFunctionData;
import com.opengamma.analytics.financial.model.option.pricing.analytic.formula.BlackPriceFunction;
import com.opengamma.analytics.financial.model.option.pricing.analytic.formula.EuropeanVanillaOption;
import com.opengamma.analytics.math.function.Function1D;
import com.opengamma.analytics.math.integration.Integrator1D;
import com.opengamma.analytics.math.integration.RungeKuttaIntegrator1D;

/**
 * 
 */
public class MarkovChainSmallTimeApprox {

    private final double _vol1;
    private final double _vol2;
    private final double _lambda12;
    private final double _lambda21;
    private final double _probState1;
    private final Integrator1D<Double, Double> _integrator = new RungeKuttaIntegrator1D();
    private final BlackPriceFunction _black = new BlackPriceFunction();

    public MarkovChainSmallTimeApprox(final double vol1, final double vol2, final double lambda12,
            final double lambda21, final double probState1) {
        Validate.isTrue(vol1 >= 0);
        Validate.isTrue(vol2 >= 0);
        Validate.isTrue(lambda12 >= 0);
        Validate.isTrue(lambda21 >= 0);
        Validate.isTrue(probState1 >= 0 && probState1 <= 1.0);
        _vol1 = vol1;
        _vol2 = vol2;
        _lambda12 = lambda12;
        _lambda21 = lambda21;
        _probState1 = probState1;
    }

    public double price(final double forward, final double df, final double strike, final double expiry) {

        final EuropeanVanillaOption option = new EuropeanVanillaOption(strike, expiry, true);
        final Function1D<BlackFunctionData, Double> priceFunc = _black.getPriceFunction(option);

        final Function1D<Double, Double> fun1 = new Function1D<Double, Double>() {

            @SuppressWarnings("synthetic-access")
            @Override
            public Double evaluate(final Double tau) {
                double sigma = _vol1 * _vol1 * tau / expiry + _vol2 * _vol2 * (1 - tau / expiry);
                sigma = Math.sqrt(sigma);
                final BlackFunctionData data = new BlackFunctionData(forward, df, sigma);
                return _lambda12 * priceFunc.evaluate(data) * Math.exp(-_lambda12 * tau);
            }
        };

        final Function1D<Double, Double> fun2 = new Function1D<Double, Double>() {

            @SuppressWarnings("synthetic-access")
            @Override
            public Double evaluate(final Double tau) {
                double sigma = _vol1 * _vol1 * (1 - tau / expiry) + _vol2 * _vol2 * tau / expiry;
                sigma = Math.sqrt(sigma);
                final BlackFunctionData data = new BlackFunctionData(forward, df, sigma);
                return _lambda21 * priceFunc.evaluate(data) * Math.exp(-_lambda21 * tau);
            }
        };

        double p1 = 0;
        double p2 = 0;

        if (_probState1 > 0.0) {
            final BlackFunctionData data = new BlackFunctionData(forward, df, _vol1);
            p1 = _integrator.integrate(fun1, 0.0, expiry)
                    + priceFunc.evaluate(data) * Math.exp(-_lambda12 * expiry);
        }

        if (_probState1 < 1.0) {
            final BlackFunctionData data = new BlackFunctionData(forward, df, _vol2);
            p2 = _integrator.integrate(fun2, 0.0, expiry)
                    + priceFunc.evaluate(data) * Math.exp(-_lambda21 * expiry);
        }
        return _probState1 * p1 + (1 - _probState1) * p2;
    }
}