Пример #1
0
        public void Add(string isin, string issueDate, string maturityDate, double coupon)
        {
            if (bonds.ContainsKey(isin))
            {
                return;
            }

            var schedule = new Schedule(new Date(issueDate, "dd/mm/yyyy"),
                                        new Date(maturityDate, "dd/mm/yyyy"),
                                        new Period(Frequency.Semiannual),
                                        new UnitedKingdom(UnitedKingdom.Market.Settlement),
                                        BusinessDayConvention.Unadjusted,
                                        BusinessDayConvention.Unadjusted,
                                        DateGeneration.Rule.Backward,
                                        false);

            var bond = new FixedRateBond(1,
                                         100.0,
                                         schedule,
                                         new DoubleVector(1)
            {
                coupon
            },
                                         new ActualActual(ActualActual.Convention.Bond),
                                         BusinessDayConvention.Unadjusted,
                                         100.0,
                                         new Date(issueDate, "dd/mm/yyyy"));

            bond.setPricingEngine(pricingEngine);

            bonds.Add(isin, bond);
        }
        public new FixedRateBond bond()
        {
            FixedRateBond ret = new FixedRateBond(NQuantLibcPINVOKE.FixedRateBondHelper_bond(swigCPtr), true);

            if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
            {
                throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
Пример #3
0
        public FixedRateBond fixedRateBond()
        {
            global::System.IntPtr cPtr = NQuantLibcPINVOKE.FixedRateBondHelper_fixedRateBond(swigCPtr);
            FixedRateBond         ret  = (cPtr == global::System.IntPtr.Zero) ? null : new FixedRateBond(cPtr, true);

            if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
            {
                throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
Пример #4
0
        public void testCurveConsistency <T, I, B>(CommonVars vars, I interpolator, double tolerance)
            where T : ITraits <YieldTermStructure>, new()
            where I : IInterpolationFactory, new()
            where B : IBootStrap <PiecewiseYieldCurve>, new()
        {
            vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.instruments,
                                                                   new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator);

            RelinkableHandle <YieldTermStructure> curveHandle = new RelinkableHandle <YieldTermStructure>();

            curveHandle.linkTo(vars.termStructure);

            // check deposits
            for (int i = 0; i < vars.deposits; i++)
            {
                Euribor index         = new Euribor(new Period(vars.depositData[i].n, vars.depositData[i].units), curveHandle);
                double  expectedRate  = vars.depositData[i].rate / 100,
                        estimatedRate = index.fixing(vars.today);
                QAssert.IsTrue(Math.Abs(expectedRate - estimatedRate) < tolerance,
                               vars.depositData[i].n + " "
                               + (vars.depositData[i].units == TimeUnit.Weeks ? "week(s)" : "month(s)")
                               + " deposit:"
                               + "\n    estimated rate: " + estimatedRate
                               + "\n    expected rate:  " + expectedRate);
            }

            // check swaps
            IborIndex euribor6m = new Euribor6M(curveHandle);

            for (int i = 0; i < vars.swaps; i++)
            {
                Period tenor = new Period(vars.swapData[i].n, vars.swapData[i].units);

                VanillaSwap swap = new MakeVanillaSwap(tenor, euribor6m, 0.0)
                                   .withEffectiveDate(vars.settlement)
                                   .withFixedLegDayCount(vars.fixedLegDayCounter)
                                   .withFixedLegTenor(new Period(vars.fixedLegFrequency))
                                   .withFixedLegConvention(vars.fixedLegConvention)
                                   .withFixedLegTerminationDateConvention(vars.fixedLegConvention);

                double expectedRate  = vars.swapData[i].rate / 100,
                       estimatedRate = swap.fairRate();
                double error         = Math.Abs(expectedRate - estimatedRate);
                QAssert.IsTrue(error < tolerance,
                               vars.swapData[i].n + " year(s) swap:\n"
                               + "\n estimated rate: " + estimatedRate
                               + "\n expected rate:  " + expectedRate
                               + "\n error:          " + error
                               + "\n tolerance:      " + tolerance);
            }

            // check bonds
            vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.bondHelpers,
                                                                   new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator);
            curveHandle.linkTo(vars.termStructure);

            for (int i = 0; i < vars.bonds; i++)
            {
                Date          maturity = vars.calendar.advance(vars.today, vars.bondData[i].n, vars.bondData[i].units);
                Date          issue    = vars.calendar.advance(maturity, -vars.bondData[i].length, TimeUnit.Years);
                List <double> coupons  = new List <double>()
                {
                    vars.bondData[i].coupon / 100.0
                };

                FixedRateBond bond = new FixedRateBond(vars.bondSettlementDays, 100.0,
                                                       vars.schedules[i], coupons,
                                                       vars.bondDayCounter, vars.bondConvention,
                                                       vars.bondRedemption, issue);

                IPricingEngine bondEngine = new DiscountingBondEngine(curveHandle);
                bond.setPricingEngine(bondEngine);

                double expectedPrice  = vars.bondData[i].price,
                       estimatedPrice = bond.cleanPrice();
                QAssert.IsTrue(Math.Abs(expectedPrice - estimatedPrice) < tolerance,
                               i + 1 + " bond failure:" +
                               "\n  estimated price: " + estimatedPrice +
                               "\n  expected price:  " + expectedPrice);
            }

            // check FRA
            vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.fraHelpers,
                                                                   new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator);
            curveHandle.linkTo(vars.termStructure);

            IborIndex euribor3m = new Euribor3M(curveHandle);

            for (int i = 0; i < vars.fras; i++)
            {
                Date start = vars.calendar.advance(vars.settlement,
                                                   vars.fraData[i].n,
                                                   vars.fraData[i].units,
                                                   euribor3m.businessDayConvention(),
                                                   euribor3m.endOfMonth());
                Date end = vars.calendar.advance(start, 3, TimeUnit.Months,
                                                 euribor3m.businessDayConvention(),
                                                 euribor3m.endOfMonth());

                ForwardRateAgreement fra = new ForwardRateAgreement(start, end, Position.Type.Long, vars.fraData[i].rate / 100,
                                                                    100.0, euribor3m, curveHandle);
                double expectedRate  = vars.fraData[i].rate / 100,
                       estimatedRate = fra.forwardRate().rate();
                QAssert.IsTrue(Math.Abs(expectedRate - estimatedRate) < tolerance,
                               i + 1 + " FRA failure:" +
                               "\n  estimated rate: " + estimatedRate +
                               "\n  expected rate:  " + expectedRate);
            }
        }
 public FixedRateBondForward(Date valueDate, Date maturityDate, Position.Type type, double strike, uint settlementDays, DayCounter dayCounter, Calendar calendar, BusinessDayConvention businessDayConvention, FixedRateBond fixedBond) : this(NQuantLibcPINVOKE.new_FixedRateBondForward__SWIG_2(Date.getCPtr(valueDate), Date.getCPtr(maturityDate), (int)type, strike, settlementDays, DayCounter.getCPtr(dayCounter), Calendar.getCPtr(calendar), (int)businessDayConvention, FixedRateBond.getCPtr(fixedBond)), true)
 {
     if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
     {
         throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
     }
 }
Пример #6
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(FixedRateBond obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }
Пример #7
0
        static void Main(string[] args)
        {
            double nominal = 575000000;

            Date _marketDate;
            Date _settlementDate;
            Dictionary <string, double> _depositRates;
            Dictionary <string, double> _swapRates;
            List <RateHelper>           _rateHelpers;
            Calendar _calendar   = new TARGET();
            int      _fixingDays = 2;

            _marketDate = new Date(new DateTime(2015, 12, 17));
            Settings.setEvaluationDate(_marketDate);

            _depositRates = new Dictionary <string, double>();
            _depositRates.Add("1M", 0.0045);
            _depositRates.Add("3M", 0.0070);
            _depositRates.Add("6M", 0.0090);

            _swapRates = new Dictionary <string, double>();
            _swapRates.Add("1Y", 0.0080);
            _swapRates.Add("2Y", 0.0109);
            _swapRates.Add("3Y", 0.0134);
            _swapRates.Add("4Y", 0.0153);
            _swapRates.Add("5Y", 0.0169);
            _swapRates.Add("7Y", 0.0193);
            _swapRates.Add("10Y", 0.0218);
            _swapRates.Add("30Y", 0.0262);

            _rateHelpers = new List <RateHelper>();
            foreach (var v in _depositRates)
            {
                SimpleQuote sq = new SimpleQuote(v.Value);
                _rateHelpers.Add(new DepositRateHelper(new Handle <Quote>(sq), new Period(v.Key),
                                                       _fixingDays, _calendar, BusinessDayConvention.ModifiedFollowing, true, new Actual360()));
            }
            foreach (var v in _swapRates)
            {
                SimpleQuote sq = new SimpleQuote(v.Value);
                _rateHelpers.Add(new SwapRateHelper(new Handle <Quote>(sq), new Period(v.Key),
                                                    _calendar, Frequency.Semiannual, BusinessDayConvention.Unadjusted,
                                                    new Thirty360(Thirty360.Thirty360Convention.USA), new Euribor3M()));
            }

            _marketDate     = _calendar.adjust(_marketDate);
            _settlementDate = _calendar.advance(_marketDate, _fixingDays, TimeUnit.Days);

            YieldTermStructure yieldTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>(
                _settlementDate, _rateHelpers, new ActualActual(ActualActual.Convention.ISDA));

            RelinkableHandle <YieldTermStructure> yieldTermStructureHandle = new RelinkableHandle <YieldTermStructure>();


            Frequency             fixedLegFrequency  = Frequency.Semiannual;
            BusinessDayConvention fixedLegConvention = BusinessDayConvention.ModifiedFollowing;
            DayCounter            fixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.USA);
            double fixedRate = 0.0144;

            Frequency             floatLegFrequency  = Frequency.Quarterly;
            BusinessDayConvention floatLegConvention = BusinessDayConvention.ModifiedFollowing;
            DayCounter            floatLegDayCounter = new Actual360();
            IborIndex             iborIndex          = new Euribor3M(yieldTermStructureHandle);

            iborIndex.addFixing(new Date(18, Month.Aug, 2015), 0.0033285);
            iborIndex.addFixing(new Date(18, Month.Nov, 2015), 0.0036960);
            double floatSpread = 0.0;

            VanillaSwap.Type swapType = VanillaSwap.Type.Receiver;

            Date     maturity      = new Date(20, Month.Nov, 2018);
            Date     effective     = new Date(20, Month.Nov, 2013);
            Schedule fixedSchedule = new Schedule(effective, maturity, new Period(fixedLegFrequency), _calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false);
            Schedule floatSchedule = new Schedule(effective, maturity, new Period(floatLegFrequency), _calendar, floatLegConvention, floatLegConvention, DateGeneration.Rule.Forward, false);

            VanillaSwap vanillaSwap = new VanillaSwap(swapType, nominal, fixedSchedule, fixedRate, fixedLegDayCounter, floatSchedule, iborIndex, floatSpread, floatLegDayCounter);

            InterestRate        interestRate = new InterestRate(fixedRate, fixedLegDayCounter, Compounding.Simple, fixedLegFrequency);
            List <InterestRate> coupons      = new List <InterestRate>();

            for (int i = 0; i < fixedSchedule.Count; i++)
            {
                coupons.Add(interestRate);
            }
            FixedRateBond    fixedBond = new FixedRateBond(_fixingDays, nominal, fixedSchedule, coupons, BusinessDayConvention.ModifiedFollowing);
            FloatingRateBond floatBond = new FloatingRateBond(_fixingDays, nominal, floatSchedule, iborIndex, floatLegDayCounter);

            IPricingEngine bondPricingEngine = new DiscountingBondEngine(yieldTermStructureHandle);

            fixedBond.setPricingEngine(bondPricingEngine);
            floatBond.setPricingEngine(bondPricingEngine);

            IPricingEngine swapPricingEngine = new DiscountingSwapEngine(yieldTermStructureHandle);

            vanillaSwap.setPricingEngine(swapPricingEngine);

            yieldTermStructureHandle.linkTo(yieldTermStructure);

            double swapNPV      = vanillaSwap.NPV();
            double swapFixedNPV = vanillaSwap.fixedLegNPV();
            double swapFloatNPV = vanillaSwap.floatingLegNPV();

            double bondFixedNPV = fixedBond.NPV();
            double bondFloatNPV = floatBond.NPV();

            int    w = (swapType == VanillaSwap.Type.Receiver ? 1 : -1);
            double asBondsMarketValue      = w * (bondFixedNPV - bondFloatNPV);
            double asBondsMarketValueNoAcc = w * (fixedBond.cleanPrice() - floatBond.cleanPrice()) / 100.0 * nominal;
            double asBondsAccruedInterest  = asBondsMarketValue - asBondsMarketValueNoAcc;

            Console.WriteLine("Vanilla Swap Maket Value      : {0:N}", swapNPV);
            Console.WriteLine("As Bonds Market Value         : {0:N}", asBondsMarketValue);
            Console.WriteLine("As Bonds Market Value (no acc): {0:N}", asBondsMarketValueNoAcc);
            Console.WriteLine("As Bonds Accrued Interest     : {0:N}", asBondsAccruedInterest);

            Date   rollDate      = new Date(1, Month.Nov, 2015);
            double bondFixedCash = 0;

            foreach (CashFlow cf in fixedBond.cashflows())
            {
                if (cf.date() > rollDate & cf.date() <= _marketDate)
                {
                    bondFixedCash += cf.amount();
                }
            }
            double bondFloatCash = 0;

            foreach (CashFlow cf in floatBond.cashflows())
            {
                if (cf.date() > rollDate & cf.date() <= _marketDate)
                {
                    bondFloatCash += cf.amount();
                }
            }
            double asBondsCash = w * (bondFixedCash - bondFloatCash);

            Console.WriteLine("As Bonds Settled Cash         : {0:N}", asBondsCash);
        }
