コード例 #1
0
ファイル: FxSwap.cs プロジェクト: wy6688/qwack
        public double CalculateParRate(IFundingModel model)
        {
            var farFx  = model.GetFxRate(FarDate, DomesticCcy, ForeignCcy);
            var nearFx = model.GetFxRate(NearDate, DomesticCcy, ForeignCcy);

            return((farFx - nearFx) * Divisor);
        }
コード例 #2
0
        public double CalculateParRate(IFundingModel model)
        {
            var discountCurve = model.Curves[CashDiscountCurve];
            var SpotRate      = model.GetFxRate(SpotDate, MetalCCY, CashCCY);
            var t             = SpotDate.CalculateYearFraction(DeliveryDate, Basis);
            var fwd           = model.GetFxRate(DeliveryDate, MetalCCY, CashCCY);
            var ctgo          = (fwd / SpotRate - 1.0) / t;

            return(ctgo);
        }
コード例 #3
0
ファイル: XccyBasisSwap.cs プロジェクト: wy6688/qwack
        public double CalculateParRate(IFundingModel model)
        {
            var discountCurvePay = model.Curves[DiscountCurvePay];
            var discountCurveRec = model.Curves[DiscountCurveRec];
            var forecastCurvePay = model.Curves[ForecastCurvePay];
            var forecastCurveRec = model.Curves[ForecastCurveRec];

            var payCCY  = MtmSwapType == MTMSwapType.ReceiveNotionalFixed ? CcyRec : CcyPay;
            var recCCY  = MtmSwapType == MTMSwapType.PayNotionalFixed ? CcyPay : CcyRec;
            var baseCCY = Pvccy ?? payCCY;

            var fxPayToBase = model.GetFxRate(model.BuildDate, payCCY, baseCCY);
            var fxRecToBase = model.GetFxRate(model.BuildDate, recCCY, baseCCY);

            if (ParSpreadPay != 0.0)
            {
                var newSched = FlowSchedulePay.Clone();

                var recPV = FlowScheduleRec.PV(discountCurveRec, forecastCurveRec, true, true, true, BasisRec, null);
                recPV *= fxRecToBase;

                var targetFunc = new Func <double, double>(spread =>
                {
                    foreach (var s in newSched.Flows.Where(x => x.FlowType == FlowType.FloatRate))
                    {
                        s.FixedRateOrMargin = spread;
                    }
                    var pv = newSched.PV(discountCurvePay, forecastCurvePay, true, true, true, BasisPay, null);
                    pv    *= fxPayToBase;
                    return(pv - recPV);
                }
                                                           );
                var newSpread = Math.Solvers.Newton1D.MethodSolve(targetFunc, 0, 0.000001);
                return(newSpread);
            }
            else
            {
                var newSched = FlowScheduleRec.Clone();
                var payPV    = FlowSchedulePay.PV(discountCurvePay, forecastCurvePay, true, true, true, BasisPay, null);
                payPV *= fxPayToBase;
                var targetFunc = new Func <double, double>(spread =>
                {
                    foreach (var s in newSched.Flows.Where(x => x.FlowType == FlowType.FloatRate))
                    {
                        s.FixedRateOrMargin = spread;
                    }
                    var pv = newSched.PV(discountCurveRec, forecastCurveRec, true, true, true, BasisRec, null);
                    pv    *= fxRecToBase;
                    return(pv - payPV);
                }
                                                           );
                var newSpread = Math.Solvers.Newton1D.MethodSolve(targetFunc, 0, 0.000001);
                return(newSpread);
            }
        }
コード例 #4
0
ファイル: FxSwap.cs プロジェクト: wy6688/qwack
        public double Pv(IFundingModel model, bool updateState)
        {
            var discName  = model.FxMatrix.GetDiscountCurve(ForeignCcy);
            var discCurve = model.GetCurve(discName);
            var farFx     = model.GetFxRate(FarDate, DomesticCcy, ForeignCcy);
            var nearFx    = model.GetFxRate(NearDate, DomesticCcy, ForeignCcy);
            var farStrike = nearFx + SwapPoints / Divisor;
            var farPv     = -(farFx - farStrike) * Notional * discCurve.GetDf(model.BuildDate, FarDate);

            return(farPv);
        }
