예제 #1
0
        public void RateCurveCalibrator_CanCalibrateTwoCurves()
        {
            var instruments              = new List <IRateCurveInstrument>();
            var zarCsaCurveDescription   = new DiscountingSourceDescription(_zar, new BankAccountNumeraire(_zar));
            var jibarDiscountDescription = new DiscountingSourceDescription(_zar, _jibar3M);

            instruments.Add(new DepoCurveInstrument(Tenor.FromMonths(3), 0.071, jibarDiscountDescription));
            instruments.Add(new FixedFloatSwapCurveInstrument(Tenor.FromMonths(6), _jibar3M, 0.0, 0.07,
                                                              zarCsaCurveDescription, FixedFloatSwapCurveInstrument.CurveToStrip.Forecast));
            instruments.Add(new FixedFloatSwapCurveInstrument(Tenor.FromYears(2), _jibar3M, 0.0, 0.07,
                                                              zarCsaCurveDescription, FixedFloatSwapCurveInstrument.CurveToStrip.Forecast));

            instruments.Add(new DepoCurveInstrument(Tenor.FromDays(1), 0.06, zarCsaCurveDescription));
            instruments.Add(new BasisSwapCurveInstrument(Tenor.FromYears(1), _jibar3M, _jibar1D, 0.0, 0.01,
                                                         zarCsaCurveDescription, BasisSwapCurveInstrument.CurveToStrip.DiscountCurve));
            instruments.Add(new BasisSwapCurveInstrument(Tenor.FromYears(2), _jibar3M, _jibar1D, 0.0, 0.01,
                                                         zarCsaCurveDescription, BasisSwapCurveInstrument.CurveToStrip.DiscountCurve));

            var calib = new RateCurveCalibrator(instruments, new MultiDimNewton(1e-8, 100),
                                                zarCsaCurveDescription, new FloatRateIndex[] { _jibar1D },
                                                jibarDiscountDescription, new FloatRateIndex[] { _jibar3M });
            var mdc = new MarketDataContainer();

            mdc.Set(calib);
            calib.TryCalibrate(_calibrationDate, mdc);
            var testValues   = instruments.Select(inst => Math.Abs(inst.Objective()));
            var maxTestValue = testValues.Max();

            Assert.AreEqual(0.0, maxTestValue, 1e-8);
        }
예제 #2
0
        public void TestInflationLinkedSwap()
        {
            //Testing the zero-coupon inflation swap
            //Parameterise test inputs below
            var payFixed  = -1;
            var startDate = new Date(2005, 8, 31);
            var nominal   = (double)5000000;
            var tenor     = Tenor.FromYears(2);
            var fixedRate = 0.036;
            var ccy       = TestHelpers.ZAR;
            var index     = new FloatRateIndex("ZAR.JIBAR.3M", ccy, "JIBAR", Tenor.FromMonths(3));
            var spread    = 0.0;

            Date[] cpiDates =
            { new Date(2005, 3, 1), new Date(2005,  4, 1), new Date(2005,  5, 1), new Date(2005,  6, 1), new Date(2005, 7, 1), new Date(2005, 8, 1),
              new Date(2005, 9, 1), new Date(2005, 10, 1), new Date(2005, 11, 1), new Date(2005, 12, 1), new Date(2006, 1, 1), new Date(2006, 2, 1),
              new Date(2006, 3, 1), new Date(2006,  4, 1), new Date(2006,  5, 1), new Date(2006,  6, 1), new Date(2006, 7, 1), new Date(2006, 8, 1),
              new Date(2006, 9, 1), new Date(2006, 10, 1), new Date(2006, 11, 1), new Date(2006, 12, 1), new Date(2007, 1, 1), new Date(2007, 2, 1),
              new Date(2007, 3, 1), new Date(2007,  4, 1), new Date(2007,  5, 1), new Date(2007,  6, 1), new Date(2007, 7, 1), new Date(2007, 8, 1),
              new Date(2007, 9, 1), new Date(2007, 10,              1)
              ,              };

            double[] cpiRates =
            {
                126.90, 127.60, 127.60, 127.40, 128.50,  129.0, 129.50, 129.60, 129.50, 129.50, 130.40, 130.50, 131.20, 131.80, 132.60, 133.60, 134.90,
                136.0,  136.30, 136.60, 136.50,  137.0, 138.20, 139.20,  138.0,  141.0, 141.80,  143.0, 144.40, 145.10, 146.10, 147.40
            };

            var zaCalendar = new Calendar("Test");

            Date[] curveDates =
            {
                new Date(2005, 8, 31), new Date(2005, 11, 30), new Date(2006, 2, 28), new Date(2006, 5, 31), new Date(2006, 8, 31), new Date(2006, 11, 30),
                new Date(2007, 2, 28), new Date(2007,  5, 31)
            };

            double[] curveRates = { 0.07004, 0.07164, 0.07092, 0.07079, 0.08224, 0.08918, 0.09075, 0.09354 };

            //Create curve used to determine swap cash flows
            IFloatingRateSource forecastCurve = new ForecastCurve(startDate, index, curveDates, curveRates);

            //Create instance of an inflation swap
            var inflationSwap = InflationLinkedSwapEx.CreateInflationLinkedSwap(payFixed, startDate, nominal, tenor, fixedRate, index, spread, zaCalendar, ccy);

            //Get results
            var results = inflationSwap.InflationLinkedSwapMeasures(cpiDates, cpiRates, forecastCurve);

            Assert.AreEqual(5856959.45, Math.Round((double)results.GetScalar(InflationLinkedSwapEx.Keys.FloatingLegCashFlows), 2), 1e-8);
            Assert.AreEqual(-5966334.90, Math.Round((double)results.GetScalar(InflationLinkedSwapEx.Keys.FixedLegCashFlows), 2), 1e-8);
            Assert.AreEqual(-109375.45, Math.Round((double)results.GetScalar(InflationLinkedSwapEx.Keys.NetCashFlows), 2), 1e-8);
        }
