コード例 #1
0
        /**
         * The value of the annuity (or RPV01 - the premium leg per unit of coupon) at a specified valuation time.
         * The actual value of the leg is this multiplied by the notional and the fractional coupon (i.e. coupon
         * in basis points divided by 10,000).
         * <p>
         * If this is a spot starting CDS (effective protection start = 0) then cash flows from premium payments
         * and accrual-on-default are risky discounted to t=0 ('today'), then rolled forward (risk-free) to the
         * valuation time; if the annuity is requested clean, the accrued premium (paid at the cash-settle time) is
         * rolled (again risk-free) to the valuation time; the absolute value of this amount is subtracted from the
         * other cash flows to give the clean annuity.
         * <p>
         * If this is a forward starting CDS (effective protection start > 0), then the premium payments are again
         * risky discounted to t=0; if the annuity is requested clean, the accrued premium is risk-free discounted
         * to the effective protection start, then risky discounted to t=0 - this gives the t=0 value of the annuity
         * including the chance that a default occurs before protection starts.
         * <p>
         * If valuationTime > 0, the value of the annuity is rolled forward (risk-free) to that time.
         * To compute the Expected value of the annuity conditional on no default before the valuationTime,
         * one must divide this number by the survival probability to the valuationTime (for unit coupon).
         *
         * @param cds  the analytic description of a CDS traded at a certain time
         * @param yieldCurve  the yield (or discount) curve
         * @param creditCurve  the credit (or survival) curve
         * @param cleanOrDirty  the clean or dirty price
         * @param valuationTime  the valuation time
         * @return 10,000 times the RPV01 (on a notional of 1)
         */
        public double Annuity(CDS cds, PiecewiseconstantHazardRate hazard,
                              YieldTermStructure yt, CdsPriceType cleanOrDirt)
        {
            List <CashFlow> cf             = cds.FixLeg;
            DateTime        tradedate      = cds.tradedate;
            DateTime        settlementDate = tradedate.AddDays(cds.Cashsettlement);
            double          recoveryrate   = cds.Recovery;
            DateTime        Stepindate     = tradedate.AddDays(1);

            OMLib.Conventions.DayCount.Actual360 dc = new OMLib.Conventions.DayCount.Actual360();
            double   notional    = cds.Notional;
            double   coupon      = cds.PremiumRate;
            DateTime lastpayment = cds.formerpaymentdate;

            if (cf.Count() == 0)
            {
                return(0.0);
            }
            double ita      = (double)365 / 360;
            double totalNPV = 0.0;

            for (int i = 0; i < cf.Count; ++i)
            {
                totalNPV += cf[i].Amount * cf[i].DiscountFactor * cf[i].Survivalprobability;
            }
            double accrualpaidondefault = calculateSinglePeriodAccrualOnDefault(cds, yt, hazard);

            totalNPV += ita * coupon * accrualpaidondefault * notional / yt.discount(tradedate.AddDays(3));
            Calendar calendar = new UnitedStates();


            return(totalNPV / yt.discount(settlementDate));
        }
コード例 #2
0
        public double ProtectionLegNPV_Exact(List <CashFlow> cf, double notional, PiecewiseconstantHazardRate hazard,
                                             YieldTermStructure yt, DateTime tradedate, DateTime settlementDate, double recoveryrate, List <DateTime> Jumps, List <DateTime> creditCurveKnot)
        {
            DateTime Stepindate = tradedate.AddDays(1);

            OMLib.Conventions.DayCount.Actual360 dc = new OMLib.Conventions.DayCount.Actual360();

            if (cf.Count() == 0)
            {
                return(0.0);
            }
            DateTime        t0        = tradedate;
            DateTime        T         = cf.Last().CashFlowDate;
            List <DateTime> JumpNodes = new List <DateTime>();

            JumpNodes.Add(t0);
            for (int j = 0; j < Jumps.Count; j++)
            {
                if ((DateTime.Compare(Jumps[j], T) < 0))
                {
                    JumpNodes.Add(Jumps[j]);
                }
            }
            JumpNodes.Add(T);
            double ht0 = hazard.getRT(JumpNodes[0]);
            double rt0 = yt.getRT(JumpNodes[0]);
            double b0  = Math.Exp(-ht0 - rt0); // risky discount factor

            double pv  = 0.0;
            double dPV = 0.0;

            for (int i = 1; i < JumpNodes.Count; ++i)
            {
                double ht1 = hazard.getRT(JumpNodes[i]);
                double rt1 = yt.getRT(JumpNodes[i]);
                double b1  = Math.Exp(-ht1 - rt1);

                double dht  = ht1 - ht0;
                double drt  = rt1 - rt0;
                double dhrt = dht + drt;

                // The formula has been modified from ISDA (but is equivalent) to avoid log(exp(x)) and explicitly
                // calculating the time step - it also handles the limit
                if (Math.Abs(dhrt) < 1e-5)
                {
                    dPV = dht * b0 * (Math.Exp(-dhrt) - 1) / (-dhrt);
                }
                else
                {
                    dPV = (b0 - b1) * dht / dhrt;
                }
                pv += dPV;
                ht0 = ht1;
                rt0 = rt1;
                b0  = b1;
            }
            return(pv * notional * (1 - recoveryrate) / yt.discount(settlementDate));
        }
