public DigitalIborCoupon(IborCoupon underlying, double?callStrike = null, Position.Type callPosition = Position.Type.Long, bool isCallATMIncluded = false, double?callDigitalPayoff = null, double?putStrike = null, Position.Type putPosition = Position.Type.Long, bool isPutATMIncluded = false, double?putDigitalPayoff = null, DigitalReplication replication = null) : base(underlying, callStrike, callPosition, isCallATMIncluded, callDigitalPayoff, putStrike, putPosition, isPutATMIncluded, putDigitalPayoff, replication) { }
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); }
// Factory - for Leg generators public virtual CashFlow factory(CmsCoupon underlying, double?callStrike, Position.Type callPosition, bool isCallATMIncluded, double?callDigitalPayoff, double?putStrike, Position.Type putPosition, bool isPutATMIncluded, double?putDigitalPayoff, DigitalReplication replication) { return(new DigitalCmsCoupon(underlying, callStrike, callPosition, isCallATMIncluded, callDigitalPayoff, putStrike, putPosition, isPutATMIncluded, putDigitalPayoff, replication)); }
public DigitalCmsLeg withReplication(DigitalReplication replication) { replication_ = replication; return(this); }
//! Constructors //! general constructor public DigitalCoupon(FloatingRateCoupon underlying, double?callStrike = null, Position.Type callPosition = Position.Type.Long, bool isCallATMIncluded = false, double?callDigitalPayoff = null, double?putStrike = null, Position.Type putPosition = Position.Type.Long, bool isPutATMIncluded = false, double?putDigitalPayoff = null, DigitalReplication replication = null) : base(underlying.date(), underlying.nominal(), underlying.accrualStartDate(), underlying.accrualEndDate(), underlying.fixingDays, underlying.index(), underlying.gearing(), underlying.spread(), underlying.referencePeriodStart, underlying.referencePeriodEnd, underlying.dayCounter(), underlying.isInArrears()) { if (replication == null) { replication = new DigitalReplication(); } underlying_ = underlying; callCsi_ = 0.0; putCsi_ = 0.0; isCallATMIncluded_ = isCallATMIncluded; isPutATMIncluded_ = isPutATMIncluded; isCallCashOrNothing_ = false; isPutCashOrNothing_ = false; callLeftEps_ = replication.gap() / 2.0; callRightEps_ = replication.gap() / 2.0; putLeftEps_ = replication.gap() / 2.0; putRightEps_ = replication.gap() / 2.0; hasPutStrike_ = false; hasCallStrike_ = false; replicationType_ = replication.replicationType(); Utils.QL_REQUIRE(replication.gap() > 0.0, () => "Non positive epsilon not allowed"); if (putStrike == null) { Utils.QL_REQUIRE(putDigitalPayoff == null, () => "Put Cash rate non allowed if put strike is null"); } if (callStrike == null) { Utils.QL_REQUIRE(callDigitalPayoff == null, () => "Call Cash rate non allowed if call strike is null"); } if (callStrike != null) { Utils.QL_REQUIRE(callStrike >= 0.0, () => "negative call strike not allowed"); hasCallStrike_ = true; callStrike_ = callStrike.GetValueOrDefault(); Utils.QL_REQUIRE(callStrike_ >= replication.gap() / 2.0, () => "call strike < eps/2"); switch (callPosition) { case Position.Type.Long: callCsi_ = 1.0; break; case Position.Type.Short: callCsi_ = -1.0; break; default: Utils.QL_FAIL("unsupported position type"); break; } if (callDigitalPayoff != null) { callDigitalPayoff_ = callDigitalPayoff.GetValueOrDefault(); isCallCashOrNothing_ = true; } } if (putStrike != null) { Utils.QL_REQUIRE(putStrike >= 0.0, () => "negative put strike not allowed"); hasPutStrike_ = true; putStrike_ = putStrike.GetValueOrDefault(); switch (putPosition) { case Position.Type.Long: putCsi_ = 1.0; break; case Position.Type.Short: putCsi_ = -1.0; break; default: Utils.QL_FAIL("unsupported position type"); break; } if (putDigitalPayoff != null) { putDigitalPayoff_ = putDigitalPayoff.GetValueOrDefault(); isPutCashOrNothing_ = true; } } switch (replicationType_) { case Replication.Type.Central: // do nothing break; case Replication.Type.Sub: if (hasCallStrike_) { switch (callPosition) { case Position.Type.Long: callLeftEps_ = 0.0; callRightEps_ = replication.gap(); break; case Position.Type.Short: callLeftEps_ = replication.gap(); callRightEps_ = 0.0; break; default: Utils.QL_FAIL("unsupported position type"); break; } } if (hasPutStrike_) { switch (putPosition) { case Position.Type.Long: putLeftEps_ = replication.gap(); putRightEps_ = 0.0; break; case Position.Type.Short: putLeftEps_ = 0.0; putRightEps_ = replication.gap(); break; default: Utils.QL_FAIL("unsupported position type"); break; } } break; case Replication.Type.Super: if (hasCallStrike_) { switch (callPosition) { case Position.Type.Long: callLeftEps_ = replication.gap(); callRightEps_ = 0.0; break; case Position.Type.Short: callLeftEps_ = 0.0; callRightEps_ = replication.gap(); break; default: Utils.QL_FAIL("unsupported position type"); break; } } if (hasPutStrike_) { switch (putPosition) { case Position.Type.Long: putLeftEps_ = 0.0; putRightEps_ = replication.gap(); break; case Position.Type.Short: putLeftEps_ = replication.gap(); putRightEps_ = 0.0; break; default: Utils.QL_FAIL("unsupported position type"); break; } } break; default: Utils.QL_FAIL("unsupported position type"); break; } underlying.registerWith(update); }