Exemplo n.º 1
0
        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]);
            }
        }
Exemplo n.º 2
0
        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));
        }