コード例 #3
0
        /// <summary>
        /// A date based description of a CDS accrual period.
        /// </summary>
        /// <param name="accStart">  the start date of the period </param>
        /// <param name="accEnd">  the end date of the period </param>
        /// <param name="paymentDate">  the payment date for the period </param>
        /// <param name="accrualDCC">  the day count used for the accrual  </param>
        public CdsCouponDes(DateTime accStart, DateTime accEnd, DateTime paymentDate, Enums.DayCount accrualDCC)
        {

            _accStart = accStart;
            _accEnd = accEnd;
            _paymentDate = paymentDate;
            OMLib.Conventions.DayCount.Actual360 accDCC = new OMLib.Conventions.DayCount.Actual360();
            _yearFrac = accDCC.YearFraction(accStart, accEnd);
        }
コード例 #4
0
ファイル: CDS.cs プロジェクト: suhasghorp/CDS_Csharp
        public CDS(double Coupon, double notional, DateTime maturity, DateTime firstpaymentday, DateTime tradedate,
                   DateTime formerpaymentday, string frequency, double recovery, int settlement, int Cashsettlement)
        {
            //  Product Setup
            OMLib.Conventions.DayCount.Actual360 AccuralDCC = new OMLib.Conventions.DayCount.Actual360();
            OMLib.Conventions.DayCount.Actual365 curveDCC   = new OMLib.Conventions.DayCount.Actual365();
            Calendar calendar = new UnitedStates();

            formerpaymentday = calendar.adjust(formerpaymentday, BusinessDayConvention.Following);
            int accrued = AccuralDCC.DayCount(formerpaymentday, calendar.adjust(tradedate, BusinessDayConvention.Following)) + 1;

            this.accruedday       = accrued;
            this.marketvalue      = new double();
            this.accruedamt       = notional * Coupon * accrued / 360;
            this.Notional         = notional;
            this._payAccOnDefault = true;
            OMLib.Conventions.BusinessDayConvention convention = new OMLib.Conventions.BusinessDayConvention(Enums.BusinessDayConvention.ModifiedFollowing, tradedate);
            this.tradedate = calendar.adjust(tradedate, BusinessDayConvention.ModifiedFollowing); /*convention.AdjustedDate;*/

            this.Recovery         = recovery;
            convention            = new OMLib.Conventions.BusinessDayConvention(Enums.BusinessDayConvention.ModifiedFollowing, firstpaymentday);
            this.firstpaymentdate = CdsAnalyticFactory.getNextIMMDate(tradedate);   /*convention.AdjustedDate;*/

            convention             = new OMLib.Conventions.BusinessDayConvention(Enums.BusinessDayConvention.ModifiedFollowing, formerpaymentday);
            this.formerpaymentdate = CdsAnalyticFactory.getPrevIMMDate(tradedate);//calendar.adjust(formerpaymentday,BusinessDayConvention.ModifiedFollowing); /*convention.AdjustedDate;*/
            this.Maturity          = maturity;
            this.PremiumRate       = Coupon;
            this.Frequency         = frequency;
            this.Cashsettlement    = Cashsettlement;
            DateTime valueDate = calendar.adjust(tradedate.AddDays(Cashsettlement));

            convention            = new OMLib.Conventions.BusinessDayConvention(Enums.BusinessDayConvention.ModifiedFollowing, tradedate.AddDays(3));
            this.evalDate         = calendar.adjust(tradedate.AddDays(settlement), BusinessDayConvention.ModifiedFollowing); /*convention.AdjustedDate;*/
            this.Payment_Schedule = PremiumDates(this.Maturity, CdsAnalyticFactory.getNextIMMDate(tradedate), this.Frequency);
            QLNet.Calendar.OrthodoxImpl cal             = new Calendar.OrthodoxImpl();
            IsdaPremiumLegSchedule      paymentSchedule = new IsdaPremiumLegSchedule(formerpaymentdate, maturity, payment_interval, StubConvention.SHORT_INITIAL, QLNet.BusinessDayConvention.ModifiedFollowing, cal, true);

            _coupons = CdsCoupon.makeCoupons(tradedate, paymentSchedule, true, ACT_360, ACT_365);
            OMLib.Conventions.DayCount.Actual365 CurveDCC = new OMLib.Conventions.DayCount.Actual365();

            DateTime effectiveStartDate = tradedate;

            _accStart = DateTime.Compare(formerpaymentdate, tradedate) < 0 ?-CurveDCC.YearFraction(formerpaymentdate, tradedate) :
                        CurveDCC.YearFraction(tradedate, formerpaymentdate);
            _cashSettlementTime       = CurveDCC.YearFraction(tradedate, valueDate);
            _effectiveProtectionStart = DateTime.Compare(effectiveStartDate, tradedate) < 0 ?
                                        -CurveDCC.YearFraction(effectiveStartDate, tradedate) :
                                        CurveDCC.YearFraction(tradedate, effectiveStartDate);
            _protectionEnd = CurveDCC.YearFraction(tradedate, maturity);


            DateTime accStart = paymentSchedule.getAccStartDate(0);
        }
