public virtual void sabrParameterByExpiryTenor_surfaceName()
        {
            SurfaceMetadata test     = Surfaces.sabrParameterByExpiryTenor(SURFACE_NAME, ACT_360, ValueType.SABR_BETA);
            SurfaceMetadata expected = DefaultSurfaceMetadata.builder().surfaceName(SURFACE_NAME).xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.YEAR_FRACTION).zValueType(ValueType.SABR_BETA).dayCount(ACT_360).build();

            assertEquals(test, expected);
        }
Ejemplo n.º 2
0
        public virtual InterpolatedNodalSurface localVolatilityFromPrice(Surface callPriceSurface, double spot, System.Func <double, double> interestRate, System.Func <double, double> dividendRate)
        {
            double[][]           stateValue  = new double[nSteps + 1][];
            double[]             df          = new double[nSteps];
            IList <DoubleMatrix> probability = new List <DoubleMatrix>(nSteps);
            int nTotal = (nSteps - 1) * (nSteps - 1) + 1;

            double[] timeRes = new double[nTotal];
            double[] spotRes = new double[nTotal];
            double[] volRes  = new double[nTotal];
            // uniform grid based on TrigeorgisLatticeSpecification, using reference values
            double refPrice      = callPriceSurface.zValue(maxTime, spot) * Math.Exp(interestRate(maxTime) * maxTime);
            double refForward    = spot * Math.Exp((interestRate(maxTime) - dividendRate(maxTime)) * maxTime);
            double refVolatility = BlackFormulaRepository.impliedVolatility(refPrice, refForward, spot, maxTime, true);
            double dt            = maxTime / nSteps;
            double dx            = refVolatility * Math.Sqrt(3d * dt);
            double upFactor      = Math.Exp(dx);
            double downFactor    = Math.Exp(-dx);

            double[] adSec      = new double[2 * nSteps + 1];
            double[] assetPrice = new double[2 * nSteps + 1];
            for (int i = nSteps; i > -1; --i)
            {
                if (i == 0)
                {
                    resolveFirstLayer(interestRate, dividendRate, nTotal, dt, spot, adSec, assetPrice, timeRes, spotRes, volRes, df, stateValue, probability);
                }
                else
                {
                    double   time             = dt * i;
                    double   zeroRate         = interestRate(time);
                    double   zeroDividendRate = dividendRate(time);
                    int      nNodes           = 2 * i + 1;
                    double[] assetPriceLocal  = new double[nNodes];
                    double[] callOptionPrice  = new double[nNodes];
                    double[] putOptionPrice   = new double[nNodes];
                    int      position         = i - 1;
                    double   assetTmp         = spot * Math.Pow(upFactor, i);
                    // call options for upper half nodes
                    for (int j = nNodes - 1; j > position - 1; --j)
                    {
                        assetPriceLocal[j] = assetTmp;
                        callOptionPrice[j] = callPriceSurface.zValue(time, assetPriceLocal[j]);
                        assetTmp          *= downFactor;
                    }
                    // put options for lower half nodes
                    assetTmp = spot * Math.Pow(downFactor, i);
                    for (int j = 0; j < position + 2; ++j)
                    {
                        assetPriceLocal[j] = assetTmp;
                        putOptionPrice[j]  = callPriceSurface.zValue(time, assetPriceLocal[j]) - spot * Math.Exp(-zeroDividendRate * time) + Math.Exp(-zeroRate * time) * assetPriceLocal[j];
                        assetTmp          *= upFactor;
                    }
                    resolveLayer(interestRate, dividendRate, i, nTotal, position, dt, zeroRate, zeroDividendRate, callOptionPrice, putOptionPrice, adSec, assetPrice, assetPriceLocal, timeRes, spotRes, volRes, df, stateValue, probability);
                }
            }
            SurfaceMetadata metadata = DefaultSurfaceMetadata.builder().xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.STRIKE).zValueType(ValueType.LOCAL_VOLATILITY).surfaceName(SurfaceName.of("localVol_" + callPriceSurface.Name)).build();

            return(InterpolatedNodalSurface.ofUnsorted(metadata, DoubleArray.ofUnsafe(timeRes), DoubleArray.ofUnsafe(spotRes), DoubleArray.ofUnsafe(volRes), interpolator));
        }
        public virtual void blackVolatilityByExpiryLogMoneyness_surfaceName()
        {
            SurfaceMetadata test     = Surfaces.blackVolatilityByExpiryLogMoneyness(SURFACE_NAME, ACT_360);
            SurfaceMetadata expected = DefaultSurfaceMetadata.builder().surfaceName(SURFACE_NAME).xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.LOG_MONEYNESS).zValueType(ValueType.BLACK_VOLATILITY).dayCount(ACT_360).build();

            assertEquals(test, expected);
        }
        //-------------------------------------------------------------------------
        public virtual void normalVolatilityByExpiryStrike_string()
        {
            SurfaceMetadata test     = Surfaces.normalVolatilityByExpiryStrike(NAME, ACT_360);
            SurfaceMetadata expected = DefaultSurfaceMetadata.builder().surfaceName(SURFACE_NAME).xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.STRIKE).zValueType(ValueType.NORMAL_VOLATILITY).dayCount(ACT_360).build();

            assertEquals(test, expected);
        }
Ejemplo n.º 5
0
            public override Builder set(string propertyName, object newValue)
            {
                switch (propertyName.GetHashCode())
                {
                case -450004177:         // metadata
                    this.metadata_Renamed = (SurfaceMetadata)newValue;
                    break;

                case 1681280954:         // xValues
                    this.xValues_Renamed = (DoubleArray)newValue;
                    break;

                case -1726182661:         // yValues
                    this.yValues_Renamed = (DoubleArray)newValue;
                    break;

                case -838678980:         // zValues
                    this.zValues_Renamed = (DoubleArray)newValue;
                    break;

                case 2096253127:         // interpolator
                    this.interpolator_Renamed = (SurfaceInterpolator)newValue;
                    break;

                default:
                    throw new NoSuchElementException("Unknown property: " + propertyName);
                }
                return(this);
            }