예제 #3
0
파일: CDSTest.cs 프로젝트: zhangz/QuantSA
        public void TestQuantoCDS()
        {
            var spot = 1.00;
            var relJumpSizeInDefault = -0.2;
            var cdsSpread            = 0.025;
            // Trades
            var anchorDate = new Date(2016, 11, 25);
            var refEntity  = TestHelpers.TestCp;

            DateGenerators.CreateDatesNoHolidays(Tenor.FromMonths(3), anchorDate, 20, out var paymentDates,
                                                 out var accrualFractions);
            var zarNotionals     = Vector.Ones(paymentDates.Length).Multiply(1000000.0);
            var zarSpreads       = Vector.Ones(paymentDates.Length).Multiply(cdsSpread);
            var usdSpreads       = zarSpreads.Multiply(1 + relJumpSizeInDefault); // Adjusted for the FX jump size.
            var boughtProtection = true;

            var cdsZAR = new CDS(refEntity, TestHelpers.ZAR, paymentDates, zarNotionals, zarSpreads, accrualFractions,
                                 boughtProtection);
            var cdsUSD = new CDS(refEntity, TestHelpers.USD, paymentDates, zarNotionals, usdSpreads, accrualFractions,
                                 boughtProtection);

            // Model
            var curveDates       = new[] { anchorDate, anchorDate.AddTenor(Tenor.FromYears(10)) };
            var expectedRecovery = 0.4;
            var hazardRates      = new[] { cdsSpread / (1 - expectedRecovery), cdsSpread / (1 - expectedRecovery) };
            var usdRates         = new[] { 0.01, 0.02 };
            var zarRates         = new[] { 0.07, 0.08 };
            var usdDiscountCurve = new DatesAndRates(TestHelpers.USD, anchorDate, curveDates, usdRates);
            var zarDiscountCurve = new DatesAndRates(TestHelpers.ZAR, anchorDate, curveDates, zarRates);
            var abcHazardCurve   = new HazardCurve(refEntity, anchorDate, curveDates, hazardRates);

            var fxSource = new FXForecastCurve(TestHelpers.USDZAR, spot, usdDiscountCurve, zarDiscountCurve);
            var fxVol    = 0.15;
            var model    = new DeterministicCreditWithFXJump(abcHazardCurve, TestHelpers.USDZAR, fxSource,
                                                             zarDiscountCurve, fxVol, relJumpSizeInDefault, expectedRecovery);

            // Valuation
            var N        = 5000;
            var coord    = new Coordinator(model, new List <Simulator>(), N);
            var zarValue = coord.Value(new[] { cdsZAR }, anchorDate);
            var usdValue = coord.Value(new[] { cdsUSD }, anchorDate);

            Assert.AreEqual(0.0, zarValue, 800.0); // about 2bp
            Assert.AreEqual(0.0, usdValue, 800.0); // about 2bp
        }