コード例 #5
0
        public double PremiumLegNPV_Exact(CDS cds, PiecewiseconstantHazardRate hazard,
                                          YieldTermStructure yt, DateTime tradedate, DateTime settlementDate, double notional, double coupon, List <double> Jumps, DateTime lastpayment)
        {
            double ita      = (double)365 / 360;
            double totalNPV = 0.0;

            CdsCoupon[] cf = cds.getCoupons();
            for (int i = 0; i < cf.Length; ++i)
            {
                totalNPV += cf[i].getYearFrac() * notional * Math.Exp(-hazard.getRT_(cf[i].getEffEnd()))
                            * Math.Exp(-yt.getRT_(cf[i].getEffEnd()));
            }
            double accrualpaidondefault = calculateSinglePeriodAccrualOnDefault(cf, coupon, tradedate, yt, hazard, lastpayment);

            totalNPV += ita * coupon * accrualpaidondefault * notional / yt.discount(tradedate.AddDays(3));
            OMLib.Conventions.DayCount.Actual360 dc = new OMLib.Conventions.DayCount.Actual360();
            Calendar calendar = new UnitedStates();


            return(totalNPV / Math.Exp(-yt.getRT_(cds.getCashSettleTime())));
        }
コード例 #6
0
        public BasicFixedLeg(
            DateTime spotDate,
            DateTime mat,
            int swapInterval
            )
        {
            OMLib.Conventions.DayCount.Thirty360 swapDCC        = new OMLib.Conventions.DayCount.Thirty360();
            OMLib.Conventions.DayCount.Actual360 moneyMarketDCC = new OMLib.Conventions.DayCount.Actual360();
            OMLib.Conventions.DayCount.Actual365 curveDCC       = new OMLib.Conventions.DayCount.Actual365();
            QLNet.UnitedStates cal   = new QLNet.UnitedStates();
            List <DateTime>    list  = new List <DateTime>();
            DateTime           tDate = mat;
            int step = 1;

            while (DateTime.Compare(tDate, spotDate) > 0)
            {
                list.Add(tDate);
                tDate = mat.AddMonths(-swapInterval * (step++));
            }

            // remove spotDate from list, if it ends up there
            list.Remove(spotDate);

            _nPayments        = list.Count();
            _swapPaymentTimes = new double[_nPayments];
            _yearFraction     = new double[_nPayments];

            DateTime prev = spotDate;
            int      j    = _nPayments - 1;

            for (int i = 0; i < _nPayments; i++, j--)
            {
                DateTime current = list[j];
                DateTime adjCurr = cal.adjust(current, QLNet.BusinessDayConvention.Following);

                _yearFraction[i]     = swapDCC.YearFraction(prev, adjCurr);
                _swapPaymentTimes[i] = curveDCC.YearFraction(spotDate, adjCurr); // Payment times always good business days
                prev = adjCurr;
            }
        }
コード例 #7
0
        public double PremiumLegNPV_Exact(List <CashFlow> cf, PiecewiseconstantHazardRate hazard,
                                          YieldTermStructure yt, DateTime tradedate, DateTime settlementDate, double notional, double coupon, List <DateTime> Jumps, DateTime lastpayment)
        {
            if (cf.Count() == 0)
            {
                return(0.0);
            }
            double ita      = (double)365 / 360;
            double totalNPV = 0.0;

            for (int i = 0; i < cf.Count; ++i)
            {
                totalNPV += cf[i].Amount * cf[i].DiscountFactor * cf[i].Survivalprobability;
            }
            double accrualpaidondefault = calculateSinglePeriodAccrualOnDefault(cf, coupon, tradedate, yt, hazard, Jumps, lastpayment);

            totalNPV += ita * coupon * accrualpaidondefault * notional / yt.discount(tradedate.AddDays(3));
            OMLib.Conventions.DayCount.Actual360 dc = new OMLib.Conventions.DayCount.Actual360();
            Calendar calendar = new UnitedStates();


            return(totalNPV / yt.discount(settlementDate));
        }
コード例 #8
0
        /**
         * The value of the full (or dirty) annuity (or RPV01 - the premium leg per unit of coupon) today (t=0).
         * The cash flows from premium payments and accrual-on-default are risky discounted to t=0
         * The actual value of the leg is this multiplied by the notional and the fractional coupon
         * (i.e. coupon in basis points divided by 10,000).
         * <p>
         * This is valid for both spot and forward starting CDS.
         *
         * @param cds  the analytic description of a CDS traded at a certain time
         * @param yieldCurve  the yield (or discount) curve
         * @param creditCurve  the credit (or survival) curve
         * @return the full (or dirty) annuity valued today. <b>Note</b> what is usually quoted is the clean annuity
         */
        public double dirtyAnnuity(CDS cds,
                                   YieldTermStructure yt, PiecewiseconstantHazardRate hazard)
        {
            DateTime        tradedate      = cds.tradedate;
            List <DateTime> Jumps          = yt.jumpDates_;
            DateTime        settlementDate = tradedate.AddDays(0);
            double          recoveryrate   = cds.Recovery;
            DateTime        Stepindate     = tradedate.AddDays(1);
            double          coupon         = cds.PremiumRate;

            OMLib.Conventions.DayCount.Actual360 dc = new OMLib.Conventions.DayCount.Actual360();

            CdsCoupon[] cf       = cds.getCoupons();
            double      notional = cds.Notional;

            double ita      = (double)365 / 360;
            double totalNPV = 0.0;

            for (int i = 0; i < cf.Length; ++i)
            {
                totalNPV += cf[i].getYearFrac() * notional * Math.Exp(-hazard.getRT_(cf[i].getEffEnd()))
                            * Math.Exp(-yt.getRT_(cf[i].getPaymentTime()));
            }

            double start = cds.getNumPayments() == 1 ? cds.getEffectiveProtectionStart() : cds.getAccStart();

            double[] integrationSchedule = DoublesScheduleGenerator.getIntegrationsPoints(start, cds.getProtectionEnd(), yt, hazard);
            double   accPV = 0.0;

            for (int i = 0; i < cf.Length; ++i)
            {
                accPV += calculateSinglePeriodAccrualOnDefault(cf[i], cds.getEffectiveProtectionStart(), integrationSchedule, yt, hazard);
            }
            totalNPV += accPV;

            return(totalNPV);
        }
