public override double seasonalityFactor(Date to) { int dir = 1; Date from = seasonalityBaseDate(); int fromMonth = from.month(); int toMonth = to.month(); Period factorPeriod = new Period(frequency()); if (toMonth < fromMonth) { int dummy = fromMonth; fromMonth = toMonth; toMonth = dummy; dir = 0; // We calculate invers Factor in loop } Utils.QL_REQUIRE(seasonalityFactors().Count == 12 && factorPeriod.units() == TimeUnit.Months,()=> "12 monthly seasonal factors needed for Kerkhof Seasonality:" + " got " + seasonalityFactors().Count); double seasonalCorrection = 1.0; for (int i = fromMonth ; i<toMonth; i++) { seasonalCorrection *= seasonalityFactors()[i]; } if (dir == 0) // invers Factor required { seasonalCorrection = 1/seasonalCorrection; } return seasonalCorrection; }
public double value(double x) { if (x <= 0.0) return 0.0; double errmax = 1e-12; const int itrmax = 10000; double lam = 0.5*ncp_; double u = Math.Exp(-lam); double v = u; double x2 = 0.5*x; double f2 = 0.5*df_; double f_x_2n = df_ - x; double t = 0.0; if (f2 * Const.QL_EPSILON > 0.125 && Math.Abs(x2-f2) < Math.Sqrt(Const.QL_EPSILON)*f2) { t = Math.Exp((1 - t) * (2 - t / (f2 + 1))) / Math.Sqrt(2.0 * Const.M_PI * (f2 + 1.0)); } else { t = Math.Exp(f2*Math.Log(x2) - x2 - GammaFunction.logValue(f2 + 1)); } double ans = v*t; bool flag = false; int n = 1; double f_2n = df_ + 2.0; f_x_2n += 2.0; double bound; for (;;) { if (f_x_2n > 0) { flag = true; bound = t * x / f_x_2n; if (bound <= errmax || n > itrmax) goto L_End; } for (;;) { u *= lam / n; v += u; t *= x / f_2n; ans += v*t; n++; f_2n += 2.0; f_x_2n += 2.0; if (!flag && n <= itrmax) break; bound = t * x / f_x_2n; if (bound <= errmax || n > itrmax) goto L_End; } } L_End: Utils.QL_REQUIRE(bound <= errmax,()=> "didn't converge"); return (ans); }
protected double calculateAbsTolerance(Func <double, double> f, double a, double b) { double relTol = Math.Max(relAccuracy_ ?? 0, Const.QL_EPSILON); double m = (a + b) / 2; double h = (b - a) / 2; double y1 = f(a); double y3 = f(m - alpha_ * h); double y5 = f(m - beta_ * h); double y7 = f(m); double y9 = f(m + beta_ * h); double y11 = f(m + alpha_ * h); double y13 = f(b); double f1 = f(m - x1_ * h); double f2 = f(m + x1_ * h); double f3 = f(m - x2_ * h); double f4 = f(m + x2_ * h); double f5 = f(m - x3_ * h); double f6 = f(m + x3_ * h); double acc = h * (0.0158271919734801831 * (y1 + y13) + 0.0942738402188500455 * (f1 + f2) + 0.1550719873365853963 * (y3 + y11) + 0.1888215739601824544 * (f3 + f4) + 0.1997734052268585268 * (y5 + y9) + 0.2249264653333395270 * (f5 + f6) + 0.2426110719014077338 * y7); increaseNumberOfEvaluations(13); if (acc.IsEqual(0.0) && (f1.IsNotEqual(0.0) || f2.IsNotEqual(0.0) || f3.IsNotEqual(0.0) || f4.IsNotEqual(0.0) || f5.IsNotEqual(0.0) || f6.IsNotEqual(0.0))) { Utils.QL_FAIL("can not calculate absolute accuracy from relative accuracy"); } double r = 1.0; if (useConvergenceEstimate_) { double integral2 = (h / 6) * (y1 + y13 + 5 * (y5 + y9)); double integral1 = (h / 1470) * (77 * (y1 + y13) + 432 * (y3 + y11) + 625 * (y5 + y9) + 672 * y7); if (Math.Abs(integral2 - acc).IsNotEqual(0.0)) { r = Math.Abs(integral1 - acc) / Math.Abs(integral2 - acc); } if (r.IsEqual(0.0) || r > 1.0) { r = 1.0; } } if (relAccuracy_ != null) { if (absoluteAccuracy() != null) { return(Math.Min(absoluteAccuracy().GetValueOrDefault(), acc * relTol) / (r * Const.QL_EPSILON)); } else { return((acc * relTol) / (r * Const.QL_EPSILON)); } } else { return(absoluteAccuracy().GetValueOrDefault() / (r * Const.QL_EPSILON)); } }
public LfmHullWhiteParameterization( LiborForwardModelProcess process, OptionletVolatilityStructure capletVol, Matrix correlation, int factors) : base(process.size(), factors) { diffusion_ = new Matrix(size_ - 1, factors_); fixingTimes_ = process.fixingTimes(); Matrix sqrtCorr = new Matrix(size_ - 1, factors_, 1.0); if (correlation.empty()) { Utils.QL_REQUIRE(factors_ == 1, () => "correlation matrix must be given for multi factor models"); } else { Utils.QL_REQUIRE(correlation.rows() == size_ - 1 && correlation.rows() == correlation.columns(), () => "wrong dimesion of the correlation matrix"); Utils.QL_REQUIRE(factors_ <= size_ - 1, () => "too many factors for given LFM process"); Matrix tmpSqrtCorr = MatrixUtilitites.pseudoSqrt(correlation, MatrixUtilitites.SalvagingAlgorithm.Spectral); // reduce to n factor model // "Reconstructing a valid correlation matrix from invalid data" // (<http://www.quarchome.org/correlationmatrix.pdf>) for (int i = 0; i < size_ - 1; ++i) { double d = 0; tmpSqrtCorr.row(i).GetRange(0, factors_).ForEach((ii, vv) => d += vv * tmpSqrtCorr.row(i)[ii]); for (int k = 0; k < factors_; ++k) { sqrtCorr[i, k] = tmpSqrtCorr.row(i).GetRange(0, factors_)[k] / Math.Sqrt(d); } } } List <double> lambda = new List <double>(); DayCounter dayCounter = process.index().dayCounter(); List <double> fixingTimes = process.fixingTimes(); List <Date> fixingDates = process.fixingDates(); for (int i = 1; i < size_; ++i) { double cumVar = 0.0; for (int j = 1; j < i; ++j) { cumVar += lambda[i - j - 1] * lambda[i - j - 1] * (fixingTimes[j + 1] - fixingTimes[j]); } double vol = capletVol.volatility(fixingDates[i], 0.0, false); double var = vol * vol * capletVol.dayCounter().yearFraction(fixingDates[0], fixingDates[i]); lambda.Add(Math.Sqrt((var - cumVar) / (fixingTimes[1] - fixingTimes[0]))); for (int q = 0; q < factors_; ++q) { diffusion_[i - 1, q] = sqrtCorr[i - 1, q] * lambda.Last(); } } covariance_ = diffusion_ * Matrix.transpose(diffusion_); }
public virtual double fairSpread() { calculate(); Utils.QL_REQUIRE(fairSpread_ != null, () => "result not available"); return fairSpread_.Value; }
public virtual double yoyLegNPV() { calculate(); Utils.QL_REQUIRE(legNPV_[1] != null, () => "result not available"); return legNPV_[1].Value; }
public override double correctYoYRate(Date d, double r, InflationTermStructure iTS) { KeyValuePair<Date,Date> lim = Utils.inflationPeriod(iTS.baseDate(), iTS.frequency()); Date curveBaseDate = lim.Value; return seasonalityCorrection(r, d, iTS.dayCounter(), curveBaseDate, false); }