/*
 Copyright (C) 2007 Richard Gomes

 This source code is release under the BSD License.

 This file is part of JQuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://jquantlib.org/

 JQuantLib is free software: you can redistribute it and/or modify it
 under the terms of the JQuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 . The license is also available online at
 .

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.

 JQuantLib is based on QuantLib. http://quantlib.org/
 When applicable, the original copyright notice follows this notice.
 */

/*
 Copyright (C) 2003 Ferdinando Ametrano
 Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl
 Copyright (C) 2007 StatPro Italia srl

 This file is part of QuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://quantlib.org/

 QuantLib is free software: you can redistribute it and/or modify it
 under the terms of the QuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 . The license is also available online at
 .

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.
 */

package org.jquantlib.instruments;

import org.jquantlib.QL;
import org.jquantlib.Settings;
import org.jquantlib.exercise.Exercise;
import org.jquantlib.lang.reflect.ReflectConstants;
import org.jquantlib.math.Constants;
import org.jquantlib.pricingengines.GenericEngine;
import org.jquantlib.pricingengines.PricingEngine;
import org.jquantlib.util.Observer;

/**
 * Base class for options on a single asset
 *
 * @author Richard Gomes
 * @author Zahid Hussain
 */
public class OneAssetOption extends Option {

    private double delta_;
    private double deltaForward_;
    private double elasticity_;
    private double gamma_;
    private double theta_;
    private double thetaPerDay_;
    private double vega_;
    private double rho_;
    private double dividendRho_;
    private double strikeSensitivity_;
    private double itmCashProbability_;

    public OneAssetOption(final Payoff payoff,
            			  final Exercise exercise) {
        super(payoff, exercise);
    }
    
    @Override
	public boolean isExpired() /* @ReadOnly */ {
        return exercise.lastDate().lt(new Settings().evaluationDate() );
    }
    
    public double delta() {
        calculate();
        QL.require(delta_ != Constants.NULL_REAL, "delta not provided");
        return delta_;
    }
    
    public double deltaForward() /* @ReadOnly */ {
        calculate();
        QL.require(deltaForward_ != Constants.NULL_REAL , "forward delta not provided");
        return deltaForward_;
    }

    public double elasticity() {
        calculate();
        QL.require(elasticity_ != Constants.NULL_REAL, "elasticity not provided");
        return elasticity_;
    }
    
    public double gamma(){
        calculate();
        QL.require(gamma_ != Constants.NULL_REAL, "gamma not provided");
        return gamma_;
    }
    
    public double theta() {
        calculate();
        QL.require(theta_ != Constants.NULL_REAL, "theta not provided");
        return theta_;
    }

    public double thetaPerDay() {
        calculate();
        QL.require(thetaPerDay_ != Constants.NULL_REAL, "theta per-day not provided");
        return thetaPerDay_;
    }
    public double vega() {
        calculate();
        QL.require(vega_ != Constants.NULL_REAL, "vega not provided");
        return vega_;
    }
    
    public double rho() {
        calculate();
        QL.require(rho_ != Constants.NULL_REAL, "rho not provided");
        return rho_;
    }
    
    public double dividendRho() {
        calculate();
        QL.require(dividendRho_ != Constants.NULL_REAL, "dividend rho not provided");
        return dividendRho_;
    }
    
    public double strikeSensitivity() {
        calculate();
        QL.require(strikeSensitivity_ != Constants.NULL_REAL,
                   "strike sensitivity not provided");
        return strikeSensitivity_;
    }

    public double itmCashProbability() {
        calculate();
        QL.require(itmCashProbability_ != Constants.NULL_REAL,
                   "in-the-money cash probability not provided");
        return itmCashProbability_;
    }
    
    @Override
	public void setupExpired() {
        super.setupExpired();
        delta_ = deltaForward_ = elasticity_ = gamma_ = theta_ =
            thetaPerDay_ = vega_ = rho_ = dividendRho_ =
            strikeSensitivity_ = itmCashProbability_ = 0.0;
    }

