/*
 Copyright (C) 2008 Daniel Kong

 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.
 */
package org.jquantlib.instruments.bonds;

import java.util.ArrayList;
import java.util.List;

import org.jquantlib.QL;
import org.jquantlib.cashflow.Callability;
import org.jquantlib.cashflow.Leg;
import org.jquantlib.daycounters.DayCounter;
import org.jquantlib.exercise.Exercise;
import org.jquantlib.instruments.CallabilitySchedule;
import org.jquantlib.instruments.DividendSchedule;
import org.jquantlib.instruments.Instrument;
import org.jquantlib.instruments.OneAssetOption;
import org.jquantlib.instruments.Option;
import org.jquantlib.instruments.PlainVanillaPayoff;
import org.jquantlib.lang.reflect.ReflectConstants;
import org.jquantlib.math.Constants;
import org.jquantlib.pricingengines.GenericEngine;
import org.jquantlib.pricingengines.PricingEngine;
import org.jquantlib.quotes.Handle;
import org.jquantlib.quotes.Quote;
import org.jquantlib.time.Date;
import org.jquantlib.time.Schedule;

/**
 *
 * @author Daniel Kong
 * @author Zahid Hussain
 */
public class ConvertibleBondOption extends OneAssetOption {

    private final ConvertibleBond bond_;
    private final double conversionRatio_;
    private final CallabilitySchedule callability_;
    private final DividendSchedule  dividends_;
    private final Handle creditSpread_;
    private final Leg cashflows_;
    private final DayCounter dayCounter_;
    private final Date issueDate_;
    private final Schedule schedule_;
    private final int settlementDays_;
    private final double redemption_;

    public ConvertibleBondOption(final ConvertibleBond bond,
                                 final Exercise exercise,
                                 final double conversionRatio,
                                 final DividendSchedule dividends,
                                 final CallabilitySchedule callability,
                                 final Handle creditSpread,
                                 final Leg cashflows,
                                 final DayCounter dayCounter,
                                 final Schedule schedule,
                                 final Date issueDate,
                                 final int  settlementDays,
                                 final double redemption) {
        super(new PlainVanillaPayoff(Option.Type.Call,bond.faceAmount()/100.0 * redemption/conversionRatio), exercise);
        this.bond_ = bond;
        this.conversionRatio_ = conversionRatio;
        this.callability_ = callability;
        this.dividends_ = dividends;
        this.creditSpread_ = creditSpread;
        this.cashflows_ = cashflows;
        this.dayCounter_ = dayCounter;
        this.issueDate_ = issueDate;
        this.schedule_ = schedule;
        this.settlementDays_ = settlementDays;
        this.redemption_ = redemption;
    }

    @Override
    public void setupArguments(final PricingEngine.Arguments args) {

        super.setupArguments(args);
        
        QL.require(ConvertibleBondOption.ArgumentsImpl.class.isAssignableFrom(args.getClass()), ReflectConstants.WRONG_ARGUMENT_TYPE); // QA:[RG]::verified
        final ConvertibleBondOption.ArgumentsImpl moreArgs = args instanceof ConvertibleBondOption.ArgumentsImpl 
                                                        ? (ConvertibleBondOption.ArgumentsImpl)args
                                                        : null;
        QL.require(moreArgs != null, "wrong argument type");

        moreArgs.conversionRatio = conversionRatio_;

        final Date settlement = bond_.settlementDate().clone();

        final int n = callability_.size();
        moreArgs.callabilityDates.clear();
        moreArgs.callabilityTypes.clear();
        moreArgs.callabilityPrices.clear();
        moreArgs.callabilityTriggers.clear();

        //Not required in Java:
        //moreArgs.callabilityDates.reserve(n);
        //moreArgs.callabilityTypes.reserve(n);
        //moreArgs.callabilityPrices.reserve(n);
        //moreArgs.callabilityTriggers.reserve(n);
        
        for (int i=0; i creditSpread;
        public DividendSchedule dividends;
        public List dividendDates;
        public List callabilityDates;
        public List callabilityTypes;
        public List callabilityPrices;
        public List callabilityTriggers;
        public List couponDates;
        public List couponAmounts;
        public Date issueDate;
        public Date settlementDate;
        public int settlementDays;
        public double redemption;

        public ArgumentsImpl() {
            conversionRatio = Constants.NULL_REAL;
            settlementDays = Constants.NULL_INTEGER;
            redemption = Constants.NULL_REAL;

            dividends = new DividendSchedule();
            dividendDates = new ArrayList();
            callabilityDates = new ArrayList();
            callabilityTypes = new ArrayList();
            callabilityPrices = new ArrayList();
            callabilityTriggers = new ArrayList();
            couponDates = new ArrayList();
            couponAmounts = new ArrayList();
        }

        @Override
        public void validate() {
            super.validate();

            QL.require(!Double.isNaN(conversionRatio), "null conversion ratio");
            QL.require(conversionRatio > 0.0, "positive conversion ratio required");
            QL.require(!Double.isNaN(redemption), "null redemption");
            QL.require(redemption >= 0.0, "positive redemption required");
            QL.require(!settlementDate.isNull(), "null settlement date");
            QL.require(settlementDays != Constants.NULL_INTEGER, "null settlement days");
            QL.require(callabilityDates.size() == callabilityTypes.size(), "different number of callability dates and types");
            QL.require(callabilityDates.size() == callabilityPrices.size(), "different number of callability dates and prices");
            QL.require(callabilityDates.size() == callabilityTriggers.size(), "different number of callability dates and triggers");
            QL.require(couponDates.size() == couponAmounts.size(), "different number of coupon dates and amounts");
        }

    }


    static public class ResultsImpl extends OneAssetOption.ResultsImpl {

        @Override
        public void reset() /* @ReadOnly */ {
            super.reset();
        }

    }


    static public abstract class EngineImpl
            extends GenericEngine {

        protected EngineImpl() {
            super(new ArgumentsImpl(), new ResultsImpl());
        }

    }

}

 

Ads help maintain this website.