コード例 #9
0
        public YieldTermStructure calculation(DateTime tradedate, List <double> QuotedSpot)
        {
            DateTime SpotDate = tradedate.AddDays(2);

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

            DateTime d1m  = SpotDate.AddMonths(1);
            DateTime d2m  = SpotDate.AddMonths(2);
            DateTime d3m  = SpotDate.AddMonths(3);
            DateTime d6m  = SpotDate.AddMonths(6);
            DateTime d9m  = SpotDate.AddMonths(9);
            DateTime d1y  = SpotDate.AddYears(1);
            DateTime d2y  = SpotDate.AddYears(2);
            DateTime d3y  = SpotDate.AddYears(3);
            DateTime d4y  = SpotDate.AddYears(4);
            DateTime d5y  = SpotDate.AddYears(5);
            DateTime d6y  = SpotDate.AddYears(6);
            DateTime d7y  = SpotDate.AddYears(7);
            DateTime d8y  = SpotDate.AddYears(8);
            DateTime d9y  = SpotDate.AddYears(9);
            DateTime d10y = SpotDate.AddYears(10);
            DateTime d11y = SpotDate.AddYears(11);
            DateTime d12y = SpotDate.AddYears(12);
            DateTime d15y = SpotDate.AddYears(15);
            DateTime d20y = SpotDate.AddYears(20);
            DateTime d25y = SpotDate.AddYears(25);
            DateTime d30y = SpotDate.AddYears(30);

            List <DateTime> dates = new List <DateTime>();

            dates.Add(d1m);
            dates.Add(d2m);
            dates.Add(d3m);
            dates.Add(d6m);
            dates.Add(d9m);
            dates.Add(d1y);
            dates.Add(d2y);
            dates.Add(d3y);
            dates.Add(d4y);
            dates.Add(d5y);
            dates.Add(d6y);
            dates.Add(d7y);
            dates.Add(d8y);
            dates.Add(d9y);
            dates.Add(d10y);
            dates.Add(d11y);
            dates.Add(d12y);
            dates.Add(d15y);
            dates.Add(d20y);
            dates.Add(d25y);
            dates.Add(d30y);
            // Any DayCounter would be fine.
            // ActualActual::ISDA ensures that 30 years is 30.0
            OMLib.Conventions.DayCount.Actual365 dc = new OMLib.Conventions.DayCount.Actual365();
            QLNet.UnitedStates calendar             = new QLNet.UnitedStates();
            String[]           YIELD_CURVE_POINTS   = new String[] { "1M", "2M", "3M", "6M", "9M", "1Y", "2Y", "3Y", "4Y", "5Y",
                                                                     "6Y", "7Y", "8Y", "9Y", "10Y", "11Y", "12Y", "15Y", "20Y", "25Y", "30Y" };
            String[] YIELD_CURVE_INSTRUMENTS = new String[] { "M", "M", "M", "M", "M", "M", "S", "S", "S", "S", "S",
                                                              "S", "S", "S", "S", "S", "S", "S", "S", "S", "S" };

            DateTime        today       = tradedate;
            List <DateTime> matDates    = dates;
            List <DateTime> adjMatDates = new List <DateTime>();

            OMLib.Conventions.DayCount.Thirty360 swapDCC        = new OMLib.Conventions.DayCount.Thirty360();
            OMLib.Conventions.DayCount.Actual360 moneyMarketDCC = new OMLib.Conventions.DayCount.Actual360();
            OMLib.Conventions.DayCount.Actual365 curveDCC       = new OMLib.Conventions.DayCount.Actual365();
            for (int i = 0; i < matDates.Count; i++)
            {
                adjMatDates.Add(calendar.adjust(matDates[i], QLNet.BusinessDayConvention.Following));
            }
            adjMatDates[2] = adjMatDates[2].AddDays(-1);
            int nMM = 0;
            int n   = YIELD_CURVE_INSTRUMENTS.Count();

            double[] _t = new double[n];
            for (int i = 0; i < n; i++)
            {
                _t[i] = curveDCC.YearFraction(SpotDate, adjMatDates[i]);
                if (YIELD_CURVE_INSTRUMENTS[i] == "M")
                {
                    nMM++;
                }
            }
            int nSwap = n - nMM;

            double[]        _mmYF     = new double[nMM];
            BasicFixedLeg[] _swaps    = new BasicFixedLeg[nSwap];
            int             mmCount   = 0;
            int             swapCount = 0;

            int swapInterval = 12;

            for (int i = 0; i < n; i++)
            {
                if (YIELD_CURVE_INSTRUMENTS[i] == "M")
                {
                    // TODO in ISDA code money market instruments of less than 21 days have special treatment
                    _mmYF[mmCount++] = moneyMarketDCC.YearFraction(SpotDate, adjMatDates[i]);
                }
                else
                {
                    _swaps[swapCount++] = new BasicFixedLeg(SpotDate, matDates[i], swapInterval);
                }
            }
            double _offset = DateTime.Compare(tradedate, SpotDate) > 0 ? curveDCC.YearFraction(SpotDate, tradedate) : -curveDCC.YearFraction(
                tradedate, SpotDate);
            YieldTermStructure curve = new YieldTermStructure(tradedate, QuotedSpot, dates, _t.ToList(), null);
            int mmCount_             = 0;
            int swapCount_           = 0;

            double[] rt_ = new double[n];
            for (int i = 0; i < n; i++)
            {
                if (YIELD_CURVE_INSTRUMENTS[i] == "M")
                {
                    // TODO in ISDA code money market instruments of less than 21 days have special treatment
                    double             z         = 1.0 / (1 + QuotedSpot[i] * _mmYF[mmCount_++]);
                    YieldTermStructure tempcurve = curve.withDiscountFactor(z, i);
                    curve = tempcurve;
                }
                else
                {
                    curve = curve.fitSwap(i, _swaps[swapCount_++], curve, QuotedSpot[i]);
                }
            }
            YieldTermStructure baseCurve = curve;
            List <double>      ZeroRates = curve.getKnotZeroRates();

            if (_offset == 0.0)
            {
                return(baseCurve);
            }

            this.Nodes = dates;
            return(baseCurve.withOffset(_offset));
        }
