public void testCurveCopy <T, I>(CommonVars vars, I interpolator) where T : ITraits <YieldTermStructure>, new() where I : IInterpolationFactory, new() { PiecewiseYieldCurve <T, I> curve = new PiecewiseYieldCurve <T, I>(vars.settlement, vars.instruments, new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator); // necessary to trigger bootstrap curve.recalculate(); PiecewiseYieldCurve copiedCurve = curve.Clone() as PiecewiseYieldCurve; // the two curves should be the same. double t = 2.718; var r1 = curve.zeroRate(t, Compounding.Continuous).value(); var r2 = copiedCurve.zeroRate(t, Compounding.Continuous).value(); if (!Utils.close(r1, r2)) { QAssert.Fail("failed to link original and copied curve"); } for (int i = 0; i < vars.rates.Count; ++i) { vars.rates[i].setValue(vars.rates[i].value() + 0.001); } // now the original curve should have changed; the copied // curve should not. double r3 = curve.zeroRate(t, Compounding.Continuous).value(); double r4 = copiedCurve.zeroRate(t, Compounding.Continuous).value(); if (Utils.close(r1, r3)) { QAssert.Fail("failed to modify original curve"); } if (!Utils.close(r2, r4)) { QAssert.Fail("failed to break link between original and copied curve"); } }
private YieldTermStructure Piecewisecurve(List <RateHelper> instruments) { YieldTermStructure yieldts; // = FastActivator<PiecewiseYieldCurve>.Create(); switch (_interpolationVariable) { case InterpolationVariable.Zero: switch (_interpolationMethod) { case InterpolationMethod.Linear: yieldts = new PiecewiseYieldCurve <ZeroYield, Linear>(_asofDate, instruments, _zeroDayCounter, null, null, _accuracy); break; case InterpolationMethod.LogLinear: yieldts = new PiecewiseYieldCurve <ZeroYield, LogLinear>(_asofDate, instruments, _zeroDayCounter, null, null, _accuracy); break; case InterpolationMethod.NaturalCubic: yieldts = new PiecewiseYieldCurve <ZeroYield, Cubic>(_asofDate, instruments, _zeroDayCounter, null, null, _accuracy, new Cubic(CubicInterpolation.DerivativeApprox.Kruger, true, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); break; case InterpolationMethod.FinancialCubic: yieldts = new PiecewiseYieldCurve <ZeroYield, Cubic>(_asofDate, instruments, _zeroDayCounter, null, null, _accuracy, new Cubic(CubicInterpolation.DerivativeApprox.Kruger, true, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); break; case InterpolationMethod.ConvexMonotone: yieldts = new PiecewiseYieldCurve <ZeroYield, ConvexMonotone>(_asofDate, instruments, _zeroDayCounter, null, null, _accuracy); break; default: Utils.QL_FAIL("Interpolation method not recognised."); throw new Exception(); } break; case InterpolationVariable.Discount: switch (_interpolationMethod) { case InterpolationMethod.Linear: yieldts = new PiecewiseYieldCurve <Discount, Linear>(_asofDate, instruments, _zeroDayCounter, null, null, _accuracy); break; case InterpolationMethod.LogLinear: yieldts = new PiecewiseYieldCurve <Discount, LogLinear>(_asofDate, instruments, _zeroDayCounter, null, null, _accuracy); break; case InterpolationMethod.NaturalCubic: yieldts = new PiecewiseYieldCurve <Discount, Cubic>(_asofDate, instruments, _zeroDayCounter, null, null, _accuracy, new Cubic(CubicInterpolation.DerivativeApprox.Kruger, true, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); break; case InterpolationMethod.FinancialCubic: yieldts = new PiecewiseYieldCurve <Discount, Cubic>( _asofDate, instruments, _zeroDayCounter, null, null, _accuracy, new Cubic(CubicInterpolation.DerivativeApprox.Kruger, true, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, CubicInterpolation.BoundaryCondition.FirstDerivative, 0.0)); break; case InterpolationMethod.ConvexMonotone: yieldts = new PiecewiseYieldCurve <Discount, ConvexMonotone>(_asofDate, instruments, _zeroDayCounter, null, null, _accuracy); break; default: Utils.QL_FAIL("Interpolation method not recognised."); throw new Exception(); } break; case InterpolationVariable.Forward: switch (_interpolationMethod) { case InterpolationMethod.Linear: yieldts = new PiecewiseYieldCurve <ForwardRate, Linear>(_asofDate, instruments, _zeroDayCounter, null, null, _accuracy); break; case InterpolationMethod.LogLinear: yieldts = new PiecewiseYieldCurve <ForwardRate, LogLinear>(_asofDate, instruments, _zeroDayCounter, null, null, _accuracy); break; case InterpolationMethod.NaturalCubic: yieldts = new PiecewiseYieldCurve <ForwardRate, Cubic>( _asofDate, instruments, _zeroDayCounter, null, null, _accuracy, new Cubic(CubicInterpolation.DerivativeApprox.Kruger, true, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); break; case InterpolationMethod.FinancialCubic: yieldts = new PiecewiseYieldCurve <ForwardRate, Cubic>( _asofDate, instruments, _zeroDayCounter, null, null, _accuracy, new Cubic(CubicInterpolation.DerivativeApprox.Kruger, true, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, CubicInterpolation.BoundaryCondition.FirstDerivative, 0.0)); break; case InterpolationMethod.ConvexMonotone: yieldts = new PiecewiseYieldCurve <ForwardRate, ConvexMonotone>(_asofDate, instruments, _zeroDayCounter, null, null, _accuracy); break; default: Utils.QL_FAIL("Interpolation method not recognised."); throw new Exception(); } break; default: Utils.QL_FAIL("Interpolation variable not recognised."); throw new Exception(); } // Build fixed zero/discount curve that matches the boostrapped curve // initially, but does NOT react to quote changes: This is a workaround // for a QuantLib problem, where a fixed reference date piecewise // yield curve reacts to evaluation date changes because the bootstrap // helper recompute their start date (because they are realtive date // helper for deposits, fras, swaps, etc.). InitializedList <Date> dates = new InitializedList <Date>(instruments.Count + 1, _asofDate); InitializedList <double> zeros = new InitializedList <double>(instruments.Count + 1, 0.0); InitializedList <double> discounts = new InitializedList <double>(instruments.Count + 1, 1.0); InitializedList <double> forwards = new InitializedList <double>(instruments.Count + 1, 0.0); if (_extrapolation) { yieldts.enableExtrapolation(); } for (int i = 0; i < instruments.Count; i++) { dates[i + 1] = instruments[i].latestDate(); zeros[i + 1] = yieldts.zeroRate(dates[i + 1], _zeroDayCounter, Compounding.Continuous).value(); discounts[i + 1] = yieldts.discount(dates[i + 1]); forwards[i + 1] = yieldts.forwardRate(dates[i + 1], dates[i + 1], _zeroDayCounter, Compounding.Continuous).value(); } zeros[0] = zeros[1]; forwards[0] = forwards[1]; if (_interpolationVariable == InterpolationVariable.Zero) { _p = Zerocurve(dates, zeros, _zeroDayCounter); } else if (_interpolationVariable == InterpolationVariable.Discount) { _p = Discountcurve(dates, discounts, _zeroDayCounter); } else if (_interpolationVariable == InterpolationVariable.Forward) { _p = Forwardcurve(dates, forwards, _zeroDayCounter); } else { Utils.QL_FAIL("Interpolation variable not recognised."); } return(_p); }