示例#1
0
        public void OISFuture()
        {
            var bd       = DateTime.Today;
            var pillars  = new[] { bd, bd.AddDays(1000) };
            var flatRate = 0.05;
            var rates    = pillars.Select(p => flatRate).ToArray();

            CalendarProvider.Collection.TryGetCalendar("LON", out var cal);
            var usd        = TestProviderHelper.CurrencyProvider["USD"];
            var discoCurve = new IrCurve(pillars, rates, bd, "USD.BLAH", Interpolator1DType.Linear, usd);
            var fModel     = new FundingModel(bd, new[] { discoCurve }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider);
            var price      = 93.0;
            var ix         = new FloatRateIndex
            {
                Currency         = usd,
                DayCountBasis    = DayCountBasis.ACT360,
                FixingOffset     = 2.Bd(),
                HolidayCalendars = cal,
                ResetTenor       = 3.Months(),
                RollConvention   = RollType.MF
            };

            var maturity     = bd.AddDays(365);
            var accrualStart = maturity.AddPeriod(RollType.F, ix.HolidayCalendars, ix.FixingOffset);
            var accrualEnd   = accrualStart.AddPeriod(ix.RollConvention, ix.HolidayCalendars, ix.ResetTenor);
            var dcf          = maturity.CalculateYearFraction(accrualEnd, DayCountBasis.ACT360);
            var s            = new OISFuture
            {
                Currency         = usd,
                ContractSize     = 1e6,
                Position         = 1,
                DCF              = dcf,
                AverageStartDate = accrualStart,
                AverageEndDate   = accrualEnd,
                ForecastCurve    = "USD.BLAH",
                Price            = price,
                Index            = ix
            };

            var pv        = s.Pv(fModel, false);
            var rateEst   = discoCurve.GetForwardRate(accrualStart, accrualEnd, RateType.Linear, ix.DayCountBasis);
            var fairPrice = 100.0 - rateEst * 100;

            var expectedPv = (price - fairPrice) * 1e6 * dcf;

            Assert.Equal(expectedPv, pv);

            var ss = s.Sensitivities(fModel);

            Assert.True(ss.Count == 1 && ss.Keys.Single() == "USD.BLAH");
            Assert.True(ss["USD.BLAH"].Count == 2 && ss["USD.BLAH"].Keys.Contains(accrualStart) && ss["USD.BLAH"].Keys.Contains(accrualEnd));

            Assert.Equal(accrualEnd, s.LastSensitivityDate);
            Assert.Empty(s.Dependencies(null));

            var s2 = (OISFuture)s.SetParRate(97);

            Assert.Equal(97, s2.Price);
        }
示例#2
0
        public double Pv(IrCurve discountCurve, IrCurve forecastCurve, bool updateState, bool updateDF, bool updateEstimate)
        {
            var totalPV = 0.0;

            if (FlowScheduleFra.Flows.Count != 1)
            {
                throw new InvalidOperationException("FRA should have a sinlge flow");
            }

            var flow = FlowScheduleFra.Flows.Single();

            var s = flow.AccrualPeriodStart;
            var e = flow.AccrualPeriodEnd;

            double FV, DF;

            if (updateEstimate)
            {
                var RateFix   = flow.FixedRateOrMargin;
                var RateFloat = forecastCurve.GetForwardRate(s, e, RateType.Linear, Basis);
                var YF        = flow.NotionalByYearFraction;
                FV = ((RateFloat - RateFix) * YF) / (1 + RateFloat * YF) * flow.Notional;

                FV *= (PayRec == SwapPayReceiveType.Payer) ? 1.0 : -1.0;
            }
            else
            {
                FV = flow.Fv;
            }

            if (updateDF)
            {
                DF = discountCurve.Pv(1.0, flow.SettleDate);
            }
            else
            {
                DF = flow.Pv / flow.Fv;
            }

            totalPV = discountCurve.Pv(FV, flow.SettleDate);

            if (!updateState)
            {
                return(totalPV);
            }
            flow.Fv = FV;
            flow.Pv = totalPV;
            return(totalPV);
        }
示例#3
0
        public static double PV(this CashFlowSchedule schedule, IrCurve discountCurve, IrCurve forecastCurve, bool updateState, bool updateDf, bool updateEstimate, DayCountBasis basisFloat, DateTime?filterDate)
        {
            double totalPv = 0;

            for (var i = 0; i < schedule.Flows.Count; i++)
            {
                var flow = schedule.Flows[i];

                if (filterDate.HasValue && flow.SettleDate < filterDate.Value)
                {
                    continue;
                }

                double fv, pv, df;

                switch (flow.FlowType)
                {
                case FlowType.FixedRate:
                {
                    if (updateState)
                    {
                        var rateLin = flow.FixedRateOrMargin;
                        var yf      = flow.YearFraction;
                        fv = rateLin * yf * flow.Notional;
                    }
                    else
                    {
                        fv = flow.Fv;
                    }

                    if (updateDf)
                    {
                        df = discountCurve.Pv(1, flow.SettleDate);
                    }
                    else
                    {
                        df = flow.Fv == flow.Pv ? 1.0 : flow.Pv / flow.Fv;
                    }

                    pv = fv * df;

                    totalPv += pv;

                    if (updateState)
                    {
                        flow.Fv = fv;
                        flow.Pv = pv;
                    }
                    break;
                }

                case FlowType.FloatRate:
                {
                    if (updateEstimate)
                    {
                        var s       = flow.AccrualPeriodStart;
                        var e       = flow.AccrualPeriodEnd;
                        var rateLin = forecastCurve.GetForwardRate(s, e, RateType.Linear, basisFloat);
                        rateLin += flow.FixedRateOrMargin;
                        var yf = flow.YearFraction;
                        fv = rateLin * yf * flow.Notional;
                    }
                    else
                    {
                        fv = flow.Fv;
                    }

                    if (updateDf)
                    {
                        df = discountCurve.Pv(1, flow.SettleDate);
                    }
                    else
                    {
                        df = flow.Fv == flow.Pv ? 1.0 : flow.Pv / flow.Fv;
                    }

                    pv       = fv * df;
                    totalPv += pv;

                    if (updateState)
                    {
                        flow.Fv = fv;
                        flow.Pv = pv;
                    }
                    break;
                }

                case FlowType.FixedAmount:
                {
                    fv = flow.Notional;

                    if (updateDf)
                    {
                        df = discountCurve.Pv(1, flow.SettleDate);
                    }
                    else
                    {
                        df = flow.Fv == flow.Pv ? 1.0 : flow.Pv / flow.Fv;
                    }

                    pv       = fv * df;
                    totalPv += pv;

                    if (updateState)
                    {
                        flow.Fv = fv;
                        flow.Pv = pv;
                    }

                    break;
                }
                }
            }

            return(totalPv);
        }
