public equivalentRate ( Date d1, Date d2, DayCounter resultDC, Compounding comp ) : |
||
d1 | Date | |
d2 | Date | |
resultDC | DayCounter | |
comp | Compounding | |
리턴 |
protected override double zeroYieldImpl(double t) { // to be fixed: user-defined daycounter should be used InterestRate zeroRate = originalCurve_.link.zeroRate(t, comp_, freq_, true); InterestRate spreadedRate = new InterestRate(zeroRate.value() + spread_.value(), zeroRate.dayCounter(), zeroRate.compounding(), zeroRate.frequency()); return spreadedRate.equivalentRate(t, Compounding.Continuous, Frequency.NoFrequency).value(); }
private void initialize(Compounding compounding, Frequency frequency, Date refDate = null) { Utils.QL_REQUIRE(dates_.Count >= interpolator_.requiredPoints, () => "not enough input dates given"); Utils.QL_REQUIRE(data_.Count == dates_.Count, () => "dates/yields count mismatch"); times_ = new List <double>(dates_.Count); double offset = 0.0; if (refDate != null) { offset = dayCounter().yearFraction(refDate, dates_[0]); } times_.Add(offset); if (compounding != Compounding.Continuous) { // We also have to convert the first rate. // The first time is 0.0, so we can't use it. // We fall back to about one day. double dt = 1.0 / 365; InterestRate r = new InterestRate(data_[0], dayCounter(), compounding, frequency); data_[0] = r.equivalentRate(Compounding.Continuous, Frequency.NoFrequency, dt).value(); #if !QL_NEGATIVE_RATES Utils.QL_REQUIRE(data_[0] > 0.0, () => "non-positive yield"); #endif } for (int i = 1; i < dates_.Count; i++) { Utils.QL_REQUIRE(dates_[i] > dates_[i - 1], () => "invalid date (" + dates_[i] + ", vs " + dates_[i - 1] + ")"); times_.Add(dayCounter().yearFraction(refDate ?? dates_[0], dates_[i])); Utils.QL_REQUIRE(!Utils.close(times_[i], times_[i - 1]), () => "two dates correspond to the same time " + "under this curve's day count convention"); // adjusting zero rates to match continuous compounding if (compounding != Compounding.Continuous) { InterestRate r = new InterestRate(data_[i], dayCounter(), compounding, frequency); data_[i] = r.equivalentRate(Compounding.Continuous, Frequency.NoFrequency, times_[i]).value(); } #if !QL_NEGATIVE_RATES Utils.QL_REQUIRE(data_[i] > 0.0, () => "non-positive yield"); // positive yields are not enough to ensure non-negative fwd rates // so here's a stronger requirement Utils.QL_REQUIRE(data_[i] * times_[i] - data_[i - 1] * times_[i - 1] >= 0.0, () => "negative forward rate implied by the zero yield " + data_[i] + " at " + dates_[i] + " (t=" + times_[i] + ") after the zero yield " + data_[i - 1] + " at " + dates_[i - 1] + " (t=" + times_[i - 1] + ")"); #endif } setupInterpolation(); interpolation_.update(); }
protected override double zeroYieldImpl(double t) { // to be fixed: user-defined daycounter should be used InterestRate zeroRate = originalCurve_.link.zeroRate(t, comp_, freq_, true); InterestRate spreadedRate = new InterestRate(zeroRate.value() + spread_.value(), zeroRate.dayCounter(), zeroRate.compounding(), zeroRate.frequency()); return(spreadedRate.equivalentRate(t, Compounding.Continuous, Frequency.NoFrequency).value()); }
protected override double zeroYieldImpl(double t) { double zeroRate1 = curve1_.link.zeroRate(t, comp_, freq_, true).rate(); double zeroRate2 = curve2_.link.zeroRate(t, comp_, freq_, true).rate(); InterestRate compositeRate = new InterestRate(f_(zeroRate1, zeroRate2), dayCounter(), comp_, freq_); return(compositeRate.equivalentRate(Compounding.Continuous, Frequency.NoFrequency, t).value()); }
protected override double zeroYieldImpl(double t) { double spread = calcSpread(t); InterestRate zeroRate = originalCurve_.link.zeroRate(t, compounding_, frequency_, true); InterestRate spreadedRate = new InterestRate(zeroRate.value() + spread, zeroRate.dayCounter(), zeroRate.compounding(), zeroRate.frequency()); return(spreadedRate.equivalentRate(Compounding.Continuous, Frequency.NoFrequency, t).value()); }
/// <summary> /// Convert a conventional spread to a reference yield curve to a /// continuous spread /// </summary> /// <param name="oas"></param> /// <param name="b"></param> /// <param name="yts"></param> /// <param name="dayCounter"></param> /// <param name="compounding"></param> /// <param name="frequency"></param> /// <returns></returns> private double convToContinuous(double oas, Bond b, Handle <YieldTermStructure> yts, DayCounter dayCounter, Compounding compounding, Frequency frequency) { double zz = yts.link.zeroRate(b.maturityDate(), dayCounter, compounding, frequency).value(); InterestRate baseRate = new InterestRate(zz, dayCounter, compounding, frequency); InterestRate spreadedRate = new InterestRate(oas + zz, dayCounter, compounding, frequency); double br = baseRate.equivalentRate(dayCounter, Compounding.Continuous, Frequency.NoFrequency, yts.link.referenceDate(), b.maturityDate()).rate(); double sr = spreadedRate.equivalentRate(dayCounter, Compounding.Continuous, Frequency.NoFrequency, yts.link.referenceDate(), b.maturityDate()).rate(); // Return the spread return(sr - br); }
public void testConversions() { InterestRateData[] cases = { // data from "Option Pricing Formulas", Haug, pag.181-182 // Rate,Compounding, Frequency, Time, Compounding2, Frequency2, Rate2, precision new InterestRateData(0.0800, Compounding.Compounded, Frequency.Quarterly, 1.00, Compounding.Continuous, Frequency.Annual, 0.0792, 4), new InterestRateData(0.1200, Compounding.Continuous, Frequency.Annual, 1.00, Compounding.Compounded, Frequency.Annual, 0.1275, 4), new InterestRateData(0.0800, Compounding.Compounded, Frequency.Quarterly, 1.00, Compounding.Compounded, Frequency.Annual, 0.0824, 4), new InterestRateData(0.0700, Compounding.Compounded, Frequency.Quarterly, 1.00, Compounding.Compounded, Frequency.Semiannual, 0.0706, 4), // undocumented, but reasonable :) new InterestRateData(0.0100, Compounding.Compounded, Frequency.Annual, 1.00, Compounding.Simple, Frequency.Annual, 0.0100, 4), new InterestRateData(0.0200, Compounding.Simple, Frequency.Annual, 1.00, Compounding.Compounded, Frequency.Annual, 0.0200, 4), new InterestRateData(0.0300, Compounding.Compounded, Frequency.Semiannual, 0.50, Compounding.Simple, Frequency.Annual, 0.0300, 4), new InterestRateData(0.0400, Compounding.Simple, Frequency.Annual, 0.50, Compounding.Compounded, Frequency.Semiannual, 0.0400, 4), new InterestRateData(0.0500, Compounding.Compounded, Frequency.EveryFourthMonth, 1.0/3, Compounding.Simple, Frequency.Annual, 0.0500, 4), new InterestRateData(0.0600, Compounding.Simple, Frequency.Annual, 1.0/3, Compounding.Compounded, Frequency.EveryFourthMonth, 0.0600, 4), new InterestRateData(0.0500, Compounding.Compounded, Frequency.Quarterly, 0.25, Compounding.Simple, Frequency.Annual, 0.0500, 4), new InterestRateData(0.0600, Compounding.Simple, Frequency.Annual, 0.25, Compounding.Compounded, Frequency.Quarterly, 0.0600, 4), new InterestRateData(0.0700, Compounding.Compounded, Frequency.Bimonthly, 1.0/6, Compounding.Simple, Frequency.Annual, 0.0700, 4), new InterestRateData(0.0800, Compounding.Simple, Frequency.Annual, 1.0/6, Compounding.Compounded, Frequency.Bimonthly, 0.0800, 4), new InterestRateData(0.0900, Compounding.Compounded, Frequency.Monthly, 1.0/12, Compounding.Simple, Frequency.Annual, 0.0900, 4), new InterestRateData(0.1000, Compounding.Simple, Frequency.Annual, 1.0/12, Compounding.Compounded, Frequency.Monthly, 0.1000, 4), new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.25, Compounding.Simple, Frequency.Annual, 0.0300, 4), new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.25, Compounding.Simple, Frequency.Semiannual, 0.0300, 4), new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.25, Compounding.Simple, Frequency.Quarterly, 0.0300, 4), new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.50, Compounding.Simple, Frequency.Annual, 0.0300, 4), new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.50, Compounding.Simple, Frequency.Semiannual, 0.0300, 4), new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.75, Compounding.Compounded, Frequency.Semiannual, 0.0300, 4), new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.25, Compounding.SimpleThenCompounded, Frequency.Quarterly, 0.0400, 4), new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.25, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.0400, 4), new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.25, Compounding.SimpleThenCompounded, Frequency.Annual, 0.0400, 4), new InterestRateData(0.0400, Compounding.Compounded, Frequency.Quarterly, 0.50, Compounding.SimpleThenCompounded, Frequency.Quarterly, 0.0400, 4), new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.50, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.0400, 4), new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.50, Compounding.SimpleThenCompounded, Frequency.Annual, 0.0400, 4), new InterestRateData(0.0400, Compounding.Compounded, Frequency.Quarterly, 0.75, Compounding.SimpleThenCompounded, Frequency.Quarterly, 0.0400, 4), new InterestRateData(0.0400, Compounding.Compounded, Frequency.Semiannual, 0.75, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.0400, 4), new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.75, Compounding.SimpleThenCompounded, Frequency.Annual, 0.0400, 4) }; Rounding roundingPrecision; double r3; double r2; Date d1 = Date.Today; Date d2; InterestRate ir; InterestRate ir2; InterestRate ir3; InterestRate expectedIR; double compoundf; double error; double disc; for (int i = 0; i < cases.Length-1 ; i++) { ir = new InterestRate(cases[i].r, new Actual360(), cases[i].comp, cases[i].freq); d2 = d1 + new Period((int)(360 * cases[i].t + 0.5) ,TimeUnit.Days); roundingPrecision = new Rounding(cases[i].precision); // check that the compound factor is the inverse of the discount factor compoundf = ir.compoundFactor(d1, d2); disc = ir.discountFactor(d1, d2); error = Math.Abs(disc - 1.0 / compoundf); if (error > 1e-15) Assert.Fail(ir + " 1.0/compound_factor: " + 1.0 / compoundf); // check that the equivalent InterestRate with *same* daycounter, // compounding, and frequency is the *same* InterestRate ir2 = ir.equivalentRate(d1, d2, ir.dayCounter(), ir.compounding(), ir.frequency()); error = Math.Abs(ir.rate() - ir2.rate()); if (error > 1e-15) Assert.Fail("original interest rate: " + ir + " equivalent interest rate: " + ir2 + " rate error: " + error); if (ir.dayCounter() != ir2.dayCounter()) Assert.Fail("day counter error original interest rate: " + ir + " equivalent interest rate: " + ir2); if (ir.compounding() != ir2.compounding()) Assert.Fail("compounding error original interest rate: " + ir + " equivalent interest rate: " + ir2); if (ir.frequency() != ir2.frequency()) Assert.Fail("frequency error original interest rate: " + ir + " equivalent interest rate: " + ir2); // check that the equivalent rate with *same* daycounter, // compounding, and frequency is the *same* rate r2 = ir.equivalentRate(d1, d2, ir.dayCounter(), ir.compounding(), ir.frequency()).rate(); error = Math.Abs(ir.rate() - r2); if (error > 1e-15) Assert.Fail("original rate: " + ir + " equivalent rate: " + r2 + " error: " + error); // check that the equivalent InterestRate with *different* // compounding, and frequency is the *expected* InterestRate ir3 = ir.equivalentRate(d1, d2, ir.dayCounter(), cases[i].comp2, cases[i].freq2); expectedIR = new InterestRate(cases[i].expected, ir.dayCounter(), cases[i].comp2, cases[i].freq2); r3 = roundingPrecision.Round(ir3.rate()); error = Math.Abs(r3 - expectedIR.rate()); if (error > 1.0e-17) Assert.Fail("original interest rate: " + ir + " calculated equivalent interest rate: " + ir3 + " truncated equivalent rate: " + r3 + " expected equivalent interest rate: " + expectedIR + " rate error: " + error); if (ir3.dayCounter() != expectedIR.dayCounter()) Assert.Fail("day counter error original interest rate: " + ir3 + " equivalent interest rate: " + expectedIR); if (ir3.compounding() != expectedIR.compounding()) Assert.Fail("compounding error original interest rate: " + ir3 + " equivalent interest rate: " + expectedIR); if (ir3.frequency() != expectedIR.frequency()) Assert.Fail("frequency error original interest rate: " + ir3 + " equivalent interest rate: " + expectedIR); // check that the equivalent rate with *different* // compounding, and frequency is the *expected* rate r3 = ir.equivalentRate(d1, d2, ir.dayCounter(), cases[i].comp2, cases[i].freq2).rate(); r3 = roundingPrecision.Round(r3); error = Math.Abs(r3 - cases[i].expected); if (error > 1.0e-17) Assert.Fail("calculated equivalent rate: " + r3 + " expected equivalent rate: " + cases[i].expected + " error: " + error); } }