Login  Register

Proposed change to Convertible Bond model

Posted by John Maiden on May 25, 2007; 12:27am
URL: http://quantlib.414.s1.nabble.com/Proposed-change-to-Convertible-Bond-model-tp9499.html

Working through and trying to understand the convertible bond model, and came up
with a proposed change. At the moment the model requires fixed cash dividends.
Proposed change to code would allow user to either choose a fixed cash dividend
(through using a FixedDividend) or a fixed percent dividend (through using a
FractionalDividend). Changes would be made to discretizedconvertible.cpp and
binomialconvertibleengine.hpp.

Besides changes to the code below, an additional change might have to
be made to DiscretizedConvertible::DiscretizedConvertible through its
initialization of the Array dividendValues_, though I'm not sure where else (or
how) in the program this array is used.

The code (changes are marked):

//Proposed change to dividends in DiscretizedConvertible.cpp
       
                Disposable<Array> DiscretizedConvertible::adjustedGrid() const {
                Time t = time();
                Array grid = method()->grid(t);
                // add back all dividend amounts in the future
                for (Size i=0; i<arguments_.dividends.size(); i++) {
                        Time dividendTime = arguments_.dividendTimes[i];
                        if (dividendTime >= t || close(dividendTime,t)) {
                                const boost::shared_ptr<Dividend>& d = arguments_.dividends[i];
                                //begin proposed change
                                boost::shared_ptr<Dividend> testdiv =
boost::dynamic_pointer_cast<FixedDividend>(arguments_.dividends[i]);
                                if(testdiv){
                                        for (Size j=0; j<grid.size(); j++)
                                                grid[j] += d->amount(grid[j]);
                                } else {
                                        for (Size j=0; j<grid.size(); j++)
                                                grid[j] *= (1 + d->amount(grid[j]));
                                }
                                //end change
                                //begin original code
                                /* for (Size j=0; j<grid.size(); j++)
                                        grid[j] += d->amount(grid[j]); */
                                //end original code

                        }
                }
                return grid;
        }

//Proposed change to dividends in BinomialConvertibleEngine.hpp
        template <class T>
        void BinomialConvertibleEngine<T>::calculate() const {

                boost::shared_ptr<GeneralizedBlackScholesProcess> process =
                        boost::dynamic_pointer_cast<GeneralizedBlackScholesProcess>(
                        this->arguments_.stochasticProcess);
                QL_REQUIRE(process, "Black-Scholes process required");

                DayCounter rfdc  = process->riskFreeRate()->dayCounter();
                DayCounter divdc = process->dividendYield()->dayCounter();
                DayCounter voldc = process->blackVolatility()->dayCounter();

                Real s0 = process->stateVariable()->value();
                Volatility v = process->blackVolatility()->blackVol(
                        arguments_.exercise->lastDate(), s0);
                Date maturityDate = arguments_.exercise->lastDate();
                Rate riskFreeRate = process->riskFreeRate()->zeroRate(
                        maturityDate, rfdc, Continuous, NoFrequency);
                Rate q = process->dividendYield()->zeroRate(
                        maturityDate, divdc, Continuous, NoFrequency);
                Date referenceDate = process->riskFreeRate()->referenceDate();

                // subtract dividends
                Size i;
                for (i=0; i<arguments_.dividends.size(); i++) {
                        boost::shared_ptr<Dividend> testdiv =
boost::dynamic_pointer_cast<FixedDividend>(arguments_.dividends[i]);
                        // begin proposed change
                        if(testdiv){
                                if (arguments_.dividends[i]->date() >= referenceDate)
                                        s0 -= arguments_.dividends[i]->amount() *
                                        process->riskFreeRate()->discount(
                                        arguments_.dividends[i]->date());
                        } else {
                                if (arguments_.dividends[i]->date() >= referenceDate)
                                        s0 /= (1 + arguments_.dividends[i]->amount()) *
                                        process->riskFreeRate()->discount(
                                        arguments_.dividends[i]->date());
                        }
                        //end proposed change
                        //begin original code
                        /*
                        if (arguments_.dividends[i]->date() >= referenceDate)
                        s0 -= arguments_.dividends[i]->amount() *
                        process->riskFreeRate()->discount(
                        arguments_.dividends[i]->date());
                        */
                        //end original code
                }
                QL_REQUIRE(s0 > 0.0,
                        "negative value after subtracting dividends");

                // binomial trees with constant coefficient
                Handle<Quote> underlying(
                        boost::shared_ptr<Quote>(new SimpleQuote(s0)));
                Handle<YieldTermStructure> flatRiskFree(
                        boost::shared_ptr<YieldTermStructure>(
                        new FlatForward(referenceDate, riskFreeRate, rfdc)));
                Handle<YieldTermStructure> flatDividends(
                        boost::shared_ptr<YieldTermStructure>(
                        new FlatForward(referenceDate, q, divdc)));
                Handle<BlackVolTermStructure> flatVol(
                        boost::shared_ptr<BlackVolTermStructure>(
                        new BlackConstantVol(referenceDate, v, voldc)));

                boost::shared_ptr<PlainVanillaPayoff> payoff =
                        boost::dynamic_pointer_cast<PlainVanillaPayoff>(arguments_.payoff);
                QL_REQUIRE(payoff, "non-plain payoff given");

                Time maturity = rfdc.yearFraction(arguments_.settlementDate,
                        maturityDate);

                boost::shared_ptr<StochasticProcess1D> bs(
                        new GeneralizedBlackScholesProcess(underlying, flatDividends,
                        flatRiskFree, flatVol));
                boost::shared_ptr<T> tree(new T(bs, maturity, timeSteps_,
                        payoff->strike()));

                Real creditSpread = arguments_.creditSpread->value();

                boost::shared_ptr<NumericalMethod> lattice(
                        new TsiveriotisFernandesLattice<T>(tree,riskFreeRate,maturity,
                        timeSteps_,creditSpread,v,q));

                // adjust times to grid
                TimeGrid grid(maturity, timeSteps_);
                for (i=0; i<arguments_.couponTimes.size(); i++)
                        arguments_.couponTimes[i] =
                        grid.closestTime(arguments_.couponTimes[i]);
                for (i=0; i<arguments_.stoppingTimes.size(); i++)
                        arguments_.stoppingTimes[i] =
                        grid.closestTime(arguments_.stoppingTimes[i]);
                for (i=0; i<arguments_.callabilityTimes.size(); i++)
                        arguments_.callabilityTimes[i] =
                        grid.closestTime(arguments_.callabilityTimes[i]);
                for (i=0; i<arguments_.dividendTimes.size(); i++)
                        arguments_.dividendTimes[i] =
                        grid.closestTime(arguments_.dividendTimes[i]);

                DiscretizedConvertible convertible(arguments_);

                convertible.initialize(lattice, maturity);
                convertible.rollback(0.0);
                results_.value = convertible.presentValue();
        }


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
QuantLib-dev mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-dev