class BlackScholesFormulaRepository {

  public static double strikeForDelta(final double spot, final double spotDelta, final double timeToExpiry, final double lognormalVol, final double interestRate, final double costOfCarry,
      final boolean isCall) {
    ArgumentChecker.isTrue(spot > 0.0, "non-positive/NaN spot; have {}", spot);
    ArgumentChecker.isTrue(timeToExpiry > 0.0, "non-positive/NaN timeToExpiry; have {}", timeToExpiry);
    ArgumentChecker.isTrue(lognormalVol > 0.0, "non-positive/NaN lognormalVol; have {}", lognormalVol);
    ArgumentChecker.isFalse(Double.isNaN(interestRate), "interestRate is NaN");
    ArgumentChecker.isFalse(Double.isNaN(costOfCarry), "costOfCarry is NaN");

    ArgumentChecker.isFalse(Double.isInfinite(spot), "spot is infinite");
    ArgumentChecker.isFalse(Double.isInfinite(spotDelta), "spotDelta is infinite");
    ArgumentChecker.isFalse(Double.isInfinite(timeToExpiry), "timeToExpiry is infinite");
    ArgumentChecker.isFalse(Double.isInfinite(lognormalVol), "lognormalVol is infinite");
    ArgumentChecker.isFalse(Double.isInfinite(interestRate), "interestRate is infinite");
    ArgumentChecker.isFalse(Double.isInfinite(costOfCarry), "costOfCarry is infinite");

    final double rescaledDelta = spotDelta * Math.exp((-costOfCarry + interestRate) * timeToExpiry);
    Validate.isTrue((isCall && rescaledDelta > 0. && rescaledDelta < 1.) || (!isCall && spotDelta < 0. && rescaledDelta > -1.),
        "delta/Math.exp((costOfCarry - interestRate) * timeToExpiry) out of range, ", rescaledDelta);

    final double sigmaRootT = lognormalVol * Math.sqrt(timeToExpiry);
    final double rescaledSpot = spot * Math.exp(costOfCarry * timeToExpiry);

    final int sign = isCall ? 1 : -1;
    final double d1 = sign * NORMAL.getInverseCDF(sign * rescaledDelta);
    return rescaledSpot * Math.exp(-d1 * sigmaRootT + 0.5 * sigmaRootT * sigmaRootT);
  }

}