コード例 #5
0
        public double Pv(IFundingModel model, bool updateState)
        {
            var discountCurve = model.Curves[CashDiscountCurve];
            var SpotRate      = model.GetFxRate(SpotDate, MetalCCY, CashCCY);
            var t             = SpotDate.CalculateYearFraction(DeliveryDate, Basis);
            var strike        = SpotRate * (1.0 + ContangoRate * t);
            var fwd           = model.GetFxRate(DeliveryDate, MetalCCY, CashCCY);
            var FV            = (fwd - strike) * MetalQuantity;
            var PV            = discountCurve.Pv(FV, DeliveryDate);

            return(PV);
        }
コード例 #6
0
        public Dictionary <string, Dictionary <DateTime, double> > Sensitivities(IFundingModel model)
        {
            var foreignCurve  = model.FxMatrix.DiscountCurveMap[CashCCY];
            var domesticCurve = model.FxMatrix.DiscountCurveMap[MetalCCY];
            var discountCurve = model.Curves[CashDiscountCurve];
            var df            = discountCurve.Pv(1.0, DeliveryDate);
            var t             = discountCurve.Basis.CalculateYearFraction(discountCurve.BuildDate, DeliveryDate);
            var spotRate      = model.GetFxRate(SpotDate, MetalCCY, CashCCY);
            var strike        = spotRate * (1.0 + ContangoRate * t);
            var fwdRate       = model.GetFxRate(DeliveryDate, MetalCCY, CashCCY);

            var domesticDict = new Dictionary <DateTime, double>()
            {
                { DeliveryDate, fwdRate *MetalQuantity *df *t }
            };

            Dictionary <DateTime, double> foreignDict;

            if (foreignCurve == CashDiscountCurve)
            {
                foreignDict = new Dictionary <DateTime, double>()
                {
                    { DeliveryDate, MetalQuantity *df *(fwdRate * -2 * t + strike * t) }
                };

                return(new Dictionary <string, Dictionary <DateTime, double> >()
                {
                    { foreignCurve, foreignDict },
                    { domesticCurve, domesticDict },
                });
            }
            else
            {
                foreignDict = new Dictionary <DateTime, double>()
                {
                    { DeliveryDate, fwdRate *MetalQuantity *df * -t }
                };
                var foreignDiscDict = new Dictionary <DateTime, double>()
                {
                    { DeliveryDate, (fwdRate - strike) * MetalQuantity * df * -t }
                };

                return(new Dictionary <string, Dictionary <DateTime, double> >()
                {
                    { foreignCurve, foreignDict },
                    { domesticCurve, domesticDict },
                    { CashDiscountCurve, foreignDiscDict },
                });
            }
        }
コード例 #7
0
        private static double GetScaleFactor(IFundingInstrument ins, double parFlat, double parBump, IFundingModel model)
        {
            switch (ins)
            {
            case FxForward fxf:
                return(1.0 / (parBump - parFlat));

            case STIRFuture st:
                return(1.0 / ((parBump - parFlat) / 0.01 * st.UnitPV01));

            case ForwardRateAgreement fra:
                return(1.0 / ((parBump - parFlat) * fra.FlowScheduleFra.Flows.First().NotionalByYearFraction));

            case ContangoSwap cs:
                var t360      = (cs.PillarDate - model.BuildDate).TotalDays / 360.0;
                var spot      = model.GetFxRate(model.BuildDate, cs.MetalCCY, cs.CashCCY);
                var fwdFlat   = (1 + parFlat * t360) * spot;
                var fwdBumped = (1 + parBump * t360) * spot;
                return(1.0 / (fwdBumped - fwdFlat));

            case IrSwap irs:
                var pv = irs.SetParRate(parBump).Pv(model, true);
                return(1.0 / pv * irs.Notional);

            case FloatingRateLoanDepo fld:
                var pvF = fld.SetParRate(parBump).Pv(model, true);
                return(1.0 / pvF * fld.Notional);

            default:
                return(1.0);
            }
        }
