public LiborForwardModel(LiborForwardModelProcess process, LmVolatilityModel volaModel, LmCorrelationModel corrModel) : base(volaModel.parameters().Count + corrModel.parameters().Count) { f_ = new InitializedList <double>(process.size()); accrualPeriod_ = new InitializedList <double>(process.size()); covarProxy_ = new LfmCovarianceProxy(volaModel, corrModel); process_ = process; int k = volaModel.parameters().Count; for (int j = 0; j < k; j++) { arguments_[j] = volaModel.parameters()[j]; } for (int j = 0; j < corrModel.parameters().Count; j++) { arguments_[j + k] = corrModel.parameters()[j]; } for (int i = 0; i < process.size(); ++i) { accrualPeriod_[i] = process.accrualEndTimes()[i] - process.accrualStartTimes()[i]; f_[i] = 1.0 / (1.0 + accrualPeriod_[i] * process_.initialValues()[i]); } }
public double discountBondOption(Option.Type type, double strike, double maturity, double bondMaturity) { List <double> accrualStartTimes = process_.accrualStartTimes(); List <double> accrualEndTimes = process_.accrualEndTimes(); Utils.QL_REQUIRE(accrualStartTimes.First() <= maturity && accrualStartTimes.Last() >= maturity, () => "capet maturity does not fit to the process"); int i = accrualStartTimes.BinarySearch(maturity); if (i < 0) { // The lower_bound() algorithm finds the first position in a sequence that value can occupy // without violating the sequence's ordering // if BinarySearch does not find value the value, the index of the prev minor item is returned i = ~i + 1; } // impose limits. we need the one before last at max or the first at min i = Math.Max(Math.Min(i, accrualStartTimes.Count - 1), 0); Utils.QL_REQUIRE(i < process_.size() && Math.Abs(maturity - accrualStartTimes[i]) < 100 * Const.QL_EPSILON && Math.Abs(bondMaturity - accrualEndTimes[i]) < 100 * Const.QL_EPSILON, () => "irregular fixings are not (yet) supported"); double tenor = accrualEndTimes[i] - accrualStartTimes[i]; double forward = process_.initialValues()[i]; double capRate = (1.0 / strike - 1.0) / tenor; double var = covarProxy_.integratedCovariance(i, i, process_.fixingTimes()[i]); double dis = process_.index().forwardingTermStructure().link.discount(bondMaturity); double black = Utils.blackFormula( (type == Option.Type.Put ? Option.Type.Call : Option.Type.Put), capRate, forward, Math.Sqrt(var)); double npv = dis * tenor * black; return(npv / (1.0 + capRate * tenor)); }