예제 #4
0
        public void RateCurveCalibrator_CanCalibrateSingleCurve()
        {
            var instruments   = new List <IRateCurveInstrument>();
            var discountCurve = new DiscountingSourceDescription(TestHelpers.ZAR);

            instruments.Add(new DepoCurveInstrument(Tenor.FromMonths(1), 0.071, discountCurve));
            instruments.Add(new DepoCurveInstrument(Tenor.FromMonths(3), 0.072, discountCurve));
            instruments.Add(new DepoCurveInstrument(Tenor.FromMonths(6), 0.073, discountCurve));
            instruments.Add(new FRACurveInstrument(Tenor.FromMonths(6), Tenor.FromMonths(9), TestHelpers.Jibar3M, 0.073));

            var calib = new RateCurveCalibrator(instruments, new MultiDimNewton(1e-8, 100), discountCurve,
                                                new FloatRateIndex[] { TestHelpers.Jibar3M });
            var mdc = new MarketDataContainer();

            mdc.Set(calib);
            calib.TryCalibrate(_calibrationDate, mdc);
            var testValues   = instruments.Select(inst => Math.Abs(inst.Objective()));
            var maxTestValue = testValues.Max();

            Assert.AreEqual(0.0, maxTestValue, 1e-8);
        }
예제 #5
0
        public static AssetSwap CreateAssetSwap(double payFixed, BesaJseBond besaJseBond, Date settleDate, FloatRateIndex index, double spread, Calendar calendar, Currency ccy, IDiscountingSource discountCurve)
        {
            //Design floating leg inputs
            var dayCount = Actual365Fixed.Instance;
            var unAdjResetDatesFloating   = new List <Date>();
            var unAdjPaymentDatesFloating = new List <Date>();
            var resetDatesFloating        = new List <Date>();
            var paymentDatesFloating      = new List <Date>();
            var accrualFractions          = new List <double>();
            var endDate             = besaJseBond.maturityDate;
            var paymentDateFloating = new Date(endDate);
            var resetDateFloating   = paymentDateFloating.SubtractTenor(index.Tenor);

            while (resetDateFloating >= settleDate)
            {
                unAdjPaymentDatesFloating.Add(paymentDateFloating);
                unAdjResetDatesFloating.Add(resetDateFloating);
                resetDatesFloating.Add(BusinessDayStore.ModifiedFollowing.Adjust(resetDateFloating, calendar));
                paymentDatesFloating.Add(BusinessDayStore.ModifiedFollowing.Adjust(paymentDateFloating, calendar));
                accrualFractions.Add(dayCount.YearFraction(BusinessDayStore.ModifiedFollowing.Adjust(resetDateFloating, calendar),
                                                           BusinessDayStore.ModifiedFollowing.Adjust(paymentDateFloating, calendar)));
                paymentDateFloating = new Date(resetDateFloating);
                resetDateFloating   = paymentDateFloating.SubtractTenor(index.Tenor);
            }

            resetDatesFloating.Reverse();
            paymentDatesFloating.Reverse();
            accrualFractions.Reverse();

            resetDatesFloating[0] = new Date(settleDate);
            var firstResetDate   = resetDatesFloating.First();
            var firstPaymentDate = paymentDatesFloating.First();

            accrualFractions[0] = dayCount.YearFraction(firstResetDate, firstPaymentDate);

            //Design Fixed leg inputs
            var unAdjPaymentDatesFixed = new List <Date>();
            var paymentDatesFixed      = new List <Date>();

            var thisYearCpn1 = new Date(settleDate.Year, besaJseBond.couponMonth1, besaJseBond.couponDay1);
            var thisYearCpn2 = new Date(settleDate.Year, besaJseBond.couponMonth2, besaJseBond.couponDay2);
            var lastYearCpn2 = new Date(settleDate.Year - 1, besaJseBond.couponMonth2, besaJseBond.couponDay2);

            Date lcd; //lcd stands for last coupon date

            if (settleDate > thisYearCpn2)
            {
                lcd = new Date(thisYearCpn2.Year, thisYearCpn2.Month, thisYearCpn2.Day);
            }
            if (settleDate > thisYearCpn1)
            {
                lcd = new Date(thisYearCpn1.Year, thisYearCpn1.Month, thisYearCpn1.Day);
            }
            lcd = new Date(lastYearCpn2.Year, lastYearCpn2.Month, lastYearCpn2.Day);

            Date ncd; //ncd stands for next coupon date

            if (lcd.Month == besaJseBond.couponMonth2)
            {
                ncd = new Date(lcd.Year + 1, besaJseBond.couponMonth1, besaJseBond.couponDay1);
            }
            else
            {
                ncd = new Date(lcd.Year, besaJseBond.couponMonth2, besaJseBond.couponDay2);
            }

            var paymentDateFixed = new Date(ncd.AddTenor(Tenor.FromMonths(6)));

            while (paymentDateFixed <= endDate)
            {
                unAdjPaymentDatesFixed.Add(paymentDateFixed);
                paymentDatesFixed.Add(BusinessDayStore.ModifiedFollowing.Adjust(paymentDateFixed, calendar));
                paymentDateFixed = paymentDateFixed.AddTenor(Tenor.FromMonths(6));
            }

            //create new instance of asset swap
            var assetSwap = new AssetSwap(payFixed, index, besaJseBond, resetDatesFloating, paymentDatesFloating, paymentDatesFixed, spread,
                                          accrualFractions, calendar, ccy);

            //Create trade date of the swap
            var effectiveDateDays = 3;
            var unAdjTradeDate    = settleDate.AddDays(-effectiveDateDays);
            var tradeDate         = BusinessDayStore.ModifiedFollowing.Adjust(unAdjTradeDate, assetSwap.zaCalendar);

            //Set value date
            assetSwap.SetValueDate(tradeDate);

            // Calculate the first fixing off the curve to use at all past dates.
            var df1       = discountCurve.GetDF(tradeDate);
            var laterDate = tradeDate.AddTenor(assetSwap.index.Tenor);
            var df2       = discountCurve.GetDF(laterDate);
            var dt        = (laterDate - tradeDate) / 365.0;
            var rate      = (df1 / df2 - 1) / dt;

            // Create the forecast curve from the discount curve
            IFloatingRateSource forecastCurve = new ForecastCurveFromDiscount(discountCurve, assetSwap.index,
                                                                              new FloatingRateFixingCurve1Rate(tradeDate, rate, assetSwap.index));

            //Setting index values
            var indexValues = new double[assetSwap.indexDates.Count];

            for (var i = 0; i < assetSwap.indexDates.Count; i++)
            {
                indexValues[i] = forecastCurve.GetForwardRate(assetSwap.indexDates[i]);
            }
            assetSwap.SetIndexValues(assetSwap.index, indexValues);

            return(assetSwap);
        }