コード例 #8
0
        public static double PV(this CashFlowSchedule schedule, Currency reportingCCy, IFundingModel model, string forecastCurve, DayCountBasis basisFloat, DateTime?filterDate)
        {
            var totalPv = 0.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;
                var    df        = model.GetDf(reportingCCy, model.BuildDate, flow.SettleDate);
                var    fwdFxRate = model.GetFxRate(flow.SettleDate, flow.Currency, reportingCCy);

                switch (flow.FlowType)
                {
                case FlowType.FixedRate:
                {
                    var rateLin = flow.FixedRateOrMargin;
                    var yf      = flow.YearFraction;
                    fv       = rateLin * yf * flow.Notional;
                    fv      *= fwdFxRate;
                    pv       = fv * df;
                    totalPv += pv;
                    break;
                }

                case FlowType.FloatRate:
                {
                    var s       = flow.AccrualPeriodStart;
                    var e       = flow.AccrualPeriodEnd;
                    var rateLin = model.GetCurve(forecastCurve).GetForwardRate(s, e, RateType.Linear, basisFloat);
                    rateLin += flow.FixedRateOrMargin;
                    var yf = flow.YearFraction;
                    fv       = rateLin * yf * flow.Notional;
                    fv      *= fwdFxRate;
                    pv       = fv * df;
                    totalPv += pv;
                    break;
                }

                case FlowType.FixedAmount:
                {
                    fv       = flow.Notional;
                    fv      *= fwdFxRate;
                    pv       = fv * df;
                    totalPv += pv;
                    break;
                }
                }
            }

            return(totalPv);
        }
コード例 #9
0
ファイル: FxForward.cs プロジェクト: wy6688/qwack
        public double FlowsT0(IFundingModel Model)
        {
            if (DeliveryDate != Model.BuildDate)
            {
                return(0.0);
            }

            var fwdRate = Model.GetFxRate(DeliveryDate, DomesticCCY, ForeignCCY);
            var FV      = (fwdRate - Strike) * DomesticQuantity;

            return(FV);
        }
コード例 #10
0
ファイル: ContangoSwap.cs プロジェクト: wy6688/qwack
        public double SuggestPillarValue(IFundingModel model)
        {
            var discountCurve = model.Curves[CashDiscountCurve];
            var SpotRate      = model.GetFxRate(SpotDate, MetalCCY, CashCCY);
            var t             = SpotDate.CalculateYearFraction(DeliveryDate, Basis);
            var fwd           = SpotRate * (1.0 + ContangoRate * t);
            var fxr           = fwd / SpotRate;
            var df1           = discountCurve.GetDf(SpotDate, PillarDate);
            var df2           = df1 / fxr;
            var rate          = -System.Math.Log(df2) / t;

            return(rate);
        }
コード例 #11
0
ファイル: FxForward.cs プロジェクト: wy6688/qwack
        public double Pv(IFundingModel Model, bool updateState, bool ignoreTodayFlows)
        {
            if (Model.BuildDate > DeliveryDate || (ignoreTodayFlows && Model.BuildDate == DeliveryDate))
            {
                return(0.0);
            }

            var discountCurve = Model.Curves[ForeignDiscountCurve];
            var fwdRate       = Model.GetFxRate(DeliveryDate, DomesticCCY, ForeignCCY);
            var FV            = (fwdRate - Strike) * DomesticQuantity;
            var PV            = discountCurve.Pv(FV, DeliveryDate);

            return(PV);
        }
コード例 #12
0
        public Dictionary <string, Dictionary <DateTime, double> > Sensitivities(IFundingModel model)
        {
            var foreignCurve  = model.FxMatrix.DiscountCurveMap[ForeignCCY];
            var domesticCurve = model.FxMatrix.DiscountCurveMap[DomesticCCY];
            var discountCurve = model.Curves[ForeignDiscountCurve];
            var df            = discountCurve.Pv(1.0, DeliveryDate);
            var t             = discountCurve.Basis.CalculateYearFraction(discountCurve.BuildDate, DeliveryDate);
            var fwdRate       = model.GetFxRate(DeliveryDate, DomesticCCY, ForeignCCY);

            var domesticDict = new Dictionary <DateTime, double>()
            {
                { DeliveryDate, fwdRate *DomesticQuantity *df *t }
            };

            Dictionary <DateTime, double> foreignDict;

            if (foreignCurve == ForeignDiscountCurve)
            {
                foreignDict = new Dictionary <DateTime, double>()
                {
                    { DeliveryDate, DomesticQuantity *df *(fwdRate * -2 * t + Strike * t) }
                };

                return(new Dictionary <string, Dictionary <DateTime, double> >()
                {
                    { foreignCurve, foreignDict },
                    { domesticCurve, domesticDict },
                });
            }
            else
            {
                foreignDict = new Dictionary <DateTime, double>()
                {
                    { DeliveryDate, fwdRate *DomesticQuantity *df * -t }
                };
                var foreignDiscDict = new Dictionary <DateTime, double>()
                {
                    { DeliveryDate, (fwdRate - Strike) * DomesticQuantity * df * -t }
                };

                return(new Dictionary <string, Dictionary <DateTime, double> >()
                {
                    { foreignCurve, foreignDict },
                    { domesticCurve, domesticDict },
                    { ForeignDiscountCurve, foreignDiscDict },
                });
            }
        }