コード例 #10
0
        public YieldTermStructure calculation2(DateTime tradedate, List <double> QuotedSpot)
        {
            /*********************
            ***  MARKET DATA  ***
            *********************/
            QLNet.UnitedStates cal = new QLNet.UnitedStates();


            DateTime SpotDate = tradedate.AddDays(4);
            //DateTime SpotDate = cal.advance(tradedate,2,QLNet.TimeUnit.Days,QLNet.BusinessDayConvention.ModifiedFollowing);
            // must be a business day

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

            DateTime d1m  = SpotDate.AddMonths(1);
            DateTime d2m  = SpotDate.AddMonths(2);
            DateTime d3m  = SpotDate.AddMonths(3);
            DateTime d6m  = SpotDate.AddMonths(6);
            DateTime d1y  = SpotDate.AddYears(1);
            DateTime d2y  = SpotDate.AddYears(2);
            DateTime d3y  = SpotDate.AddYears(3);
            DateTime d4y  = SpotDate.AddYears(4);
            DateTime d5y  = SpotDate.AddYears(5);
            DateTime d6y  = SpotDate.AddYears(6);
            DateTime d7y  = SpotDate.AddYears(7);
            DateTime d8y  = SpotDate.AddYears(8);
            DateTime d9y  = SpotDate.AddYears(9);
            DateTime d10y = SpotDate.AddYears(10);
            DateTime d12y = SpotDate.AddYears(12);
            DateTime d15y = SpotDate.AddYears(15);
            DateTime d20y = SpotDate.AddYears(20);
            DateTime d25y = SpotDate.AddYears(25);
            DateTime d30y = SpotDate.AddYears(30);

            List <DateTime> dates = new List <DateTime>();

            dates.Add(d1m);
            dates.Add(d2m);
            dates.Add(d3m);
            dates.Add(d6m);
            dates.Add(d1y);
            dates.Add(d2y);
            dates.Add(d3y);
            dates.Add(d4y);
            dates.Add(d5y);
            dates.Add(d6y);
            dates.Add(d7y);
            dates.Add(d8y);
            dates.Add(d9y);
            dates.Add(d10y);
            dates.Add(d12y);
            dates.Add(d15y);
            dates.Add(d20y);
            dates.Add(d25y);
            dates.Add(d30y);
            // Any DayCounter would be fine.
            // ActualActual::ISDA ensures that 30 years is 30.0
            OMLib.Conventions.DayCount.Actual365 dc = new OMLib.Conventions.DayCount.Actual365();
            QLNet.UnitedStates calendar             = new QLNet.UnitedStates();
            String[]           YIELD_CURVE_POINTS   = new String[] { "1M", "2M", "3M", "6M", "1Y", "2Y", "3Y", "4Y", "5Y",
                                                                     "6Y", "7Y", "8Y", "9Y", "10Y", "12Y", "15Y", "20Y", "25Y", "30Y" };
            String[] YIELD_CURVE_INSTRUMENTS = new String[] { "M", "M", "M", "M", "M", "S", "S", "S", "S", "S",
                                                              "S", "S", "S", "S", "S", "S", "S", "S", "S" };
            List <double> YIELD_CURVE_RATES = QuotedSpot;

            DateTime        spotDate    = SpotDate;
            List <DateTime> matDates    = dates;
            List <DateTime> adjMatDates = new List <DateTime>();

            OMLib.Conventions.DayCount.Thirty360 swapDCC        = new OMLib.Conventions.DayCount.Thirty360();
            OMLib.Conventions.DayCount.Actual360 moneyMarketDCC = new OMLib.Conventions.DayCount.Actual360();
            OMLib.Conventions.DayCount.Actual365 curveDCC       = new OMLib.Conventions.DayCount.Actual365();
            for (int i = 0; i < matDates.Count; i++)
            {
                adjMatDates.Add(calendar.adjust(matDates[i], QLNet.BusinessDayConvention.ModifiedFollowing));
            }
            int nMM = 0;
            int n   = YIELD_CURVE_INSTRUMENTS.Count();

            double[] _t = new double[n];
            for (int i = 0; i < n; i++)
            {
                _t[i] = curveDCC.YearFraction(spotDate, adjMatDates[i]);
                if (YIELD_CURVE_INSTRUMENTS[i] == "M")
                {
                    nMM++;
                }
            }
            int nSwap = n - nMM;

            double[]        _mmYF     = new double[nMM];
            BasicFixedLeg[] _swaps    = new BasicFixedLeg[nSwap];
            int             mmCount   = 0;
            int             swapCount = 0;

            int swapInterval = 6;

            for (int i = 0; i < n; i++)
            {
                if (YIELD_CURVE_INSTRUMENTS[i] == "M")
                {
                    // TODO in ISDA code money market instruments of less than 21 days have special treatment
                    _mmYF[mmCount++] = moneyMarketDCC.YearFraction(spotDate, adjMatDates[i]);
                }
                else
                {
                    _swaps[swapCount++] = new BasicFixedLeg(spotDate, matDates[i], swapInterval);
                }
            }
            double _offset = DateTime.Compare(tradedate, spotDate) > 0 ? curveDCC.YearFraction(spotDate, tradedate) : -curveDCC.YearFraction(
                tradedate, spotDate);
            YieldTermStructure curve = new YieldTermStructure(tradedate, YIELD_CURVE_RATES, dates, _t.ToList(), null);
            int mmCount_             = 0;
            int swapCount_           = 0;

            double[] rt_ = new double[n];
            for (int i = 0; i < n; i++)
            {
                if (YIELD_CURVE_INSTRUMENTS[i] == "M")
                {
                    // TODO in ISDA code money market instruments of less than 21 days have special treatment
                    double             z         = 1.0 / (1 + YIELD_CURVE_RATES[i] * _mmYF[mmCount_++]);
                    YieldTermStructure tempcurve = curve.withDiscountFactor(z, i);
                    curve = tempcurve;
                }
                else
                {
                    curve = curve.fitSwap(i, _swaps[swapCount_++], curve, YIELD_CURVE_RATES[i]);
                }
            }
            YieldTermStructure baseCurve = curve;
            List <double>      ZeroRates = curve.getKnotZeroRates();

            if (_offset == 0.0)
            {
                return(baseCurve);
            }

            this.Nodes = dates;
            curve      = baseCurve.withOffset(_offset);
            //List<double> rt = new List<double>() { 1.399914257002842E-4, 3.452229985902273E-4, 6.151397497988689E-4, 0.0017010975470283791, 0.005696357532861686, 0.008854793051714499, 0.0235368691596982, 0.04799336562986048, 0.07980430061988725, 0.11682686636178839, 0.1569272410971123, 0.1988340941576404, 0.24178776149530337, 0.2862865792161734, 0.37671732698783206, 0.512340347238558, 0.7299269275257245, 0.9365962573841474, 1.1363739062462221};
            //curve.rt = rt;
            return(curve);
        }
