Пример #1
0
 public double weight(double strike, double forward, double stdDev, List <double?> addParams)
 {
     if (Convert.ToDouble(addParams[1]) == 0.0)
     {
         return(Utils.blackFormulaStdDevDerivative(strike, forward, stdDev, 1.0, addParams[0].Value));
     }
     else
     {
         return(Utils.bachelierBlackFormulaStdDevDerivative(strike, forward, stdDev, 1.0));
     }
 }
Пример #2
0
 public double vega(double strike, double atmForward, double stdDev, double exerciseTime, double annuity,
                    double displacement = 0.0)
 {
     return(Math.Sqrt(exerciseTime) *
            Utils.blackFormulaStdDevDerivative(strike, atmForward, stdDev, annuity, displacement));
 }
Пример #3
0
        public override void calculate()
        {
            double        value      = 0.0;
            double        vega       = 0.0;
            int           optionlets = arguments_.startDates.Count;
            List <double> values     = new InitializedList <double>(optionlets);
            List <double> vegas      = new InitializedList <double>(optionlets);
            List <double> stdDevs    = new InitializedList <double>(optionlets);
            CapFloorType  type       = arguments_.type;
            Date          today      = vol_.link.referenceDate();
            Date          settlement = discountCurve_.link.referenceDate();

            for (int i = 0; i < optionlets; ++i)
            {
                Date paymentDate = arguments_.endDates[i];
                if (paymentDate > settlement)
                {
                    // discard expired caplets
                    double d = arguments_.nominals[i] *
                               arguments_.gearings[i] *
                               discountCurve_.link.discount(paymentDate) *
                               arguments_.accrualTimes[i];

                    double?forward = arguments_.forwards[i];

                    Date   fixingDate = arguments_.fixingDates[i];
                    double sqrtTime   = 0.0;
                    if (fixingDate > today)
                    {
                        sqrtTime = Math.Sqrt(vol_.link.timeFromReference(fixingDate));
                    }

                    if (type == CapFloorType.Cap || type == CapFloorType.Collar)
                    {
                        double?strike = arguments_.capRates[i];
                        if (sqrtTime > 0.0)
                        {
                            stdDevs[i] = Math.Sqrt(vol_.link.blackVariance(fixingDate, strike.Value));
                            vegas[i]   = Utils.blackFormulaStdDevDerivative(strike.Value, forward.Value, stdDevs[i], d, displacement_) * sqrtTime;
                        }
                        // include caplets with past fixing date
                        values[i] = Utils.blackFormula(Option.Type.Call, strike.Value,
                                                       forward.Value, stdDevs[i], d, displacement_);
                    }
                    if (type == CapFloorType.Floor || type == CapFloorType.Collar)
                    {
                        double?strike       = arguments_.floorRates[i];
                        double floorletVega = 0.0;

                        if (sqrtTime > 0.0)
                        {
                            stdDevs[i]   = Math.Sqrt(vol_.link.blackVariance(fixingDate, strike.Value));
                            floorletVega = Utils.blackFormulaStdDevDerivative(strike.Value, forward.Value, stdDevs[i], d, displacement_) * sqrtTime;
                        }
                        double floorlet = Utils.blackFormula(Option.Type.Put, strike.Value,
                                                             forward.Value, stdDevs[i], d, displacement_);
                        if (type == CapFloorType.Floor)
                        {
                            values[i] = floorlet;
                            vegas[i]  = floorletVega;
                        }
                        else
                        {
                            // a collar is long a cap and short a floor
                            values[i] -= floorlet;
                            vegas[i]  -= floorletVega;
                        }
                    }
                    value += values[i];
                    vega  += vegas[i];
                }
            }
            results_.value = value;
            results_.additionalResults["vega"] = vega;

            results_.additionalResults["optionletsPrice"]      = values;
            results_.additionalResults["optionletsVega"]       = vegas;
            results_.additionalResults["optionletsAtmForward"] = arguments_.forwards;
            if (type != CapFloorType.Collar)
            {
                results_.additionalResults["optionletsStdDev"] = stdDevs;
            }
        }