示例#4
0
文件: IrSwap.cs 项目: mpvyard/qwack
        private double PV(IrCurve discountCurve, IrCurve forecastCurve, bool updateState, bool updateDf, bool updateEstimate)
        {
            double totalPv = 0;

            for (var i = 0; i < FlowScheduleFixed.Flows.Count; i++)
            {
                var    flow = FlowScheduleFixed.Flows[i];
                double fv, df;
                if (updateState)
                {
                    var rateLin = flow.FixedRateOrMargin;
                    var yf      = flow.NotionalByYearFraction;
                    fv = rateLin * yf * flow.Notional;
                }
                else
                {
                    fv = flow.Fv;
                }

                if (updateDf)
                {
                    df = discountCurve.Pv(1, flow.SettleDate);
                }
                else
                {
                    df = flow.Fv == flow.Pv ? 1.0 : flow.Pv / flow.Fv;
                }

                var pv = fv * df;

                totalPv += pv;

                if (updateState)
                {
                    flow.Fv = fv;
                    flow.Pv = pv;
                }
            }

            for (var i = 0; i < FlowScheduleFloat.Flows.Count; i++)
            {
                var    flow = FlowScheduleFloat.Flows[i];
                double fv, df;

                if (updateEstimate)
                {
                    var s       = flow.AccrualPeriodStart;
                    var e       = flow.AccrualPeriodEnd;
                    var rateLin = forecastCurve.GetForwardRate(s, e, RateType.Linear, BasisFloat);
                    var yf      = flow.NotionalByYearFraction;
                    fv = rateLin * yf * flow.Notional;
                }
                else
                {
                    fv = flow.Fv;
                }

                if (updateDf)
                {
                    df = discountCurve.Pv(1, flow.SettleDate);
                }
                else
                {
                    df = flow.Fv == flow.Pv ? 1.0 : flow.Pv / flow.Fv;
                }

                var pv = fv * df;
                totalPv += pv;

                if (updateState)
                {
                    flow.Fv = fv;
                    flow.Pv = pv;
                }
            }
            return(totalPv);
        }
示例#5
0
        public double Pv(IrCurve discountCurve, IrCurve forecastCurvePay, IrCurve forecastCurveRec, bool updateState, bool updateDF, bool updatePayEst, bool updateRecEst)
        {
            double totalPV = 0;

            for (var i = 0; i < FlowSchedulePay.Flows.Count; i++)
            {
                double FV, DF;

                var flow = FlowSchedulePay.Flows[i];

                if (updatePayEst)
                {
                    var s       = flow.AccrualPeriodStart;
                    var e       = flow.AccrualPeriodEnd;
                    var RateLin = forecastCurvePay.GetForwardRate(s, e, RateType.Linear, BasisPay)
                                  + flow.FixedRateOrMargin;
                    var YF = flow.NotionalByYearFraction;
                    FV = RateLin * YF * flow.Notional;
                }
                else
                {
                    FV = flow.Fv;
                }

                if (updateDF)
                {
                    DF = discountCurve.Pv(1, flow.SettleDate);
                }
                else
                {
                    DF = (flow.Fv == flow.Pv) ? 1.0 : flow.Pv / flow.Fv;
                }

                var PV = DF * FV;

                if (updateState)
                {
                    flow.Fv = FV;
                    flow.Pv = PV;
                }

                totalPV += PV;
            }

            for (var i = 0; i < FlowScheduleRec.Flows.Count; i++)
            {
                double FV, DF;

                var flow = FlowScheduleRec.Flows[i];

                if (updateRecEst)
                {
                    var s       = flow.AccrualPeriodStart;
                    var e       = flow.AccrualPeriodEnd;
                    var RateLin = forecastCurveRec.GetForwardRate(s, e, RateType.Linear, BasisRec)
                                  + flow.FixedRateOrMargin;
                    var YF = flow.NotionalByYearFraction;
                    FV = RateLin * YF * flow.Notional;
                }
                else
                {
                    FV = flow.Fv;
                }

                if (updateDF)
                {
                    DF = discountCurve.Pv(1, flow.SettleDate);
                }
                else
                {
                    DF = (flow.Fv == flow.Pv) ? 1.0 : flow.Pv / flow.Fv;
                }

                var PV = DF * FV;

                if (updateState)
                {
                    flow.Fv = FV;
                    flow.Pv = PV;
                }

                totalPV += PV;
            }

            return(totalPV);
        }