コード例 #11
0
        /**
         * Set up a strip of increasing maturity CDSs that have some coupons in common.  The trade date, step-in date and valuation date and
         * accrual start date are all common, as is the payment frequency. The maturities are expressed as integer multiples of the
         * payment interval from a reference date (the next IMM date after the trade date for standard CDSs) - this guarantees that premiums
         * will be the same across several CDSs.
         * @param tradeDate The trade date
         * @param stepinDate (aka Protection Effective sate or assignment date). Date when party assumes ownership. This is usually T+1. This is when protection
         * (and risk) starts in terms of the model. Note, this is sometimes just called the Effective Date, however this can cause
         * confusion with the legal effective date which is T-60 or T-90.
         * @param cashSettlementDate The cash settlement date. The date that values are PVed to. Is is normally today + 3 business days.
         * @param accStartDate  Accrual Start Date. This is when the CDS nominally starts in terms of premium payments.  i.e. the number
         * of days in the first period (and thus the amount of the first premium payment) is counted from this date.
         * @param maturityReferanceDate A reference date that maturities are measured from. For standard CDSSs, this is the next IMM  date after
         * the trade date, so the actually maturities will be some fixed periods after this.
         * @param maturityIndexes The maturities are fixed integer multiples of the payment interval, so for 6M, 1Y and 2Y tenors with a 3M
         * payment interval, would require 2, 4, and 8 as the indices
         * @param payAccOnDefault Is the accrued premium paid in the event of a default
         * @param paymentInterval The nominal step between premium payments (e.g. 3 months, 6 months).
         * @param stubType the stub convention
         * @param protectStart If protectStart = true, then protections starts at the beginning of the day, otherwise it is at the end.
         * @param recoveryRate The recovery rate
         * @param businessdayAdjustmentConvention How are adjustments for non-business days made
         * @param calendar HolidayCalendar defining what is a non-business day
         * @param accrualDayCount Day count used for accrual
         * @param curveDayCount Day count used on curve (NOTE ISDA uses ACT/365 and it is not recommended to change this)
         */
        public MultiCdsAnalytic(
            DateTime tradeDate,
            DateTime stepinDate,
            DateTime cashSettlementDate,
            DateTime accStartDate,
            DateTime maturityReferanceDate,
            int[] maturityIndexes,
            Boolean payAccOnDefault,
            int paymentInterval,
            StubConvention stubType,
            Boolean protectStart,
            double recoveryRate,
            QLNet.BusinessDayConvention businessdayAdjustmentConvention,
            QLNet.Calendar calendar,
            Enums.DayCount accrualDayCount,
            Enums.DayCount curveDayCount)
        {
            OMLib.Conventions.DayCount.Thirty360 swapDCC        = new OMLib.Conventions.DayCount.Thirty360();
            OMLib.Conventions.DayCount.Actual360 moneyMarketDCC = new OMLib.Conventions.DayCount.Actual360();
            OMLib.Conventions.DayCount.Actual365 curveDCC       = new OMLib.Conventions.DayCount.Actual365();

            _nMaturities     = maturityIndexes.Length;
            _payAccOnDefault = payAccOnDefault;


            _accStart = DateTime.Compare(accStartDate, tradeDate) < 0 ?
                        -curveDCC.YearFraction(accStartDate, tradeDate) :
                        curveDCC.YearFraction(tradeDate, accStartDate);
            DateTime temp = DateTime.Compare(stepinDate, accStartDate) > 0 ? stepinDate : accStartDate;
            DateTime effectiveStartDate = protectStart ? temp.AddDays(-1) : temp;

            _cashSettlementTime       = curveDCC.YearFraction(tradeDate, cashSettlementDate);
            _effectiveProtectionStart = curveDCC.YearFraction(tradeDate, effectiveStartDate);
            _lgd = 1 - recoveryRate;

            DateTime[] maturities = new DateTime[_nMaturities];
            _protectionEnd = new double[_nMaturities];
            int period = paymentInterval;

            for (int i = 0; i < _nMaturities; i++)
            {
                int tStep = period * maturityIndexes[i];
                maturities[i]     = maturityReferanceDate.AddMonths(tStep);
                _protectionEnd[i] = curveDCC.YearFraction(tradeDate, maturities[i]);
            }

            IsdaPremiumLegSchedule fullPaymentSchedule = new IsdaPremiumLegSchedule(accStartDate, maturities[_nMaturities - 1], period,
                                                                                    stubType, businessdayAdjustmentConvention, calendar, protectStart);
            //remove already expired coupons
            IsdaPremiumLegSchedule paymentSchedule = fullPaymentSchedule.truncateSchedule(stepinDate);
            int couponOffset = fullPaymentSchedule.getNumPayments() - paymentSchedule.getNumPayments();

            _totalPayments   = paymentSchedule.getNumPayments();
            _standardCoupons = new CdsCoupon[_totalPayments - 1];
            for (int i = 0; i < (_totalPayments - 1); i++)
            {     //The last coupon is actually a terminal coupon, so not included here
                _standardCoupons[i] = new CdsCoupon(
                    tradeDate, paymentSchedule.getAccPaymentDateTriplet(i), protectStart, accrualDayCount, curveDayCount);
            }

            //find the terminal coupons
            _terminalCoupons    = new CdsCoupon[_nMaturities];
            _matIndexToPayments = new int[_nMaturities];
            _accruedDays        = new int[_nMaturities];
            _accrued            = new double[_nMaturities];
            long secondJulianDate = stepinDate.Ticks;

            for (int i = 0; i < _nMaturities; i++)
            {
                int index = fullPaymentSchedule.getNominalPaymentDateIndex(maturities[i]);

                //maturity is unadjusted, but if protectionStart=true (i.e. standard CDS) there is effectively an extra day of accrued interest
                DateTime accEnd = protectStart ? maturities[i].AddDays(1) : maturities[i];
                _terminalCoupons[i] = new CdsCoupon(
                    tradeDate, fullPaymentSchedule.getAccStartDate(index), accEnd,
                    fullPaymentSchedule.getPaymentDate(index), protectStart);
                _matIndexToPayments[i] = index - couponOffset;
                //This will only matter for the edge case when the trade date is 1 day before maturity
                DateTime tDate2 = _matIndexToPayments[i] < 0 ?
                                  fullPaymentSchedule.getAccStartDate(couponOffset - 1) : paymentSchedule.getAccStartDate(0);
                long firstJulianDate = tDate2.Ticks;
                _accruedDays[i] = secondJulianDate > firstJulianDate ? (int)(secondJulianDate - firstJulianDate) : 0;
                _accrued[i]     = DateTime.Compare(tDate2, stepinDate) < 0 ? swapDCC.YearFraction(tDate2, stepinDate) : 0.0;
            }
        }
