public double CalculateParRate(IFundingModel model) { var farFx = model.GetFxRate(FarDate, DomesticCcy, ForeignCcy); var nearFx = model.GetFxRate(NearDate, DomesticCcy, ForeignCcy); return((farFx - nearFx) * Divisor); }
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); }
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); } }
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); }
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); }
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 }, }); } }
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); } }
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); }
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); }
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); }
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); }
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 }, }); } }
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); }
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); }
public double CalculateParRate(IFundingModel Model) => Model.GetFxRate(DeliveryDate, DomesticCCY, ForeignCCY);