Пример #4
0
        public override void calculate()
        {
            double basisPoint = 1.0e-4;

            Date exerciseDate = arguments_.exercise.date(0);

            // the part of the swap preceding exerciseDate should be truncated
            // to avoid taking into account unwanted cashflows
            VanillaSwap swap = arguments_.swap;

            double strike = swap.fixedRate;

            // using the forecasting curve
            swap.setPricingEngine(new DiscountingSwapEngine(swap.iborIndex().forwardingTermStructure()));
            double atmForward = swap.fairRate();

            // Volatilities are quoted for zero-spreaded swaps.
            // Therefore, any spread on the floating leg must be removed
            // with a corresponding correction on the fixed leg.
            if (swap.spread != 0.0)
            {
                double correction = swap.spread * Math.Abs(swap.floatingLegBPS() / swap.fixedLegBPS());
                strike     -= correction;
                atmForward -= correction;
                results_.additionalResults["spreadCorrection"] = correction;
            }
            else
            {
                results_.additionalResults["spreadCorrection"] = 0.0;
            }
            results_.additionalResults["strike"]     = strike;
            results_.additionalResults["atmForward"] = atmForward;

            // using the discounting curve
            swap.setPricingEngine(new DiscountingSwapEngine(termStructure_));
            double annuity;

            switch (arguments_.settlementType)
            {
            case Settlement.Type.Physical: {
                annuity = Math.Abs(swap.fixedLegBPS()) / basisPoint;
                break;
            }

            case Settlement.Type.Cash: {
                List <CashFlow> fixedLeg        = swap.fixedLeg();
                FixedRateCoupon firstCoupon     = (FixedRateCoupon)fixedLeg[0];
                DayCounter      dayCount        = firstCoupon.dayCounter();
                double          fixedLegCashBPS =
                    CashFlows.bps(fixedLeg,
                                  new InterestRate(atmForward, dayCount, QLNet.Compounding.Compounded, Frequency.Annual), false,
                                  termStructure_.link.referenceDate());
                annuity = Math.Abs(fixedLegCashBPS / basisPoint);
                break;
            }

            default:
                throw new ApplicationException("unknown settlement type");
            }
            results_.additionalResults["annuity"] = annuity;

            // the swap length calculation might be improved using the value date
            // of the exercise date
            double swapLength = volatility_.link.swapLength(exerciseDate,
                                                            arguments_.floatingPayDates.Last());

            results_.additionalResults["swapLength"] = swapLength;

            double variance = volatility_.link.blackVariance(exerciseDate,
                                                             swapLength,
                                                             strike);
            double stdDev = Math.Sqrt(variance);

            results_.additionalResults["stdDev"] = stdDev;
            Option.Type w = (arguments_.type == VanillaSwap.Type.Payer) ?
                            Option.Type.Call : Option.Type.Put;
            results_.value = Utils.blackFormula(w, strike, atmForward, stdDev, annuity);

            double exerciseTime = volatility_.link.timeFromReference(exerciseDate);

            results_.additionalResults["vega"] = Math.Sqrt(exerciseTime) *
                                                 Utils.blackFormulaStdDevDerivative(strike, atmForward, stdDev, annuity);
        }
Пример #5
0
 public double weight(double strike, double forward, double stdDev, List <double?> addParams)
 {
     return(Utils.blackFormulaStdDevDerivative(strike, forward, stdDev, 1.0));
 }