Ejemplo n.º 6
0
 // basic validation
 private void validateInputs(SurfaceMetadata metadata, DoubleArray xValues, DoubleArray yValues, DoubleArray zValues, SurfaceInterpolator interpolator)
 {
     ArgChecker.notNull(metadata, "metadata");
     ArgChecker.notNull(xValues, "times");
     ArgChecker.notNull(yValues, "values");
     ArgChecker.notNull(interpolator, "interpolator");
     if (xValues.size() < 2)
     {
         throw new System.ArgumentException("Length of x-values must be at least 2");
     }
     if (xValues.size() != yValues.size())
     {
         throw new System.ArgumentException("Length of x-values and y-values must match");
     }
     if (xValues.size() != zValues.size())
     {
         throw new System.ArgumentException("Length of x-values and z-values must match");
     }
     metadata.ParameterMetadata.ifPresent(@params =>
     {
         if (xValues.size() != @params.size())
         {
             throw new System.ArgumentException("Length of x-values and parameter metadata must match when metadata present");
         }
     });
 }
        public virtual void normalVolatilityByExpirySimpleMoneyness_surfaceName()
        {
            SurfaceMetadata test     = Surfaces.normalVolatilityByExpirySimpleMoneyness(SURFACE_NAME, ACT_360, MoneynessType.PRICE);
            SurfaceMetadata expected = DefaultSurfaceMetadata.builder().surfaceName(SURFACE_NAME).xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.SIMPLE_MONEYNESS).zValueType(ValueType.NORMAL_VOLATILITY).dayCount(ACT_360).addInfo(SurfaceInfoType.MONEYNESS_TYPE, MoneynessType.PRICE).build();

            assertEquals(test, expected);
        }
        public virtual DeformedSurface localVolatilityFromPrice(Surface callPriceSurface, double spot, System.Func <double, double> interestRate, System.Func <double, double> dividendRate)
        {
            System.Func <DoublesPair, ValueDerivatives> func = (DoublesPair x) =>
            {
                double      t          = x.First;
                double      k          = x.Second;
                double      r          = interestRate(t);
                double      q          = dividendRate(t);
                double      price      = callPriceSurface.zValue(t, k);
                DoubleArray priceSensi = callPriceSurface.zValueParameterSensitivity(t, k).Sensitivity;
                double      divT       = FIRST_DERIV.differentiate(u => callPriceSurface.zValue(u, k)).apply(t);
                DoubleArray divTSensi  = FIRST_DERIV_SENSI.differentiate(u => callPriceSurface.zValueParameterSensitivity(u.get(0), k).Sensitivity).apply(DoubleArray.of(t)).column(0);
                double      divK       = FIRST_DERIV.differentiate(l => callPriceSurface.zValue(t, l)).apply(k);
                DoubleArray divKSensi  = FIRST_DERIV_SENSI.differentiate(l => callPriceSurface.zValueParameterSensitivity(t, l.get(0)).Sensitivity).apply(DoubleArray.of(k)).column(0);
                double      divK2      = SECOND_DERIV.differentiate(l => callPriceSurface.zValue(t, l)).apply(k);
                DoubleArray divK2Sensi = SECOND_DERIV_SENSI.differentiateNoCross(l => callPriceSurface.zValueParameterSensitivity(t, l.get(0)).Sensitivity).apply(DoubleArray.of(k)).column(0);
                double      var        = 2d * (divT + q * price + (r - q) * k * divK) / (k * k * divK2);
                if (var < 0d)
                {
                    throw new System.ArgumentException("Negative variance");
                }
                double      localVol      = Math.Sqrt(var);
                double      factor        = 1d / (localVol * k * k * divK2);
                DoubleArray localVolSensi = divTSensi.multipliedBy(factor).plus(divKSensi.multipliedBy((r - q) * k * factor)).plus(priceSensi.multipliedBy(q * factor)).plus(divK2Sensi.multipliedBy(-0.5 * localVol / divK2));
                return(ValueDerivatives.of(localVol, localVolSensi));
            };
            SurfaceMetadata metadata = DefaultSurfaceMetadata.builder().xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.STRIKE).zValueType(ValueType.LOCAL_VOLATILITY).surfaceName(SurfaceName.of("localVol_" + callPriceSurface.Name)).build();

            return(DeformedSurface.of(metadata, callPriceSurface, func));
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Restricted copy constructor. </summary>
 /// <param name="beanToCopy">  the bean to copy from, not null </param>
 internal Builder(InterpolatedNodalSurface beanToCopy)
 {
     this.metadata_Renamed     = beanToCopy.Metadata;
     this.xValues_Renamed      = beanToCopy.XValues;
     this.yValues_Renamed      = beanToCopy.YValues;
     this.zValues_Renamed      = beanToCopy.ZValues;
     this.interpolator_Renamed = beanToCopy.Interpolator;
 }
Ejemplo n.º 10
0
 private DeformedSurface(SurfaceMetadata metadata, Surface originalSurface, System.Func <DoublesPair, ValueDerivatives> deformationFunction)
 {
     JodaBeanUtils.notNull(metadata, "metadata");
     JodaBeanUtils.notNull(originalSurface, "originalSurface");
     JodaBeanUtils.notNull(deformationFunction, "deformationFunction");
     this.metadata            = metadata;
     this.originalSurface     = originalSurface;
     this.deformationFunction = deformationFunction;
 }
Ejemplo n.º 11
0
        //-------------------------------------------------------------------------
        public virtual InterpolatedNodalSurface localVolatilityFromImpliedVolatility(Surface impliedVolatilitySurface, double spot, System.Func <double, double> interestRate, System.Func <double, double> dividendRate)
        {
            System.Func <DoublesPair, double> surface = (DoublesPair tk) =>
            {
                return(impliedVolatilitySurface.zValue(tk));
            };
            ImmutableList <double[]> localVolData = calibrate(surface, spot, interestRate, dividendRate).First;
            SurfaceMetadata          metadata     = DefaultSurfaceMetadata.builder().xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.STRIKE).zValueType(ValueType.LOCAL_VOLATILITY).surfaceName(SurfaceName.of("localVol_" + impliedVolatilitySurface.Name)).build();

            return(InterpolatedNodalSurface.ofUnsorted(metadata, DoubleArray.ofUnsafe(localVolData.get(0)), DoubleArray.ofUnsafe(localVolData.get(1)), DoubleArray.ofUnsafe(localVolData.get(2)), interpolator));
        }
