public static List <CashFlow> FloatingDigitalLeg <InterestRateIndexType, FloatingCouponType, DigitalCouponType>( List <double> nominals, Schedule schedule, InterestRateIndexType index, DayCounter paymentDayCounter, BusinessDayConvention paymentAdj, List <int> fixingDays, List <double> gearings, List <double> spreads, bool isInArrears, List <double> callStrikes, Position.Type callPosition, bool isCallATMIncluded, List <double> callDigitalPayoffs, List <double> putStrikes, Position.Type putPosition, bool isPutATMIncluded, List <double> putDigitalPayoffs, DigitalReplication replication) where InterestRateIndexType : InterestRateIndex, new() where FloatingCouponType : FloatingRateCoupon, new() where DigitalCouponType : DigitalCoupon, new() { int n = schedule.Count; Utils.QL_REQUIRE(!nominals.empty(), () => "no notional given"); Utils.QL_REQUIRE(nominals.Count <= n, () => "too many nominals (" + nominals.Count + "), only " + n + " required"); if (gearings != null) { Utils.QL_REQUIRE(gearings.Count <= n, () => "too many gearings (" + gearings.Count + "), only " + n + " required"); } if (spreads != null) { Utils.QL_REQUIRE(spreads.Count <= n, () => "too many spreads (" + spreads.Count + "), only " + n + " required"); } if (callStrikes != null) { Utils.QL_REQUIRE(callStrikes.Count <= n, () => "too many nominals (" + callStrikes.Count + "), only " + n + " required"); } if (putStrikes != null) { Utils.QL_REQUIRE(putStrikes.Count <= n, () => "too many nominals (" + putStrikes.Count + "), only " + n + " required"); } List <CashFlow> leg = new List <CashFlow>(); // the following is not always correct Calendar calendar = schedule.calendar(); Date refStart, start, refEnd, end; Date paymentDate; for (int i = 0; i < n; ++i) { refStart = start = schedule.date(i); refEnd = end = schedule.date(i + 1); paymentDate = calendar.adjust(end, paymentAdj); if (i == 0 && !schedule.isRegular(i + 1)) { BusinessDayConvention bdc = schedule.businessDayConvention(); refStart = calendar.adjust(end - schedule.tenor(), bdc); } if (i == n - 1 && !schedule.isRegular(i + 1)) { BusinessDayConvention bdc = schedule.businessDayConvention(); refEnd = calendar.adjust(start + schedule.tenor(), bdc); } if (Utils.Get(gearings, i, 1.0).IsEqual(0.0)) { // fixed coupon leg.Add(new FixedRateCoupon(paymentDate, Utils.Get(nominals, i, 1.0), Utils.Get(spreads, i, 1.0), paymentDayCounter, start, end, refStart, refEnd)); } else { // floating digital coupon FloatingCouponType underlying = FastActivator <FloatingCouponType> .Create().factory( Utils.Get(nominals, i, 1.0), paymentDate, start, end, Utils.Get(fixingDays, i, index.fixingDays()), index, Utils.Get(gearings, i, 1.0), Utils.Get(spreads, i, 0.0), refStart, refEnd, paymentDayCounter, isInArrears) as FloatingCouponType; DigitalCouponType digitalCoupon = FastActivator <DigitalCouponType> .Create().factory( underlying, Utils.toNullable(Utils.Get(callStrikes, i, Double.MinValue)), callPosition, isCallATMIncluded, Utils.toNullable(Utils.Get(callDigitalPayoffs, i, Double.MinValue)), Utils.toNullable(Utils.Get(putStrikes, i, Double.MinValue)), putPosition, isPutATMIncluded, Utils.toNullable(Utils.Get(putDigitalPayoffs, i, Double.MinValue)), replication) as DigitalCouponType; leg.Add(digitalCoupon); } } return(leg); }
public static List <CashFlow> FloatingLeg <InterestRateIndexType, FloatingCouponType, CappedFlooredCouponType>( List <double> nominals, Schedule schedule, InterestRateIndexType index, DayCounter paymentDayCounter, BusinessDayConvention paymentAdj, List <int> fixingDays, List <double> gearings, List <double> spreads, List <double> caps, List <double> floors, bool isInArrears, bool isZero) where InterestRateIndexType : InterestRateIndex, new() where FloatingCouponType : FloatingRateCoupon, new() where CappedFlooredCouponType : CappedFlooredCoupon, new() { int n = schedule.Count; Utils.QL_REQUIRE(!nominals.empty(), () => "no notional given"); Utils.QL_REQUIRE(nominals.Count <= n, () => "too many nominals (" + nominals.Count + "), only " + n + " required"); if (gearings != null) { Utils.QL_REQUIRE(gearings.Count <= n, () => "too many gearings (" + gearings.Count + "), only " + n + " required"); } if (spreads != null) { Utils.QL_REQUIRE(spreads.Count <= n, () => "too many spreads (" + spreads.Count + "), only " + n + " required"); } if (caps != null) { Utils.QL_REQUIRE(caps.Count <= n, () => "too many caps (" + caps.Count + "), only " + n + " required"); } if (floors != null) { Utils.QL_REQUIRE(floors.Count <= n, () => "too many floors (" + floors.Count + "), only " + n + " required"); } Utils.QL_REQUIRE(!isZero || !isInArrears, () => "in-arrears and zero features are not compatible"); List <CashFlow> leg = new List <CashFlow>(); // the following is not always correct Calendar calendar = schedule.calendar(); Date lastPaymentDate = calendar.adjust(schedule[n - 1], paymentAdj); for (int i = 0; i < n - 1; ++i) { Date refStart, start, refEnd, end; refStart = start = schedule[i]; refEnd = end = schedule[i + 1]; Date paymentDate = isZero ? lastPaymentDate : calendar.adjust(end, paymentAdj); if (i == 0 && !schedule.isRegular(i + 1)) { refStart = calendar.adjust(end - schedule.tenor(), schedule.businessDayConvention()); } if (i == n - 1 && !schedule.isRegular(i + 1)) { refEnd = calendar.adjust(start + schedule.tenor(), schedule.businessDayConvention()); } if (Utils.Get(gearings, i, 1).IsEqual(0.0)) { // fixed coupon leg.Add(new FixedRateCoupon(paymentDate, Utils.Get(nominals, i), Utils.effectiveFixedRate(spreads, caps, floors, i), paymentDayCounter, start, end, refStart, refEnd)); } else { if (Utils.noOption(caps, floors, i)) { leg.Add(FastActivator <FloatingCouponType> .Create().factory( Utils.Get(nominals, i), paymentDate, start, end, Utils.Get(fixingDays, i, index.fixingDays()), index, Utils.Get(gearings, i, 1), Utils.Get(spreads, i), refStart, refEnd, paymentDayCounter, isInArrears)); } else { leg.Add(FastActivator <CappedFlooredCouponType> .Create().factory( Utils.Get(nominals, i), paymentDate, start, end, Utils.Get(fixingDays, i, index.fixingDays()), index, Utils.Get(gearings, i, 1), Utils.Get(spreads, i), Utils.toNullable(Utils.Get(caps, i, Double.MinValue)), Utils.toNullable(Utils.Get(floors, i, Double.MinValue)), refStart, refEnd, paymentDayCounter, isInArrears)); } } } return(leg); }
public override void calculate() { DayCounter rfdc = process_.riskFreeRate().link.dayCounter(); DayCounter divdc = process_.dividendYield().link.dayCounter(); DayCounter voldc = process_.blackVolatility().link.dayCounter(); Calendar volcal = process_.blackVolatility().link.calendar(); double s0 = process_.stateVariable().link.value(); Utils.QL_REQUIRE(s0 > 0.0, () => "negative or null underlying given"); double v = process_.blackVolatility().link.blackVol(arguments_.exercise.lastDate(), s0); Date maturityDate = arguments_.exercise.lastDate(); double r = process_.riskFreeRate().link.zeroRate(maturityDate, rfdc, Compounding.Continuous, Frequency.NoFrequency).rate(); double q = process_.dividendYield().link.zeroRate(maturityDate, divdc, Compounding.Continuous, Frequency.NoFrequency).rate(); Date referenceDate = process_.riskFreeRate().link.referenceDate(); // binomial trees with constant coefficient var flatRiskFree = new Handle <YieldTermStructure>(new FlatForward(referenceDate, r, rfdc)); var flatDividends = new Handle <YieldTermStructure>(new FlatForward(referenceDate, q, divdc)); var flatVol = new Handle <BlackVolTermStructure>(new BlackConstantVol(referenceDate, volcal, v, voldc)); PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff; Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given"); double maturity = rfdc.yearFraction(referenceDate, maturityDate); StochasticProcess1D bs = new GeneralizedBlackScholesProcess(process_.stateVariable(), flatDividends, flatRiskFree, flatVol); TimeGrid grid = new TimeGrid(maturity, timeSteps_); T tree = FastActivator <T> .Create().factory(bs, maturity, timeSteps_, payoff.strike()); BlackScholesLattice <T> lattice = new BlackScholesLattice <T>(tree, r, maturity, timeSteps_); DiscretizedVanillaOption option = new DiscretizedVanillaOption(arguments_, process_, grid); option.initialize(lattice, maturity); // Partial derivatives calculated from various points in the // binomial tree (Odegaard) // Rollback to third-last step, and get underlying price (s2) & // option values (p2) at this point option.rollback(grid[2]); Vector va2 = new Vector(option.values()); Utils.QL_REQUIRE(va2.size() == 3, () => "Expect 3 nodes in grid at second step"); double p2h = va2[2]; // high-price double s2 = lattice.underlying(2, 2); // high price // Rollback to second-last step, and get option value (p1) at // this point option.rollback(grid[1]); Vector va = new Vector(option.values()); Utils.QL_REQUIRE(va.size() == 2, () => "Expect 2 nodes in grid at first step"); double p1 = va[1]; // Finally, rollback to t=0 option.rollback(0.0); double p0 = option.presentValue(); double s1 = lattice.underlying(1, 1); // Calculate partial derivatives double delta0 = (p1 - p0) / (s1 - s0); // dp/ds double delta1 = (p2h - p1) / (s2 - s1); // dp/ds // Store results results_.value = p0; results_.delta = delta0; results_.gamma = 2.0 * (delta1 - delta0) / (s2 - s0); //d(delta)/ds results_.theta = Utils.blackScholesTheta(process_, results_.value.GetValueOrDefault(), results_.delta.GetValueOrDefault(), results_.gamma.GetValueOrDefault()); }
public GenericTimeSetter(Vector grid, GeneralizedBlackScholesProcess process) { grid_ = new LogGrid(grid); pde_ = (PdeClass)FastActivator <PdeClass> .Create().factory(process); }
public void setInterpolation <Interpolator>() where Interpolator : IInterpolationFactory, new () { setInterpolation <Interpolator>(FastActivator <Interpolator> .Create()); }
public FDConditionTemplate(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) : base(process, timeSteps, gridPoints, timeDependent) { // init engine engine_ = (baseEngine)FastActivator <baseEngine> .Create().factory(process, timeSteps, gridPoints, timeDependent); }
//! basic calculate method provided to inherited pricing engines public void calculate(double?requiredTolerance, int?requiredSamples, int?maxSamples) { Utils.QL_REQUIRE(requiredTolerance != null || requiredSamples != null, () => "neither tolerance nor number of samples set"); //! Initialize the one-factor Monte Carlo if (this.controlVariate_) { double?controlVariateValue = this.controlVariateValue(); Utils.QL_REQUIRE(controlVariateValue != null, () => "engine does not provide control-variation price"); PathPricer <IPath> controlPP = this.controlPathPricer(); Utils.QL_REQUIRE(controlPP != null, () => "engine does not provide control-variation path pricer"); IPathGenerator <IRNG> controlPG = this.controlPathGenerator(); this.mcModel_ = new MonteCarloModel <MC, RNG, S>(pathGenerator(), pathPricer(), FastActivator <S> .Create(), antitheticVariate_, controlPP, controlVariateValue.GetValueOrDefault(), controlPG); } else { this.mcModel_ = new MonteCarloModel <MC, RNG, S>(pathGenerator(), pathPricer(), FastActivator <S> .Create(), antitheticVariate_); } if (requiredTolerance != null) { if (maxSamples != null) { value(requiredTolerance.Value, maxSamples.Value); } else { value(requiredTolerance.Value); } } else { valueWithSamples(requiredSamples.GetValueOrDefault()); } }
//public FDEngineAdapter(GeneralizedBlackScholesProcess process, Size timeSteps=100, Size gridPoints=100, bool timeDependent = false) public FDEngineAdapter(GeneralizedBlackScholesProcess process, int timeSteps, int gridPoints, bool timeDependent) { optionBase = (Base)FastActivator <Base> .Create().factory(process, timeSteps, gridPoints, timeDependent); process.registerWith(update); }
public LogInterpolationImpl(List <double> xBegin, int size, List <double> yBegin) : this(xBegin, size, yBegin, FastActivator <Interpolator> .Create()) { }
public InterpolatedYoYInflationCurve(Date referenceDate, Calendar calendar, DayCounter dayCounter, Period lag, Frequency frequency, bool indexIsInterpolated, Handle <YieldTermStructure> yTS, List <Date> dates, List <double> rates) : this(referenceDate, calendar, dayCounter, lag, frequency, indexIsInterpolated, yTS, dates, rates, FastActivator <Interpolator> .Create()) { }
public XABRCoeffHolder(double t, double forward, List <double?> _params, List <bool> paramIsFixed) { t_ = t; forward_ = forward; params_ = _params; paramIsFixed_ = new InitializedList <bool>(paramIsFixed.Count, false); weights_ = new List <double>(); error_ = null; maxError_ = null; XABREndCriteria_ = EndCriteria.Type.None; Utils.QL_REQUIRE(t > 0.0, () => "expiry time must be positive: " + t + " not allowed"); Utils.QL_REQUIRE(_params.Count == FastActivator <Model> .Create().dimension(), () => "wrong number of parameters (" + _params.Count + "), should be " + FastActivator <Model> .Create().dimension()); Utils.QL_REQUIRE(paramIsFixed.Count == FastActivator <Model> .Create().dimension(), () => "wrong number of fixed parameters flags (" + paramIsFixed.Count + "), should be " + FastActivator <Model> .Create().dimension()); for (int i = 0; i < _params.Count; ++i) { if (_params[i] != null) { paramIsFixed_[i] = paramIsFixed[i]; } } FastActivator <Model> .Create().defaultValues(params_, paramIsFixed_, forward_, t_); updateModelInstance(); }