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 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 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 SuggestPillarValue(IFundingModel model) => SolveCurve == ForecastCurvePay ? model.GetCurve(ForecastCurveRec).GetForwardCCRate(model.BuildDate, PillarDate) + ParSpreadRec : model.GetCurve(ForecastCurvePay).GetForwardCCRate(model.BuildDate, PillarDate) + ParSpreadPay;
public double SuggestPillarValue(IFundingModel model) => model.GetCurve(ForecastCurve).GetForwardCCRate(model.BuildDate, PillarDate) + Spread;
public void Solve(IFundingModel fundingModel, FundingInstrumentCollection instruments, Dictionary <string, SolveStage> stages) { var sw = new Stopwatch(); sw.Start(); var itterationsPerStage = new Dictionary <SolveStage, int>(); var maxStage = stages.Values.Max(x => x.Stage); for (var stage = 0; stage <= maxStage; stage++) { var inThisStage = stages.Where(x => x.Value.Stage == stage) .GroupBy(x => x.Value.SubStage) .ToDictionary(x => x.Key, x => x.Select(y => y.Key).ToArray()); ParallelUtils.Instance.Foreach(inThisStage.Keys.ToList(), subStage => { var curvesForStage = inThisStage[subStage].Select(c => (IIrCurve)fundingModel.GetCurve(c)).ToList(); var fundingInstruments = new List <IFundingInstrument>(); var insForCurve = new List <IFundingInstrument>(); foreach (var curve in curvesForStage) { foreach (var inst in instruments) { if (inst.SolveCurve == curve.Name) { insForCurve.Add(inst); fundingInstruments.Add(inst); } } if (InLineCurveGuessing) { var points = insForCurve.ToDictionary(x => x.PillarDate, x => x.SuggestPillarValue(fundingModel)); for (var i = 0; i < curve.NumberOfPillars; i++) { curve.SetRate(i, points[((IrCurve)curve).PillarDates[i]], true); } } } var currentGuess = new double[fundingInstruments.Count]; var currentPvs = new double[fundingInstruments.Count]; var bumpedPvs = new double[fundingInstruments.Count]; var jacobian = Math.Matrix.DoubleArrayFunctions.MatrixCreate(fundingInstruments.Count, fundingInstruments.Count); for (var i = 0; i < MaxItterations; i++) { ComputePVs(true, fundingInstruments, fundingModel, currentPvs); if (currentPvs.Max(x => System.Math.Abs(x)) < Tollerance) { UsedItterations += i + 1; break; } ComputeJacobian(fundingInstruments, fundingModel, curvesForStage, currentGuess, bumpedPvs, currentPvs, ref jacobian); ComputeNextGuess(currentGuess, fundingInstruments.Count, curvesForStage, jacobian, currentPvs); } }).Wait(); } //fundingModel.CalibrationItterations = itterationsPerStage; fundingModel.CalibrationTimeMs = sw.ElapsedMilliseconds; sw.Stop(); }