public TimeGrid(List <double> times, int offset, int steps) { Utils.QL_REQUIRE(times.Count > 0, () => "empty time sequence"); //not really finished bu run well for actals tests mandatoryTimes_ = times.GetRange(0, offset); mandatoryTimes_.Sort(); Utils.QL_REQUIRE(mandatoryTimes_[0] >= 0.0, () => "negative times not allowed"); for (int i = 0; i < mandatoryTimes_.Count - 1; ++i) { if (Utils.close_enough(mandatoryTimes_[i], mandatoryTimes_[i + 1])) { mandatoryTimes_.RemoveAt(i); i--; } } // The resulting timegrid have points at times listed in the input // list. Between these points, there are inner-points which are // regularly spaced. times_ = new List <double>(steps); dt_ = new List <double>(steps); double last = mandatoryTimes_.Last(); double dtMax = 0; if (steps == 0) { List <double> diff = new List <double>(); } else { dtMax = last / steps; } double periodBegin = 0.0; times_.Add(periodBegin); for (int k = 0; k < mandatoryTimes_.Count; k++) { double dt = 0; double periodEnd = mandatoryTimes_[k]; if (periodEnd.IsNotEqual(0.0)) { // the nearest integer int nSteps = (int)((periodEnd - periodBegin) / dtMax + 0.5); // at least one time step! nSteps = (nSteps != 0 ? nSteps : 1); dt = (periodEnd - periodBegin) / nSteps; for (int n = 1; n <= nSteps; ++n) { times_.Add(periodBegin + n * dt); dt_.Add(dt); } } periodBegin = periodEnd; } }
/// <summary> /// Time grid with mandatory time points /// <remarks> /// Mandatory points are guaranteed to belong to the grid. /// No additional points are added. /// </remarks> /// </summary> /// <param name="times"></param> public TimeGrid(List <double> times) { Utils.QL_REQUIRE(times.Count > 0, () => "empty time sequence"); mandatoryTimes_ = new List <double>(times); mandatoryTimes_.Sort(); Utils.QL_REQUIRE(mandatoryTimes_[0] >= 0.0, () => "negative times not allowed"); for (int i = 0; i < mandatoryTimes_.Count - 1; ++i) { if (Utils.close_enough(mandatoryTimes_[i], mandatoryTimes_[i + 1])) { mandatoryTimes_.RemoveAt(i); i--; } } times_ = new List <double>(mandatoryTimes_); if (mandatoryTimes_[0] > 0.0) { times_.Insert(0, 0.0); } var dt = times_.Zip(times_.Skip(1), (x, y) => y - x); dt_ = dt.ToList(); }
public TimeGrid(List <double> times, int offset) { //not really finished bu run well for actals tests mandatoryTimes_ = times.GetRange(0, offset); mandatoryTimes_.Sort(); if (!(mandatoryTimes_[0] >= 0.0)) { throw new ApplicationException("negative times not allowed"); } for (int i = 0; i < mandatoryTimes_.Count - 1; ++i) { if (Utils.close_enough(mandatoryTimes_[i], mandatoryTimes_[i + 1])) { mandatoryTimes_.RemoveAt(i); i--; } } times_ = new List <double>(mandatoryTimes_); if (mandatoryTimes_[0] > 0.0) { times_.Insert(0, 0.0); } var dt = times_.Zip(times_.Skip(1), (x, y) => y - x); dt_ = dt.ToList(); }
//! time-range check protected void checkRange(double t, bool extrapolate) { Utils.QL_REQUIRE(t >= 0.0, "negative time (" + t + ") given"); Utils.QL_REQUIRE(extrapolate || allowsExtrapolation() || t <= maxTime() || Utils.close_enough(t, maxTime()), "time (" + t + ") is past max curve time (" + maxTime() + ")"); }
public BlackVanillaOptionPricer(double forwardValue, Date expiryDate, Period swapTenor, SwaptionVolatilityStructure volatilityStructure) { forwardValue_ = forwardValue; expiryDate_ = expiryDate; swapTenor_ = swapTenor; volatilityStructure_ = volatilityStructure; smile_ = volatilityStructure_.smileSection(expiryDate_, swapTenor_); Utils.QL_REQUIRE(volatilityStructure.volatilityType() == VolatilityType.ShiftedLognormal && Utils.close_enough(volatilityStructure.shift(expiryDate, swapTenor), 0.0), () => "BlackVanillaOptionPricer: zero-shift lognormal volatility required"); }
//! time-range check protected void checkRange(double t, bool extrapolate) { if (t < 0) { throw new ArgumentException("negative time (" + t + ") is given"); } if (!(extrapolate || allowsExtrapolation() || t <= maxTime() || Utils.close_enough(t, maxTime()))) { throw new ArgumentException("time (" + t + ") is past max curve time (" + maxTime() + ")"); } }
// function public double value(double x) { if (x < 0.0 || x > 1.0) { // try to recover if due to numerical error if (Utils.close_enough(x, 1.0)) { x = 1.0; } else if (Math.Abs(x) < Const.QL_EPSILON) { x = 0.0; } else { Utils.QL_FAIL("InverseCumulativeNormal(" + x + ") undefined: must be 0 < x < 1"); } } double z, r; if (x < x_low_) { // Rational approximation for the lower region 0<x<u_low z = Math.Sqrt(-2.0 * Math.Log(x)); z = (((((c1_ * z + c2_) * z + c3_) * z + c4_) * z + c5_) * z + c6_) / ((((d1_ * z + d2_) * z + d3_) * z + d4_) * z + 1.0); } else if (x <= x_high_) { // Rational approximation for the central region u_low<=x<=u_high z = x - 0.5; r = z * z; z = (((((a1_ * r + a2_) * r + a3_) * r + a4_) * r + a5_) * r + a6_) * z / (((((b1_ * r + b2_) * r + b3_) * r + b4_) * r + b5_) * r + 1.0); } else { // Rational approximation for the upper region u_high<x<1 z = Math.Sqrt(-2.0 * Math.Log(1.0 - x)); z = -(((((c1_ * z + c2_) * z + c3_) * z + c4_) * z + c5_) * z + c6_) / ((((d1_ * z + d2_) * z + d3_) * z + d4_) * z + 1.0); }
public TimeGrid(List <double> times, int steps) { //not really finished bu run well for actals tests mandatoryTimes_ = times; mandatoryTimes_.Sort(); if (!(mandatoryTimes_[0] >= 0.0)) { throw new ApplicationException("negative times not allowed"); } for (int i = 0; i < mandatoryTimes_.Count - 1; ++i) { if (Utils.close_enough(mandatoryTimes_[i], mandatoryTimes_[i + 1])) { mandatoryTimes_.RemoveAt(i); i--; } } // The resulting timegrid have points at times listed in the input // list. Between these points, there are inner-points which are // regularly spaced. times_ = new List <double>(steps); dt_ = new List <double>(steps); double last = mandatoryTimes_.Last(); double dtMax = 0; if (steps == 0) { List <double> diff = new List <double>(); //std::vector<Time> diff; //std::adjacent_difference(mandatoryTimes_.begin(), // mandatoryTimes_.end(), // std::back_inserter(diff)); //if (diff.front()==0.0) // diff.erase(diff.begin()); //dtMax = *(std::min_element(diff.begin(), diff.end())); } else { dtMax = last / steps; } double periodBegin = 0.0; times_.Add(periodBegin); for (int k = 0; k < mandatoryTimes_.Count; k++) { double dt = 0; double periodEnd = mandatoryTimes_[k]; if (periodEnd != 0.0) { // the nearest integer int nSteps = (int)((periodEnd - periodBegin) / dtMax + 0.5); // at least one time step! nSteps = (nSteps != 0 ? nSteps : 1); dt = (periodEnd - periodBegin) / nSteps; //times_.Capacity=nSteps+1; for (int n = 1; n <= nSteps; ++n) { times_.Add(periodBegin + n * dt); dt_.Add(dt); } } periodBegin = periodEnd; } }
/// <summary> /// Time grid with mandatory time points /// <remarks> /// Mandatory points are guaranteed to belong to the grid. /// Additional points are then added with regular spacing /// between pairs of mandatory times in order to reach the /// desired number of steps. /// </remarks> /// </summary> /// <param name="times"></param> /// <param name="steps"></param> public TimeGrid(List <double> times, int steps) { Utils.QL_REQUIRE(times.Count > 0, () => "empty time sequence"); //not really finished bu run well for actals tests mandatoryTimes_ = new List <double>(times); mandatoryTimes_.Sort(); Utils.QL_REQUIRE(mandatoryTimes_[0] >= 0.0, () => "negative times not allowed"); for (int i = 0; i < mandatoryTimes_.Count - 1; ++i) { if (Utils.close_enough(mandatoryTimes_[i], mandatoryTimes_[i + 1])) { mandatoryTimes_.RemoveAt(i); i--; } } double last = mandatoryTimes_.Last(); double dtMax; // The resulting timegrid have points at times listed in the input // list. Between these points, there are inner-points which are // regularly spaced. if (steps == 0) { List <double> diff = mandatoryTimes_.Zip(mandatoryTimes_.Skip(1), (x, y) => y - x).ToList(); if (diff.First().IsEqual(0.0)) { diff.RemoveAt(0); } dtMax = diff.Min(); } else { dtMax = last / steps; } double periodBegin = 0.0; times_ = new List <double>(); times_.Add(periodBegin); foreach (var t in mandatoryTimes_) { double periodEnd = t; if (periodEnd.IsNotEqual(0.0)) { // the nearest integer int nSteps = (int)((periodEnd - periodBegin) / dtMax + 0.5); // at least one time step! nSteps = (nSteps != 0 ? nSteps : 1); double dt = (periodEnd - periodBegin) / nSteps; //times_.reserve(nSteps); for (int n = 1; n <= nSteps; ++n) { times_.Add(periodBegin + n * dt); } } periodBegin = periodEnd; } var dtf = times_.Zip(times_.Skip(1), (x, y) => y - x); dt_ = dtf.ToList(); }
protected override double localVolImpl(double t, double strike) { t = Math.Min(times_.Last(), Math.Max(t, times_.First())); int idx = times_.BinarySearch(t); if (idx < 0) { idx = ~idx; } if (idx == times_.Count) { idx--; } if (Utils.close_enough(t, times_[idx])) { if (strikes_[idx].First() < strikes_[idx].Last()) { return(localVolInterpol_[idx].value(strike, true)); } else { return(localVolMatrix_[localVolMatrix_.rows() / 2, idx]); } } else { double earlierStrike = strike, laterStrike = strike; if (lowerExtrapolation_ == Extrapolation.ConstantExtrapolation) { if (strike < strikes_[idx - 1].First()) { earlierStrike = strikes_[idx - 1].First(); } if (strike < strikes_[idx].First()) { laterStrike = strikes_[idx].First(); } } if (upperExtrapolation_ == Extrapolation.ConstantExtrapolation) { if (strike > strikes_[idx - 1].Last()) { earlierStrike = strikes_[idx - 1].Last(); } if (strike > strikes_[idx].Last()) { laterStrike = strikes_[idx].Last(); } } double earlyVol = (strikes_[idx - 1].First() < strikes_[idx - 1].Last()) ? localVolInterpol_[idx - 1].value(earlierStrike, true) : localVolMatrix_[localVolMatrix_.rows() / 2, idx - 1]; double laterVol = localVolInterpol_[idx].value(laterStrike, true); return(earlyVol + (laterVol - earlyVol) / (times_[idx] - times_[idx - 1]) * (t - times_[idx - 1])); } }
public bool Equals(Pair <double?, double?> p1, Pair <double?, double?> p2) { return(Utils.close_enough(p1.first.Value, p2.first.Value, 1000)); }