protected 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) { 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); }