public DiscretizedCallableFixedRateBond(CallableBond.Arguments args,
                                                Date referenceDate,
                                                DayCounter dayCounter)
        {
            arguments_      = args;
            redemptionTime_ = dayCounter.yearFraction(referenceDate, args.redemptionDate);

            for (int i = 0; i < args.couponDates.Count; ++i)
            {
                couponTimes_.Add(dayCounter.yearFraction(referenceDate, args.couponDates[i]));
            }

            for (int i = 0; i < args.callabilityDates.Count; ++i)
            {
                callabilityTimes_.Add(dayCounter.yearFraction(referenceDate, args.callabilityDates[i]));
            }

            // similar to the tree swaption engine, we collapse similar coupon
            // and exercise dates to avoid mispricing. Delete if unnecessary.

            for (int i = 0; i < callabilityTimes_.Count; i++)
            {
                double exerciseTime = callabilityTimes_[i];
                for (int j = 0; j < couponTimes_.Count; j++)
                {
                    if (withinNextWeek(exerciseTime, couponTimes_[j]))
                    {
                        couponTimes_[j] = exerciseTime;
                    }
                }
            }
        }
Beispiel #2
0
        public override void setupArguments(IPricingEngineArguments args)
        {
            base.setupArguments(args);
            CallableBond.Arguments arguments = args as CallableBond.Arguments;

            Utils.QL_REQUIRE(arguments != null, () => "no arguments given");

            Date settlement = arguments.settlementDate;

            arguments.redemption     = redemption().amount();
            arguments.redemptionDate = redemption().date();

            List <CashFlow> cfs = cashflows();

            arguments.couponDates   = new List <Date>(cfs.Count - 1);
            arguments.couponAmounts = new List <double>(cfs.Count - 1);

            for (int i = 0; i < cfs.Count; i++)
            {
                if (!cfs[i].hasOccurred(settlement, false))
                {
                    if (cfs[i] is QLCore.FixedRateCoupon)
                    {
                        arguments.couponDates.Add(cfs[i].date());
                        arguments.couponAmounts.Add(cfs[i].amount());
                    }
                }
            }

            arguments.callabilityPrices = new List <double>(putCallSchedule_.Count);
            arguments.callabilityDates  = new List <Date>(putCallSchedule_.Count);
            arguments.paymentDayCounter = paymentDayCounter_;
            arguments.frequency         = frequency_;
            arguments.putCallSchedule   = putCallSchedule_;

            for (int i = 0; i < putCallSchedule_.Count; i++)
            {
                if (!putCallSchedule_[i].hasOccurred(settlement, false))
                {
                    arguments.callabilityDates.Add(putCallSchedule_[i].date());
                    arguments.callabilityPrices.Add(putCallSchedule_[i].price().amount());

                    if (putCallSchedule_[i].price().type() == Callability.Price.Type.Clean)
                    {
                        /* calling accrued() forces accrued interest to be zero
                         * if future option date is also coupon date, so that dirty
                         * price = clean price. Use here because callability is
                         * always applied before coupon in the tree engine.
                         */
                        arguments.callabilityPrices[arguments.callabilityPrices.Count - 1] += this.accrued(putCallSchedule_[i].date());
                    }
                }
            }
        }
Beispiel #3
0
            public double value(double x)
            {
                CallableBond.Arguments args = bond_.engine_.getArguments() as CallableBond.Arguments;
                // Pops the original value when function finishes
                double originalSpread = args.spread;

                args.spread = x;
                bond_.engine_.calculate();
                args.spread = originalSpread;
                return(results_.value.Value);
            }