コード例 #12
0
        public List <CashFlow> Calculation(double fixrate, double initialNotional, List <DateTime> fixedSchedule, DateTime tradedate,
                                           YieldTermStructure yt, PiecewiseconstantHazardRate piecewiseFlatHazardRate, int settlement, DateTime lastpaymentdate)
        {
            List <CashFlow> result = new List <CashFlow>();

            OMLib.Conventions.DayCount.Actual360 daycountconvention = new OMLib.Conventions.DayCount.Actual360();
            for (int i = 0; i < fixedSchedule.Count; i++)
            {
                CashFlow cf       = new CashFlow();
                Calendar calendar = new UnitedStates();
                //fixedSchedule[i] = calendar.adjust(fixedSchedule[i], BusinessDayConvention.Following);
                cf.CashFlowDate = fixedSchedule[i];
                if (i == 0)
                {
                    //The protection buyer pays the next coupon in full on the coupon date,
                    //(even if this is the next day); in return the buyer receives (from the protection seller) the accrued
                    //interest[Geoff Chaplin. Credit Derivatives.], which is paid on the cash settlement date.
                    if (lastpaymentdate != null)
                    {
                        lastpaymentdate = calendar.adjust(lastpaymentdate, BusinessDayConvention.Following);
                        cf.Amount       = (double)initialNotional * fixrate * (daycountconvention.DayCount(lastpaymentdate, fixedSchedule[i])) / 360;
                    }
                    else
                    {
                        cf.Amount = (double)initialNotional * fixrate * (daycountconvention.DayCount(tradedate, fixedSchedule[i])) / 360;
                    }
                }
                else
                {
                    //Each coupon is equal to (annual coupon/360) (# of days in accrual period).
                    //The accrual period always stretches from (previous coupon payment date) through (this coupon
                    //payment date–1), inclusive; except a contract's last accrual period, which ends with (and
                    //includes) the unadjusted maturity date.
                    if (i == fixedSchedule.Count - 1)
                    {
                        cf.Amount = (double)initialNotional * fixrate * (daycountconvention.DayCount(fixedSchedule[i - 1], fixedSchedule[i].AddDays(1))) / 360;
                    }
                    else
                    {
                        cf.Amount = (double)initialNotional * fixrate * (daycountconvention.DayCount(fixedSchedule[i - 1], fixedSchedule[i])) / 360;
                    }
                }

                //Assume all cash flows are discounted to the cash settlement date

                cf.DiscountFactor = yt.discount(fixedSchedule[i]);

                if (i == fixedSchedule.Count - 1)
                {
                    cf.Survivalprobability = piecewiseFlatHazardRate.SurvivalProb(fixedSchedule[i].AddDays(1));
                }
                else
                {
                    cf.Survivalprobability = piecewiseFlatHazardRate.SurvivalProb(fixedSchedule[i]);
                }

                result.Add(cf);
            }

            return(result);
        }