Пример #8
0
        public void testBrazilianCached()
        {
            //("Testing Brazilian public bond prices against cached values...");

            CommonVars vars = new CommonVars();

            double faceAmount = 1000.0;
            double redemption = 100.0;
            Date   issueDate  = new Date(1, Month.January, 2007);

            Date today = new Date(6, Month.June, 2007);

            Settings.setEvaluationDate(today);

            // NTN-F maturity dates
            InitializedList <Date> maturityDates = new InitializedList <Date>(6);

            maturityDates[0] = new Date(1, Month.January, 2008);
            maturityDates[1] = new Date(1, Month.January, 2010);
            maturityDates[2] = new Date(1, Month.July, 2010);
            maturityDates[3] = new Date(1, Month.January, 2012);
            maturityDates[4] = new Date(1, Month.January, 2014);
            maturityDates[5] = new Date(1, Month.January, 2017);

            // NTN-F yields
            InitializedList <double> yields = new InitializedList <double>(6);

            yields[0] = 0.114614;
            yields[1] = 0.105726;
            yields[2] = 0.105328;
            yields[3] = 0.104283;
            yields[4] = 0.103218;
            yields[5] = 0.102948;

            // NTN-F prices
            InitializedList <double> prices = new InitializedList <double>(6);

            prices[0] = 1034.63031372;
            prices[1] = 1030.09919487;
            prices[2] = 1029.98307160;
            prices[3] = 1028.13585068;
            prices[4] = 1028.33383817;
            prices[5] = 1026.19716497;

            int settlementDays = 1;

            vars.faceAmount = 1000.0;

            // The tolerance is high because Andima truncate yields
            double tolerance = 1.0e-4;

            InitializedList <InterestRate> couponRates = new InitializedList <InterestRate>(1);

            couponRates[0] = new InterestRate(0.1, new Thirty360(), Compounding.Compounded, Frequency.Annual);

            for (int bondIndex = 0; bondIndex < maturityDates.Count; bondIndex++)
            {
                // plain
                InterestRate yield = new InterestRate(yields[bondIndex], new Business252(new Brazil()),
                                                      Compounding.Compounded, Frequency.Annual);

                Schedule schedule = new Schedule(new Date(1, Month.January, 2007),
                                                 maturityDates[bondIndex], new Period(Frequency.Semiannual),
                                                 new Brazil(Brazil.Market.Settlement),
                                                 BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                                 DateGeneration.Rule.Backward, false);


                FixedRateBond bond = new FixedRateBond(settlementDays,
                                                       faceAmount,
                                                       schedule,
                                                       couponRates,
                                                       BusinessDayConvention.Following,
                                                       redemption,
                                                       issueDate);

                double cachedPrice = prices[bondIndex];

                double price = vars.faceAmount * (bond.cleanPrice(yield.rate(),
                                                                  yield.dayCounter(),
                                                                  yield.compounding(),
                                                                  yield.frequency(),
                                                                  today) + bond.accruedAmount(today)) / 100;
                if (Math.Abs(price - cachedPrice) > tolerance)
                {
                    Assert.Fail("failed to reproduce cached price:\n"
                                + "    calculated: " + price + "\n"
                                + "    expected:   " + cachedPrice + "\n"
                                + "    error:      " + (price - cachedPrice) + "\n"
                                );
                }
            }
        }
Пример #9
0
        public void testCachedFixed()
        {
            // "Testing fixed-coupon bond prices against cached values...");

            CommonVars vars = new CommonVars();

            Date today = new Date(22, Month.November, 2004);

            Settings.setEvaluationDate(today);

            int settlementDays = 1;

            var discountCurve = new Handle <YieldTermStructure>(Utilities.flatRate(today, 0.03, new Actual360()));

            double tolerance = 1.0e-6;

            // plain
            Schedule sch = new Schedule(new Date(30, Month.November, 2004),
                                        new Date(30, Month.November, 2008), new Period(Frequency.Semiannual),
                                        new UnitedStates(UnitedStates.Market.GovernmentBond),
                                        BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false);

            FixedRateBond bond1 = new FixedRateBond(settlementDays, vars.faceAmount, sch, new List <double>()
            {
                0.02875
            },
                                                    new ActualActual(ActualActual.Convention.ISMA), BusinessDayConvention.ModifiedFollowing,
                                                    100.0, new Date(30, Month.November, 2004));

            IPricingEngine bondEngine = new DiscountingBondEngine(discountCurve);

            bond1.setPricingEngine(bondEngine);

            double cachedPrice1 = 99.298100;

            double price = bond1.cleanPrice();

            if (Math.Abs(price - cachedPrice1) > tolerance)
            {
                Console.WriteLine("failed to reproduce cached price:\n"
                                  + "    calculated: " + price + "\n"
                                  + "    expected:   " + cachedPrice1 + "\n"
                                  + "    error:      " + (price - cachedPrice1));
            }

            // varying coupons
            InitializedList <double> couponRates = new InitializedList <double>(4);

            couponRates[0] = 0.02875;
            couponRates[1] = 0.03;
            couponRates[2] = 0.03125;
            couponRates[3] = 0.0325;

            FixedRateBond bond2 = new FixedRateBond(settlementDays, vars.faceAmount, sch, couponRates,
                                                    new ActualActual(ActualActual.Convention.ISMA),
                                                    BusinessDayConvention.ModifiedFollowing,
                                                    100.0, new Date(30, Month.November, 2004));

            bond2.setPricingEngine(bondEngine);

            double cachedPrice2 = 100.334149;

            price = bond2.cleanPrice();
            if (Math.Abs(price - cachedPrice2) > tolerance)
            {
                Console.WriteLine("failed to reproduce cached price:\n"
                                  + "    calculated: " + price + "\n"
                                  + "    expected:   " + cachedPrice2 + "\n"
                                  + "    error:      " + (price - cachedPrice2));
            }

            // stub date
            Schedule sch3 = new Schedule(new Date(30, Month.November, 2004),
                                         new Date(30, Month.March, 2009), new Period(Frequency.Semiannual),
                                         new UnitedStates(UnitedStates.Market.GovernmentBond),
                                         BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false,
                                         null, new Date(30, Month.November, 2008));

            FixedRateBond bond3 = new FixedRateBond(settlementDays, vars.faceAmount, sch3,
                                                    couponRates, new ActualActual(ActualActual.Convention.ISMA),
                                                    BusinessDayConvention.ModifiedFollowing,
                                                    100.0, new Date(30, Month.November, 2004));

            bond3.setPricingEngine(bondEngine);

            double cachedPrice3 = 100.382794;

            price = bond3.cleanPrice();
            if (Math.Abs(price - cachedPrice3) > tolerance)
            {
                Assert.Fail("failed to reproduce cached price:\n"
                            + "    calculated: " + price + "\n"
                            + "    expected:   " + cachedPrice3 + "\n"
                            + "    error:      " + (price - cachedPrice3));
            }
        }