Ejemplo n.º 12
0
	  static BlackSwaptionExpiryTenorVolatilitiesTest()
	  {
		IList<SwaptionSurfaceExpiryTenorParameterMetadata> list = new List<SwaptionSurfaceExpiryTenorParameterMetadata>();
		int nData = TIME.size();
		for (int i = 0; i < nData; ++i)
		{
		  SwaptionSurfaceExpiryTenorParameterMetadata parameterMetadata = SwaptionSurfaceExpiryTenorParameterMetadata.of(TIME.get(i), TENOR.get(i));
		  list.Add(parameterMetadata);
		}
		METADATA = Surfaces.blackVolatilityByExpiryTenor("GOVT1-SWAPTION-VOL", ACT_365F).withParameterMetadata(list);
	  }
Ejemplo n.º 13
0
        //-------------------------------------------------------------------------
        public override IborCapletFloorletVolatilityCalibrationResult calibrate(IborCapletFloorletVolatilityDefinition definition, ZonedDateTime calibrationDateTime, RawOptionData capFloorData, RatesProvider ratesProvider)
        {
            ArgChecker.isTrue(ratesProvider.ValuationDate.Equals(calibrationDateTime.toLocalDate()), "valuationDate of ratesProvider should be coherent to calibrationDateTime");
            ArgChecker.isTrue(definition is SabrIborCapletFloorletVolatilityCalibrationDefinition, "definition should be SabrIborCapletFloorletVolatilityCalibrationDefinition");
            SabrIborCapletFloorletVolatilityCalibrationDefinition sabrDefinition = (SabrIborCapletFloorletVolatilityCalibrationDefinition)definition;
            // unpack cap data, create node caps
            IborIndex index           = sabrDefinition.Index;
            LocalDate calibrationDate = calibrationDateTime.toLocalDate();
            LocalDate baseDate        = index.EffectiveDateOffset.adjust(calibrationDate, ReferenceData);
            LocalDate startDate       = baseDate.plus(index.Tenor);

            System.Func <Surface, IborCapletFloorletVolatilities> volatilitiesFunction = this.volatilitiesFunction(sabrDefinition, calibrationDateTime, capFloorData);
            SurfaceMetadata metadata   = sabrDefinition.createMetadata(capFloorData);
            IList <Period>  expiries   = capFloorData.Expiries;
            DoubleArray     strikes    = capFloorData.Strikes;
            int             nExpiries  = expiries.Count;
            IList <double>  timeList   = new List <double>();
            IList <double>  strikeList = new List <double>();
            IList <double>  volList    = new List <double>();
            IList <ResolvedIborCapFloorLeg> capList = new List <ResolvedIborCapFloorLeg>();
            IList <double> priceList   = new List <double>();
            IList <double> errorList   = new List <double>();
            DoubleMatrix   errorMatrix = capFloorData.Error.orElse(DoubleMatrix.filled(nExpiries, strikes.size(), 1d));

            int[] startIndex = new int[nExpiries + 1];
            for (int i = 0; i < nExpiries; ++i)
            {
                LocalDate   endDate           = baseDate.plus(expiries[i]);
                DoubleArray volatilityForTime = capFloorData.Data.row(i);
                DoubleArray errorForTime      = errorMatrix.row(i);
                reduceRawData(sabrDefinition, ratesProvider, capFloorData.Strikes, volatilityForTime, errorForTime, startDate, endDate, metadata, volatilitiesFunction, timeList, strikeList, volList, capList, priceList, errorList);
                startIndex[i + 1] = volList.Count;
                ArgChecker.isTrue(startIndex[i + 1] > startIndex[i], "no valid option data for {}", expiries[i]);
            }
            // create initial caplet vol surface
            IList <CurveMetadata> metadataList                = sabrDefinition.createSabrParameterMetadata();
            DoubleArray           initialValues               = sabrDefinition.createFullInitialValues();
            IList <Curve>         curveList                   = sabrDefinition.createSabrParameterCurve(metadataList, initialValues);
            SabrParameters        sabrParamsInitial           = SabrParameters.of(curveList[0], curveList[1], curveList[2], curveList[3], sabrDefinition.ShiftCurve, sabrDefinition.SabrVolatilityFormula);
            SabrParametersIborCapletFloorletVolatilities vols = SabrParametersIborCapletFloorletVolatilities.of(sabrDefinition.Name, index, calibrationDateTime, sabrParamsInitial);
            // solve least square
            UncoupledParameterTransforms transform = new UncoupledParameterTransforms(initialValues, sabrDefinition.createFullTransform(TRANSFORMS), new BitArray());

            System.Func <DoubleArray, DoubleArray>  valueFunction    = createPriceFunction(sabrDefinition, ratesProvider, vols, capList, priceList);
            System.Func <DoubleArray, DoubleMatrix> jacobianFunction = createJacobianFunction(sabrDefinition, ratesProvider, vols, capList, priceList, index.Currency);
            NonLinearTransformFunction      transFunc    = new NonLinearTransformFunction(valueFunction, jacobianFunction, transform);
            LeastSquareResults              res          = solver.solve(DoubleArray.filled(priceList.Count, 1d), DoubleArray.copyOf(errorList), transFunc.FittingFunction, transFunc.FittingJacobian, transform.transform(initialValues));
            LeastSquareResultsWithTransform resTransform = new LeastSquareResultsWithTransform(res, transform);

            vols = updateParameters(sabrDefinition, vols, resTransform.ModelParameters);

            return(IborCapletFloorletVolatilityCalibrationResult.ofLeastSquare(vols, res.ChiSq));
        }