    @Override
	public void fetchResults(final PricingEngine.Results r) {
        super.fetchResults(r);
        
        QL.require(OneAssetOption.Results.class.isAssignableFrom(r.getClass()), ReflectConstants.WRONG_ARGUMENT_TYPE); // QA:[RG]::verified
        //final Greeks results = (Greeks)(r);

        final OneAssetOption.ResultsImpl ri = (OneAssetOption.ResultsImpl)r;
        final GreeksImpl     results = ri.greeks();
        
        QL.ensure(results != null,
                  "no greeks returned from pricing engine");
        /* no check on null values - just copy.
           this allows:
           a) to decide in derived options what to do when null
           results are returned (throw? numerical calculation?)
           b) to implement slim engines which only calculate the
           value---of course care must be taken not to call
           the greeks methods when using these.
        */
        delta_          = results.delta;
        gamma_          = results.gamma;
        theta_          = results.theta;
        vega_           = results.vega;
        rho_            = results.rho;
        dividendRho_    = results.dividendRho;

        final MoreGreeksImpl moreResults = ri.moreGreeks();
        QL.ensure(moreResults != null,
                  "no more greeks returned from pricing engine");
        /* no check on null values - just copy.
           this allows:
           a) to decide in derived options what to do when null
           results are returned (throw? numerical calculation?)
           b) to implement slim engines which only calculate the
           value---of course care must be taken not to call
           the greeks methods when using these.
        */
        deltaForward_       = moreResults.deltaForward;
        elasticity_         = moreResults.elasticity;
        thetaPerDay_        = moreResults.thetaPerDay;
        strikeSensitivity_  = moreResults.strikeSensitivity;
        itmCashProbability_ = moreResults.itmCashProbability;
    }

    /**
     * {@inheritDoc}
     * 

* Obtains {@link Greeks} and {@link MoreGreeks} calculated by a {@link PricingEngine} * * @see Greeks * @see MoreGreeks * @see PricingEngine */ // @Override // public void fetchResults(final PricingEngine.Results results) /* @ReadOnly */ { // super.fetchResults(results); // // // bind a Results interface to specific classes // QL.require(OneAssetOption.Results.class.isAssignableFrom(results.getClass()), ReflectConstants.WRONG_ARGUMENT_TYPE); // QA:[RG]::verified // final OneAssetOption.ResultsImpl r = (OneAssetOption.ResultsImpl)results; // final GreeksImpl greeks = r.greeks(); // final MoreGreeksImpl moreGreeks = r.moreGreeks(); // // // // // No check on Double.NaN values - just copy. this allows: // // a) To decide in derived options what to do when null results are returned // // (throw numerical calculation?) // // b) To implement slim engines which only calculate the value. // // Of course care must be taken not to call the greeks methods when using these. // // // delta = greeks.delta; // gamma = greeks.gamma; // theta = greeks.theta; // vega = greeks.vega; // rho = greeks.rho; // dividendRho = greeks.dividendRho; // // // // // No check on Double.NaN values - just copy. this allows: // // a) To decide in derived options what to do when null results are returned // // (throw numerical calculation?) // // b) To implement slim engines which only calculate the value. // // Of course care must be taken not to call the greeks methods when using these. // // // deltaForward = moreGreeks.deltaForward; // elasticity = moreGreeks.elasticity; // thetaPerDay = moreGreeks.thetaPerDay; // itmCashProbability = moreGreeks.itmCashProbability; // } // // public inner interfaces // //! %Results from single-asset option calculation // class OneAssetOption::results : public Instrument::results, // public Greeks, // public MoreGreeks { // public: // void reset() { // Instrument::results::reset(); // Greeks::reset(); // MoreGreeks::reset(); // } // }; // // class OneAssetOption::engine : // public GenericEngine {}; /** * basic option arguments * * @author Richard Gomes */ public interface Arguments extends Option.Arguments { /* marking interface */ } /** * Results from single-asset option calculation * * @author Richard Gomes */ public interface Results extends Instrument.Results, Option.Greeks, Option.MoreGreeks { /* marking interface */ } public interface Engine extends PricingEngine, Observer { /* marking interface */ } // // public inner classes // static public class ArgumentsImpl extends Option.ArgumentsImpl implements OneAssetOption.Arguments { /* marking interface */ } /** * Results from single-asset option calculation * * @author Richard Gomes */ static public class ResultsImpl extends Instrument.ResultsImpl implements OneAssetOption.Results { private final Option.GreeksImpl greeks; private final Option.MoreGreeksImpl moreGreeks; public ResultsImpl() { greeks = new Option.GreeksImpl(); moreGreeks = new Option.MoreGreeksImpl(); } final public Option.GreeksImpl greeks() { return greeks; } final public Option.MoreGreeksImpl moreGreeks() { return moreGreeks; } // // implements Results // @Override public void reset() /* @ReadOnly */ { super.reset(); greeks.reset(); moreGreeks.reset(); } } /** * The pricing engine for one-asset options * * @author Richard Gomes */ static abstract public class EngineImpl extends GenericEngine implements OneAssetOption.Engine { public EngineImpl() { super(new ArgumentsImpl(), new ResultsImpl()); } public EngineImpl(final OneAssetOption.Arguments arguments, final OneAssetOption.Results results) { super(arguments, results); } } }

Ads help maintain this website.