/** * Date calculations * * @see <a * href="http://www.bba.org.uk/bba/jsp/polopoly.jsp?d=225&a=1412">http://www.bba.org.uk/bba/jsp/polopoly.jsp?d=225&a=1412</a> */ @Override public Date valueDate(final Date fixingDate) { // http://www.bba.org.uk/bba/jsp/polopoly.jsp?d=225&a=1412 : // In the case of EUR the Value Date shall be two TARGET // business days after the Fixing Date. QL.require(isValidFixingDate(fixingDate), "Fixing date " + fixingDate + " is not valid"); return this.target.advance(fixingDate, fixingDays, TimeUnit.Days); }
@Override public void fetchResults(final PricingEngine.Results r) { super.fetchResults(r); QL.require( OneAssetOption.Results.class.isAssignableFrom(r.getClass()), ReflectConstants.WRONG_ARGUMENT_TYPE); // QA:[RG]::verified // final Greeks results = (Greeks)(r); final OneAssetOption.ResultsImpl ri = (OneAssetOption.ResultsImpl) r; final GreeksImpl results = ri.greeks(); QL.ensure(results != null, "no greeks returned from pricing engine"); /* no check on null values - just copy. this allows: a) to decide in derived options what to do when null results are returned (throw? numerical calculation?) b) to implement slim engines which only calculate the value---of course care must be taken not to call the greeks methods when using these. */ delta_ = results.delta; gamma_ = results.gamma; theta_ = results.theta; vega_ = results.vega; rho_ = results.rho; dividendRho_ = results.dividendRho; final MoreGreeksImpl moreResults = ri.moreGreeks(); QL.ensure(moreResults != null, "no more greeks returned from pricing engine"); /* no check on null values - just copy. this allows: a) to decide in derived options what to do when null results are returned (throw? numerical calculation?) b) to implement slim engines which only calculate the value---of course care must be taken not to call the greeks methods when using these. */ deltaForward_ = moreResults.deltaForward; elasticity_ = moreResults.elasticity; thetaPerDay_ = moreResults.thetaPerDay; strikeSensitivity_ = moreResults.strikeSensitivity; itmCashProbability_ = moreResults.itmCashProbability; }
/** * Constructor which initializes {@latex$ \mu } and {@latex \sigma }. * * @param average * @param sigma */ public NormalDistribution(final double average, final double sigma) { QL.require(sigma > 0.0, "sigma must be greater than 0.0"); // TODO: message this.average = average; this.sigma = sigma; this.normalizationFactor = Constants.M_SQRT_2 * Constants.M_1_SQRTPI / sigma; this.denormalizationFactor = sigma * sigma; this.denominator = 2.0 * denormalizationFactor; }
@Override public double op(final double x) { QL.require(x > 0.0, "strike must be positive: " + x + " not allowed"); return (new Sabr()) .sabrVolatility( x, forward_, itsCoeffs.t_, itsCoeffs.alpha_, itsCoeffs.beta_, itsCoeffs.nu_, itsCoeffs.rho_); }
public SABRCoeffHolder( final @Time double t, final double forward, final double alpha, final double beta, final double nu, final double rho, final boolean alphaIsFixed, final boolean betaIsFixed, final boolean nuIsFixed, final boolean rhoIsFixed) { t_ = t; forward_ = forward; alpha_ = alpha; beta_ = beta; nu_ = nu; rho_ = rho; alphaIsFixed_ = false; betaIsFixed_ = false; nuIsFixed_ = false; rhoIsFixed_ = false; weights_ = new Array(0); // ZH:TBD:verify with QL097, it is vector<Real> in QL097 error_ = Constants.NULL_REAL; maxError_ = Constants.NULL_REAL; SABREndCriteria_ = EndCriteria.Type.None; QL.require(t > 0.0, "expiry time must be positive: " + t + " not allowed"); if (!Double.isNaN(alpha_)) { alphaIsFixed_ = alphaIsFixed; } else { alpha_ = Math.sqrt(0.2); } if (!Double.isNaN(beta_)) { betaIsFixed_ = betaIsFixed; } else { beta_ = 0.5; } if (!Double.isNaN(nu_)) { nuIsFixed_ = nuIsFixed; } else { nu_ = Math.sqrt(0.4); } if (!Double.isNaN(rho_)) { rhoIsFixed_ = rhoIsFixed; } else { rho_ = 0.0; } (new Sabr()).validateSabrParameters(alpha_, beta_, nu_, rho_); }
public EURLibor(final Period tenor, final YieldTermStructure h) { super( "EURLibor", tenor, 2, // settlement days new EURCurrency(), new JointCalendar( new UnitedKingdom(Market.Exchange), new Target(), JointCalendarRule.JoinBusinessDays), eurliborConvention(tenor), eurliborEOM(tenor), new Actual360(), h); QL.require( tenor().units() != TimeUnit.Days, "for daily tenors dedicated DailyTenor constructor must be used"); this.target = new Target(); }
public double deltaForward() /* @ReadOnly */ { calculate(); QL.require(deltaForward_ != Constants.NULL_REAL, "forward delta not provided"); return deltaForward_; }
public void log() { QL.info(toString()); }
public double vega() { calculate(); QL.require(vega_ != Constants.NULL_REAL, "vega not provided"); return vega_; }
public double rho() { calculate(); QL.require(rho_ != Constants.NULL_REAL, "rho not provided"); return rho_; }
public double thetaPerDay() { calculate(); QL.require(thetaPerDay_ != Constants.NULL_REAL, "theta per-day not provided"); return thetaPerDay_; }
@Override public void update() { // forward_ might have changed QL.require( forward_ > 0.0, "at the money forward rate must be " + "positive: " + forward_ + " not allowed"); // we should also check that y contains positive values only // we must update weights if it is vegaWeighted if (vegaWeighted_) { // itsCoeffs.weights_.clear(); double weightsSum = 0.0; for (int i = 0; i < vx.size(); i++) { final double x = vx.get(i); final double y = vy.get(i); final double stdDev = Math.sqrt(y * y * itsCoeffs.t_); itsCoeffs.weights_.set(i, BlackFormula.blackFormulaStdDevDerivative(x, forward_, stdDev)); weightsSum += itsCoeffs.weights_.get(i); } // weight normalization for (int i = 0; i < itsCoeffs.weights_.size(); i++) { itsCoeffs.weights_.set(i, itsCoeffs.weights_.get(i) / weightsSum); } } // there is nothing to optimize if (itsCoeffs.alphaIsFixed_ && itsCoeffs.betaIsFixed_ && itsCoeffs.nuIsFixed_ && itsCoeffs.rhoIsFixed_) { itsCoeffs.error_ = interpolationError(); itsCoeffs.maxError_ = interpolationMaxError(); itsCoeffs.SABREndCriteria_ = EndCriteria.Type.None; return; } else { final SABRError costFunction = new SABRError(this); transformation_ = new SabrParametersTransformation(); final Array guess = new Array(4); guess.set(0, itsCoeffs.alpha_); guess.set(1, itsCoeffs.beta_); guess.set(2, itsCoeffs.nu_); guess.set(3, itsCoeffs.rho_); final boolean[] parameterAreFixed = new boolean[4]; parameterAreFixed[0] = itsCoeffs.alphaIsFixed_; parameterAreFixed[1] = itsCoeffs.betaIsFixed_; parameterAreFixed[2] = itsCoeffs.nuIsFixed_; parameterAreFixed[3] = itsCoeffs.rhoIsFixed_; final Array inversedTransformatedGuess = new Array(transformation_.inverse(guess)); final ProjectedCostFunction constrainedSABRError = new ProjectedCostFunction(costFunction, inversedTransformatedGuess, parameterAreFixed); final Array projectedGuess = new Array(constrainedSABRError.project(inversedTransformatedGuess)); final NoConstraint constraint = new NoConstraint(); final Problem problem = new Problem(constrainedSABRError, constraint, projectedGuess); itsCoeffs.SABREndCriteria_ = optMethod_.minimize(problem, endCriteria_); final Array projectedResult = new Array(problem.currentValue()); final Array transfResult = new Array(constrainedSABRError.include(projectedResult)); final Array result = transformation_.direct(transfResult); itsCoeffs.alpha_ = result.get(0); itsCoeffs.beta_ = result.get(1); itsCoeffs.nu_ = result.get(2); itsCoeffs.rho_ = result.get(3); } itsCoeffs.error_ = interpolationError(); itsCoeffs.maxError_ = interpolationMaxError(); }
@Test public void testBeagleholeValues() { QL.info("Testing barrier options against Beaglehole's values..."); /** * Data from "Going to Extreme: Correcting Simulation Bias in Exotic Option Valuation" - D.R. * Beaglehole, P.H. Dybvig and G. Zhou Financial Analysts Journal; Jan / Feb 1997; 53, 1 */ final BarrierOptionData values[] = { new BarrierOptionData(BarrierType.DownOut, 0.50, 50, 45, 5.477, 0.0) }; final double underlyingPrice = 50.0; final double rebate = 0.0; final double r = Math.log(1.1); final double q = 0.00; final DayCounter dc = new Actual360(); final Date today = Date.todaysDate(); new Settings().setEvaluationDate(today); final Quote underlying = new SimpleQuote(underlyingPrice); final Quote qH_SME = new SimpleQuote(q); final YieldTermStructure qTS = Utilities.flatRate(today, qH_SME, dc); final Quote rH_SME = new SimpleQuote(r); final YieldTermStructure rTS = Utilities.flatRate(today, rH_SME, dc); final SimpleQuote volatility = new SimpleQuote(0.10); final BlackVolTermStructure volTS = Utilities.flatVol(today, volatility, dc); final Date exDate = today.add(360); final Exercise exercise = new EuropeanExercise(exDate); for (final BarrierOptionData value : values) { volatility.setValue(value.volatility); final StrikedTypePayoff callPayoff = new PlainVanillaPayoff(Option.Type.Call, value.strike); final BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess( new Handle<Quote>(underlying), new Handle<YieldTermStructure>(qTS), new Handle<YieldTermStructure>(rTS), new Handle<BlackVolTermStructure>(volTS)); final PricingEngine engine = new AnalyticBarrierEngine(stochProcess); final BarrierOption barrierCallOption = new BarrierOption(value.barrierType, value.barrier, rebate, callPayoff, exercise); barrierCallOption.setPricingEngine(engine); final double calculated = barrierCallOption.NPV(); final double expected = value.callValue; final double error = Math.abs(calculated - expected); final double maxErrorAllowed = 1.0e-3; if (error > maxErrorAllowed) { REPORT_FAILURE( "value", value.barrierType, value.barrier, rebate, callPayoff, exercise, underlyingPrice, q, r, today, value.volatility, expected, calculated, error, maxErrorAllowed); } } // TODO: MC Barrier engine not implemented yet. /* final double maxMcRelativeErrorAllowed = 0.01; final int timeSteps = 1; final boolean brownianBridge = true; final boolean antitheticVariate = false; final boolean controlVariate = false; final int requiredSamples = 131071; //2^17-1 final double requiredTolerance; final int maxSamples = 1048575; // 2^20-1 final boolean isBiased = false; final double seed = 10; boost::shared_ptr<PricingEngine> mcEngine( new MCBarrierEngine<LowDiscrepancy>(timeSteps, brownianBridge, antitheticVariate, controlVariate, requiredSamples, requiredTolerance, maxSamples, isBiased, seed)); barrierCallOption.setPricingEngine(mcEngine); calculated = barrierCallOption.NPV(); error = std::fabs(calculated-expected)/expected; if (error>maxMcRelativeErrorAllowed) { REPORT_FAILURE("value", values[i].type, values[i].barrier, rebate, callPayoff, exercise, underlyingPrice, q, r, today, values[i].volatility, expected, calculated, error, maxMcRelativeErrorAllowed); } */ }
@Test public void testHaugValues() { QL.info("Testing barrier options against Haug's values..."); final NewBarrierOptionData values[] = { // // The data below are from "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 pag. 72 // // barrierType, barrier, rebate, type, strike, s, q, r, t, v, // result, tol new NewBarrierOptionData( BarrierType.DownOut, 95.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 9.0246, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 95.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 6.7924, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 95.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 4.8759, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 100.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 100.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 100.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), new NewBarrierOptionData( BarrierType.UpOut, 105.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 2.6789, 1.0e-4), new NewBarrierOptionData( BarrierType.UpOut, 105.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 2.3580, 1.0e-4), new NewBarrierOptionData( BarrierType.UpOut, 105.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 2.3453, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 95.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 7.7627, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 95.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 4.0109, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 95.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 2.0576, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 100.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 13.8333, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 100.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 7.8494, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 100.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 3.9795, 1.0e-4), new NewBarrierOptionData( BarrierType.UpIn, 105.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 14.1112, 1.0e-4), new NewBarrierOptionData( BarrierType.UpIn, 105.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 8.4482, 1.0e-4), new NewBarrierOptionData( BarrierType.UpIn, 105.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 4.5910, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 95.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 8.8334, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 95.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 7.0285, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 95.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 5.4137, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 100.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 3.0000, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 100.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 3.0000, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 100.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 3.0000, 1.0e-4), new NewBarrierOptionData( BarrierType.UpOut, 105.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 2.6341, 1.0e-4), new NewBarrierOptionData( BarrierType.UpOut, 105.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 2.4389, 1.0e-4), new NewBarrierOptionData( BarrierType.UpOut, 105.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 2.4315, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 95.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 9.0093, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 95.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 5.1370, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 95.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 2.8517, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 100.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 14.8816, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 100.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 9.2045, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 100.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 5.3043, 1.0e-4), new NewBarrierOptionData( BarrierType.UpIn, 105.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 15.2098, 1.0e-4), new NewBarrierOptionData( BarrierType.UpIn, 105.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 9.7278, 1.0e-4), new NewBarrierOptionData( BarrierType.UpIn, 105.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 5.8350, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 95.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 2.2798, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 95.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 2.2947, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 95.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 2.6252, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 100.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 100.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 100.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 3.0000, 1.0e-4), new NewBarrierOptionData( BarrierType.UpOut, 105.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 3.7760, 1.0e-4), new NewBarrierOptionData( BarrierType.UpOut, 105.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 5.4932, 1.0e-4), new NewBarrierOptionData( BarrierType.UpOut, 105.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 7.5187, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 95.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 2.9586, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 95.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 6.5677, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 95.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 11.9752, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 100.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 2.2845, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 100.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 5.9085, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 100.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 11.6465, 1.0e-4), new NewBarrierOptionData( BarrierType.UpIn, 105.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.25, 1.4653, 1.0e-4), new NewBarrierOptionData( BarrierType.UpIn, 105.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.25, 3.3721, 1.0e-4), new NewBarrierOptionData( BarrierType.UpIn, 105.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.25, 7.0846, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 95.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 2.4170, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 95.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 2.4258, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 95.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 2.6246, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 100.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 3.0000, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 100.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 3.0000, 1.0e-4), new NewBarrierOptionData( BarrierType.DownOut, 100.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 3.0000, 1.0e-4), new NewBarrierOptionData( BarrierType.UpOut, 105.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 4.2293, 1.0e-4), new NewBarrierOptionData( BarrierType.UpOut, 105.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 5.8032, 1.0e-4), new NewBarrierOptionData( BarrierType.UpOut, 105.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 7.5649, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 95.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 3.8769, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 95.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 7.7989, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 95.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 13.3078, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 100.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 3.3328, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 100.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 7.2636, 1.0e-4), new NewBarrierOptionData( BarrierType.DownIn, 100.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 12.9713, 1.0e-4), new NewBarrierOptionData( BarrierType.UpIn, 105.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.30, 2.0658, 1.0e-4), new NewBarrierOptionData( BarrierType.UpIn, 105.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.30, 4.4226, 1.0e-4), new NewBarrierOptionData( BarrierType.UpIn, 105.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.30, 8.3686, 1.0e-4), // // Data from "Going to Extreme: Correcting Simulation Bias in Exotic Option Valuation" // D.R. Beaglehole, P.H. Dybvig and G. Zhou // Financial Analysts Journal; Jan / Feb 1997; 53, 1 // // barrierType, barrier, rebate, type, strike, s, q, r, t, v, // result, tol // ---- new NewBarrierOptionData( BarrierType.DownOut, 45.0, 0.0, Option.Type.PUT, // 50, 50.0,-0.05, 0.10, 0.25, 0.50, 4.032, 1.0e-3 ), // ---- new NewBarrierOptionData( BarrierType.DownOut, 45.0, 0.0, Option.Type.PUT, // 50, 50.0,-0.05, 0.10, 1.00, 0.50, 5.477, 1.0e-3 ) }; final DayCounter dc = new Actual360(); final Date today = Date.todaysDate(); new Settings().setEvaluationDate(today); final SimpleQuote spot = new SimpleQuote(0.0); final SimpleQuote qRate = new SimpleQuote(0.0); final YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc); final SimpleQuote rRate = new SimpleQuote(0.0); final YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc); final SimpleQuote vol = new SimpleQuote(0.0); final BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); for (final NewBarrierOptionData value : values) { final Date exDate = today.add(timeToDays(value.t)); final Exercise exercise = new EuropeanExercise(exDate); spot.setValue(value.s); qRate.setValue(value.q); rRate.setValue(value.r); vol.setValue(value.v); final StrikedTypePayoff payoff = new PlainVanillaPayoff(value.type, value.strike); final BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess( new Handle<Quote>(spot), new Handle<YieldTermStructure>(qTS), new Handle<YieldTermStructure>(rTS), new Handle<BlackVolTermStructure>(volTS)); final PricingEngine engine = new AnalyticBarrierEngine(stochProcess); final BarrierOption barrierOption = new BarrierOption(value.barrierType, value.barrier, value.rebate, payoff, exercise); barrierOption.setPricingEngine(engine); final double calculated = barrierOption.NPV(); final double expected = value.result; final double error = Math.abs(calculated - expected); if (error > value.tol) { REPORT_FAILURE( "value", value.barrierType, value.barrier, value.rebate, payoff, exercise, value.s, value.q, value.r, today, value.v, expected, calculated, error, value.tol); } } }
@Override public void run() { QL.validateExperimentalMode(); QL.info("::::: " + this.getClass().getSimpleName() + " :::::"); final String fmt = "%-45s %-15s %-15s\n"; try { final StopClock clock = new StopClock(); clock.startClock(); final Date today = new Date(29, Month.May, 2006); new Settings().setEvaluationDate(today); // the option to replicate final BarrierType barrierType = BarrierType.DownOut; final double barrier = 70.0; final double rebate = 0.0; final Option.Type type = Option.Type.Put; final double underlyingValue = 100; final Handle<SimpleQuote> underlying = new Handle<SimpleQuote>(new SimpleQuote(underlyingValue)); final double strike = 100.0; final Handle<SimpleQuote> riskFreeRate = new Handle<SimpleQuote>(new SimpleQuote(0.04)); final Handle<SimpleQuote> volatility = new Handle<SimpleQuote>(new SimpleQuote(0.20)); final Date maturity = today.add(Period.ONE_YEAR_FORWARD); System.out.println("\n"); // write column headings - we don't need these values ... final int widths[] = {45, 15, 15}; final int totalWidth = widths[0] + widths[1] + widths[2]; System.out.println("Initial Market conditions"); System.out.printf(fmt, "Option", "NPV", "Error"); /* Size widths[] = { 45, 15, 15 }; Size totalWidth = widths[0]+widths[1]+widths[2]; std::string rule(totalWidth, '-'), dblrule(totalWidth, '='); std::cout << dblrule << std::endl; std::cout << "Initial market conditions" << std::endl; std::cout << dblrule << std::endl; std::cout << std::setw(widths[0]) << std::left << "Option" << std::setw(widths[1]) << std::left << "NPV" << std::setw(widths[2]) << std::left << "Error" << std::endl; std::cout << rule << std::endl; */ // bootstrap the yield/vol curves final DayCounter dayCounter = new Actual365Fixed(); final Handle<Quote> h1 = new Handle<Quote>(riskFreeRate.currentLink()); final Handle<Quote> h2 = new Handle<Quote>(volatility.currentLink()); final Handle<YieldTermStructure> flatRate = new Handle<YieldTermStructure>(new FlatForward(0, new NullCalendar(), h1, dayCounter)); final Handle<BlackConstantVol> flatVol = new Handle<BlackConstantVol>(new BlackConstantVol(0, new NullCalendar(), h2, dayCounter)); // instantiate the option final Exercise exercise = new EuropeanExercise(maturity); final Payoff payoff = new PlainVanillaPayoff(type, strike); // FIXME:Review BlackScholes, GeneralizedBlackScholesStochasticProcess // Handle<StochasticProcess> stochasticProcess = new Handle<StochasticProcess>(new // GeneralizedBlackScholesProcess(underlying, flatRate, flatVol)); } catch (final Exception ex) { ex.printStackTrace(); } finally { } }
public double delta() { calculate(); QL.require(delta_ != Constants.NULL_REAL, "delta not provided"); return delta_; }
public double dividendRho() { calculate(); QL.require(dividendRho_ != Constants.NULL_REAL, "dividend rho not provided"); return dividendRho_; }
public double itmCashProbability() { calculate(); QL.require( itmCashProbability_ != Constants.NULL_REAL, "in-the-money cash probability not provided"); return itmCashProbability_; }
public double strikeSensitivity() { calculate(); QL.require(strikeSensitivity_ != Constants.NULL_REAL, "strike sensitivity not provided"); return strikeSensitivity_; }
@Test public void testBabsiriValues() { QL.info("Testing barrier options against Babsiri's values..."); /** * Data from "Simulating Path-Dependent Options: A New Approach" - M. El Babsiri and G. Noel * Journal of Derivatives; Winter 1998; 6, 2 */ final BarrierOptionData values[] = { new BarrierOptionData(BarrierType.DownIn, 0.10, 100, 90, 0.07187, 0.0), new BarrierOptionData(BarrierType.DownIn, 0.15, 100, 90, 0.60638, 0.0), new BarrierOptionData(BarrierType.DownIn, 0.20, 100, 90, 1.64005, 0.0), new BarrierOptionData(BarrierType.DownIn, 0.25, 100, 90, 2.98495, 0.0), new BarrierOptionData(BarrierType.DownIn, 0.30, 100, 90, 4.50952, 0.0), new BarrierOptionData(BarrierType.UpIn, 0.10, 100, 110, 4.79148, 0.0), new BarrierOptionData(BarrierType.UpIn, 0.15, 100, 110, 7.08268, 0.0), new BarrierOptionData(BarrierType.UpIn, 0.20, 100, 110, 9.11008, 0.0), new BarrierOptionData(BarrierType.UpIn, 0.25, 100, 110, 11.06148, 0.0), new BarrierOptionData(BarrierType.UpIn, 0.30, 100, 110, 12.98351, 0.0) }; final double underlyingPrice = 100.0; final double rebate = 0.0; final double r = 0.05; final double q = 0.02; final DayCounter dc = new Actual360(); final Date today = Date.todaysDate(); new Settings().setEvaluationDate(today); final Quote underlying = new SimpleQuote(underlyingPrice); final Quote qH_SME = new SimpleQuote(q); final YieldTermStructure qTS = Utilities.flatRate(today, qH_SME, dc); final Quote rH_SME = new SimpleQuote(r); final YieldTermStructure rTS = Utilities.flatRate(today, rH_SME, dc); final SimpleQuote volatility = new SimpleQuote(0.10); final BlackVolTermStructure volTS = Utilities.flatVol(today, volatility, dc); final Date exDate = today.add(360); final Exercise exercise = new EuropeanExercise(exDate); for (final BarrierOptionData value : values) { volatility.setValue(value.volatility); final StrikedTypePayoff callPayoff = new PlainVanillaPayoff(Option.Type.Call, value.strike); final BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess( new Handle<Quote>(underlying), new Handle<YieldTermStructure>(qTS), new Handle<YieldTermStructure>(rTS), new Handle<BlackVolTermStructure>(volTS)); final PricingEngine engine = new AnalyticBarrierEngine(stochProcess); final BarrierOption barrierCallOption = new BarrierOption(value.barrierType, value.barrier, rebate, callPayoff, exercise); barrierCallOption.setPricingEngine(engine); final double calculated = barrierCallOption.NPV(); final double expected = value.callValue; final double error = Math.abs(calculated - expected); final double maxErrorAllowed = 1.0e-3; if (error > maxErrorAllowed) { REPORT_FAILURE( "value", value.barrierType, value.barrier, rebate, callPayoff, exercise, underlyingPrice, q, r, today, value.volatility, expected, calculated, error, maxErrorAllowed); } } }
public double elasticity() { calculate(); QL.require(elasticity_ != Constants.NULL_REAL, "elasticity not provided"); return elasticity_; }
public BarrierOptionTest() { QL.info("::::: " + this.getClass().getSimpleName() + " :::::"); }
public double gamma() { calculate(); QL.require(gamma_ != Constants.NULL_REAL, "gamma not provided"); return gamma_; }
public FalsePositionTest() { QL.info("::::: " + this.getClass().getSimpleName() + " :::::"); }
public double theta() { calculate(); QL.require(theta_ != Constants.NULL_REAL, "theta not provided"); return theta_; }