Ejemplo n.º 14
0
        static NormalSwaptionExpirySimpleMoneynessVolatilitiesTest()
        {
            IList <SwaptionSurfaceExpirySimpleMoneynessParameterMetadata> list = new List <SwaptionSurfaceExpirySimpleMoneynessParameterMetadata>();
            int nData = TIME.size();

            for (int i = 0; i < nData; ++i)
            {
                SwaptionSurfaceExpirySimpleMoneynessParameterMetadata parameterMetadata = SwaptionSurfaceExpirySimpleMoneynessParameterMetadata.of(TIME.get(i), SIMPLE_MONEYNESS.get(i));
                list.Add(parameterMetadata);
            }
            METADATA = Surfaces.normalVolatilityByExpirySimpleMoneyness("GOVT1-SWAPTION-VOL", ACT_365F, MoneynessType.RATES).withParameterMetadata(list);
        }
        static ShiftedBlackIborCapletFloorletExpiryStrikeVolatilitiesTest()
        {
            IList <GenericVolatilitySurfaceYearFractionParameterMetadata> list = new List <GenericVolatilitySurfaceYearFractionParameterMetadata>();
            int nData = TIME.size();

            for (int i = 0; i < nData; ++i)
            {
                GenericVolatilitySurfaceYearFractionParameterMetadata parameterMetadata = GenericVolatilitySurfaceYearFractionParameterMetadata.of(TIME.get(i), SimpleStrike.of(STRIKE.get(i)));
                list.Add(parameterMetadata);
            }
            METADATA = Surfaces.blackVolatilityByExpiryStrike("CAP_VOL", ACT_365F).withParameterMetadata(list);
        }
Ejemplo n.º 16
0
        static BlackBondFutureOptionMarginedProductPricerTest()
        {
            IList <GenericVolatilitySurfaceYearFractionParameterMetadata> list = new List <GenericVolatilitySurfaceYearFractionParameterMetadata>();
            int nData = TIME.size();

            for (int i = 0; i < nData; ++i)
            {
                GenericVolatilitySurfaceYearFractionParameterMetadata parameterMetadata = GenericVolatilitySurfaceYearFractionParameterMetadata.of(TIME.get(i), LogMoneynessStrike.of(MONEYNESS.get(i)));
                list.Add(parameterMetadata);
            }
            METADATA = DefaultSurfaceMetadata.builder().surfaceName(SurfaceName.of("GOVT1-BOND-FUT-VOL")).xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.LOG_MONEYNESS).zValueType(ValueType.BLACK_VOLATILITY).parameterMetadata(list).dayCount(ACT_365F).build();
        }
        static NormalSwaptionExpiryStrikeVolatilitiesTest()
        {
            IList <SwaptionSurfaceExpiryStrikeParameterMetadata> list = new List <SwaptionSurfaceExpiryStrikeParameterMetadata>();
            int nData = TIME.size();

            for (int i = 0; i < nData; ++i)
            {
                SwaptionSurfaceExpiryStrikeParameterMetadata parameterMetadata = SwaptionSurfaceExpiryStrikeParameterMetadata.of(TIME.get(i), STRIKE.get(i));
                list.Add(parameterMetadata);
            }
            METADATA = Surfaces.normalVolatilityByExpiryStrike("GOVT1-SWAPTION-VOL", ACT_365F).withParameterMetadata(list);
        }
            public override Builder set(string propertyName, object newValue)
            {
                switch (propertyName.GetHashCode())
                {
                case -450004177:         // metadata
                    this.metadata = (SurfaceMetadata)newValue;
                    break;

                case -719790825:         // zValue
                    this.zValue = (double?)newValue.Value;
                    break;

                default:
                    throw new NoSuchElementException("Unknown property: " + propertyName);
                }
                return(this);
            }
        public virtual void test_presentValueSensitivityRatesStickyModel_stickyStrike()
        {
            SwaptionVolatilities volSabr    = SwaptionSabrRateVolatilityDataSet.getVolatilitiesUsd(VAL_DATE, false);
            double               impliedVol = SWAPTION_PRICER.impliedVolatility(SWAPTION_REC_LONG, RATE_PROVIDER, volSabr);
            SurfaceMetadata      blackMeta  = Surfaces.blackVolatilityByExpiryTenor("CST", VOLS.DayCount);
            SwaptionVolatilities volCst     = BlackSwaptionExpiryTenorVolatilities.of(VOLS.Convention, VOLS.ValuationDateTime, ConstantSurface.of(blackMeta, impliedVol));
            // To obtain a constant volatility surface which create a sticky strike sensitivity
            PointSensitivityBuilder        pointRec    = SWAPTION_PRICER.presentValueSensitivityRatesStickyStrike(SWAPTION_REC_LONG, RATE_PROVIDER, volSabr);
            CurrencyParameterSensitivities computedRec = RATE_PROVIDER.parameterSensitivity(pointRec.build());
            CurrencyParameterSensitivities expectedRec = FD_CAL.sensitivity(RATE_PROVIDER, (p) => SWAPTION_PRICER.presentValue(SWAPTION_REC_LONG, (p), volCst));

            assertTrue(computedRec.equalWithTolerance(expectedRec, NOTIONAL * FD_EPS * 100d));

            PointSensitivityBuilder        pointPay    = SWAPTION_PRICER.presentValueSensitivityRatesStickyStrike(SWAPTION_PAY_SHORT, RATE_PROVIDER, volSabr);
            CurrencyParameterSensitivities computedPay = RATE_PROVIDER.parameterSensitivity(pointPay.build());
            CurrencyParameterSensitivities expectedPay = FD_CAL.sensitivity(RATE_PROVIDER, (p) => SWAPTION_PRICER.presentValue(SWAPTION_PAY_SHORT, (p), volCst));

            assertTrue(computedPay.equalWithTolerance(expectedPay, NOTIONAL * FD_EPS * 100d));
        }
        public virtual DeformedSurface localVolatilityFromImpliedVolatility(Surface impliedVolatilitySurface, double spot, System.Func <double, double> interestRate, System.Func <double, double> dividendRate)
        {
            System.Func <DoublesPair, ValueDerivatives> func = (DoublesPair x) =>
            {
                double      t         = x.First;
                double      k         = x.Second;
                double      r         = interestRate(t);
                double      q         = dividendRate(t);
                double      vol       = impliedVolatilitySurface.zValue(t, k);
                DoubleArray volSensi  = impliedVolatilitySurface.zValueParameterSensitivity(t, k).Sensitivity;
                double      divT      = FIRST_DERIV.differentiate(u => impliedVolatilitySurface.zValue(u, k)).apply(t);
                DoubleArray divTSensi = FIRST_DERIV_SENSI.differentiate(u => impliedVolatilitySurface.zValueParameterSensitivity(u.get(0), k).Sensitivity).apply(DoubleArray.of(t)).column(0);
                double      localVol;
                DoubleArray localVolSensi = DoubleArray.of();
                if (k < SMALL)
                {
                    localVol      = Math.Sqrt(vol * vol + 2 * vol * t * (divT));
                    localVolSensi = volSensi.multipliedBy((vol + t * divT) / localVol).plus(divTSensi.multipliedBy(vol * t / localVol));
                }
                else
                {
                    double      divK       = FIRST_DERIV.differentiate(l => impliedVolatilitySurface.zValue(t, l)).apply(k);
                    DoubleArray divKSensi  = FIRST_DERIV_SENSI.differentiate(l => impliedVolatilitySurface.zValueParameterSensitivity(t, l.get(0)).Sensitivity).apply(DoubleArray.of(k)).column(0);
                    double      divK2      = SECOND_DERIV.differentiate(l => impliedVolatilitySurface.zValue(t, l)).apply(k);
                    DoubleArray divK2Sensi = SECOND_DERIV_SENSI.differentiateNoCross(l => impliedVolatilitySurface.zValueParameterSensitivity(t, l.get(0)).Sensitivity).apply(DoubleArray.of(k)).column(0);
                    double      rq         = r - q;
                    double      h1         = (Math.Log(spot / k) + (rq + 0.5 * vol * vol) * t) / vol;
                    double      h2         = h1 - vol * t;
                    double      den        = 1d + 2d * h1 * k * divK + k * k * (h1 * h2 * divK * divK + t * vol * divK2);
                    double      var        = (vol * vol + 2d * vol * t * (divT + k * rq * divK)) / den;
                    if (var < 0d)
                    {
                        throw new System.ArgumentException("Negative variance");
                    }
                    localVol      = Math.Sqrt(var);
                    localVolSensi = volSensi.multipliedBy(localVol * k * h2 * divK * (1d + 0.5 * k * h2 * divK) / vol / den + 0.5 * localVol * Math.Pow(k * h1 * divK, 2) / vol / den + (vol + divT * t + rq * t * k * divK) / (localVol * den) - 0.5 * divK2 * localVol * k * k * t / den).plus(divKSensi.multipliedBy((vol * t * rq * k / localVol - localVol * k * h1 * (1d + k * h2 * divK)) / den)).plus(divTSensi.multipliedBy(vol * t / (localVol * den))).plus(divK2Sensi.multipliedBy(-0.5 * vol * localVol * k * k * t / den));
                }
                return(ValueDerivatives.of(localVol, localVolSensi));
            };
            SurfaceMetadata metadata = DefaultSurfaceMetadata.builder().xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.STRIKE).zValueType(ValueType.LOCAL_VOLATILITY).surfaceName(SurfaceName.of("localVol_" + impliedVolatilitySurface.Name)).build();

            return(DeformedSurface.of(metadata, impliedVolatilitySurface, func));
        }
