Beispiel #1
0
        // A parsimonious constructor is chosen, which for example
        // doesn't need a strike. The reason for this is, that we'd
        // like this class to calculate deltas for different strikes
        // many times, e.g. in a numerical routine, which will be the
        // case in the smile setup procedure.
        public BlackDeltaCalculator(Option.Type ot,
                                    DeltaVolQuote.DeltaType dt,
                                    double spot,
                                    double dDiscount, // domestic discount
                                    double fDiscount, // foreign discount
                                    double stdDev)
        {
            dt_        = dt;
            ot_        = ot;
            dDiscount_ = dDiscount;
            fDiscount_ = fDiscount;
            stdDev_    = stdDev;
            spot_      = spot;
            forward_   = spot * fDiscount / dDiscount;
            phi_       = (int)ot;


            Utils.QL_REQUIRE(spot_ > 0.0, () => "positive spot value required: " + spot_ + " not allowed");
            Utils.QL_REQUIRE(dDiscount_ > 0.0, () => "positive domestic discount factor required: " + dDiscount_ + " not allowed");
            Utils.QL_REQUIRE(fDiscount_ > 0.0, () => "positive foreign discount factor required: " + fDiscount_ + " not allowed");
            Utils.QL_REQUIRE(stdDev_ >= 0.0, () => "non-negative standard deviation required: " + stdDev_ + " not allowed");

            fExpPos_ = forward_ * Math.Exp(0.5 * stdDev_ * stdDev_);
            fExpNeg_ = forward_ * Math.Exp(-0.5 * stdDev_ * stdDev_);
        }
Beispiel #2
0
 public BlackDeltaCalculator(Option.Type ot, DeltaVolQuote.DeltaType dt, double spot, double dDiscount, double fDiscount, double stDev) : this(NQuantLibcPINVOKE.new_BlackDeltaCalculator((int)ot, (int)dt, spot, dDiscount, fDiscount, stDev), true)
 {
     if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
     {
         throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
     }
 }
Beispiel #3
0
 public DeltaVolQuote(QuoteHandle vol, DeltaVolQuote.DeltaType deltaType, double maturity, DeltaVolQuote.AtmType atmType) : this(NQuantLibcPINVOKE.new_DeltaVolQuote__SWIG_1(QuoteHandle.getCPtr(vol), (int)deltaType, maturity, (int)atmType), true)
 {
     if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
     {
         throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
     }
 }
Beispiel #4
0
 public BlackDeltaPremiumAdjustedMaxStrikeClass(Option.Type ot,
                                                DeltaVolQuote.DeltaType dt,
                                                double spot,
                                                double dDiscount, // domestic discount
                                                double fDiscount, // foreign  discount
                                                double stdDev)
 {
     bdc_    = new BlackDeltaCalculator(ot, dt, spot, dDiscount, fDiscount, stdDev);
     stdDev_ = stdDev;
 }
Beispiel #5
0
 public BlackDeltaPremiumAdjustedSolverClass(Option.Type ot,
                                             DeltaVolQuote.DeltaType dt,
                                             double spot,
                                             double dDiscount, // domestic discount
                                             double fDiscount, // foreign  discount
                                             double stdDev,
                                             double delta)
 {
     bdc_   = new BlackDeltaCalculator(ot, dt, spot, dDiscount, fDiscount, stdDev);
     delta_ = delta;
 }
Beispiel #6
0
 public DeltaData(Option.Type ot, DeltaVolQuote.DeltaType dt, double spot, double dDf, double fDf,
                  double stdDev, double strike, double value) : this()
 {
     this.ot     = ot;
     this.dt     = dt;
     this.spot   = spot;
     this.dDf    = dDf;
     this.fDf    = fDf;
     this.stdDev = stdDev;
     this.strike = strike;
     this.value  = value;
 }
Beispiel #7
0
        // alternative delta type
        private double strikeFromDelta(double delta, DeltaVolQuote.DeltaType dt)
        {
            double res = 0.0;
            double arg = 0.0;
            InverseCumulativeNormal f = new InverseCumulativeNormal();

            Utils.QL_REQUIRE(delta * phi_ >= 0.0, () => "Option type and delta are incoherent.");

            switch (dt)
            {
            case DeltaVolQuote.DeltaType.Spot:
                Utils.QL_REQUIRE(Math.Abs(delta) <= fDiscount_, () => "Spot delta out of range.");
                arg = -phi_ *f.value(phi_ *delta / fDiscount_) * stdDev_ + 0.5 * stdDev_ * stdDev_;

                res = forward_ * Math.Exp(arg);
                break;

            case DeltaVolQuote.DeltaType.Fwd:
                Utils.QL_REQUIRE(Math.Abs(delta) <= 1.0, () => "Forward delta out of range.");
                arg = -phi_ *f.value(phi_ *delta) * stdDev_ + 0.5 * stdDev_ * stdDev_;

                res = forward_ * Math.Exp(arg);
                break;

            case DeltaVolQuote.DeltaType.PaSpot:
            case DeltaVolQuote.DeltaType.PaFwd:
                // This has to be solved numerically. One of the
                // problems is that the premium adjusted call delta is
                // not monotonic in strike, such that two solutions
                // might occur. The one right to the max of the delta is
                // considered to be the correct strike.  Some proper
                // interval bounds for the strike need to be chosen, the
                // numerics can otherwise be very unreliable and
                // unstable.  I've chosen Brent over Newton, since the
                // interval can be specified explicitly and we can not
                // run into the area on the left of the maximum.  The
                // put delta doesn't have this property and can be
                // solved without any problems, but also numerically.

                BlackDeltaPremiumAdjustedSolverClass f1 = new BlackDeltaPremiumAdjustedSolverClass(
                    ot_, dt, spot_, dDiscount_, fDiscount_, stdDev_, delta);

                Brent solver = new Brent();
                solver.setMaxEvaluations(1000);
                double accuracy = 1.0e-10;

                double rightLimit = 0.0;
                double leftLimit  = 0.0;

                // Strike of not premium adjusted is always to the right of premium adjusted
                if (dt == DeltaVolQuote.DeltaType.PaSpot)
                {
                    rightLimit = strikeFromDelta(delta, DeltaVolQuote.DeltaType.Spot);
                }
                else
                {
                    rightLimit = strikeFromDelta(delta, DeltaVolQuote.DeltaType.Fwd);
                }

                if (phi_ < 0)
                {
                    // if put
                    res = solver.solve(f1, accuracy, rightLimit, 0.0, spot_ * 100.0);
                    break;
                }
                else
                {
                    // find out the left limit which is the strike
                    // corresponding to the value where premium adjusted
                    // deltas have their maximum.

                    BlackDeltaPremiumAdjustedMaxStrikeClass g = new BlackDeltaPremiumAdjustedMaxStrikeClass(
                        ot_, dt, spot_, dDiscount_, fDiscount_, stdDev_);

                    leftLimit = solver.solve(g, accuracy, rightLimit * 0.5, 0.0, rightLimit);

                    double guess = leftLimit + (rightLimit - leftLimit) * 0.5;

                    res = solver.solve(f1, accuracy, guess, leftLimit, rightLimit);
                } // end if phi<0 else

                break;


            default:
                Utils.QL_FAIL("invalid delta type");
                break;
            }

            return(res);
        }
Beispiel #8
0
 public void setDeltaType(DeltaVolQuote.DeltaType dt)
 {
     dt_ = dt;
 }