コード例 #13
0
ファイル: FxForward.cs プロジェクト: wy6688/qwack
        public double SuggestPillarValue(IFundingModel model)
        {
            var pair          = model.FxMatrix.GetFxPair(Pair);
            var spotDate      = pair.SpotDate(model.BuildDate);
            var fxr           = Strike / model.GetFxRate(spotDate, Pair);
            var df1           = model.GetCurve(model.FxMatrix.GetDiscountCurve(DomesticCCY.Ccy)).GetDf(spotDate, PillarDate);
            var df2           = df1 / fxr;
            var discountCurve = model.Curves[SolveCurve];
            var t             = discountCurve.Basis.CalculateYearFraction(spotDate, PillarDate);
            var rate          = -Log(df2) / t;

            if (double.IsNaN(rate) || double.IsInfinity(rate))
            {
                rate = 0.05;
            }
            return(rate);
        }
コード例 #14
0
ファイル: XccyBasisSwap.cs プロジェクト: wy6688/qwack
        public double PV(IFundingModel model, bool updateState, bool updateDfPay, bool updateDfRec, bool updatePayEst, bool updateRecEst)
        {
            var    discountCurvePay = model.Curves[DiscountCurvePay];
            var    discountCurveRec = model.Curves[DiscountCurveRec];
            var    forecastCurvePay = model.Curves[ForecastCurvePay];
            var    forecastCurveRec = model.Curves[ForecastCurveRec];
            double totalPVRec       = 0;
            double totalPVPay       = 0;


            var payCCY  = MtmSwapType == MTMSwapType.ReceiveNotionalFixed ? CcyRec : CcyPay;
            var recCCY  = MtmSwapType == MTMSwapType.PayNotionalFixed ? CcyPay : CcyRec;
            var baseCCY = Pvccy ?? payCCY;

            var fxPayToBase = model.GetFxRate(model.BuildDate, payCCY, baseCCY);
            var fxRecToBase = model.GetFxRate(model.BuildDate, recCCY, baseCCY);

            var fixedNotional = (double)(MtmSwapType == MTMSwapType.PayNotionalFixed ? PayLeg.Nominal :
                                         MtmSwapType == MTMSwapType.ReceiveNotionalFixed ? RecLeg.Nominal : 0M);

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

                var flow = FlowSchedulePay.Flows[i];

                if (updatePayEst && flow.FlowType != FlowType.FixedAmount)
                {
                    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 *
                         (MtmSwapType == MTMSwapType.ReceiveNotionalFixed ? fixedNotional : flow.Notional);
                    fv *= -1.0;
                }
                else
                {
                    fv = flow.Fv;
                }

                if (updateDfPay)
                {
                    df = discountCurvePay.Pv(1, flow.SettleDate);
                }
                else
                {
                    df = flow.Pv / flow.Fv;
                }

                var pv = df * fv;

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

                totalPVPay += pv;
            }

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

                var flow = FlowScheduleRec.Flows[i];

                if (updateRecEst && flow.FlowType != FlowType.FixedAmount)
                {
                    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 * (MtmSwapType == MTMSwapType.PayNotionalFixed ? fixedNotional : flow.Notional);
                }
                else
                {
                    FV = flow.Fv;
                }

                if (updateDfRec)
                {
                    DF = discountCurveRec.Pv(1, flow.SettleDate);
                }
                else
                {
                    DF = flow.Pv / flow.Fv;
                }

                var PV = DF * FV;

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

                totalPVPay += PV;
            }

            return(totalPVRec * fxRecToBase + totalPVPay * fxPayToBase);
        }
コード例 #15
0
ファイル: FxForward.cs プロジェクト: wy6688/qwack
 public double CalculateParRate(IFundingModel Model) => Model.GetFxRate(DeliveryDate, DomesticCCY, ForeignCCY);