com.opengamma.analytics.financial.model.option.pricing.analytic.AnalyticOptionModel.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.analytics.financial.model.option.pricing.analytic.AnalyticOptionModel.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.analytic;

import java.util.Set;

import org.apache.commons.lang.Validate;

import com.opengamma.analytics.financial.greeks.Greek;
import com.opengamma.analytics.financial.greeks.GreekResultCollection;
import com.opengamma.analytics.financial.greeks.GreekVisitor;
import com.opengamma.analytics.financial.model.option.definition.OptionDefinition;
import com.opengamma.analytics.financial.model.option.definition.StandardOptionDataBundle;
import com.opengamma.analytics.financial.model.option.pricing.FiniteDifferenceGreekVisitor;
import com.opengamma.analytics.financial.model.option.pricing.OptionModel;
import com.opengamma.analytics.math.function.Function1D;
import com.opengamma.analytics.math.statistics.distribution.NormalDistribution;
import com.opengamma.analytics.math.statistics.distribution.ProbabilityDistribution;
import com.opengamma.util.CompareUtils;

/**
 * @param <T> The type of the option definition
 * @param <U> The type of the option data bundle
 * Base class for analytic option models.
 */
public abstract class AnalyticOptionModel<T extends OptionDefinition, U extends StandardOptionDataBundle>
        implements OptionModel<T, U> {

    /**
     * Returns a pricing function.
     * @param definition The option definition, not null
     * @return The pricing function
     */
    public abstract Function1D<U, Double> getPricingFunction(T definition);

    /**
     * Returns a visitor that calculates greeks. By default, the calculation method is finite difference. If a different
     * method is possible (e.g. analytic formulae) then this method should be overridden in the implementing class.
     * @param pricingFunction The pricing function, not null
     * @param data The data, not null
     * @param definition The option definition, not null
     * @return A visitor that calculates greeks
     */
    public GreekVisitor<Double> getGreekVisitor(final Function1D<U, Double> pricingFunction, final U data,
            final T definition) {
        Validate.notNull(pricingFunction);
        Validate.notNull(data);
        Validate.notNull(definition);
        return new AnalyticOptionModelFiniteDifferenceGreekVisitor<>(pricingFunction, data, definition);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public GreekResultCollection getGreeks(final T definition, final U data, final Set<Greek> requiredGreeks) {
        Validate.notNull(definition);
        Validate.notNull(data);
        Validate.notNull(requiredGreeks);
        final Function1D<U, Double> pricingFunction = getPricingFunction(definition);
        final GreekResultCollection results = new GreekResultCollection();
        final GreekVisitor<Double> visitor = getGreekVisitor(pricingFunction, data, definition);
        for (final Greek greek : requiredGreeks) {
            final Double result = greek.accept(visitor);
            results.put(greek, result);
        }
        return results;
    }

    protected double getD1(final double s, final double k, final double t, final double sigma, final double b) {
        final double numerator = (Math.log(s / k) + t * (b + sigma * sigma / 2));
        if (CompareUtils.closeEquals(numerator, 0, 1e-16)) {
            return 0;
        }
        return numerator / (sigma * Math.sqrt(t));
    }

    protected double getD2(final double d1, final double sigma, final double t) {
        return d1 - sigma * Math.sqrt(t);
    }

    protected double getDF(final double r, final double b, final double t) {
        return Math.exp(t * (b - r));
    }

    /**
     * Extends the finite difference greek visitor to allow calculation of dZetaDVol
     * @param <S> The type of the option data bundle
     * @param <R> The type of the option definition
     */
    protected class AnalyticOptionModelFiniteDifferenceGreekVisitor<S extends StandardOptionDataBundle, R extends OptionDefinition>
            extends FiniteDifferenceGreekVisitor<S, R> {
        private static final double EPS = 1e-3;
        private final S _data;
        private final R _definition;
        private final ProbabilityDistribution<Double> _normal = new NormalDistribution(0, 1);

        public AnalyticOptionModelFiniteDifferenceGreekVisitor(final Function1D<S, Double> pricingFunction,
                final S data, final R definition) {
            super(pricingFunction, data, definition);
            _data = data;
            _definition = definition;
        }

        @Override
        public Double visitDZetaDVol() {
            final double s = _data.getSpot();
            final double k = _definition.getStrike();
            final double t = _definition.getTimeToExpiry(_data.getDate());
            final double b = _data.getCostOfCarry();
            final double sigma = _data.getVolatility(t, k);
            final int sign = _definition.isCall() ? 1 : -1;
            final double nUp = _normal.getCDF(sign * getD2(getD1(s, k, t, sigma + EPS, b), sigma + EPS, t));
            final double nDown = _normal.getCDF(sign * getD2(getD1(s, k, t, sigma - EPS, b), sigma - EPS, t));
            return (nUp - nDown) / (2 * EPS);
        }
    }
}