Ejemplo n.º 21
0
        // constructor that sorts (artificial boolean flag)
        private InterpolatedNodalSurface(SurfaceMetadata metadata, DoubleArray xValues, DoubleArray yValues, DoubleArray zValues, SurfaceInterpolator interpolator, bool sort)
        {
            validateInputs(metadata, xValues, yValues, zValues, interpolator);
            // sort inputs
            IDictionary <DoublesPair, ObjDoublePair <ParameterMetadata> > sorted = new SortedDictionary <DoublesPair, ObjDoublePair <ParameterMetadata> >();

            for (int i = 0; i < xValues.size(); i++)
            {
                ParameterMetadata pm = metadata.getParameterMetadata(i);
                sorted[DoublesPair.of(xValues.get(i), yValues.get(i))] = ObjDoublePair.of(pm, zValues.get(i));
            }
            double[]            sortedX  = new double[sorted.Count];
            double[]            sortedY  = new double[sorted.Count];
            double[]            sortedZ  = new double[sorted.Count];
            ParameterMetadata[] sortedPm = new ParameterMetadata[sorted.Count];
            int pos = 0;

            foreach (KeyValuePair <DoublesPair, ObjDoublePair <ParameterMetadata> > entry in sorted.SetOfKeyValuePairs())
            {
                sortedX[pos]  = entry.Key.First;
                sortedY[pos]  = entry.Key.Second;
                sortedZ[pos]  = entry.Value.Second;
                sortedPm[pos] = entry.Value.First;
                pos++;
            }
            // assign
            SurfaceMetadata sortedMetadata = metadata.withParameterMetadata(Arrays.asList(sortedPm));

            this.metadata = sortedMetadata;
            this.xValues  = DoubleArray.ofUnsafe(sortedX);
            this.yValues  = DoubleArray.ofUnsafe(sortedY);
            this.zValues  = DoubleArray.ofUnsafe(sortedZ);
            IDictionary <DoublesPair, double> pairs = new Dictionary <DoublesPair, double>();

            for (int i = 0; i < xValues.size(); i++)
            {
                pairs[DoublesPair.of(xValues.get(i), yValues.get(i))] = zValues.get(i);
            }
            this.interpolator      = interpolator;
            this.boundInterpolator = interpolator.bind(this.xValues, this.yValues, this.zValues);
            this.parameterMetadata = IntStream.range(0, ParameterCount).mapToObj(i => sortedMetadata.getParameterMetadata(i)).collect(toImmutableList());
        }