예제 #6
0
        public void TestAssetSwap()
        {
            var settleDate         = new Date(2013, 3, 8);
            var maturityDate       = new Date(2015, 9, 15);
            var annualCouponRate   = 0.135;
            var couponMonth1       = 3;
            var couponDay1         = 15;
            var couponMonth2       = 9;
            var couponDay2         = 15;
            var booksCloseDateDays = 10;
            var notional           = 100000000;
            var payFixed           = -1;

            var ccy    = TestHelpers.ZAR;
            var index  = new FloatRateIndex("ZAR.JIBAR.3M", ccy, "JIBAR", Tenor.FromMonths(3));
            var ytm    = 0.05757;
            var spread = 0.0;


            Date[] holidays =
            {
                new Date(2013,  1,  1), new Date(2013, 3, 21), new Date(2013, 3, 29), new Date(2013,  4,  1), new Date(2013,  4, 27), new Date(2013,  5,  1),
                new Date(2013,  6, 17), new Date(2013, 8,  9), new Date(2013, 9, 24), new Date(2013, 12, 16), new Date(2013, 12, 25), new Date(2013, 12, 26),
                new Date(2014,  1,  1), new Date(2014, 3, 21), new Date(2014, 4, 18), new Date(2014,  4, 21), new Date(2014,  4, 28), new Date(2014,  5,  1),
                new Date(2014,  5,  7), new Date(2014, 6, 16), new Date(2014, 8,  9), new Date(2014,  9, 24), new Date(2014, 12, 16), new Date(2014, 12, 25),
                new Date(2014, 12, 26), new Date(2015, 1,  1), new Date(2015, 3, 21), new Date(2015,  4,  3), new Date(2015,  4,  6), new Date(2015,  4, 27),
                new Date(2015,  5,  1), new Date(2015, 6, 16), new Date(2015, 8, 10), new Date(2015,  9, 24), new Date(2015, 12, 16), new Date(2020, 12, 25),
                new Date(2020, 12, 26)
            };

            var zaCalendar = new Calendar("Test", holidays);

            var bond = new BesaJseBond(maturityDate, notional, annualCouponRate, couponMonth1,
                                       couponDay1, couponMonth2, couponDay2, booksCloseDateDays, zaCalendar, ccy);

            Date[] discountDates =
            {
                new Date(2013,  3, 6), new Date(2013, 4, 5), new Date(2013,  6, 5), new Date(2013, 9, 5), new Date(2013, 12, 5), new Date(2014, 3, 5),
                new Date(2014,  6, 5), new Date(2014, 9, 5), new Date(2014, 12, 5), new Date(2015, 3, 5), new Date(2015,  6, 5), new Date(2015, 9, 7),
                new Date(2015, 12, 7), new Date(2016, 3, 7), new Date(2016,  6, 6), new Date(2016, 9, 5), new Date(2016, 12, 5), new Date(2017, 3, 6),
                new Date(2017,  6, 5), new Date(2017, 9, 5), new Date(2017, 12, 5), new Date(2018, 3, 5), new Date(2018,  6, 5), new Date(2018, 9, 5),
                new Date(2018, 12, 5), new Date(2019, 3, 5), new Date(2019,  6, 5), new Date(2019, 9, 5), new Date(2019, 12, 5), new Date(2020, 3, 5),
            };

            double[] discountRates = { 0.0476968834358959, 0.0501430754329056, 0.0509218045201335, 0.0507490287827958, 0.0506113173158310, 0.0506165682297636,
                                       0.0507674467276694, 0.0510331587565828, 0.0513967654284081, 0.0518952383980752, 0.0524896820133486, 0.0530856475345829, 0.0536795171239116,
                                       0.0542763619213055, 0.0550232983685124, 0.0557743840043158, 0.0565215576596013, 0.0572650196269946, 0.0580081291489062, 0.0587559589725926,
                                       0.0595015505438427, 0.0602449665660311, 0.0609574950515419, 0.0616761490635943, 0.0623935543507907, 0.0631097408589442, 0.0637906604035856,
                                       0.0644782668196503, 0.0651654909303646, 0.0658597518938604 };

            var effectiveDateDays = 3;
            var unAdjTradeDate    = settleDate.AddDays(-effectiveDateDays);
            var tradeDate         = BusinessDayStore.ModifiedFollowing.Adjust(unAdjTradeDate, zaCalendar);

            IDiscountingSource discountCurve = new DatesAndRates(ccy, tradeDate, discountDates, discountRates);

            var swap    = AssetSwapEx.CreateAssetSwap(payFixed, bond, settleDate, index, spread, zaCalendar, ccy, discountCurve);
            var results = swap.AssetSwapMeasures(settleDate, ytm, discountCurve);

            Assert.AreEqual(117.66281, Math.Round((double)results.GetScalar(AssetSwapEx.Keys.RoundedAip), 5), 1e-8);
            Assert.AreEqual(17.65586, Math.Round((double)results.GetScalar(AssetSwapEx.Keys.PVFirstCF), 5), 1e-8);
            Assert.AreEqual(-18.645, Math.Round((double)results.GetScalar(AssetSwapEx.Keys.NumeratorCashFlowsPrice), 3), 1e-8);
            Assert.AreEqual(-234.909, Math.Round((double)results.GetScalar(AssetSwapEx.Keys.DenominatorCashFlowsPrice), 3), 1e-8);
            Assert.AreEqual(0.004211, Math.Round((double)results.GetScalar(AssetSwapEx.Keys.AssetSwapSpread), 6), 1e-8);
        }