コード例 #13
0
        public double protectionLeg(CDS cds, YieldTermStructure yt, PiecewiseconstantHazardRate hazard,
                                    double valuationTime)
        {
            List <double> Jumps = yt.t;
            List <double> tenor = hazard.t;
            List <double> result = new List <double>();
            int           index = 0, indexj = 0, lastIndex = 0;

            while (index < Jumps.Count || indexj < tenor.Count)
            {
                if (lastIndex > 0)
                {
                    if (index >= Jumps.Count)
                    {
                        if (!DateTime.Equals(result.Last(), tenor[indexj]))
                        {
                            result.Add(tenor[indexj]);
                            lastIndex++;
                        }
                        indexj++;
                        continue;
                    }
                    if (indexj >= tenor.Count)
                    {
                        if (!DateTime.Equals(result.Last(), Jumps[index]))
                        {
                            result.Add(Jumps[index]);
                            lastIndex++;
                        }
                        index++;
                        continue;
                    }
                }
                double smallestVal = tenor.Last();

                // Choose the smaller of a or b
                if (Jumps[index] < tenor[indexj])
                {
                    smallestVal = Jumps[index++];
                }
                else
                {
                    smallestVal = tenor[indexj++];
                }

                // Don't insert duplicates
                if (lastIndex > 0)
                {
                    if (result.Last() != smallestVal)
                    {
                        result.Add(smallestVal);
                        lastIndex++;
                    }
                }
                else
                {
                    result.Add(smallestVal);
                    lastIndex++;
                }
            }
            DateTime tradedate      = cds.tradedate;
            DateTime settlementDate = tradedate.AddDays((int)valuationTime * 365);
            double   recoveryrate   = cds.Recovery;
            DateTime Stepindate     = tradedate.AddDays(1);

            OMLib.Conventions.DayCount.Actual360 dc = new OMLib.Conventions.DayCount.Actual360();
            CdsCoupon[] cf       = cds.getCoupons();
            double      notional = cds.Notional;

            DateTime      t0        = tradedate;
            double        T         = cf.Last().getEffEnd();
            List <double> JumpNodes = new List <double>();

            JumpNodes.Add(0);
            for (int j = 0; j < result.Count; j++)
            {
                if (result[j] < T)
                {
                    JumpNodes.Add(result[j]);
                }
            }
            JumpNodes.Add(T);
            double ht0 = hazard.getRT_(JumpNodes[0]);
            double rt0 = yt.getRT_(JumpNodes[0]);
            double b0  = Math.Exp(-ht0 - rt0); // risky discount factor

            double pv  = 0.0;
            double dPV = 0.0;

            for (int i = 1; i < JumpNodes.Count; ++i)
            {
                double ht1 = hazard.getRT_(JumpNodes[i]);
                double rt1 = yt.getRT_(JumpNodes[i]);
                double b1  = Math.Exp(-ht1 - rt1);

                double dht  = ht1 - ht0;
                double drt  = rt1 - rt0;
                double dhrt = dht + drt;

                // The formula has been modified from ISDA (but is equivalent) to avoid log(exp(x)) and explicitly
                // calculating the time step - it also handles the limit
                if (Math.Abs(dhrt) < 1e-5)
                {
                    dPV = dht * b0 * Maths.Epsilon.epsilon(-dhrt) / (-dhrt);
                }
                else
                {
                    dPV = (b0 - b1) * dht / dhrt;
                }
                pv += dPV;
                ht0 = ht1;
                rt0 = rt1;
                b0  = b1;
            }
            pv = pv * notional * (1 - recoveryrate);
            return(pv / yt.discount(settlementDate));
        }