Ejemplo n.º 22
0
        public virtual void test_createMetadata_normal()
        {
            SurfaceIborCapletFloorletVolatilityBootstrapDefinition @base = SurfaceIborCapletFloorletVolatilityBootstrapDefinition.of(NAME, USD_LIBOR_3M, ACT_ACT_ISDA, LINEAR, DOUBLE_QUADRATIC);
            RawOptionData capData = RawOptionData.of(ImmutableList.of(Period.ofYears(1), Period.ofYears(5)), DoubleArray.of(0.005, 0.01, 0.015), ValueType.STRIKE, DoubleMatrix.copyOf(new double[][]
            {
                new double[] { 0.15, 0.12, 0.13 },
                new double[] { 0.1, Double.NaN, 0.09 }
            }), ValueType.NORMAL_VOLATILITY);
            IList <GenericVolatilitySurfacePeriodParameterMetadata> list = new List <GenericVolatilitySurfacePeriodParameterMetadata>();

            list.Add(GenericVolatilitySurfacePeriodParameterMetadata.of(Period.ofYears(1), SimpleStrike.of(0.005)));
            list.Add(GenericVolatilitySurfacePeriodParameterMetadata.of(Period.ofYears(1), SimpleStrike.of(0.01)));
            list.Add(GenericVolatilitySurfacePeriodParameterMetadata.of(Period.ofYears(1), SimpleStrike.of(0.015)));
            list.Add(GenericVolatilitySurfacePeriodParameterMetadata.of(Period.ofYears(5), SimpleStrike.of(0.005)));
            list.Add(GenericVolatilitySurfacePeriodParameterMetadata.of(Period.ofYears(5), SimpleStrike.of(0.015)));
            SurfaceMetadata expected = Surfaces.normalVolatilityByExpiryStrike(NAME.Name, ACT_ACT_ISDA).withParameterMetadata(list);
            SurfaceMetadata computed = @base.createMetadata(capData);

            assertEquals(computed, expected);
        }
Ejemplo n.º 23
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @SuppressWarnings("unchecked") @Override public Builder set(String propertyName, Object newValue)
            public override Builder set(string propertyName, object newValue)
            {
                switch (propertyName.GetHashCode())
                {
                case -450004177:         // metadata
                    this.metadata_Renamed = (SurfaceMetadata)newValue;
                    break;

                case 1982430620:         // originalSurface
                    this.originalSurface_Renamed = (Surface)newValue;
                    break;

                case -360086200:         // deformationFunction
                    this.deformationFunction_Renamed = (System.Func <DoublesPair, ValueDerivatives>)newValue;
                    break;

                default:
                    throw new NoSuchElementException("Unknown property: " + propertyName);
                }
                return(this);
            }
Ejemplo n.º 24
0
        //-------------------------------------------------------------------------
        // restricted constructor
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @ImmutableConstructor private InterpolatedNodalSurface(SurfaceMetadata metadata, com.opengamma.strata.collect.array.DoubleArray xValues, com.opengamma.strata.collect.array.DoubleArray yValues, com.opengamma.strata.collect.array.DoubleArray zValues, com.opengamma.strata.market.surface.interpolator.SurfaceInterpolator interpolator)
        private InterpolatedNodalSurface(SurfaceMetadata metadata, DoubleArray xValues, DoubleArray yValues, DoubleArray zValues, SurfaceInterpolator interpolator)
        {
            validateInputs(metadata, xValues, yValues, zValues, interpolator);
            for (int i = 1; i < xValues.size(); i++)
            {
                if (xValues.get(i) < xValues.get(i - 1))
                {
                    throw new System.ArgumentException("Array of x-values must be sorted");
                }
                if (xValues.get(i) == xValues.get(i - 1) && yValues.get(i) <= yValues.get(i - 1))
                {
                    throw new System.ArgumentException("Array of y-values must be sorted and unique within x-values");
                }
            }
            this.metadata          = metadata;
            this.xValues           = xValues;
            this.yValues           = yValues;
            this.zValues           = zValues;
            this.interpolator      = interpolator;
            this.boundInterpolator = interpolator.bind(xValues, yValues, zValues);
            this.parameterMetadata = IntStream.range(0, ParameterCount).mapToObj(i => metadata.getParameterMetadata(i)).collect(toImmutableList());
        }
Ejemplo n.º 25
0
 public virtual Surface withMetadata(SurfaceMetadata metadata)
 {
     return(this);
 }
