//-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the price sensitivity of the bond future option product based on curves.
        /// <para>
        /// The price sensitivity of the product is the sensitivity of the price to the underlying curves.
        /// The volatility is unchanged for a fixed strike in the sensitivity computation, hence the "StickyStrike" name.
        /// </para>
        /// <para>
        /// This calculates the underlying future price using the future pricer.
        ///
        /// </para>
        /// </summary>
        /// <param name="futureOption">  the option product </param>
        /// <param name="discountingProvider">  the discounting provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <returns> the price curve sensitivity of the product </returns>
        public PointSensitivities priceSensitivityRatesStickyStrike(ResolvedBondFutureOption futureOption, LegalEntityDiscountingProvider discountingProvider, BlackBondFutureVolatilities volatilities)
        {
            ArgChecker.isTrue(futureOption.PremiumStyle.Equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN");
            double futurePrice = this.futurePrice(futureOption, discountingProvider);

            return(priceSensitivityRatesStickyStrike(futureOption, discountingProvider, volatilities, futurePrice));
        }
        /// <summary>
        /// Solves the system Ax = y for the unknown vector x, where A is a tridiagonal matrix and y is a vector.
        /// This takes order n operations where n is the size of the system
        /// (number of linear equations), as opposed to order n^3 for the general problem. </summary>
        /// <param name="aM"> tridiagonal matrix </param>
        /// <param name="b"> known vector (must be same length as rows/columns of matrix) </param>
        /// <returns> vector (as an array of doubles) with same length as y </returns>
        public static double[] solvTriDag(TridiagonalMatrix aM, double[] b)
        {
            ArgChecker.notNull(aM, "null matrix");
            ArgChecker.notNull(b, "null vector");
            double[] d = aM.Diagonal;     //b is modified, so get copy of diagonal
            int      n = d.Length;

            ArgChecker.isTrue(n == b.Length, "vector y wrong length for matrix");
            double[] y = Arrays.copyOf(b, n);

            double[] l = aM.LowerSubDiagonalData;
            double[] u = aM.UpperSubDiagonalData;

            double[] x = new double[n];
            for (int i = 1; i < n; i++)
            {
                double m = l[i - 1] / d[i - 1];
                d[i] = d[i] - m * u[i - 1];
                y[i] = y[i] - m * y[i - 1];
            }

            x[n - 1] = y[n - 1] / d[n - 1];

            for (int i = n - 2; i >= 0; i--)
            {
                x[i] = (y[i] - u[i] * x[i + 1]) / d[i];
            }

            return(x);
        }
 /// <summary>
 /// Creates an instance.
 /// </summary>
 /// <param name="x1">  the lower edge </param>
 /// <param name="x2">  the upper edge, must be greater than x1 </param>
 /// <param name="y">  the height  </param>
 public TopHatFunction(double x1, double x2, double y)
 {
     ArgChecker.isTrue(x1 < x2, "x1 must be less than x2");
     _x1 = x1;
     _x2 = x2;
     _y  = y;
 }
        /// <summary>
        /// Gamma is in the  form gamma^i_{j,k} =\partial^2y_j/\partial x_i \partial x_k, where i is the
        /// index of the matrix in the stack (3rd index of the tensor), and j,k are the individual
        /// matrix indices. We would like it in the form H^i_{j,k} =\partial^2y_i/\partial x_j \partial x_k,
        /// so that each matrix is a Hessian (for the dependent variable y_i), hence the reshaping below.
        /// </summary>
        /// <param name="gamma">  the rank 3 tensor </param>
        /// <returns> the reshaped rank 3 tensor </returns>
        private DoubleMatrix[] reshapeTensor(DoubleMatrix[] gamma)
        {
            int m = gamma.Length;
            int n = gamma[0].rowCount();

            ArgChecker.isTrue(gamma[0].columnCount() == m, "tenor wrong size. Seond index is {}, should be {}", gamma[0].columnCount(), m);
            DoubleMatrix[] res = new DoubleMatrix[n];
            for (int i = 0; i < n; i++)
            {
//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[][] temp = new double[m][m];
                double[][] temp = RectangularArrays.ReturnRectangularDoubleArray(m, m);
                for (int j = 0; j < m; j++)
                {
                    DoubleMatrix gammaJ = gamma[j];
                    for (int k = j; k < m; k++)
                    {
                        temp[j][k] = gammaJ.get(i, k);
                    }
                }
                for (int j = 0; j < m; j++)
                {
                    for (int k = 0; k < j; k++)
                    {
                        temp[j][k] = temp[k][j];
                    }
                }
                res[i] = DoubleMatrix.copyOf(temp);
            }
            return(res);
        }
Example #5
0
        public override Pair <DoubleFunction1D, DoubleFunction1D>[] getPolynomialsAndFirstDerivative(int n)
        {
            ArgChecker.isTrue(n >= 0);
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @SuppressWarnings("unchecked") com.opengamma.strata.collect.tuple.Pair<com.opengamma.strata.math.impl.function.DoubleFunction1D, com.opengamma.strata.math.impl.function.DoubleFunction1D>[] polynomials = new com.opengamma.strata.collect.tuple.Pair[n + 1];
            Pair <DoubleFunction1D, DoubleFunction1D>[] polynomials = new Pair[n + 1];
            DoubleFunction1D p, dp;

            for (int i = 0; i <= n; i++)
            {
                if (i == 0)
                {
                    polynomials[i] = Pair.of(One, Zero);
                }
                else if (i == 1)
                {
                    polynomials[i] = Pair.of(X, One);
                }
                else
                {
                    p              = (polynomials[i - 1].First.multiply(X).multiply(2 * i - 1).subtract(polynomials[i - 2].First.multiply(i - 1))).multiply(1.0 / i);
                    dp             = p.derivative();
                    polynomials[i] = Pair.of(p, dp);
                }
            }
            return(polynomials);
        }
Example #6
0
 /// <summary>
 /// Creates an instance specifying the value of eps.
 /// </summary>
 /// <param name="eps">  the step size used to approximate the derivative </param>
 public MatrixFieldFirstOrderDifferentiator(double eps)
 {
     ArgChecker.isTrue(eps > 1e-15, "eps of {} is below machine tolerance of 1e-15. Please choose a higher value", eps);
     this.eps           = eps;
     this.twoEps        = 2 * eps;
     this.oneOverTwpEps = 1.0 / twoEps;
 }
        /// <summary>
        /// Calculates polynomials and derivative. </summary>
        /// <param name="n">  the n value </param>
        /// <param name="alpha">  the alpha value </param>
        /// <param name="beta">  the beta value </param>
        /// <returns> the result </returns>
        public virtual Pair <DoubleFunction1D, DoubleFunction1D>[] getPolynomialsAndFirstDerivative(int n, double alpha, double beta)
        {
            ArgChecker.isTrue(n >= 0);
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @SuppressWarnings("unchecked") com.opengamma.strata.collect.tuple.Pair<com.opengamma.strata.math.impl.function.DoubleFunction1D, com.opengamma.strata.math.impl.function.DoubleFunction1D>[] polynomials = new com.opengamma.strata.collect.tuple.Pair[n + 1];
            Pair <DoubleFunction1D, DoubleFunction1D>[] polynomials = new Pair[n + 1];
            DoubleFunction1D p, dp, p1, p2;

            for (int i = 0; i <= n; i++)
            {
                if (i == 0)
                {
                    polynomials[i] = Pair.of(One, Zero);
                }
                else if (i == 1)
                {
                    double a1 = (alpha + beta + 2) / 2;
                    polynomials[i] = Pair.of((DoubleFunction1D) new RealPolynomialFunction1D(new double[] { (alpha - beta) / 2, a1 }), (DoubleFunction1D) new RealPolynomialFunction1D(new double[] { a1 }));
                }
                else
                {
                    int j = i - 1;
                    p1 = polynomials[j].First;
                    p2 = polynomials[j - 1].First;
                    DoubleFunction1D temp1 = p1.multiply(getB(alpha, beta, j));
                    DoubleFunction1D temp2 = p1.multiply(X).multiply(getC(alpha, beta, j));
                    DoubleFunction1D temp3 = p2.multiply(getD(alpha, beta, j));
                    p              = (temp1.add(temp2).add(temp3)).divide(getA(alpha, beta, j));
                    dp             = p.derivative();
                    polynomials[i] = Pair.of(p, dp);
                }
            }
            return(polynomials);
        }
Example #8
0
        protected internal override QuantileResult expectedShortfall(double level, DoubleArray sample)
        {
            ArgChecker.isTrue(level > 0, "Quantile should be above 0.");
            ArgChecker.isTrue(level < 1, "Quantile should be below 1.");
            int sampleSize = sampleCorrection(sample.size());

            double[] order = createIndexArray(sample.size());
            double[] s     = sample.toArray();
            DoubleArrayMath.sortPairs(s, order);
            double fractionalIndex = level * sampleSize;
            int    index           = (int)checkIndex(this.index(fractionalIndex), sample.size(), true);

            int[]    indices  = new int[index];
            double[] weights  = new double[index];
            double   interval = 1d / (double)sampleSize;
            double   losses   = s[0] * interval *indexShift();

            for (int i = 0; i < index - 1; i++)
            {
                losses    += s[i] * interval;
                indices[i] = (int)order[i];
                weights[i] = interval;
            }
            losses            += s[index - 1] * (fractionalIndex - index + 1 - indexShift()) * interval;
            indices[index - 1] = (int)order[index - 1];
            weights[0]        += interval * indexShift();
            weights[index - 1] = (fractionalIndex - index + 1 - indexShift()) * interval;
            return(QuantileResult.of(losses / level, indices, DoubleArray.ofUnsafe(weights).dividedBy(level)));
        }
Example #9
0
        public virtual double pvbp(RatePaymentPeriod paymentPeriod, RatesProvider provider)
        {
            ArgChecker.isTrue(!paymentPeriod.FxReset.Present, "FX reset is not supported");
            int accPeriodCount = paymentPeriod.AccrualPeriods.size();

            ArgChecker.isTrue(accPeriodCount == 1 || paymentPeriod.CompoundingMethod.Equals(CompoundingMethod.FLAT), "Only one accrued period or Flat compounding supported");
            // no compounding
            if (accPeriodCount == 1)
            {
                RateAccrualPeriod accrualPeriod = paymentPeriod.AccrualPeriods.get(0);
                double            df            = provider.discountFactor(paymentPeriod.Currency, paymentPeriod.PaymentDate);
                return(df * accrualPeriod.YearFraction * paymentPeriod.Notional);
            }
            else
            {
                // Flat compounding
                switch (paymentPeriod.CompoundingMethod)
                {
                case FLAT:
                    return(pvbpCompoundedFlat(paymentPeriod, provider));

                default:
                    throw new System.NotSupportedException("PVBP not implemented yet for non FLAT compounding");
                }
            }
        }
        /// <summary>
        /// Gets the polynomials and derivative.
        /// </summary>
        /// <param name="n">  the n value </param>
        /// <param name="alpha">  the alpha value </param>
        /// <returns> the result </returns>
        public virtual Pair <DoubleFunction1D, DoubleFunction1D>[] getPolynomialsAndFirstDerivative(int n, double alpha)
        {
            ArgChecker.isTrue(n >= 0);
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @SuppressWarnings("unchecked") com.opengamma.strata.collect.tuple.Pair<com.opengamma.strata.math.impl.function.DoubleFunction1D, com.opengamma.strata.math.impl.function.DoubleFunction1D>[] polynomials = new com.opengamma.strata.collect.tuple.Pair[n + 1];
            Pair <DoubleFunction1D, DoubleFunction1D>[] polynomials = new Pair[n + 1];
            DoubleFunction1D p, dp, p1, p2;

            for (int i = 0; i <= n; i++)
            {
                if (i == 0)
                {
                    polynomials[i] = Pair.of(One, Zero);
                }
                else if (i == 1)
                {
                    polynomials[i] = Pair.of(F1, DF1);
                }
                else
                {
                    p1             = polynomials[i - 1].First;
                    p2             = polynomials[i - 2].First;
                    p              = (p1.multiply(2.0 * i + alpha - 1).subtract(p1.multiply(X)).subtract(p2.multiply((i - 1.0 + alpha))).divide(i));
                    dp             = (p.multiply(i).subtract(p1.multiply(i + alpha))).divide(X);
                    polynomials[i] = Pair.of(p, dp);
                }
            }
            return(polynomials);
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the price sensitivity of the Ibor future option product based on curves.
        /// <para>
        /// The price sensitivity of the product is the sensitivity of the price to the underlying curves.
        /// The volatility is unchanged for a fixed strike in the sensitivity computation, hence the "StickyStrike" name.
        /// </para>
        /// <para>
        /// This calculates the underlying future price using the future pricer.
        ///
        /// </para>
        /// </summary>
        /// <param name="futureOption">  the option product </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <returns> the price curve sensitivity of the product </returns>
        public virtual PointSensitivities priceSensitivityRatesStickyStrike(ResolvedIborFutureOption futureOption, RatesProvider ratesProvider, NormalIborFutureOptionVolatilities volatilities)
        {
            ArgChecker.isTrue(futureOption.PremiumStyle.Equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN");

            double futurePrice = this.futurePrice(futureOption, ratesProvider);

            return(priceSensitivityRatesStickyStrike(futureOption, ratesProvider, volatilities, futurePrice));
        }
Example #12
0
 /// <summary>
 /// Returns the quotient of two matrices $C = \frac{A}{B} = AB^{-1}$, where
 /// $B^{-1}$ is the pseudo-inverse of $B$ i.e. $BB^{-1} = \mathbb{1}$. </summary>
 /// <param name="m1"> The numerator matrix, not null. This matrix must be a <seealso cref="DoubleMatrix"/>. </param>
 /// <param name="m2"> The denominator, not null. This matrix must be a <seealso cref="DoubleMatrix"/>. </param>
 /// <returns> The result </returns>
 public virtual Matrix divide(Matrix m1, Matrix m2)
 {
     ArgChecker.notNull(m1, "m1");
     ArgChecker.notNull(m2, "m2");
     ArgChecker.isTrue(m1 is DoubleMatrix, "Can only divide a 2D matrix");
     ArgChecker.isTrue(m2 is DoubleMatrix, "Can only perform division with a 2D matrix");
     return(multiply(m1, getInverse(m2)));
 }
 /// <param name="abscissas"> An array containing the abscissas, not null </param>
 /// <param name="weights"> An array containing the weights, not null, must be the same length as the abscissa array </param>
 public GaussianQuadratureData(double[] abscissas, double[] weights)
 {
     ArgChecker.notNull(abscissas, "abscissas");
     ArgChecker.notNull(weights, "weights");
     ArgChecker.isTrue(abscissas.Length == weights.Length, "Abscissa and weight arrays must be the same length");
     _weights   = weights;
     _abscissas = abscissas;
 }
Example #14
0
 /// <summary>
 /// Creates an instance.
 /// </summary>
 /// <param name="n"> The number of sample points to be used in the integration, not negative or zero </param>
 /// <param name="generator"> The generator of weights and abscissas </param>
 public GaussianQuadratureIntegrator1D(int n, QuadratureWeightAndAbscissaFunction generator)
 {
     ArgChecker.isTrue(n > 0, "number of intervals must be > 0");
     ArgChecker.notNull(generator, "generating function");
     this.size       = n;
     this.generator  = generator;
     this.quadrature = generator.generate(size);
 }
Example #15
0
        public override double?apply(double[] x)
        {
            ArgChecker.notNull(x, "x");
            int n = x.Length;

            ArgChecker.isTrue(n >= 2, "Need at least two points to calculate the population variance");
            return(_variance.apply(x) * (n - 1) / n);
        }
 /// <summary>
 /// Tests that the inputs to the root-finder are not null, and that a root is bracketed by the bounding values.
 /// </summary>
 /// <param name="function"> The function, not null </param>
 /// <param name="x1"> The first bound, not null </param>
 /// <param name="x2"> The second bound, not null, must be greater than x1 </param>
 /// <exception cref="IllegalArgumentException"> if x1 and x2 do not bracket a root </exception>
 protected internal virtual void checkInputs(DoubleFunction1D function, double?x1, double?x2)
 {
     ArgChecker.notNull(function, "function");
     ArgChecker.notNull(x1, "x1");
     ArgChecker.notNull(x2, "x2");
     ArgChecker.isTrue(x1 <= x2, "x1 must be less or equal to  x2");
     ArgChecker.isTrue(function.applyAsDouble(x1) * function.applyAsDouble(x2) <= 0, "x1 and x2 do not bracket a root");
 }
Example #17
0
        //-------------------------------------------------------------------------
        // gets the settlement price
        private double settlementPrice(ResolvedDsfTrade trade, RatesProvider ratesProvider)
        {
            StandardId standardId = trade.Product.SecurityId.StandardId;
            QuoteId    id         = QuoteId.of(standardId, FieldName.SETTLEMENT_PRICE);
            double     price      = ratesProvider.data(id);

            ArgChecker.isTrue(price < 10, "Price must be in decimal form, such as 1.007 for a 0.7% present value, but was: {}", price);
            return(price);
        }
Example #18
0
 protected internal virtual double[] writeArrayAsVector(double[][] x)
 {
     ArgChecker.isTrue(x[0].Length == 1, "Trying to convert matrix to vector");
     double[] result = new double[x.Length];
     for (int i = 0; i < x.Length; i++)
     {
         result[i] = x[i][0];
     }
     return(result);
 }
        /// <summary>
        /// Calculates the delta of the Ibor future option product
        /// based on the price of the underlying future.
        /// <para>
        /// The delta of the product is the sensitivity of the option price to the future price.
        /// The volatility is unchanged for a fixed strike in the sensitivity computation, hence the "StickyStrike" name.
        ///
        /// </para>
        /// </summary>
        /// <param name="futureOption">  the option product </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <param name="futurePrice">  the price of the underlying future, in decimal form </param>
        /// <returns> the price curve sensitivity of the product </returns>
        public virtual double deltaStickyStrike(ResolvedIborFutureOption futureOption, RatesProvider ratesProvider, NormalIborFutureOptionVolatilities volatilities, double futurePrice)
        {
            ArgChecker.isTrue(futureOption.PremiumStyle.Equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN");

            double             timeToExpiry = volatilities.relativeTime(futureOption.Expiry);
            double             strike       = futureOption.StrikePrice;
            ResolvedIborFuture future       = futureOption.UnderlyingFuture;
            double             volatility   = volatilities.volatility(timeToExpiry, future.LastTradeDate, strike, futurePrice);

            return(NormalFormulaRepository.delta(futurePrice, strike, timeToExpiry, volatility, futureOption.PutCall));
        }
 //-------------------------------------------------------------------------
 /// <summary>
 /// Evaluates the function.
 /// </summary>
 /// <param name="x"> The argument of the function, not null. Must have $x_1 < x < x_2$ </param>
 /// <returns> The value of the function </returns>
 public override double?apply(double?x)
 {
     ArgChecker.notNull(x, "x");
     ArgChecker.isTrue(x.Value != _x1, "Function is undefined for x = x1");
     ArgChecker.isTrue(x.Value != _x2, "Function is undefined for x = x2");
     if (x.Value > _x1 && x.Value < _x2)
     {
         return(_y);
     }
     return(0.0);
 }
        /// <summary>
        /// Calculates the theta of the bond future option product based on the price of the underlying future.
        /// <para>
        /// The theta of the product is minus of the option price sensitivity to the time to expiry.
        /// The volatility is unchanged for a fixed strike in the sensitivity computation, hence the "StickyStrike" name.
        ///
        /// </para>
        /// </summary>
        /// <param name="futureOption">  the option product </param>
        /// <param name="discountingProvider">  the discounting provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <param name="futurePrice">  the price of the underlying future </param>
        /// <returns> the price curve sensitivity of the product </returns>
        public double theta(ResolvedBondFutureOption futureOption, LegalEntityDiscountingProvider discountingProvider, BlackBondFutureVolatilities volatilities, double futurePrice)
        {
            ArgChecker.isTrue(futureOption.PremiumStyle.Equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN");
            double             strike       = futureOption.StrikePrice;
            ResolvedBondFuture future       = futureOption.UnderlyingFuture;
            double             volatility   = volatilities.volatility(futureOption.Expiry, future.LastTradeDate, strike, futurePrice);
            double             timeToExpiry = volatilities.relativeTime(futureOption.Expiry);
            double             theta        = BlackFormulaRepository.driftlessTheta(futurePrice, strike, timeToExpiry, volatility);

            return(theta);
        }
Example #22
0
 /// <summary>
 /// Creates an instance.
 /// </summary>
 /// <param name="a">  a, $a > 0$ </param>
 /// <param name="b">  b, $b > 0$ </param>
 /// <param name="eps">  approximation accuracy, $\epsilon \geq 0$ </param>
 /// <param name="maxIter">  maximum number of iterations, $\iter \geq 1$ </param>
 public IncompleteBetaFunction(double a, double b, double eps, int maxIter)
 {
     ArgChecker.isTrue(a > 0, "a must be > 0");
     ArgChecker.isTrue(b > 0, "b must be > 0");
     ArgChecker.isTrue(eps >= 0, "eps must not be negative");
     ArgChecker.isTrue(maxIter >= 1, "maximum number of iterations must be greater than zero");
     _a       = a;
     _b       = b;
     _eps     = eps;
     _maxIter = maxIter;
 }
        /// <summary>
        /// Calculates the price sensitivity to the Black volatility used for the pricing of the bond future option
        /// based on the price of the underlying future.
        /// </summary>
        /// <param name="futureOption">  the option product </param>
        /// <param name="discountingProvider">  the discounting provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <param name="futurePrice">  the underlying future price </param>
        /// <returns> the sensitivity </returns>
        public BondFutureOptionSensitivity priceSensitivityModelParamsVolatility(ResolvedBondFutureOption futureOption, LegalEntityDiscountingProvider discountingProvider, BlackBondFutureVolatilities volatilities, double futurePrice)
        {
            ArgChecker.isTrue(futureOption.PremiumStyle.Equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN");
            double             strike       = futureOption.StrikePrice;
            ResolvedBondFuture future       = futureOption.UnderlyingFuture;
            double             volatility   = volatilities.volatility(futureOption.Expiry, future.LastTradeDate, strike, futurePrice);
            double             timeToExpiry = volatilities.relativeTime(futureOption.Expiry);
            double             vega         = BlackFormulaRepository.vega(futurePrice, strike, timeToExpiry, volatility);

            return(BondFutureOptionSensitivity.of(volatilities.Name, timeToExpiry, future.LastTradeDate, strike, futurePrice, future.Currency, vega));
        }
Example #24
0
 //-------------------------------------------------------------------------
 /// <summary>
 /// Evaluates the function.
 /// </summary>
 /// <param name="x">  x </param>
 /// <returns> the value of the function </returns>
 /// <exception cref="IllegalArgumentException"> if $x < 0$ or $x > 1$ </exception>
 public override double?apply(double?x)
 {
     ArgChecker.isTrue(x >= 0 && x <= 1, "x must be in the range 0 to 1");
     try
     {
         return(Beta.regularizedBeta(x, _a, _b, _eps, _maxIter));
     }
     catch (MaxCountExceededException e)
     {
         throw new MathException(e);
     }
 }
Example #25
0
        /// <param name="a"> An array containing the diagonal values of the matrix, not null </param>
        /// <param name="b"> An array containing the upper sub-diagonal values of the matrix, not null.
        ///   Its length must be one less than the length of the diagonal array </param>
        /// <param name="c"> An array containing the lower sub-diagonal values of the matrix, not null.
        ///   Its length must be one less than the length of the diagonal array </param>
        public TridiagonalMatrix(double[] a, double[] b, double[] c)
        {
            ArgChecker.notNull(a, "a");
            ArgChecker.notNull(b, "b");
            ArgChecker.notNull(c, "c");
            int n = a.Length;

            ArgChecker.isTrue(b.Length == n - 1, "Length of subdiagonal b is incorrect");
            ArgChecker.isTrue(c.Length == n - 1, "Length of subdiagonal c is incorrect");
            _a = a;
            _b = b;
            _c = c;
        }
        /// <summary>
        /// Calculates the price sensitivity to the normal volatility used for the pricing of the Ibor future option
        /// based on the price of the underlying future.
        /// <para>
        /// This sensitivity is also called the <i>price normal vega</i>.
        ///
        /// </para>
        /// </summary>
        /// <param name="futureOption">  the option product </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <param name="futurePrice">  the underlying future price, in decimal form </param>
        /// <returns> the sensitivity </returns>
        public virtual IborFutureOptionSensitivity priceSensitivityModelParamsVolatility(ResolvedIborFutureOption futureOption, RatesProvider ratesProvider, NormalIborFutureOptionVolatilities volatilities, double futurePrice)
        {
            ArgChecker.isTrue(futureOption.PremiumStyle.Equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN");

            double             timeToExpiry = volatilities.relativeTime(futureOption.Expiry);
            double             strike       = futureOption.StrikePrice;
            ResolvedIborFuture future       = futureOption.UnderlyingFuture;
            double             volatility   = volatilities.volatility(timeToExpiry, future.LastTradeDate, strike, futurePrice);

            double vega = NormalFormulaRepository.vega(futurePrice, strike, timeToExpiry, volatility, futureOption.PutCall);

            return(IborFutureOptionSensitivity.of(volatilities.Name, timeToExpiry, future.LastTradeDate, strike, futurePrice, future.Currency, vega));
        }
Example #27
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @SuppressWarnings("synthetic-access") @Override public com.opengamma.strata.collect.array.DoubleMatrix[] apply(com.opengamma.strata.collect.array.DoubleArray x)
            public override DoubleMatrix[] apply(DoubleArray x)
            {
                ArgChecker.notNull(x, "x");
                ArgChecker.isTrue(domain(x), "point {} is not in the function domain", x.ToString());

                int n = x.size();

                DoubleMatrix[] y   = new DoubleMatrix[3];
                DoubleMatrix[] res = new DoubleMatrix[n];
                double[]       w;
                for (int i = 0; i < n; i++)
                {
                    double      xi           = x.get(i);
                    DoubleArray xPlusOneEps  = x.with(i, xi + outerInstance.eps);
                    DoubleArray xMinusOneEps = x.with(i, xi - outerInstance.eps);
                    if (!domain(xPlusOneEps))
                    {
                        DoubleArray xMinusTwoEps = x.with(i, xi - outerInstance.twoEps);
                        if (!domain(xMinusTwoEps))
                        {
                            throw new MathException("cannot get derivative at point " + x.ToString() + " in direction " + i);
                        }
                        y[0] = function(xMinusTwoEps);
                        y[2] = function(x);
                        y[1] = function(xMinusOneEps);
                        w    = wBack;
                    }
                    else
                    {
                        if (!domain(xMinusOneEps))
                        {
                            y[1] = function(xPlusOneEps);
                            y[0] = function(x);
                            y[2] = function(x.with(i, xi + outerInstance.twoEps));
                            w    = wFwd;
                        }
                        else
                        {
                            y[2] = function(xPlusOneEps);
                            y[0] = function(xMinusOneEps);
                            w    = wCent;
                        }
                    }
                    res[i] = (DoubleMatrix)MA.add(MA.scale(y[0], w[0]), MA.scale(y[2], w[2]));
                    if (w[1] != 0)
                    {
                        res[i] = (DoubleMatrix)MA.add(res[i], MA.scale(y[1], w[1]));
                    }
                }
                return(res);
            }
        /// <summary>
        /// Creates an instance.
        /// </summary>
        /// <param name="xValues">  the x-values of the curve, must be sorted from low to high </param>
        /// <param name="yValues">  the y-values of the curve </param>
        protected internal AbstractBoundCurveInterpolator(DoubleArray xValues, DoubleArray yValues)
        {
            ArgChecker.notNull(xValues, "xValues");
            ArgChecker.notNull(yValues, "yValues");
            int size = xValues.size();

            ArgChecker.isTrue(size == yValues.size(), "Curve node arrays must have same size");
            ArgChecker.isTrue(size > 1, "Curve node arrays must have at least two nodes");
            this.extrapolatorLeft  = ExceptionCurveExtrapolator.INSTANCE;
            this.extrapolatorRight = ExceptionCurveExtrapolator.INSTANCE;
            this.firstXValue       = xValues.get(0);
            this.lastXValue        = xValues.get(size - 1);
            this.lastYValue        = yValues.get(size - 1);
        }
Example #29
0
        public LeastSquareResults(double chiSq, DoubleArray parameters, DoubleMatrix covariance, DoubleMatrix inverseJacobian)
        {
            ArgChecker.isTrue(chiSq >= 0, "chi square < 0");
            ArgChecker.notNull(parameters, "parameters");
            ArgChecker.notNull(covariance, "covariance");
            int n = parameters.size();

            ArgChecker.isTrue(covariance.columnCount() == n, "covariance matrix not square");
            ArgChecker.isTrue(covariance.rowCount() == n, "covariance matrix wrong size");
            //TODO test size of inverse Jacobian
            _chiSq           = chiSq;
            _parameters      = parameters;
            _covariance      = covariance;
            _inverseJacobian = inverseJacobian;
        }
Example #30
0
        protected internal override QuantileResult quantile(double level, DoubleArray sample, bool isExtrapolated)
        {
            ArgChecker.isTrue(level > 0, "Quantile should be above 0.");
            ArgChecker.isTrue(level < 1, "Quantile should be below 1.");
            int sampleSize = sampleCorrection(sample.size());

            double[] order = createIndexArray(sample.size());
            double[] s     = sample.toArray();
            DoubleArrayMath.sortPairs(s, order);
            int index = (int)checkIndex(this.index(level * sampleSize), sample.size(), isExtrapolated);

            int[] ind = new int[1];
            ind[0] = (int)order[index - 1];
            return(QuantileResult.of(s[index - 1], ind, DoubleArray.of(1)));
        }