com.opengamma.analytics.financial.model.option.pricing.fourier.CGMYCharacteristicExponent.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.analytics.financial.model.option.pricing.fourier.CGMYCharacteristicExponent.java

Source

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

import static com.opengamma.analytics.math.ComplexMathUtils.add;
import static com.opengamma.analytics.math.ComplexMathUtils.multiply;
import static com.opengamma.analytics.math.ComplexMathUtils.pow;
import static com.opengamma.analytics.math.ComplexMathUtils.subtract;
import static com.opengamma.analytics.math.number.ComplexNumber.I;
import static com.opengamma.analytics.math.number.ComplexNumber.ZERO;

import org.apache.commons.lang.NotImplementedException;
import org.apache.commons.lang.Validate;

import com.opengamma.analytics.math.function.Function1D;
import com.opengamma.analytics.math.function.special.GammaFunction;
import com.opengamma.analytics.math.number.ComplexNumber;

/**
 * This class represents the characteristic function of the
 * Carr-Madan-Geman-Yor (CGMY) process. This process is a pure jump process
 * (i.e.  there is no Brownian component).
 * <p>
 * The characteristic function is given by:
 * $$
 * \begin{align*}
 * \phi(u; C, G, M, Y) = \exp\left(C \Gamma(-Y)\left[(M - iu)^Y - M^Y + (G + iu)^Y - G^Y\right]\right)
 * \end{align*}
 * $$
 */
public class CGMYCharacteristicExponent implements CharacteristicExponent {
    private static final GammaFunction GAMMA_FUNCTION = new GammaFunction();
    private final double _c;
    private final double _g;
    private final double _m;
    private final double _y;
    private final double _minAlpha;
    private final double _maxAlpha;
    private final double _r1;
    private final double _r2;
    private final double _r3;

    /**
     * The parameters for the CGMY process
     * @param c C, > 0
     * @param g G, > 0
     * @param m M, > 1
     * @param y Y, < 2
     */
    public CGMYCharacteristicExponent(final double c, final double g, final double m, final double y) {
        Validate.isTrue(c > 0, "C > 0");
        Validate.isTrue(g > 0, "G > 0");
        Validate.isTrue(m > 1, "M > 1");
        Validate.isTrue(y < 2, "Y < 2");
        _c = c;
        _g = g;
        _m = m;
        _y = y;
        _minAlpha = -(_g + 1.0);
        _maxAlpha = _m - 1.0;
        _r1 = Math.pow(_m, _y) + Math.pow(_g, _y);
        _r2 = _c * GAMMA_FUNCTION.evaluate(-_y);
        _r3 = (Math.pow(_m - 1, _y) + Math.pow(_g + 1, _y) - _r1);
    }

    @Override
    public Function1D<ComplexNumber, ComplexNumber> getFunction(final double t) {
        return new Function1D<ComplexNumber, ComplexNumber>() {
            @Override
            public ComplexNumber evaluate(ComplexNumber u) {
                return getValue(u, t);
            }
        };
    }

    @Override
    public ComplexNumber getValue(ComplexNumber u, double t) {
        final double r2 = t * _r2;
        final ComplexNumber complexR3 = new ComplexNumber(r2 * _r3);
        if (u.getReal() == 0.0) {
            if (u.getImaginary() == 0.0) {
                return ZERO;
            }
            if (u.getImaginary() == -1.0) {
                return complexR3;
            }
        }
        final ComplexNumber iu = multiply(I, u);
        final ComplexNumber c1 = pow(subtract(_m, iu), _y);
        final ComplexNumber c2 = pow(add(_g, iu), _y);
        final ComplexNumber c3 = add(c1, c2);
        final ComplexNumber c4 = subtract(c3, _r1);
        final ComplexNumber res = multiply(r2, c4);
        return res;
    }

    /**
     * Gets C
     * @return C
     */
    public double getC() {
        return _c;
    }

    /**
     * Gets G
     * @return G
     */
    public double getG() {
        return _g;
    }

    /**
     * Gets M
     * @return M
     */
    public double getM() {
        return _m;
    }

    /**
     * Gets Y
     * @return Y
     */
    public double getY() {
        return _y;
    }

    /**
     * 
     * @return $M - 1$
     */
    @Override
    public double getLargestAlpha() {
        return _maxAlpha;
    }

    /**
     * 
     * @return $-G - 1$
     */
    @Override
    public double getSmallestAlpha() {
        return _minAlpha;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        long temp;
        temp = Double.doubleToLongBits(_c);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits(_g);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits(_m);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits(_y);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final CGMYCharacteristicExponent other = (CGMYCharacteristicExponent) obj;
        if (Double.doubleToLongBits(_c) != Double.doubleToLongBits(other._c)) {
            return false;
        }
        if (Double.doubleToLongBits(_g) != Double.doubleToLongBits(other._g)) {
            return false;
        }
        if (Double.doubleToLongBits(_m) != Double.doubleToLongBits(other._m)) {
            return false;
        }
        return Double.doubleToLongBits(_y) == Double.doubleToLongBits(other._y);
    }

    @Override
    public ComplexNumber[] getCharacteristicExponentAdjoint(ComplexNumber u, double t) {
        throw new NotImplementedException();
    }

    @Override
    public Function1D<ComplexNumber, ComplexNumber[]> getAdjointFunction(double t) {
        throw new NotImplementedException();
    }

}