Ejemplo n.º 1
0
  /**
   * Calculates the Bachelier option implied volatility of a call, i.e., the payoff
   *
   * <p><i>max(S(T)-K,0)</i>, where <i>S</i> follows a normal process with constant volatility.
   *
   * @param forward The forward of the underlying.
   * @param optionMaturity The option maturity T.
   * @param optionStrike The option strike. If the option strike is &le; 0.0 the method returns the
   *     value of the forward contract paying S(T)-K in T.
   * @param payoffUnit The payoff unit (e.g., the discount factor)
   * @param optionValue The option value.
   * @return Returns the implied volatility of a European call option under the Bachelier model.
   */
  public static double bachelierOptionImpliedVolatility(
      double forward,
      double optionMaturity,
      double optionStrike,
      double payoffUnit,
      double optionValue) {
    // Limit the maximum number of iterations, to ensure this calculation returns fast, e.g. in
    // cases when there is no such thing as an implied vol
    // TODO: An exception should be thrown, when there is no implied volatility for the given value.
    int maxIterations = 100;
    double maxAccuracy = 0.0;

    if (optionStrike <= 0.0) {
      // Actually it is not an option
      return 0.0;
    } else {
      // Calculate an lower and upper bound for the volatility
      double volatilityLowerBound = 0.0;
      double volatilityUpperBound =
          (optionValue + Math.abs(forward - optionStrike)) / Math.sqrt(optionMaturity) / payoffUnit;
      volatilityUpperBound /=
          Math.min(
              1.0,
              NormalDistribution.density(
                  (forward - optionStrike) / (volatilityUpperBound * Math.sqrt(optionMaturity))));

      // Solve for implied volatility
      GoldenSectionSearch solver =
          new GoldenSectionSearch(volatilityLowerBound, volatilityUpperBound);
      while (solver.getAccuracy() > maxAccuracy
          && !solver.isDone()
          && solver.getNumberOfIterations() < maxIterations) {
        double volatility = solver.getNextPoint();

        double valueAnalytic =
            bachelierOptionValue(forward, volatility, optionMaturity, optionStrike, payoffUnit);

        double error = valueAnalytic - optionValue;

        solver.setValue(error * error);
      }

      return solver.getBestPoint();
    }
  }
Ejemplo n.º 2
0
  /**
   * Calculates the option value of a call, i.e., the payoff max(S(T)-K,0) P, where S follows a
   * normal process with constant volatility, i.e., a Bachelier model.
   *
   * @param forward The forward of the underlying.
   * @param volatility The Bachelier volatility.
   * @param optionMaturity The option maturity T.
   * @param optionStrike The option strike.
   * @param payoffUnit The payoff unit (e.g., the discount factor)
   * @return Returns the value of a European call option under the Bachelier model.
   */
  public static double bachelierOptionValue(
      double forward,
      double volatility,
      double optionMaturity,
      double optionStrike,
      double payoffUnit) {
    if (optionMaturity < 0) {
      return 0;
    } else {
      // Calculate analytic value
      double dPlus = (forward - optionStrike) / (volatility * Math.sqrt(optionMaturity));

      double valueAnalytic =
          ((forward - optionStrike) * NormalDistribution.cumulativeDistribution(dPlus)
                  + (volatility * Math.sqrt(optionMaturity)) * NormalDistribution.density(dPlus))
              * payoffUnit;

      return valueAnalytic;
    }
  }