Ejemplo n.º 26
0
        //-------------------------------------------------------------------------
        public override IborCapletFloorletVolatilityCalibrationResult calibrate(IborCapletFloorletVolatilityDefinition definition, ZonedDateTime calibrationDateTime, RawOptionData capFloorData, RatesProvider ratesProvider)
        {
            ArgChecker.isTrue(ratesProvider.ValuationDate.Equals(calibrationDateTime.toLocalDate()), "valuationDate of ratesProvider should be coherent to calibrationDateTime");
            ArgChecker.isTrue(definition is SabrIborCapletFloorletVolatilityBootstrapDefinition, "definition should be SabrIborCapletFloorletVolatilityBootstrapDefinition");
            SabrIborCapletFloorletVolatilityBootstrapDefinition bsDefinition = (SabrIborCapletFloorletVolatilityBootstrapDefinition)definition;
            IborIndex index           = bsDefinition.Index;
            LocalDate calibrationDate = calibrationDateTime.toLocalDate();
            LocalDate baseDate        = index.EffectiveDateOffset.adjust(calibrationDate, ReferenceData);
            LocalDate startDate       = baseDate.plus(index.Tenor);

            System.Func <Surface, IborCapletFloorletVolatilities> volatilitiesFunction = this.volatilitiesFunction(bsDefinition, calibrationDateTime, capFloorData);
            SurfaceMetadata metaData                = bsDefinition.createMetadata(capFloorData);
            IList <Period>  expiries                = capFloorData.Expiries;
            int             nExpiries               = expiries.Count;
            DoubleArray     strikes                 = capFloorData.Strikes;
            DoubleMatrix    errorsMatrix            = capFloorData.Error.orElse(DoubleMatrix.filled(nExpiries, strikes.size(), 1d));
            IList <double>  timeList                = new List <double>();
            IList <double>  strikeList              = new List <double>();
            IList <double>  volList                 = new List <double>();
            IList <ResolvedIborCapFloorLeg> capList = new List <ResolvedIborCapFloorLeg>();
            IList <double> priceList                = new List <double>();
            IList <double> errorList                = new List <double>();

            int[] startIndex = new int[nExpiries + 1];
            for (int i = 0; i < nExpiries; ++i)
            {
                LocalDate   endDate        = baseDate.plus(expiries[i]);
                DoubleArray volatilityData = capFloorData.Data.row(i);
                DoubleArray errors         = errorsMatrix.row(i);
                reduceRawData(bsDefinition, ratesProvider, strikes, volatilityData, errors, startDate, endDate, metaData, volatilitiesFunction, timeList, strikeList, volList, capList, priceList, errorList);
                startIndex[i + 1] = volList.Count;
                ArgChecker.isTrue(startIndex[i + 1] > startIndex[i], "no valid option data for {}", expiries[i]);
            }

            IList <CurveMetadata> metadataList   = bsDefinition.createSabrParameterMetadata();
            DoubleArray           timeToExpiries = DoubleArray.of(nExpiries, i => timeList[startIndex[i]]);

            BitArray @fixed  = new BitArray();
            bool     betaFix = false;
            Curve    betaCurve;
            Curve    rhoCurve;

            if (bsDefinition.BetaCurve.Present)
            {
                betaFix = true;
                @fixed.Set(1, true);
                betaCurve = bsDefinition.BetaCurve.get();
                rhoCurve  = InterpolatedNodalCurve.of(metadataList[2], timeToExpiries, DoubleArray.filled(nExpiries), bsDefinition.Interpolator, bsDefinition.ExtrapolatorLeft, bsDefinition.ExtrapolatorRight);
            }
            else
            {
                @fixed.Set(2, true);
                betaCurve = InterpolatedNodalCurve.of(metadataList[1], timeToExpiries, DoubleArray.filled(nExpiries), bsDefinition.Interpolator, bsDefinition.ExtrapolatorLeft, bsDefinition.ExtrapolatorRight);
                rhoCurve  = bsDefinition.RhoCurve.get();
            }
            InterpolatedNodalCurve alphaCurve = InterpolatedNodalCurve.of(metadataList[0], timeToExpiries, DoubleArray.filled(nExpiries), bsDefinition.Interpolator, bsDefinition.ExtrapolatorLeft, bsDefinition.ExtrapolatorRight);
            InterpolatedNodalCurve nuCurve    = InterpolatedNodalCurve.of(metadataList[3], timeToExpiries, DoubleArray.filled(nExpiries), bsDefinition.Interpolator, bsDefinition.ExtrapolatorLeft, bsDefinition.ExtrapolatorRight);
            Curve          shiftCurve         = bsDefinition.ShiftCurve;
            SabrParameters sabrParams         = SabrParameters.of(alphaCurve, betaCurve, rhoCurve, nuCurve, shiftCurve, bsDefinition.SabrVolatilityFormula);
            SabrParametersIborCapletFloorletVolatilities vols = SabrParametersIborCapletFloorletVolatilities.of(bsDefinition.Name, index, calibrationDateTime, sabrParams);
            double        totalChiSq = 0d;
            ZonedDateTime prevExpiry = calibrationDateTime.minusDays(1L);     // included if calibrationDateTime == fixingDateTime

            for (int i = 0; i < nExpiries; ++i)
            {
                DoubleArray start = computeInitialValues(ratesProvider, betaCurve, shiftCurve, timeList, volList, capList, startIndex, i, betaFix, capFloorData.DataType);
                UncoupledParameterTransforms transform = new UncoupledParameterTransforms(start, TRANSFORMS, @fixed);
                int nCaplets     = startIndex[i + 1] - startIndex[i];
                int currentStart = startIndex[i];
                System.Func <DoubleArray, DoubleArray>  valueFunction    = createPriceFunction(ratesProvider, vols, prevExpiry, capList, priceList, startIndex, nExpiries, i, nCaplets, betaFix);
                System.Func <DoubleArray, DoubleMatrix> jacobianFunction = createJacobianFunction(ratesProvider, vols, prevExpiry, capList, priceList, index.Currency, startIndex, nExpiries, i, nCaplets, betaFix);
                NonLinearTransformFunction transFunc = new NonLinearTransformFunction(valueFunction, jacobianFunction, transform);
                DoubleArray        adjustedPrices    = this.adjustedPrices(ratesProvider, vols, prevExpiry, capList, priceList, startIndex, i, nCaplets);
                DoubleArray        errors            = DoubleArray.of(nCaplets, n => errorList[currentStart + n]);
                LeastSquareResults res = solver.solve(adjustedPrices, errors, transFunc.FittingFunction, transFunc.FittingJacobian, transform.transform(start));
                LeastSquareResultsWithTransform resTransform = new LeastSquareResultsWithTransform(res, transform);
                vols        = updateParameters(vols, nExpiries, i, betaFix, resTransform.ModelParameters);
                totalChiSq += res.ChiSq;
                prevExpiry  = capList[startIndex[i + 1] - 1].FinalFixingDateTime;
            }
            return(IborCapletFloorletVolatilityCalibrationResult.ofLeastSquare(vols, totalChiSq));
        }
 /// <summary>
 /// Creates a constant surface with a specific value.
 /// </summary>
 /// <param name="metadata">  the surface metadata </param>
 /// <param name="zValue">  the constant z-value </param>
 /// <returns> the surface </returns>
 public static ConstantSurface of(SurfaceMetadata metadata, double zValue)
 {
     return(new ConstantSurface(metadata, zValue));
 }
 private ConstantSurface(SurfaceMetadata metadata, double zValue)
 {
     JodaBeanUtils.notNull(metadata, "metadata");
     this.metadata       = metadata;
     this.zValue_Renamed = zValue;
 }
 //-------------------------------------------------------------------------
 public ConstantSurface withMetadata(SurfaceMetadata metadata)
 {
     return(new ConstantSurface(metadata.withParameterMetadata(null), zValue_Renamed));
 }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Runs the calibration of swaptions and print the calibrated smile results on the console.
        /// </summary>
        /// <param name="args">  -s to use the sparse data, i.e. a cube with missing data points </param>
        public static void Main(string[] args)
        {
            // select data
            TenorRawOptionData data = DATA_FULL;

            if (args.Length > 0)
            {
                if (args[0].Equals("-s"))
                {
                    data = DATA_SPARSE;
                }
            }
            Console.WriteLine("Start calibration");
            double          beta         = 0.50;
            SurfaceMetadata betaMetadata = DefaultSurfaceMetadata.builder().xValueType(ValueType.YEAR_FRACTION).yValueType(ValueType.YEAR_FRACTION).zValueType(ValueType.SABR_BETA).surfaceName("Beta").build();
            Surface         betaSurface  = ConstantSurface.of(betaMetadata, beta);
            double          shift        = 0.0300;
            Surface         shiftSurface = ConstantSurface.of("Shift", shift);
            SabrParametersSwaptionVolatilities calibrated = SABR_CALIBRATION.calibrateWithFixedBetaAndShift(DEFINITION, CALIBRATION_TIME, data, MULTICURVE, betaSurface, shiftSurface);

            Console.WriteLine("End calibration");
            /* Graph calibration */
            int    nbStrikesGraph = 50;
            double moneyMin       = -0.0250;
            double moneyMax       = +0.0300;

            double[] moneyGraph = new double[nbStrikesGraph + 1];
            for (int i = 0; i < nbStrikesGraph + 1; i++)
            {
                moneyGraph[i] = moneyMin + i * (moneyMax - moneyMin) / nbStrikesGraph;
            }
//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: double[][][] strikesGraph = new double[NB_TENORS][NB_EXPIRIES][nbStrikesGraph + 1];
            double[][][] strikesGraph = RectangularArrays.ReturnRectangularDoubleArray(NB_TENORS, NB_EXPIRIES, nbStrikesGraph + 1);
//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: double[][][] volLNGraph = new double[NB_TENORS][NB_EXPIRIES][nbStrikesGraph + 1];
            double[][][] volLNGraph = RectangularArrays.ReturnRectangularDoubleArray(NB_TENORS, NB_EXPIRIES, nbStrikesGraph + 1);
//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: double[][][] volNGraph = new double[NB_TENORS][NB_EXPIRIES][nbStrikesGraph + 1];
            double[][][] volNGraph = RectangularArrays.ReturnRectangularDoubleArray(NB_TENORS, NB_EXPIRIES, nbStrikesGraph + 1);
//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: double[][] parRate = new double[NB_TENORS][NB_EXPIRIES];
            double[][] parRate = RectangularArrays.ReturnRectangularDoubleArray(NB_TENORS, NB_EXPIRIES);
            for (int looptenor = 0; looptenor < TENORS.size(); looptenor++)
            {
                double tenor = TENORS.get(looptenor).get(ChronoUnit.YEARS);
                for (int loopexpiry = 0; loopexpiry < EXPIRIES.size(); loopexpiry++)
                {
                    LocalDate expiry        = EUR_FIXED_1Y_EURIBOR_6M.FloatingLeg.StartDateBusinessDayAdjustment.adjust(CALIBRATION_DATE.plus(EXPIRIES.get(loopexpiry)), REF_DATA);
                    LocalDate effectiveDate = EUR_FIXED_1Y_EURIBOR_6M.calculateSpotDateFromTradeDate(expiry, REF_DATA);
                    LocalDate endDate       = effectiveDate.plus(TENORS.get(looptenor));
                    SwapTrade swap          = EUR_FIXED_1Y_EURIBOR_6M.toTrade(CALIBRATION_DATE, effectiveDate, endDate, BuySell.BUY, 1.0, 0.0);
                    parRate[looptenor][loopexpiry] = SWAP_PRICER.parRate(swap.resolve(REF_DATA).Product, MULTICURVE);
                    ZonedDateTime expiryDateTime = expiry.atTime(11, 0).atZone(ZoneId.of("Europe/Berlin"));
                    double        time           = calibrated.relativeTime(expiryDateTime);
                    for (int i = 0; i < nbStrikesGraph + 1; i++)
                    {
                        strikesGraph[looptenor][loopexpiry][i] = parRate[looptenor][loopexpiry] + moneyGraph[i];
                        volLNGraph[looptenor][loopexpiry][i]   = calibrated.volatility(expiryDateTime, tenor, strikesGraph[looptenor][loopexpiry][i], parRate[looptenor][loopexpiry]);
                        volNGraph[looptenor][loopexpiry][i]    = NormalFormulaRepository.impliedVolatilityFromBlackApproximated(parRate[looptenor][loopexpiry] + shift, strikesGraph[looptenor][loopexpiry][i] + shift, time, volLNGraph[looptenor][loopexpiry][i]);
                    }
                }
            }

            /* Graph export */
            string svn = "Moneyness";

            for (int looptenor = 0; looptenor < TENORS.size(); looptenor++)
            {
                for (int loopexpiry = 0; loopexpiry < EXPIRIES.size(); loopexpiry++)
                {
                    svn = svn + ", Strike_" + EXPIRIES.get(loopexpiry).ToString() + "x" + TENORS.get(looptenor).ToString() + ", NormalVol_" + EXPIRIES.get(loopexpiry).ToString() + "x" + TENORS.get(looptenor).ToString();
                }
            }
            svn = svn + "\n";
            for (int i = 0; i < nbStrikesGraph + 1; i++)
            {
                svn = svn + moneyGraph[i];
                for (int looptenor = 0; looptenor < TENORS.size(); looptenor++)
                {
                    for (int loopexpiry = 0; loopexpiry < EXPIRIES.size(); loopexpiry++)
                    {
                        svn = svn + ", " + strikesGraph[looptenor][loopexpiry][i];
                        svn = svn + ", " + volNGraph[looptenor][loopexpiry][i];
                    }
                }
                svn = svn + "\n";
            }
            Console.WriteLine(svn);
        }