Пример #10
0
        public void testYield()
        {
            //"Testing consistency of bond price/yield calculation...");

            CommonVars vars = new CommonVars();

            double tolerance      = 1.0e-7;
            int    maxEvaluations = 100;

            int[] issueMonths    = new int[] { -24, -18, -12, -6, 0, 6, 12, 18, 24 };
            int[] lengths        = new int[] { 3, 5, 10, 15, 20 };
            int   settlementDays = 3;

            double[]              coupons           = new double[] { 0.02, 0.05, 0.08 };
            Frequency[]           frequencies       = new Frequency[] { Frequency.Semiannual, Frequency.Annual };
            DayCounter            bondDayCount      = new Thirty360();
            BusinessDayConvention accrualConvention = BusinessDayConvention.Unadjusted;
            BusinessDayConvention paymentConvention = BusinessDayConvention.ModifiedFollowing;
            double redemption = 100.0;

            double[]      yields      = new double[] { 0.03, 0.04, 0.05, 0.06, 0.07 };
            Compounding[] compounding = new Compounding[] { Compounding.Compounded, Compounding.Continuous };

            for (int i = 0; i < issueMonths.Length; i++)
            {
                for (int j = 0; j < lengths.Length; j++)
                {
                    for (int k = 0; k < coupons.Length; k++)
                    {
                        for (int l = 0; l < frequencies.Length; l++)
                        {
                            for (int n = 0; n < compounding.Length; n++)
                            {
                                Date dated    = vars.calendar.advance(vars.today, issueMonths[i], TimeUnit.Months);
                                Date issue    = dated;
                                Date maturity = vars.calendar.advance(issue, lengths[j], TimeUnit.Years);

                                Schedule sch = new Schedule(dated, maturity, new Period(frequencies[l]), vars.calendar,
                                                            accrualConvention, accrualConvention, DateGeneration.Rule.Backward, false);

                                FixedRateBond bond = new FixedRateBond(settlementDays, vars.faceAmount, sch,
                                                                       new List <double>()
                                {
                                    coupons[k]
                                },
                                                                       bondDayCount, paymentConvention,
                                                                       redemption, issue);

                                for (int m = 0; m < yields.Length; m++)
                                {
                                    double price      = bond.cleanPrice(yields[m], bondDayCount, compounding[n], frequencies[l]);
                                    double calculated = bond.yield(price, bondDayCount, compounding[n], frequencies[l], null,
                                                                   tolerance, maxEvaluations);

                                    if (Math.Abs(yields[m] - calculated) > tolerance)
                                    {
                                        // the difference might not matter
                                        double price2 = bond.cleanPrice(calculated, bondDayCount, compounding[n], frequencies[l]);
                                        if (Math.Abs(price - price2) / price > tolerance)
                                        {
                                            Assert.Fail("yield recalculation failed:\n"
                                                        + "    issue:     " + issue + "\n"
                                                        + "    maturity:  " + maturity + "\n"
                                                        + "    coupon:    " + coupons[k] + "\n"
                                                        + "    frequency: " + frequencies[l] + "\n\n"
                                                        + "    yield:  " + yields[m] + " "
                                                        + (compounding[n] == Compounding.Compounded ? "compounded" : "continuous") + "\n"
                                                        + "    price:  " + price + "\n"
                                                        + "    yield': " + calculated + "\n"
                                                        + "    price': " + price2);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #11
0
        public void testCached()
        {
            // ("Testing bond price/yield calculation against cached values...");

            CommonVars vars = new CommonVars();

            // with implicit settlement calculation:
            Date today = new Date(22, Month.November, 2004);

            Settings.setEvaluationDate(today);

            Calendar   bondCalendar   = new NullCalendar();
            DayCounter bondDayCount   = new ActualActual(ActualActual.Convention.ISMA);
            int        settlementDays = 1;

            var discountCurve = new Handle <YieldTermStructure>(Utilities.flatRate(today, new SimpleQuote(0.03), new Actual360()));

            // actual market values from the evaluation date
            Frequency freq = Frequency.Semiannual;
            Schedule  sch1 = new Schedule(new Date(31, Month.October, 2004), new Date(31, Month.October, 2006), new Period(freq),
                                          bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                          DateGeneration.Rule.Backward, false);

            FixedRateBond bond1 = new FixedRateBond(settlementDays, vars.faceAmount, sch1, new List <double>()
            {
                0.025
            },
                                                    bondDayCount, BusinessDayConvention.ModifiedFollowing, 100.0, new Date(1, Month.November, 2004));

            IPricingEngine bondEngine = new DiscountingBondEngine(discountCurve);

            bond1.setPricingEngine(bondEngine);

            double marketPrice1 = 99.203125;
            double marketYield1 = 0.02925;

            Schedule sch2 = new Schedule(new Date(15, Month.November, 2004), new Date(15, Month.November, 2009), new Period(freq),
                                         bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                         DateGeneration.Rule.Backward, false);

            FixedRateBond bond2 = new FixedRateBond(settlementDays, vars.faceAmount, sch2, new List <double>()
            {
                0.035
            },
                                                    bondDayCount, BusinessDayConvention.ModifiedFollowing,
                                                    100.0, new Date(15, Month.November, 2004));

            bond2.setPricingEngine(bondEngine);

            double marketPrice2 = 99.6875;
            double marketYield2 = 0.03569;

            // calculated values
            double cachedPrice1a = 99.204505, cachedPrice2a = 99.687192;
            double cachedPrice1b = 98.943393, cachedPrice2b = 101.986794;
            double cachedYield1a = 0.029257, cachedYield2a = 0.035689;
            double cachedYield1b = 0.029045, cachedYield2b = 0.035375;
            double cachedYield1c = 0.030423, cachedYield2c = 0.030432;

            // check
            double tolerance = 1.0e-6;
            double price, yield;

            price = bond1.cleanPrice(marketYield1, bondDayCount, Compounding.Compounded, freq);
            if (Math.Abs(price - cachedPrice1a) > tolerance)
            {
                Assert.Fail("failed to reproduce cached price:"
                            + "\n    calculated: " + price
                            + "\n    expected:   " + cachedPrice1a
                            + "\n    tolerance:  " + tolerance
                            + "\n    error:      " + (price - cachedPrice1a));
            }

            price = bond1.cleanPrice();
            if (Math.Abs(price - cachedPrice1b) > tolerance)
            {
                Assert.Fail("failed to reproduce cached price:"
                            + "\n    calculated: " + price
                            + "\n    expected:   " + cachedPrice1b
                            + "\n    tolerance:  " + tolerance
                            + "\n    error:      " + (price - cachedPrice1b));
            }

            yield = bond1.yield(marketPrice1, bondDayCount, Compounding.Compounded, freq);
            if (Math.Abs(yield - cachedYield1a) > tolerance)
            {
                Assert.Fail("failed to reproduce cached compounded yield:"
                            + "\n    calculated: " + yield
                            + "\n    expected:   " + cachedYield1a
                            + "\n    tolerance:  " + tolerance
                            + "\n    error:      " + (yield - cachedYield1a));
            }

            yield = bond1.yield(marketPrice1, bondDayCount, Compounding.Continuous, freq);
            if (Math.Abs(yield - cachedYield1b) > tolerance)
            {
                Assert.Fail("failed to reproduce cached continuous yield:"
                            + "\n    calculated: " + yield
                            + "\n    expected:   " + cachedYield1b
                            + "\n    tolerance:  " + tolerance
                            + "\n    error:      " + (yield - cachedYield1b));
            }

            yield = bond1.yield(bondDayCount, Compounding.Continuous, freq);
            if (Math.Abs(yield - cachedYield1c) > tolerance)
            {
                Assert.Fail("failed to reproduce cached continuous yield:"
                            + "\n    calculated: " + yield
                            + "\n    expected:   " + cachedYield1c
                            + "\n    tolerance:  " + tolerance
                            + "\n    error:      " + (yield - cachedYield1c));
            }


            price = bond2.cleanPrice(marketYield2, bondDayCount, Compounding.Compounded, freq);
            if (Math.Abs(price - cachedPrice2a) > tolerance)
            {
                Assert.Fail("failed to reproduce cached price:"
                            + "\n    calculated: " + price
                            + "\n    expected:   " + cachedPrice2a
                            + "\n    tolerance:  " + tolerance
                            + "\n    error:      " + (price - cachedPrice2a));
            }

            price = bond2.cleanPrice();
            if (Math.Abs(price - cachedPrice2b) > tolerance)
            {
                Assert.Fail("failed to reproduce cached price:"
                            + "\n    calculated: " + price
                            + "\n    expected:   " + cachedPrice2b
                            + "\n    tolerance:  " + tolerance
                            + "\n    error:      " + (price - cachedPrice2b));
            }

            yield = bond2.yield(marketPrice2, bondDayCount, Compounding.Compounded, freq);
            if (Math.Abs(yield - cachedYield2a) > tolerance)
            {
                Assert.Fail("failed to reproduce cached compounded yield:"
                            + "\n    calculated: " + yield
                            + "\n    expected:   " + cachedYield2a
                            + "\n    tolerance:  " + tolerance
                            + "\n    error:      " + (yield - cachedYield2a));
            }

            yield = bond2.yield(marketPrice2, bondDayCount, Compounding.Continuous, freq);
            if (Math.Abs(yield - cachedYield2b) > tolerance)
            {
                Assert.Fail("failed to reproduce cached continuous yield:"
                            + "\n    calculated: " + yield
                            + "\n    expected:   " + cachedYield2b
                            + "\n    tolerance:  " + tolerance
                            + "\n    error:      " + (yield - cachedYield2b));
            }

            yield = bond2.yield(bondDayCount, Compounding.Continuous, freq);
            if (Math.Abs(yield - cachedYield2c) > tolerance)
            {
                Assert.Fail("failed to reproduce cached continuous yield:"
                            + "\n    calculated: " + yield
                            + "\n    expected:   " + cachedYield2c
                            + "\n    tolerance:  " + tolerance
                            + "\n    error:      " + (yield - cachedYield2c));
            }

            // with explicit settlement date:
            Schedule sch3 = new Schedule(new Date(30, Month.November, 2004), new Date(30, Month.November, 2006), new Period(freq),
                                         new UnitedStates(UnitedStates.Market.GovernmentBond), BusinessDayConvention.Unadjusted,
                                         BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false);

            FixedRateBond bond3 = new FixedRateBond(settlementDays, vars.faceAmount, sch3, new List <double>()
            {
                0.02875
            },
                                                    new ActualActual(ActualActual.Convention.ISMA),
                                                    BusinessDayConvention.ModifiedFollowing, 100.0, new Date(30, Month.November, 2004));

            bond3.setPricingEngine(bondEngine);

            double marketYield3 = 0.02997;

            Date   settlementDate = new Date(30, Month.November, 2004);
            double cachedPrice3   = 99.764874;

            price = bond3.cleanPrice(marketYield3, bondDayCount, Compounding.Compounded, freq, settlementDate);
            if (Math.Abs(price - cachedPrice3) > tolerance)
            {
                Assert.Fail("failed to reproduce cached price:"
                            + "\n    calculated: " + price + ""
                            + "\n    expected:   " + cachedPrice3 + ""
                            + "\n    error:      " + (price - cachedPrice3));
            }

            // this should give the same result since the issue date is the
            // earliest possible settlement date
            Settings.setEvaluationDate(new Date(22, Month.November, 2004));

            price = bond3.cleanPrice(marketYield3, bondDayCount, Compounding.Compounded, freq);
            if (Math.Abs(price - cachedPrice3) > tolerance)
            {
                Assert.Fail("failed to reproduce cached price:"
                            + "\n    calculated: " + price + ""
                            + "\n    expected:   " + cachedPrice3 + ""
                            + "\n    error:      " + (price - cachedPrice3));
            }
        }
Пример #12
0
        public void testTheoretical()
        {
            // "Testing theoretical bond price/yield calculation...");

            CommonVars vars = new CommonVars();

            double tolerance      = 1.0e-7;
            int    maxEvaluations = 100;

            int[] lengths        = new int[] { 3, 5, 10, 15, 20 };
            int   settlementDays = 3;

            double[]              coupons           = new double[] { 0.02, 0.05, 0.08 };
            Frequency[]           frequencies       = new Frequency[] { Frequency.Semiannual, Frequency.Annual };
            DayCounter            bondDayCount      = new Actual360();
            BusinessDayConvention accrualConvention = BusinessDayConvention.Unadjusted;
            BusinessDayConvention paymentConvention = BusinessDayConvention.ModifiedFollowing;
            double redemption = 100.0;

            double[] yields = new double[] { 0.03, 0.04, 0.05, 0.06, 0.07 };

            for (int j = 0; j < lengths.Length; j++)
            {
                for (int k = 0; k < coupons.Length; k++)
                {
                    for (int l = 0; l < frequencies.Length; l++)
                    {
                        Date dated    = vars.today;
                        Date issue    = dated;
                        Date maturity = vars.calendar.advance(issue, lengths[j], TimeUnit.Years);

                        SimpleQuote rate          = new SimpleQuote(0.0);
                        var         discountCurve = new Handle <YieldTermStructure>(Utilities.flatRate(vars.today, rate, bondDayCount));

                        Schedule sch = new Schedule(dated, maturity, new Period(frequencies[l]), vars.calendar,
                                                    accrualConvention, accrualConvention, DateGeneration.Rule.Backward, false);

                        FixedRateBond bond = new FixedRateBond(settlementDays, vars.faceAmount, sch, new List <double>()
                        {
                            coupons[k]
                        },
                                                               bondDayCount, paymentConvention, redemption, issue);

                        IPricingEngine bondEngine = new DiscountingBondEngine(discountCurve);
                        bond.setPricingEngine(bondEngine);

                        for (int m = 0; m < yields.Length; m++)
                        {
                            rate.setValue(yields[m]);

                            double price           = bond.cleanPrice(yields[m], bondDayCount, Compounding.Continuous, frequencies[l]);
                            double calculatedPrice = bond.cleanPrice();

                            if (Math.Abs(price - calculatedPrice) > tolerance)
                            {
                                Assert.Fail("price calculation failed:"
                                            + "\n    issue:     " + issue
                                            + "\n    maturity:  " + maturity
                                            + "\n    coupon:    " + coupons[k]
                                            + "\n    frequency: " + frequencies[l] + "\n"
                                            + "\n    yield:     " + yields[m]
                                            + "\n    expected:    " + price
                                            + "\n    calculated': " + calculatedPrice
                                            + "\n    error':      " + (price - calculatedPrice));
                            }

                            double calculatedYield = bond.yield(bondDayCount, Compounding.Continuous, frequencies[l],
                                                                tolerance, maxEvaluations);
                            if (Math.Abs(yields[m] - calculatedYield) > tolerance)
                            {
                                Assert.Fail("yield calculation failed:"
                                            + "\n    issue:     " + issue
                                            + "\n    maturity:  " + maturity
                                            + "\n    coupon:    " + coupons[k]
                                            + "\n    frequency: " + frequencies[l] + "\n"
                                            + "\n    yield:  " + yields[m]
                                            + "\n    price:  " + price
                                            + "\n    yield': " + calculatedYield);
                            }
                        }
                    }
                }
            }
        }
Пример #13
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Tests yield. </summary>
        ///
        /// <param name="ms">   The milliseconds. </param>
        ///
        /// <returns>   True if the test passes, false if the test fails. </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        public bool testYield(QuantMicroService ms)
        {
            //"Testing consistency of bond price/yield calculation...");

            CommonVars vars = new CommonVars();

            double tolerance      = 1.0e-7;
            int    maxEvaluations = 100;

            int[] issueMonths    = new int[] { -24, -18, -12, -6, 0, 6, 12, 18, 24 };
            int[] lengths        = new int[] { 3, 5, 10, 15, 20 };
            int   settlementDays = 3;

            double[]              coupons           = new double[] { 0.02, 0.05, 0.08 };
            Frequency[]           frequencies       = new Frequency[] { Frequency.Semiannual, Frequency.Annual };
            DayCounter            bondDayCount      = new Thirty360();
            BusinessDayConvention accrualConvention = BusinessDayConvention.Unadjusted;
            BusinessDayConvention paymentConvention = BusinessDayConvention.ModifiedFollowing;
            double redemption = 100.0;

            double[]      yields      = new double[] { 0.03, 0.04, 0.05, 0.06, 0.07 };
            Compounding[] compounding = new Compounding[] { Compounding.Compounded, Compounding.Continuous };

            foreach (var t in issueMonths)
            {
                foreach (var t1 in lengths)
                {
                    foreach (var t2 in coupons)
                    {
                        foreach (var t3 in frequencies)
                        {
                            foreach (var t4 in compounding)
                            {
                                Date dated    = vars.calendar.advance(vars.today, t, TimeUnit.Months);
                                Date issue    = dated;
                                Date maturity = vars.calendar.advance(issue, t1, TimeUnit.Years);

                                Schedule sch = new Schedule(dated, maturity, new Period(t3), vars.calendar,
                                                            accrualConvention, accrualConvention, DateGeneration.Rule.Backward, false);

                                FixedRateBond bond = new FixedRateBond(settlementDays, vars.faceAmount, sch,
                                                                       new List <double>()
                                {
                                    t2
                                }, bondDayCount, paymentConvention, redemption, issue);

                                foreach (var t5 in yields)
                                {
                                    double price      = bond.cleanPrice(t5, bondDayCount, t4, t3);
                                    double calculated = bond.yield(price, bondDayCount, t4, t3, null,
                                                                   tolerance, maxEvaluations);

                                    double price2          = bond.cleanPrice(calculated, bondDayCount, t4, t3);
                                    BondsResponseMessage r = new BondsResponseMessage();
                                    r.message = (Math.Abs(price - price2) / price > tolerance) ?
                                                "yield recalculation failed:" : "";
                                    r.issue       = issue;
                                    r.maturity    = maturity;
                                    r.coupon      = t2;
                                    r.frequency   = (int)t3;
                                    r.yield       = t5;
                                    r.compounding = (t4 == Compounding.Compounded
                                        ? "compounded" : "continuous");
                                    r.price     = price;
                                    r.price2    = price2;
                                    r.calcYield = calculated;

                                    ms.PublishBondResponseMessage(r, "BondResponse");

                                    if (Math.Abs(t5 - calculated) > tolerance)
                                    {
                                        return(Math.Abs(price - price2) / price > tolerance);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(true);
        }
Пример #14
0
        public void testBond()
        {
            /* when deeply out-of-the-money, the value of the convertible bond
             * should equal that of the underlying plain-vanilla bond. */

            // Testing out-of-the-money convertible bonds against vanilla bonds

            CommonVars vars = new CommonVars();

            vars.conversionRatio = 1.0e-16;

            Exercise euExercise = new EuropeanExercise(vars.maturityDate);
            Exercise amExercise = new AmericanExercise(vars.issueDate, vars.maturityDate);

            int            timeSteps = 1001;
            IPricingEngine engine    = new BinomialConvertibleEngine <CoxRossRubinstein>(vars.process, timeSteps);

            Handle <YieldTermStructure> discountCurve = new Handle <YieldTermStructure>(new ForwardSpreadedTermStructure(vars.riskFreeRate, vars.creditSpread));

            // zero-coupon

            Schedule schedule = new MakeSchedule().from(vars.issueDate)
                                .to(vars.maturityDate)
                                .withFrequency(Frequency.Once)
                                .withCalendar(vars.calendar)
                                .backwards().value();

            ConvertibleZeroCouponBond euZero = new ConvertibleZeroCouponBond(euExercise, vars.conversionRatio,
                                                                             vars.no_dividends, vars.no_callability,
                                                                             vars.creditSpread,
                                                                             vars.issueDate, vars.settlementDays,
                                                                             vars.dayCounter, schedule,
                                                                             vars.redemption);

            euZero.setPricingEngine(engine);

            ConvertibleZeroCouponBond amZero = new ConvertibleZeroCouponBond(amExercise, vars.conversionRatio,
                                                                             vars.no_dividends, vars.no_callability,
                                                                             vars.creditSpread,
                                                                             vars.issueDate, vars.settlementDays,
                                                                             vars.dayCounter, schedule,
                                                                             vars.redemption);

            amZero.setPricingEngine(engine);

            ZeroCouponBond zero = new ZeroCouponBond(vars.settlementDays, vars.calendar,
                                                     100.0, vars.maturityDate,
                                                     BusinessDayConvention.Following, vars.redemption, vars.issueDate);

            IPricingEngine bondEngine = new DiscountingBondEngine(discountCurve);

            zero.setPricingEngine(bondEngine);

            double tolerance = 1.0e-2 * (vars.faceAmount / 100.0);

            double error = Math.Abs(euZero.NPV() - zero.settlementValue());

            if (error > tolerance)
            {
                QAssert.Fail("failed to reproduce zero-coupon bond price:"
                             + "\n    calculated: " + euZero.NPV()
                             + "\n    expected:   " + zero.settlementValue()
                             + "\n    error:      " + error);
            }

            error = Math.Abs(amZero.NPV() - zero.settlementValue());
            if (error > tolerance)
            {
                QAssert.Fail("failed to reproduce zero-coupon bond price:"
                             + "\n    calculated: " + amZero.NPV()
                             + "\n    expected:   " + zero.settlementValue()
                             + "\n    error:      " + error);
            }

            // coupon

            List <double> coupons = new InitializedList <double>(1, 0.05);

            schedule = new MakeSchedule().from(vars.issueDate)
                       .to(vars.maturityDate)
                       .withFrequency(vars.frequency)
                       .withCalendar(vars.calendar)
                       .backwards().value();

            ConvertibleFixedCouponBond euFixed = new ConvertibleFixedCouponBond(euExercise, vars.conversionRatio,
                                                                                vars.no_dividends, vars.no_callability,
                                                                                vars.creditSpread,
                                                                                vars.issueDate, vars.settlementDays,
                                                                                coupons, vars.dayCounter,
                                                                                schedule, vars.redemption);

            euFixed.setPricingEngine(engine);

            ConvertibleFixedCouponBond amFixed = new ConvertibleFixedCouponBond(amExercise, vars.conversionRatio,
                                                                                vars.no_dividends, vars.no_callability,
                                                                                vars.creditSpread,
                                                                                vars.issueDate, vars.settlementDays,
                                                                                coupons, vars.dayCounter,
                                                                                schedule, vars.redemption);

            amFixed.setPricingEngine(engine);

            FixedRateBond fixedBond = new FixedRateBond(vars.settlementDays, vars.faceAmount, schedule,
                                                        coupons, vars.dayCounter, BusinessDayConvention.Following,
                                                        vars.redemption, vars.issueDate);

            fixedBond.setPricingEngine(bondEngine);

            tolerance = 2.0e-2 * (vars.faceAmount / 100.0);

            error = Math.Abs(euFixed.NPV() - fixedBond.settlementValue());
            if (error > tolerance)
            {
                QAssert.Fail("failed to reproduce fixed-coupon bond price:"
                             + "\n    calculated: " + euFixed.NPV()
                             + "\n    expected:   " + fixedBond.settlementValue()
                             + "\n    error:      " + error);
            }

            error = Math.Abs(amFixed.NPV() - fixedBond.settlementValue());
            if (error > tolerance)
            {
                QAssert.Fail("failed to reproduce fixed-coupon bond price:"
                             + "\n    calculated: " + amFixed.NPV()
                             + "\n    expected:   " + fixedBond.settlementValue()
                             + "\n    error:      " + error);
            }

            // floating-rate

            IborIndex     index      = new Euribor1Y(discountCurve);
            int           fixingDays = 2;
            List <double> gearings   = new InitializedList <double>(1, 1.0);
            List <double> spreads    = new List <double>();

            ConvertibleFloatingRateBond euFloating = new ConvertibleFloatingRateBond(euExercise, vars.conversionRatio,
                                                                                     vars.no_dividends, vars.no_callability,
                                                                                     vars.creditSpread,
                                                                                     vars.issueDate, vars.settlementDays,
                                                                                     index, fixingDays, spreads,
                                                                                     vars.dayCounter, schedule,
                                                                                     vars.redemption);

            euFloating.setPricingEngine(engine);

            ConvertibleFloatingRateBond amFloating = new ConvertibleFloatingRateBond(amExercise, vars.conversionRatio,
                                                                                     vars.no_dividends, vars.no_callability,
                                                                                     vars.creditSpread,
                                                                                     vars.issueDate, vars.settlementDays,
                                                                                     index, fixingDays, spreads,
                                                                                     vars.dayCounter, schedule,
                                                                                     vars.redemption);

            amFloating.setPricingEngine(engine);

            IborCouponPricer pricer = new BlackIborCouponPricer(new Handle <OptionletVolatilityStructure>());

            Schedule floatSchedule = new Schedule(vars.issueDate, vars.maturityDate,
                                                  new Period(vars.frequency),
                                                  vars.calendar, BusinessDayConvention.Following, BusinessDayConvention.Following,
                                                  DateGeneration.Rule.Backward, false);

            FloatingRateBond floating = new FloatingRateBond(vars.settlementDays, vars.faceAmount, floatSchedule,
                                                             index, vars.dayCounter, BusinessDayConvention.Following, fixingDays,
                                                             gearings, spreads,
                                                             new List <double?>(), new List <double?>(),
                                                             false,
                                                             vars.redemption, vars.issueDate);

            floating.setPricingEngine(bondEngine);
            Utils.setCouponPricer(floating.cashflows(), pricer);

            tolerance = 2.0e-2 * (vars.faceAmount / 100.0);

            error = Math.Abs(euFloating.NPV() - floating.settlementValue());
            if (error > tolerance)
            {
                QAssert.Fail("failed to reproduce floating-rate bond price:"
                             + "\n    calculated: " + euFloating.NPV()
                             + "\n    expected:   " + floating.settlementValue()
                             + "\n    error:      " + error);
            }

            error = Math.Abs(amFloating.NPV() - floating.settlementValue());
            if (error > tolerance)
            {
                QAssert.Fail("failed to reproduce floating-rate bond price:"
                             + "\n    calculated: " + amFloating.NPV()
                             + "\n    expected:   " + floating.settlementValue()
                             + "\n    error:      " + error);
            }
        }
Пример #15
0
        static void Main(string[] args)
        {
            try
            {
                var timer = new System.Diagnostics.Stopwatch();
                timer.Start();

                #region MARKET DATA

                var calendar = new TARGET();

                var settlementDate = new Date(18, Month.September, 2008);
                // must be a business day
                settlementDate = calendar.adjust(settlementDate);

                int  fixingDays     = 3;
                uint settlementDays = 3;

                var todaysDate = calendar.advance(settlementDate, -fixingDays, TimeUnit.Days);
                // nothing to do with Date::todaysDate
                Settings.instance().setEvaluationDate(todaysDate);

                Console.WriteLine("Today: {0} {1} {2} {3}", todaysDate.weekday(), todaysDate.dayOfMonth(), todaysDate.month(), todaysDate.year());
                Console.WriteLine("Settlement date: {0} {1} {2} {3}", settlementDate.weekday(), settlementDate.dayOfMonth(), settlementDate.month(), settlementDate.year());

                // Building of the bonds discounting yield curve

                #endregion

                #region RATE HELPERS

                // RateHelpers are built from the above quotes together with
                // other instrument dependant infos.  Quotes are passed in
                // relinkable handles which could be relinked to some other
                // data source later.

                // Common data

                // ZC rates for the short end
                double zc3mQuote = 0.0096;
                double zc6mQuote = 0.0145;
                double zc1yQuote = 0.0194;

                var zc3mRate = new SimpleQuote(zc3mQuote);
                var zc6mRate = new SimpleQuote(zc6mQuote);
                var zc1yRate = new SimpleQuote(zc1yQuote);

                var zcBondsDayCounter = new Actual365Fixed();

                var zc3m = new DepositRateHelper(new QuoteHandle(zc3mRate),
                                                 new Period(3, TimeUnit.Months),
                                                 (uint)fixingDays,
                                                 calendar,
                                                 BusinessDayConvention.ModifiedFollowing,
                                                 true,
                                                 zcBondsDayCounter);

                var zc6m = new DepositRateHelper(new QuoteHandle(zc6mRate),
                                                 new Period(6, TimeUnit.Months),
                                                 (uint)fixingDays,
                                                 calendar,
                                                 BusinessDayConvention.ModifiedFollowing,
                                                 true,
                                                 zcBondsDayCounter);

                var zc1y = new DepositRateHelper(new QuoteHandle(zc1yRate),
                                                 new Period(1, TimeUnit.Years),
                                                 (uint)fixingDays,
                                                 calendar,
                                                 BusinessDayConvention.ModifiedFollowing,
                                                 true,
                                                 zcBondsDayCounter);

                // setup bonds
                double redemption = 100.0;

                const uint numberOfBonds = 5;

                var issueDates = new Date[] { new Date(15, Month.March, 2005),
                                              new Date(15, Month.June, 2005),
                                              new Date(30, Month.June, 2006),
                                              new Date(15, Month.November, 2002),
                                              new Date(15, Month.May, 1987) };

                var maturities = new Date[] { new Date(31, Month.August, 2010),
                                              new Date(31, Month.August, 2011),
                                              new Date(31, Month.August, 2013),
                                              new Date(15, Month.August, 2018),
                                              new Date(15, Month.May, 2038) };

                var couponRates = new double[] { 0.02375,
                                                 0.04625,
                                                 0.03125,
                                                 0.04000,
                                                 0.04500 };

                var marketQuotes = new double[] { 100.390625,
                                                  106.21875,
                                                  100.59375,
                                                  101.6875,
                                                  102.140625 };

                var quote = new QuoteVector((int)numberOfBonds);
                for (uint i = 0; i < numberOfBonds; i++)
                {
                    var cp = new SimpleQuote(marketQuotes[i]);
                    quote.Add(cp);
                }

                var quoteHandle = new RelinkableQuoteHandleVector((int)numberOfBonds);
                for (int i = 0; i < (int)numberOfBonds; i++)
                {
                    quoteHandle.Add(new RelinkableQuoteHandle());
                    quoteHandle[i].linkTo(quote[i]);
                }

                // Definition of the rate helpers
                var bondsHelpers = new RateHelperVector((int)numberOfBonds);
                for (int i = 0; i < (int)numberOfBonds; i++)
                {
                    var schedule = new Schedule(issueDates[i],
                                                maturities[i],
                                                new Period(Frequency.Semiannual),
                                                new UnitedStates(UnitedStates.Market.GovernmentBond),
                                                BusinessDayConvention.Unadjusted,
                                                BusinessDayConvention.Unadjusted,
                                                DateGeneration.Rule.Backward,
                                                false);

                    var bondHelper = new FixedRateBondHelper(quoteHandle[i],
                                                             settlementDays,
                                                             100.0,
                                                             schedule,
                                                             new DoubleVector(1)
                    {
                        couponRates[i]
                    },
                                                             new ActualActual(ActualActual.Convention.Bond),
                                                             BusinessDayConvention.Unadjusted,
                                                             redemption,
                                                             issueDates[i]);

                    bondsHelpers.Add(bondHelper);
                }

                #endregion

                #region CURVE BUILDING

                // Any DayCounter would be fine.
                // ActualActual::ISDA ensures that 30 years is 30.0
                var termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA);
                //double tolerance = 1.0e-15;

                // A depo-bond curve
                var bondInstruments = new RateHelperVector();

                // Adding the ZC bonds to the curve for the short end
                bondInstruments.Add(zc3m);
                bondInstruments.Add(zc6m);
                bondInstruments.Add(zc1y);

                // Adding the Fixed rate bonds to the curve for the long end
                for (int i = 0; i < numberOfBonds; i++)
                {
                    bondInstruments.Add(bondsHelpers[3]);
                }

                var bondDiscountingTermStructure = new PiecewiseFlatForward(settlementDate,
                                                                            bondInstruments,
                                                                            termStructureDayCounter);

                // Building of the Libor forecasting curve
                // deposits
                double d1wQuote = 0.043375;
                double d1mQuote = 0.031875;
                double d3mQuote = 0.0320375;
                double d6mQuote = 0.03385;
                double d9mQuote = 0.0338125;
                double d1yQuote = 0.0335125;
                // swaps
                double s2yQuote  = 0.0295;
                double s3yQuote  = 0.0323;
                double s5yQuote  = 0.0359;
                double s10yQuote = 0.0412;
                double s15yQuote = 0.0433;

                #endregion

                #region QUOTES

                // SimpleQuote stores a value which can be manually changed;
                // other Quote subclasses could read the value from a database
                // or some kind of data feed.

                // deposits
                var d1wRate = new SimpleQuote(d1wQuote);
                var d1mRate = new SimpleQuote(d1mQuote);
                var d3mRate = new SimpleQuote(d3mQuote);
                var d6mRate = new SimpleQuote(d6mQuote);
                var d9mRate = new SimpleQuote(d9mQuote);
                var d1yRate = new SimpleQuote(d1yQuote);
                // swaps
                var s2yRate  = new SimpleQuote(s2yQuote);
                var s3yRate  = new SimpleQuote(s3yQuote);
                var s5yRate  = new SimpleQuote(s5yQuote);
                var s10yRate = new SimpleQuote(s10yQuote);
                var s15yRate = new SimpleQuote(s15yQuote);

                #endregion

                #region RATE HELPERS

                // RateHelpers are built from the above quotes together with
                // other instrument dependant infos.  Quotes are passed in
                // relinkable handles which could be relinked to some other
                // data source later.

                // deposits
                var depositDayCounter = new Actual360();

                var d1w = new DepositRateHelper(new QuoteHandle(d1wRate),
                                                new Period(1, TimeUnit.Weeks),
                                                (uint)fixingDays,
                                                calendar,
                                                BusinessDayConvention.ModifiedFollowing,
                                                true,
                                                depositDayCounter);

                var d1m = new DepositRateHelper(new QuoteHandle(d1mRate),
                                                new Period(1, TimeUnit.Months),
                                                (uint)fixingDays,
                                                calendar,
                                                BusinessDayConvention.ModifiedFollowing,
                                                true,
                                                depositDayCounter);

                var d3m = new DepositRateHelper(new QuoteHandle(d3mRate),
                                                new Period(3, TimeUnit.Months),
                                                (uint)fixingDays,
                                                calendar,
                                                BusinessDayConvention.ModifiedFollowing,
                                                true,
                                                depositDayCounter);

                var d6m = new DepositRateHelper(new QuoteHandle(d6mRate),
                                                new Period(6, TimeUnit.Months),
                                                (uint)fixingDays,
                                                calendar,
                                                BusinessDayConvention.ModifiedFollowing,
                                                true,
                                                depositDayCounter);

                var d9m = new DepositRateHelper(new QuoteHandle(d9mRate),
                                                new Period(9, TimeUnit.Months),
                                                (uint)fixingDays,
                                                calendar,
                                                BusinessDayConvention.ModifiedFollowing,
                                                true,
                                                depositDayCounter);

                var d1y = new DepositRateHelper(new QuoteHandle(d1yRate),
                                                new Period(1, TimeUnit.Years),
                                                (uint)fixingDays,
                                                calendar,
                                                BusinessDayConvention.ModifiedFollowing,
                                                true,
                                                depositDayCounter);

                // setup swaps
                var swFixedLegFrequency  = Frequency.Annual;
                var swFixedLegConvention = BusinessDayConvention.Unadjusted;
                var swFixedLegDayCounter = new Thirty360(Thirty360.Convention.European);
                var swFloatingLegIndex   = new Euribor6M();

                var forwardStart = new Period(1, TimeUnit.Days);

                var s2y = new SwapRateHelper(new QuoteHandle(s2yRate),
                                             new Period(2, TimeUnit.Years),
                                             calendar,
                                             swFixedLegFrequency,
                                             swFixedLegConvention,
                                             swFixedLegDayCounter,
                                             swFloatingLegIndex,
                                             new QuoteHandle(),
                                             forwardStart);

                var s3y = new SwapRateHelper(new QuoteHandle(s3yRate),
                                             new Period(3, TimeUnit.Years),
                                             calendar,
                                             swFixedLegFrequency,
                                             swFixedLegConvention,
                                             swFixedLegDayCounter,
                                             swFloatingLegIndex,
                                             new QuoteHandle(),
                                             forwardStart);

                var s5y = new SwapRateHelper(new QuoteHandle(s5yRate),
                                             new Period(5, TimeUnit.Years),
                                             calendar,
                                             swFixedLegFrequency,
                                             swFixedLegConvention,
                                             swFixedLegDayCounter,
                                             swFloatingLegIndex,
                                             new QuoteHandle(),
                                             forwardStart);

                var s10y = new SwapRateHelper(new QuoteHandle(s10yRate),
                                              new Period(10, TimeUnit.Years),
                                              calendar,
                                              swFixedLegFrequency,
                                              swFixedLegConvention,
                                              swFixedLegDayCounter,
                                              swFloatingLegIndex,
                                              new QuoteHandle(),
                                              forwardStart);

                var s15y = new SwapRateHelper(new QuoteHandle(s15yRate),
                                              new Period(15, TimeUnit.Years),
                                              calendar,
                                              swFixedLegFrequency,
                                              swFixedLegConvention,
                                              swFixedLegDayCounter,
                                              swFloatingLegIndex,
                                              new QuoteHandle(),
                                              forwardStart);

                #endregion

                #region CURVE BUILDING

                // Any DayCounter would be fine.
                // ActualActual::ISDA ensures that 30 years is 30.0

                // A depo-swap curve
                var depoSwapInstruments = new RateHelperVector();
                depoSwapInstruments.Add(d1w);
                depoSwapInstruments.Add(d1m);
                depoSwapInstruments.Add(d3m);
                depoSwapInstruments.Add(d6m);
                depoSwapInstruments.Add(d9m);
                depoSwapInstruments.Add(d1y);
                depoSwapInstruments.Add(s2y);
                depoSwapInstruments.Add(s3y);
                depoSwapInstruments.Add(s5y);
                depoSwapInstruments.Add(s10y);
                depoSwapInstruments.Add(s15y);

                var depoSwapTermStructure = new PiecewiseFlatForward(settlementDate,
                                                                     depoSwapInstruments,
                                                                     termStructureDayCounter);

                // Term structures that will be used for pricing:
                // the one used for discounting cash flows
                var discountingTermStructure = new RelinkableYieldTermStructureHandle();
                // the one used for forward rate forecasting
                //var forecastingTermStructure = new RelinkableYieldTermStructureHandle();

                #endregion

                #region BONDS TO BE PRICED

                // Common data
                double faceAmount = 100;

                // Pricing engine
                var bondEngine = new DiscountingBondEngine(new YieldTermStructureHandle(bondDiscountingTermStructure));

                // Zero coupon bond
                var zeroCouponBond = new ZeroCouponBond(settlementDays,
                                                        new UnitedStates(UnitedStates.Market.GovernmentBond),
                                                        faceAmount,
                                                        new Date(15, Month.August, 2013),
                                                        BusinessDayConvention.Following,
                                                        116.92,
                                                        new Date(15, Month.August, 2003));

                zeroCouponBond.setPricingEngine(bondEngine);

                // Fixed 4.5% US Treasury Note
                var fixedBondSchedule = new Schedule(new Date(15, Month.May, 2007),
                                                     new Date(15, Month.May, 2017),
                                                     new Period(Frequency.Semiannual),
                                                     new UnitedStates(UnitedStates.Market.GovernmentBond),
                                                     BusinessDayConvention.Unadjusted,
                                                     BusinessDayConvention.Unadjusted,
                                                     DateGeneration.Rule.Backward,
                                                     false);

                var fixedRateBond = new FixedRateBond((int)settlementDays,
                                                      faceAmount,
                                                      fixedBondSchedule,
                                                      new DoubleVector(1)
                {
                    0.045
                },
                                                      new ActualActual(ActualActual.Convention.Bond),
                                                      BusinessDayConvention.ModifiedFollowing,
                                                      100.0,
                                                      new Date(15, Month.May, 2007));

                fixedRateBond.setPricingEngine(bondEngine);

                // Floating rate bond (3M USD Libor + 0.1%)
                // Should and will be priced on another curve later...

                var liborTermStructure = new RelinkableYieldTermStructureHandle();
                var libor3m            = new USDLibor(new Period(3, TimeUnit.Months),
                                                      liborTermStructure);
                libor3m.addFixing(new Date(17, Month.July, 2008), 0.0278625);

                var floatingBondSchedule = new Schedule(new Date(21, Month.October, 2005),
                                                        new Date(21, Month.October, 2010),
                                                        new Period(Frequency.Quarterly),
                                                        new UnitedStates(UnitedStates.Market.NYSE),
                                                        BusinessDayConvention.Unadjusted,
                                                        BusinessDayConvention.Unadjusted,
                                                        DateGeneration.Rule.Backward,
                                                        true);

                var floatingRateBond = new FloatingRateBond(settlementDays,
                                                            faceAmount,
                                                            floatingBondSchedule,
                                                            libor3m,
                                                            new Actual360(),
                                                            BusinessDayConvention.ModifiedFollowing,
                                                            2,
                                                            // Gearings
                                                            new DoubleVector(1)
                {
                    1.0
                },
                                                            // Spreads
                                                            new DoubleVector(1)
                {
                    0.001
                },
                                                            // Caps
                                                            new DoubleVector(),
                                                            // Floors
                                                            new DoubleVector(),
                                                            // Fixing in arrears
                                                            true,
                                                            100.0,
                                                            new Date(21, Month.October, 2005));

                floatingRateBond.setPricingEngine(bondEngine);

                // Coupon pricers
                var pricer = new BlackIborCouponPricer();

                // optionLet volatilities
                double volatility = 0.0;
                var    vol        = new OptionletVolatilityStructureHandle(new ConstantOptionletVolatility(settlementDays,
                                                                                                           calendar,
                                                                                                           BusinessDayConvention.ModifiedFollowing,
                                                                                                           volatility,
                                                                                                           new Actual365Fixed()));

                pricer.setCapletVolatility(vol);
                NQuantLibc.setCouponPricer(floatingRateBond.cashflows(), pricer);

                // Yield curve bootstrapping
                //forecastingTermStructure.linkTo(depoSwapTermStructure);
                discountingTermStructure.linkTo(bondDiscountingTermStructure);

                // We are using the depo & swap curve to estimate the future Libor rates
                liborTermStructure.linkTo(depoSwapTermStructure);

                #endregion

                #region BOND PRICING

                Console.WriteLine();

                // write column headings
                int[] widths = new int[] { 0, 28, 38, 48 };

                Console.CursorLeft = widths[0]; Console.Write("                 ");
                Console.CursorLeft = widths[1]; Console.Write("ZC");
                Console.CursorLeft = widths[2]; Console.Write("Fixed");
                Console.CursorLeft = widths[3]; Console.WriteLine("Floating");

                //string separator = " | ";
                int    width   = widths[3];
                string rule    = new string('-', width);
                string dblrule = new string('=', width);
                string tab     = new string(' ', 8);

                Console.WriteLine(rule);

                Console.CursorLeft = widths[0]; Console.Write("Net present value");
                Console.CursorLeft = widths[1]; Console.Write(zeroCouponBond.NPV().ToString("000.00"));
                Console.CursorLeft = widths[2]; Console.Write(fixedRateBond.NPV().ToString("000.00"));
                Console.CursorLeft = widths[3]; Console.WriteLine(floatingRateBond.NPV().ToString("000.00"));

                Console.CursorLeft = widths[0]; Console.Write("Clean price");
                Console.CursorLeft = widths[1]; Console.Write(zeroCouponBond.cleanPrice().ToString("000.00"));
                Console.CursorLeft = widths[2]; Console.Write(fixedRateBond.cleanPrice().ToString("000.00"));
                Console.CursorLeft = widths[3]; Console.WriteLine(floatingRateBond.cleanPrice().ToString("000.00"));

                Console.CursorLeft = widths[0]; Console.Write("Dirty price");
                Console.CursorLeft = widths[1]; Console.Write(zeroCouponBond.dirtyPrice().ToString("000.00"));
                Console.CursorLeft = widths[2]; Console.Write(fixedRateBond.dirtyPrice().ToString("000.00"));
                Console.CursorLeft = widths[3]; Console.WriteLine(floatingRateBond.dirtyPrice().ToString("000.00"));

                Console.CursorLeft = widths[0]; Console.Write("Accrued coupon");
                Console.CursorLeft = widths[1]; Console.Write(zeroCouponBond.accruedAmount().ToString("000.00"));
                Console.CursorLeft = widths[2]; Console.Write(fixedRateBond.accruedAmount().ToString("000.00"));
                Console.CursorLeft = widths[3]; Console.WriteLine(floatingRateBond.accruedAmount().ToString("000.00"));

                Console.CursorLeft = widths[0]; Console.Write("Previous coupon");
                Console.CursorLeft = widths[1]; Console.Write("N/A");
                Console.CursorLeft = widths[2]; Console.Write(fixedRateBond.previousCouponRate().ToString("000.00"));
                Console.CursorLeft = widths[3]; Console.WriteLine(floatingRateBond.previousCouponRate().ToString("000.00"));

                Console.CursorLeft = widths[0]; Console.Write("Next coupon");
                Console.CursorLeft = widths[1]; Console.Write("N/A");
                Console.CursorLeft = widths[2]; Console.Write(fixedRateBond.nextCouponRate().ToString("000.00"));
                Console.CursorLeft = widths[3]; Console.WriteLine(floatingRateBond.nextCouponRate().ToString("000.00"));

                Console.CursorLeft = widths[0]; Console.Write("Yield");
                Console.CursorLeft = widths[1]; Console.Write(zeroCouponBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual).ToString("000.00"));
                Console.CursorLeft = widths[2]; Console.Write(fixedRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual).ToString("000.00"));
                Console.CursorLeft = widths[3]; Console.WriteLine(floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual).ToString("000.00"));

                double yield = fixedRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual);
                Console.CursorLeft = widths[2]; Console.Write(BondFunctions.duration(fixedRateBond, new InterestRate(yield, fixedRateBond.dayCounter(), Compounding.Compounded, Frequency.Annual), Duration.Type.Modified));

                Console.WriteLine();

                // Other computations
                Console.WriteLine("Sample indirect computations (for the floating rate bond): ");
                Console.WriteLine(rule);

                Console.WriteLine("Yield to Clean Price: {0}", floatingRateBond.cleanPrice(floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual), new Actual360(), Compounding.Compounded, Frequency.Annual, settlementDate).ToString("000.00"));

                Console.WriteLine("Clean Price to Yield: {0}", floatingRateBond.yield(floatingRateBond.cleanPrice(), new Actual360(), Compounding.Compounded, Frequency.Annual, settlementDate).ToString("000.00"));

                /* "Yield to Price"
                *  "Price to Yield" */

                double milliseconds = timer.ElapsedMilliseconds;
                Console.WriteLine();
                Console.WriteLine("Run completed in " + milliseconds + "ms");

                #endregion
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                Console.Read();
            }
        }
Пример #16
0
        static void Main(string[] args)
        {
            DateTime timer = DateTime.Now;

            Date        repoSettlementDate     = new Date(14, Month.February, 2000);;
            Date        repoDeliveryDate       = new Date(15, Month.August, 2000);
            double      repoRate               = 0.05;
            DayCounter  repoDayCountConvention = new Actual360();
            int         repoSettlementDays     = 0;
            Compounding repoCompounding        = Compounding.Simple;
            Frequency   repoCompoundFreq       = Frequency.Annual;

            // assume a ten year bond- this is irrelevant
            Date      bondIssueDate       = new Date(15, Month.September, 1995);
            Date      bondDatedDate       = new Date(15, Month.September, 1995);
            Date      bondMaturityDate    = new Date(15, Month.September, 2005);
            double    bondCoupon          = 0.08;
            Frequency bondCouponFrequency = Frequency.Semiannual;
            // unknown what calendar fincad is using
            Calendar   bondCalendar           = new NullCalendar();
            DayCounter bondDayCountConvention = new Thirty360(Thirty360.Thirty360Convention.BondBasis);
            // unknown what fincad is using. this may affect accrued calculation
            int bondSettlementDays = 0;
            BusinessDayConvention bondBusinessDayConvention = BusinessDayConvention.Unadjusted;
            double bondCleanPrice = 89.97693786;
            double bondRedemption = 100.0;
            double faceAmount     = 100.0;


            Settings.setEvaluationDate(repoSettlementDate);

            RelinkableHandle <YieldTermStructure> bondCurve = new RelinkableHandle <YieldTermStructure>();

            bondCurve.linkTo(new FlatForward(repoSettlementDate,
                                             .01,                                               // dummy rate
                                             bondDayCountConvention,
                                             Compounding.Compounded,
                                             bondCouponFrequency));

            /*
             * boost::shared_ptr<FixedRateBond> bond(
             *                         new FixedRateBond(faceAmount,
             *                                                               bondIssueDate,
             *                                                               bondDatedDate,
             *                                                               bondMaturityDate,
             *                                                               bondSettlementDays,
             *                                                               std::vector<Rate>(1,bondCoupon),
             *                                                               bondCouponFrequency,
             *                                                               bondCalendar,
             *                                                               bondDayCountConvention,
             *                                                               bondBusinessDayConvention,
             *                                                               bondBusinessDayConvention,
             *                                                               bondRedemption,
             *                                                               bondCurve));
             */

            Schedule bondSchedule = new Schedule(bondDatedDate, bondMaturityDate,
                                                 new Period(bondCouponFrequency),
                                                 bondCalendar, bondBusinessDayConvention,
                                                 bondBusinessDayConvention,
                                                 DateGeneration.Rule.Backward, false);
            FixedRateBond bond = new FixedRateBond(bondSettlementDays,
                                                   faceAmount,
                                                   bondSchedule,
                                                   new List <double>()
            {
                bondCoupon
            },
                                                   bondDayCountConvention,
                                                   bondBusinessDayConvention,
                                                   bondRedemption,
                                                   bondIssueDate);

            bond.setPricingEngine(new DiscountingBondEngine(bondCurve));

            bondCurve.linkTo(new FlatForward(repoSettlementDate,
                                             bond.yield(bondCleanPrice,
                                                        bondDayCountConvention,
                                                        Compounding.Compounded,
                                                        bondCouponFrequency),
                                             bondDayCountConvention,
                                             Compounding.Compounded,
                                             bondCouponFrequency));

            Position.Type fwdType     = Position.Type.Long;
            double        dummyStrike = 91.5745;

            RelinkableHandle <YieldTermStructure> repoCurve = new RelinkableHandle <YieldTermStructure>();

            repoCurve.linkTo(new FlatForward(repoSettlementDate,
                                             repoRate,
                                             repoDayCountConvention,
                                             repoCompounding,
                                             repoCompoundFreq));


            FixedRateBondForward bondFwd = new FixedRateBondForward(repoSettlementDate,
                                                                    repoDeliveryDate,
                                                                    fwdType,
                                                                    dummyStrike,
                                                                    repoSettlementDays,
                                                                    repoDayCountConvention,
                                                                    bondCalendar,
                                                                    bondBusinessDayConvention,
                                                                    bond,
                                                                    repoCurve,
                                                                    repoCurve);


            Console.WriteLine("Underlying bond clean price: " + bond.cleanPrice());
            Console.WriteLine("Underlying bond dirty price: " + bond.dirtyPrice());
            Console.WriteLine("Underlying bond accrued at settlement: "
                              + bond.accruedAmount(repoSettlementDate));
            Console.WriteLine("Underlying bond accrued at delivery:   "
                              + bond.accruedAmount(repoDeliveryDate));
            Console.WriteLine("Underlying bond spot income: "
                              + bondFwd.spotIncome(repoCurve));
            Console.WriteLine("Underlying bond fwd income:  "
                              + bondFwd.spotIncome(repoCurve) /
                              repoCurve.link.discount(repoDeliveryDate));
            Console.WriteLine("Repo strike: " + dummyStrike);
            Console.WriteLine("Repo NPV:    " + bondFwd.NPV());
            Console.WriteLine("Repo clean forward price: "
                              + bondFwd.cleanForwardPrice());
            Console.WriteLine("Repo dirty forward price: "
                              + bondFwd.forwardPrice());
            Console.WriteLine("Repo implied yield: "
                              + bondFwd.impliedYield(bond.dirtyPrice(),
                                                     dummyStrike,
                                                     repoSettlementDate,
                                                     repoCompounding,
                                                     repoDayCountConvention));
            Console.WriteLine("Market repo rate:   "
                              + repoCurve.link.zeroRate(repoDeliveryDate,
                                                        repoDayCountConvention,
                                                        repoCompounding,
                                                        repoCompoundFreq));

            Console.WriteLine("\nCompare with example given at \n"
                              + "http://www.fincad.com/support/developerFunc/mathref/BFWD.htm");
            Console.WriteLine("Clean forward price = 88.2408");
            Console.WriteLine("\nIn that example, it is unknown what bond calendar they are\n"
                              + "using, as well as settlement Days. For that reason, I have\n"
                              + "made the simplest possible assumptions here: NullCalendar\n"
                              + "and 0 settlement days.\n");


            Console.WriteLine("nRun completed in {0}", DateTime.Now - timer);

            Console.Write("Press any key to continue ...");
            Console.ReadKey();
        }
Пример #17
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(FixedRateBond obj) {
   return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
 }
Пример #18
0
        static void Main(string[] args)
        {
            DateTime timer = DateTime.Now;

            /*********************
            ***  MARKET DATA  ***
            *********************/

            Calendar calendar = new TARGET();

            Date settlementDate = new Date(18, Month.September, 2008);

            // must be a business day
            settlementDate = calendar.adjust(settlementDate);

            int fixingDays     = 3;
            int settlementDays = 3;

            Date todaysDate = calendar.advance(settlementDate, -fixingDays, TimeUnit.Days);

            // nothing to do with Date::todaysDate
            Settings.setEvaluationDate(todaysDate);

            Console.WriteLine("Today: {0}, {1}", todaysDate.DayOfWeek, todaysDate);
            Console.WriteLine("Settlement date: {0}, {1}", settlementDate.DayOfWeek, settlementDate);


            // Building of the bonds discounting yield curve

            /*********************
            ***  RATE HELPERS ***
            *********************/

            // RateHelpers are built from the above quotes together with
            // other instrument dependant infos.  Quotes are passed in
            // relinkable handles which could be relinked to some other
            // data source later.

            // Common data

            // ZC rates for the short end
            double zc3mQuote = 0.0096;
            double zc6mQuote = 0.0145;
            double zc1yQuote = 0.0194;

            Quote zc3mRate = new SimpleQuote(zc3mQuote);
            Quote zc6mRate = new SimpleQuote(zc6mQuote);
            Quote zc1yRate = new SimpleQuote(zc1yQuote);

            DayCounter zcBondsDayCounter = new Actual365Fixed();

            RateHelper zc3m = new DepositRateHelper(new Handle <Quote>(zc3mRate),
                                                    new Period(3, TimeUnit.Months), fixingDays,
                                                    calendar, BusinessDayConvention.ModifiedFollowing,
                                                    true, zcBondsDayCounter);
            RateHelper zc6m = new DepositRateHelper(new Handle <Quote>(zc6mRate),
                                                    new Period(6, TimeUnit.Months), fixingDays,
                                                    calendar, BusinessDayConvention.ModifiedFollowing,
                                                    true, zcBondsDayCounter);
            RateHelper zc1y = new DepositRateHelper(new Handle <Quote>(zc1yRate),
                                                    new Period(1, TimeUnit.Years), fixingDays,
                                                    calendar, BusinessDayConvention.ModifiedFollowing,
                                                    true, zcBondsDayCounter);

            // setup bonds
            double redemption = 100.0;

            const int numberOfBonds = 5;

            Date[] issueDates =
            {
                new Date(15, Month.March,    2005),
                new Date(15, Month.June,     2005),
                new Date(30, Month.June,     2006),
                new Date(15, Month.November, 2002),
                new Date(15, Month.May, 1987)
            };

            Date[] maturities =
            {
                new Date(31, Month.August, 2010),
                new Date(31, Month.August, 2011),
                new Date(31, Month.August, 2013),
                new Date(15, Month.August, 2018),
                new Date(15, Month.May, 2038)
            };

            double[] couponRates =
            {
                0.02375,
                0.04625,
                0.03125,
                0.04000,
                0.04500
            };

            double[] marketQuotes =
            {
                100.390625,
                106.21875,
                100.59375,
                101.6875,
                102.140625
            };

            List <SimpleQuote> quote = new List <SimpleQuote>();

            for (int i = 0; i < numberOfBonds; i++)
            {
                SimpleQuote cp = new SimpleQuote(marketQuotes[i]);
                quote.Add(cp);
            }

            List <RelinkableHandle <Quote> > quoteHandle = new InitializedList <RelinkableHandle <Quote> >(numberOfBonds);

            for (int i = 0; i < numberOfBonds; i++)
            {
                quoteHandle[i].linkTo(quote[i]);
            }

            // Definition of the rate helpers
            List <FixedRateBondHelper> bondsHelpers = new List <FixedRateBondHelper>();

            for (int i = 0; i < numberOfBonds; i++)
            {
                Schedule schedule = new Schedule(issueDates[i], maturities[i], new Period(Frequency.Semiannual),
                                                 new UnitedStates(UnitedStates.Market.GovernmentBond),
                                                 BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                                 DateGeneration.Rule.Backward, false);

                FixedRateBondHelper bondHelper = new FixedRateBondHelper(quoteHandle[i],
                                                                         settlementDays,
                                                                         100.0,
                                                                         schedule,
                                                                         new List <double>()
                {
                    couponRates[i]
                },
                                                                         new ActualActual(ActualActual.Convention.Bond),
                                                                         BusinessDayConvention.Unadjusted,
                                                                         redemption,
                                                                         issueDates[i]);

                bondsHelpers.Add(bondHelper);
            }

            /*********************
            **  CURVE BUILDING **
            *********************/

            // Any DayCounter would be fine.
            // ActualActual::ISDA ensures that 30 years is 30.0
            DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA);

            double tolerance = 1.0e-15;

            // A depo-bond curve
            List <RateHelper> bondInstruments = new List <RateHelper>();

            // Adding the ZC bonds to the curve for the short end
            bondInstruments.Add(zc3m);
            bondInstruments.Add(zc6m);
            bondInstruments.Add(zc1y);

            // Adding the Fixed rate bonds to the curve for the long end
            for (int i = 0; i < numberOfBonds; i++)
            {
                bondInstruments.Add(bondsHelpers[i]);
            }

            YieldTermStructure bondDiscountingTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>(
                settlementDate, bondInstruments,
                termStructureDayCounter,
                new List <Handle <Quote> >(),
                new List <Date>(),
                tolerance);

            // Building of the Libor forecasting curve
            // deposits
            double d1wQuote = 0.043375;
            double d1mQuote = 0.031875;
            double d3mQuote = 0.0320375;
            double d6mQuote = 0.03385;
            double d9mQuote = 0.0338125;
            double d1yQuote = 0.0335125;
            // swaps
            double s2yQuote  = 0.0295;
            double s3yQuote  = 0.0323;
            double s5yQuote  = 0.0359;
            double s10yQuote = 0.0412;
            double s15yQuote = 0.0433;


            /********************
            ***    QUOTES    ***
            ********************/

            // SimpleQuote stores a value which can be manually changed;
            // other Quote subclasses could read the value from a database
            // or some kind of data feed.

            // deposits
            Quote d1wRate = new SimpleQuote(d1wQuote);
            Quote d1mRate = new SimpleQuote(d1mQuote);
            Quote d3mRate = new SimpleQuote(d3mQuote);
            Quote d6mRate = new SimpleQuote(d6mQuote);
            Quote d9mRate = new SimpleQuote(d9mQuote);
            Quote d1yRate = new SimpleQuote(d1yQuote);
            // swaps
            Quote s2yRate  = new SimpleQuote(s2yQuote);
            Quote s3yRate  = new SimpleQuote(s3yQuote);
            Quote s5yRate  = new SimpleQuote(s5yQuote);
            Quote s10yRate = new SimpleQuote(s10yQuote);
            Quote s15yRate = new SimpleQuote(s15yQuote);

            /*********************
            ***  RATE HELPERS ***
            *********************/

            // RateHelpers are built from the above quotes together with
            // other instrument dependant infos.  Quotes are passed in
            // relinkable handles which could be relinked to some other
            // data source later.

            // deposits
            DayCounter depositDayCounter = new Actual360();

            RateHelper d1w = new DepositRateHelper(
                new Handle <Quote>(d1wRate),
                new Period(1, TimeUnit.Weeks), fixingDays,
                calendar, BusinessDayConvention.ModifiedFollowing,
                true, depositDayCounter);
            RateHelper d1m = new DepositRateHelper(
                new Handle <Quote>(d1mRate),
                new Period(1, TimeUnit.Months), fixingDays,
                calendar, BusinessDayConvention.ModifiedFollowing,
                true, depositDayCounter);
            RateHelper d3m = new DepositRateHelper(
                new Handle <Quote>(d3mRate),
                new Period(3, TimeUnit.Months), fixingDays,
                calendar, BusinessDayConvention.ModifiedFollowing,
                true, depositDayCounter);
            RateHelper d6m = new DepositRateHelper(
                new Handle <Quote>(d6mRate),
                new Period(6, TimeUnit.Months), fixingDays,
                calendar, BusinessDayConvention.ModifiedFollowing,
                true, depositDayCounter);
            RateHelper d9m = new DepositRateHelper(
                new Handle <Quote>(d9mRate),
                new Period(9, TimeUnit.Months), fixingDays,
                calendar, BusinessDayConvention.ModifiedFollowing,
                true, depositDayCounter);
            RateHelper d1y = new DepositRateHelper(
                new Handle <Quote>(d1yRate),
                new Period(1, TimeUnit.Years), fixingDays,
                calendar, BusinessDayConvention.ModifiedFollowing,
                true, depositDayCounter);

            // setup swaps
            Frequency             swFixedLegFrequency  = Frequency.Annual;
            BusinessDayConvention swFixedLegConvention = BusinessDayConvention.Unadjusted;
            DayCounter            swFixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European);
            IborIndex             swFloatingLegIndex   = new Euribor6M();

            Period forwardStart = new Period(1, TimeUnit.Days);

            RateHelper s2y = new SwapRateHelper(
                new Handle <Quote>(s2yRate), new Period(2, TimeUnit.Years),
                calendar, swFixedLegFrequency,
                swFixedLegConvention, swFixedLegDayCounter,
                swFloatingLegIndex, new Handle <Quote>(), forwardStart);
            RateHelper s3y = new SwapRateHelper(
                new Handle <Quote>(s3yRate), new Period(3, TimeUnit.Years),
                calendar, swFixedLegFrequency,
                swFixedLegConvention, swFixedLegDayCounter,
                swFloatingLegIndex, new Handle <Quote>(), forwardStart);
            RateHelper s5y = new SwapRateHelper(
                new Handle <Quote>(s5yRate), new Period(5, TimeUnit.Years),
                calendar, swFixedLegFrequency,
                swFixedLegConvention, swFixedLegDayCounter,
                swFloatingLegIndex, new Handle <Quote>(), forwardStart);
            RateHelper s10y = new SwapRateHelper(
                new Handle <Quote>(s10yRate), new Period(10, TimeUnit.Years),
                calendar, swFixedLegFrequency,
                swFixedLegConvention, swFixedLegDayCounter,
                swFloatingLegIndex, new Handle <Quote>(), forwardStart);
            RateHelper s15y = new SwapRateHelper(
                new Handle <Quote>(s15yRate), new Period(15, TimeUnit.Years),
                calendar, swFixedLegFrequency,
                swFixedLegConvention, swFixedLegDayCounter,
                swFloatingLegIndex, new Handle <Quote>(), forwardStart);


            /*********************
            **  CURVE BUILDING **
            *********************/

            // Any DayCounter would be fine.
            // ActualActual::ISDA ensures that 30 years is 30.0

            // A depo-swap curve
            List <RateHelper> depoSwapInstruments = new List <RateHelper>();

            depoSwapInstruments.Add(d1w);
            depoSwapInstruments.Add(d1m);
            depoSwapInstruments.Add(d3m);
            depoSwapInstruments.Add(d6m);
            depoSwapInstruments.Add(d9m);
            depoSwapInstruments.Add(d1y);
            depoSwapInstruments.Add(s2y);
            depoSwapInstruments.Add(s3y);
            depoSwapInstruments.Add(s5y);
            depoSwapInstruments.Add(s10y);
            depoSwapInstruments.Add(s15y);
            YieldTermStructure depoSwapTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>(
                settlementDate, depoSwapInstruments,
                termStructureDayCounter,
                new List <Handle <Quote> >(),
                new List <Date>(),
                tolerance);

            // Term structures that will be used for pricing:
            // the one used for discounting cash flows
            RelinkableHandle <YieldTermStructure> discountingTermStructure = new RelinkableHandle <YieldTermStructure>();
            // the one used for forward rate forecasting
            RelinkableHandle <YieldTermStructure> forecastingTermStructure = new RelinkableHandle <YieldTermStructure>();

            /*********************
             * BONDS TO BE PRICED *
             **********************/

            // Common data
            double faceAmount = 100;

            // Pricing engine
            IPricingEngine bondEngine = new DiscountingBondEngine(discountingTermStructure);

            // Zero coupon bond
            ZeroCouponBond zeroCouponBond = new ZeroCouponBond(
                settlementDays,
                new UnitedStates(UnitedStates.Market.GovernmentBond),
                faceAmount,
                new Date(15, Month.August, 2013),
                BusinessDayConvention.Following,
                116.92,
                new Date(15, Month.August, 2003));

            zeroCouponBond.setPricingEngine(bondEngine);

            // Fixed 4.5% US Treasury Note
            Schedule fixedBondSchedule = new Schedule(new Date(15, Month.May, 2007),
                                                      new Date(15, Month.May, 2017), new Period(Frequency.Semiannual),
                                                      new UnitedStates(UnitedStates.Market.GovernmentBond),
                                                      BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false);

            FixedRateBond fixedRateBond = new FixedRateBond(
                settlementDays,
                faceAmount,
                fixedBondSchedule,
                new List <double>()
            {
                0.045
            },
                new ActualActual(ActualActual.Convention.Bond),
                BusinessDayConvention.ModifiedFollowing,
                100.0, new Date(15, Month.May, 2007));

            fixedRateBond.setPricingEngine(bondEngine);

            // Floating rate bond (3M USD Libor + 0.1%)
            // Should and will be priced on another curve later...

            RelinkableHandle <YieldTermStructure> liborTermStructure = new RelinkableHandle <YieldTermStructure>();
            IborIndex libor3m = new USDLibor(new Period(3, TimeUnit.Months), liborTermStructure);

            libor3m.addFixing(new Date(17, Month.July, 2008), 0.0278625);

            Schedule floatingBondSchedule = new Schedule(new Date(21, Month.October, 2005),
                                                         new Date(21, Month.October, 2010), new Period(Frequency.Quarterly),
                                                         new UnitedStates(UnitedStates.Market.NYSE),
                                                         BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, true);

            FloatingRateBond floatingRateBond = new FloatingRateBond(
                settlementDays,
                faceAmount,
                floatingBondSchedule,
                libor3m,
                new Actual360(),
                BusinessDayConvention.ModifiedFollowing,
                2,
                // Gearings
                new List <double>()
            {
                1.0
            },
                // Spreads
                new List <double>()
            {
                0.001
            },
                // Caps
                new List <double?>(),
                // Floors
                new List <double?>(),
                // Fixing in arrears
                true,
                100.0,
                new Date(21, Month.October, 2005));

            floatingRateBond.setPricingEngine(bondEngine);

            // Coupon pricers
            IborCouponPricer pricer = new BlackIborCouponPricer();

            // optionLet volatilities
            double volatility = 0.0;
            Handle <OptionletVolatilityStructure> vol;

            vol = new Handle <OptionletVolatilityStructure>(
                new ConstantOptionletVolatility(
                    settlementDays,
                    calendar,
                    BusinessDayConvention.ModifiedFollowing,
                    volatility,
                    new Actual365Fixed()));

            pricer.setCapletVolatility(vol);
            Utils.setCouponPricer(floatingRateBond.cashflows(), pricer);

            // Yield curve bootstrapping
            forecastingTermStructure.linkTo(depoSwapTermStructure);
            discountingTermStructure.linkTo(bondDiscountingTermStructure);

            // We are using the depo & swap curve to estimate the future Libor rates
            liborTermStructure.linkTo(depoSwapTermStructure);

            /***************
             * BOND PRICING *
             ****************/

            // write column headings
            int[] widths = { 18, 10, 10, 10 };

            Console.WriteLine("{0,18}{1,10}{2,10}{3,10}", "", "ZC", "Fixed", "Floating");

            int width = widths[0]
                        + widths[1]
                        + widths[2]
                        + widths[3];
            string rule = "".PadLeft(width, '-'), dblrule = "".PadLeft(width, '=');
            string tab = "".PadLeft(8, ' ');

            Console.WriteLine(rule);

            Console.WriteLine("Net present value".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}",
                              zeroCouponBond.NPV(),
                              fixedRateBond.NPV(),
                              floatingRateBond.NPV());

            Console.WriteLine("Clean price".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}",
                              zeroCouponBond.cleanPrice(),
                              fixedRateBond.cleanPrice(),
                              floatingRateBond.cleanPrice());

            Console.WriteLine("Dirty price".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}",
                              zeroCouponBond.dirtyPrice(),
                              fixedRateBond.dirtyPrice(),
                              floatingRateBond.dirtyPrice());

            Console.WriteLine("Accrued coupon".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}",
                              zeroCouponBond.accruedAmount(),
                              fixedRateBond.accruedAmount(),
                              floatingRateBond.accruedAmount());

            Console.WriteLine("Previous coupon".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}",
                              "N/A",
                              fixedRateBond.previousCouponRate(),
                              floatingRateBond.previousCouponRate());

            Console.WriteLine("Next coupon".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}",
                              "N/A",
                              fixedRateBond.nextCouponRate(),
                              floatingRateBond.nextCouponRate());

            Console.WriteLine("Yield".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}",
                              zeroCouponBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual),
                              fixedRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual),
                              floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual));

            Console.WriteLine();

            // Other computations
            Console.WriteLine("Sample indirect computations (for the floating rate bond): ");
            Console.WriteLine(rule);

            Console.WriteLine("Yield to Clean Price: {0:n2}",
                              floatingRateBond.cleanPrice(floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual),
                                                          new Actual360(), Compounding.Compounded, Frequency.Annual,
                                                          settlementDate));

            Console.WriteLine("Clean Price to Yield: {0:0.00%}",
                              floatingRateBond.yield(floatingRateBond.cleanPrice(), new Actual360(), Compounding.Compounded, Frequency.Annual,
                                                     settlementDate));

            /* "Yield to Price"
            *  "Price to Yield" */

            Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer);
            Console.WriteLine();

            Console.Write("Press any key to continue ...");
            Console.ReadKey();
        }
Пример #19
0
 public new FixedRateBond bond() {
   FixedRateBond ret = new FixedRateBond(NQuantLibcPINVOKE.FixedRateBondHelper_bond(swigCPtr), true);
   if (NQuantLibcPINVOKE.SWIGPendingException.Pending) throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
   return ret;
 }