Пример #6
0
        public override void update()
        {
            this.coeff_.updateModelInstance();

            // we should also check that y contains positive values only

            // we must update weights if it is vegaWeighted
            if (vegaWeighted_)
            {
                coeff_.weights_.Clear();
                double weightsSum = 0.0;

                for (int i = 0; i < xBegin_.Count; i++)
                {
                    double stdDev = Math.Sqrt((yBegin_[i]) * (yBegin_[i]) * this.coeff_.t_);
                    coeff_.weights_.Add(Utils.blackFormulaStdDevDerivative(xBegin_[i], forward_, stdDev));
                    weightsSum += coeff_.weights_.Last();
                }

                // weight normalization
                for (int i = 0; i < coeff_.weights_.Count; i++)
                {
                    coeff_.weights_[i] /= weightsSum;
                }
            }

            // there is nothing to optimize
            if (coeff_.paramIsFixed_.Aggregate((a, b) => b & a))
            {
                coeff_.error_           = interpolationError();
                coeff_.maxError_        = interpolationMaxError();
                coeff_.XABREndCriteria_ = EndCriteria.Type.None;
                return;
            }
            else
            {
                XABRError costFunction = new XABRError(this);

                Vector guess = new Vector(coeff_.model_.dimension());
                for (int i = 0; i < guess.size(); ++i)
                {
                    guess[i] = coeff_.params_[i].Value;
                }

                int    iterations     = 0;
                int    freeParameters = 0;
                double bestError      = double.MaxValue;
                Vector bestParameters = new Vector();
                for (int i = 0; i < coeff_.model_.dimension(); ++i)
                {
                    if (!coeff_.paramIsFixed_[i])
                    {
                        ++freeParameters;
                    }
                }
                HaltonRsg        halton = new HaltonRsg(freeParameters, 42);
                EndCriteria.Type tmpEndCriteria;
                double           tmpInterpolationError;

                do
                {
                    if (iterations > 0)
                    {
                        Sample <List <double> > s = halton.nextSequence();
                        coeff_.model_.guess(guess, coeff_.paramIsFixed_, forward_, coeff_.t_, s.value);
                        for (int i = 0; i < coeff_.paramIsFixed_.Count; ++i)
                        {
                            if (coeff_.paramIsFixed_[i])
                            {
                                guess[i] = coeff_.params_[i].Value;
                            }
                        }
                    }

                    Vector inversedTransformatedGuess = new Vector(coeff_.model_.inverse(guess, coeff_.paramIsFixed_, coeff_.params_, forward_));

                    ProjectedCostFunction rainedXABRError = new ProjectedCostFunction(costFunction, inversedTransformatedGuess,
                                                                                      coeff_.paramIsFixed_);

                    Vector projectedGuess = new Vector(rainedXABRError.project(inversedTransformatedGuess));

                    NoConstraint raint   = new NoConstraint();
                    Problem      problem = new Problem(rainedXABRError, raint, projectedGuess);
                    tmpEndCriteria = optMethod_.minimize(problem, endCriteria_);
                    // TEST
                    // coeff_.params_[3] = 0.0099999966589763966;
                    // TEST
                    Vector projectedResult = new Vector(problem.currentValue());
                    Vector transfResult    = new Vector(rainedXABRError.include(projectedResult));
                    //transfResult[3] = 0.0099999966589763966; ;
                    Vector result = coeff_.model_.direct(transfResult, coeff_.paramIsFixed_, coeff_.params_, forward_);
                    //result[3] = 0.0099999966589763966;
                    tmpInterpolationError = useMaxError_ ? interpolationMaxError()
                                                     : interpolationError();

                    if (tmpInterpolationError < bestError)
                    {
                        bestError               = tmpInterpolationError;
                        bestParameters          = result;
                        coeff_.XABREndCriteria_ = tmpEndCriteria;
                    }
                } while (++iterations < maxGuesses_ &&
                         tmpInterpolationError > errorAccept_);

                for (int i = 0; i < bestParameters.size(); ++i)
                {
                    coeff_.params_[i] = bestParameters[i];
                }

                coeff_.error_    = interpolationError();
                coeff_.maxError_ = interpolationMaxError();
            }
        }