crosscurrencyswap::crosscurrencyswap( Type type, Currency fixedCurrency, Real fixedLegnominal, const Schedule& fixedSchedule, Rate fixedRate, const DayCounter& fixedDayCount, const boost::shared_ptr<IborIndex>& fixedIborIndex, Currency floatCurrency, Real floatLegnominal, const Schedule& floatSchedule, const boost::shared_ptr<IborIndex>& floatIborIndex, Spread spread, const DayCounter& floatingDayCount, boost::optional<BusinessDayConvention> paymentConvention) : Swap(2), type_(type), fixedCurrency_(fixedCurrency),Fixedlegnominal_(fixedLegnominal), fixedSchedule_(fixedSchedule), fixedRate_(fixedRate), fixedDayCount_(fixedDayCount), fixedIborIndex_(fixedIborIndex), floatCurrency_(floatCurrency), Floatlegnominal_(floatLegnominal), floatingSchedule_(floatSchedule), floatIborIndex_(floatIborIndex), spread_(spread), floatingDayCount_(floatingDayCount) { if (paymentConvention) paymentConvention_ = *paymentConvention; else paymentConvention_ = floatingSchedule_.businessDayConvention(); legs_[0] = FixedRateLeg(fixedSchedule_) .withNotionals(Fixedlegnominal_) .withCouponRates(fixedRate_, fixedDayCount_) .withPaymentAdjustment(paymentConvention_); legs_[1] = IborLeg(floatingSchedule_, floatIborIndex_) .withNotionals(Floatlegnominal_) .withPaymentDayCounter(floatingDayCount_) .withPaymentAdjustment(paymentConvention_) .withSpreads(spread_); for (Leg::const_iterator i = legs_[1].begin(); i < legs_[1].end(); ++i) registerWith(*i); switch (type_) { case Payer: payer_[0] = -1.0; payer_[1] = +1.0; break; case Receiver: payer_[0] = +1.0; payer_[1] = -1.0; break; default: QL_FAIL("Unknown Cross Currency Swap type"); } }
std::vector<Real> cap_floor(Date evaluationDate, CapFloor::Type type, Real strike, Real nominal, Schedule schedule, Natural fixingDays, BusinessDayConvention convention, boost::shared_ptr<IborIndex> index, boost::shared_ptr<YieldTermStructure> termStructure, Volatility volatility) { Date todaysDate = evaluationDate; Settings::instance().evaluationDate() = todaysDate; std::vector<Real> nominals = std::vector<Real>(1, nominal); /*Make Leg*/ Leg leg = IborLeg(schedule, index) .withNotionals(nominals) .withPaymentDayCounter(index->dayCounter()) .withPaymentAdjustment(convention) .withFixingDays(fixingDays); /*Make Engine*/ Handle<Quote> vol(boost::shared_ptr<Quote>(new SimpleQuote(volatility))); boost::shared_ptr<PricingEngine> engine = boost::shared_ptr<PricingEngine>(new BlackCapFloorEngine(Handle<YieldTermStructure>(termStructure), vol)); /*Pricing*/ boost::shared_ptr<CapFloor> testProduct; switch (type) { case CapFloor::Cap: testProduct = boost::shared_ptr<CapFloor>(new Cap(leg, std::vector<Rate>(1, strike))); break; case CapFloor::Floor: testProduct = boost::shared_ptr<CapFloor>(new Floor(leg, std::vector<Rate>(1, strike))); break; default: QL_FAIL("unknown cap/floor type"); } testProduct->setPricingEngine(engine); std::vector<Real> rst; rst.push_back(testProduct->NPV()); return rst; }
void IBOROISBasisSwap::initialize() { legs_[0] = IborLeg(floatingSchedule_, iborIndex_) .withNotionals(nominals_) .withPaymentDayCounter(floatingDayCount_) .withPaymentAdjustment(paymentConvention_); legs_[1] = OvernightLeg(overnightSchedule_, overnightIndex_) .withNotionals(nominals_) .withPaymentDayCounter(overnightDayCount_) .withPaymentAdjustment(paymentConvention_) .withSpreads(spread_); if(arithmeticAveragedCoupon_) { boost::shared_ptr<FloatingRateCouponPricer> arithmeticPricer( new ArithmeticAveragedOvernightIndexedCouponPricer()); for(Size i = 0; i < legs_[1].size(); i++) { boost::shared_ptr<OvernightIndexedCoupon> c = boost::dynamic_pointer_cast<OvernightIndexedCoupon> (legs_[1][i]); c->setPricer(arithmeticPricer); } } for (Size j=0; j<2; ++j) { for (Leg::iterator i = legs_[j].begin(); i!= legs_[j].end(); ++i) registerWith(*i); } switch (type_) { case Payer: payer_[0] = -1.0; payer_[1] = +1.0; break; case Receiver: payer_[0] = +1.0; payer_[1] = -1.0; break; default: QL_FAIL("Unknown overnight-basis-swap type"); } }
FloatingCatBond::FloatingCatBond( Natural settlementDays, Real faceAmount, const Schedule& schedule, const boost::shared_ptr<IborIndex>& iborIndex, const DayCounter& paymentDayCounter, boost::shared_ptr<NotionalRisk> notionalRisk, BusinessDayConvention paymentConvention, Natural fixingDays, const std::vector<Real>& gearings, const std::vector<Spread>& spreads, const std::vector<Rate>& caps, const std::vector<Rate>& floors, bool inArrears, Real redemption, const Date& issueDate) : CatBond(settlementDays, schedule.calendar(), issueDate, notionalRisk) { maturityDate_ = schedule.endDate(); cashflows_ = IborLeg(schedule, iborIndex) .withNotionals(faceAmount) .withPaymentDayCounter(paymentDayCounter) .withPaymentAdjustment(paymentConvention) .withFixingDays(fixingDays) .withGearings(gearings) .withSpreads(spreads) .withCaps(caps) .withFloors(floors) .inArrears(inArrears); addRedemptionsToCashflows(std::vector<Real>(1, redemption)); QL_ENSURE(!cashflows().empty(), "bond with no cashflows!"); QL_ENSURE(redemptions_.size() == 1, "multiple redemptions created"); registerWith(iborIndex); }
MakeCms::operator boost::shared_ptr<Swap>() const { Date startDate; if (effectiveDate_ != Date()) startDate = effectiveDate_; else { Natural fixingDays = iborIndex_->fixingDays(); Date refDate = Settings::instance().evaluationDate(); // if the evaluation date is not a business day // then move to the next business day refDate = floatCalendar_.adjust(refDate); Date spotDate = floatCalendar_.advance(refDate, fixingDays*Days); startDate = spotDate+forwardStart_; } Date terminationDate = startDate+swapTenor_; Schedule cmsSchedule(startDate, terminationDate, cmsTenor_, cmsCalendar_, cmsConvention_, cmsTerminationDateConvention_, cmsRule_, cmsEndOfMonth_, cmsFirstDate_, cmsNextToLastDate_); Schedule floatSchedule(startDate, terminationDate, floatTenor_, floatCalendar_, floatConvention_, floatTerminationDateConvention_, floatRule_ , floatEndOfMonth_, floatFirstDate_, floatNextToLastDate_); Leg cmsLeg = CmsLeg(cmsSchedule, swapIndex_) .withNotionals(nominal_) .withPaymentDayCounter(cmsDayCount_) .withPaymentAdjustment(cmsConvention_) .withFixingDays(swapIndex_->fixingDays()) .withGearings(cmsGearing_) .withSpreads(cmsSpread_) .withCaps(cmsCap_) .withFloors(cmsFloor_); if (couponPricer_) setCouponPricer(cmsLeg, couponPricer_); Rate usedSpread = iborSpread_; if (useAtmSpread_) { QL_REQUIRE(!iborIndex_->forwardingTermStructure().empty(), "null term structure set to this instance of " << iborIndex_->name()); QL_REQUIRE(!swapIndex_->forwardingTermStructure().empty(), "null term structure set to this instance of " << swapIndex_->name()); QL_REQUIRE(couponPricer_, "no CmsCouponPricer set (yet)"); Leg floatLeg = IborLeg(floatSchedule, iborIndex_) .withNotionals(nominal_) .withPaymentDayCounter(floatDayCount_) .withPaymentAdjustment(floatConvention_) .withFixingDays(iborIndex_->fixingDays()); Swap temp(cmsLeg, floatLeg); temp.setPricingEngine(engine_); Real npv = temp.legNPV(0)+temp.legNPV(1); usedSpread = -npv/temp.legBPS(1)*1e-4; } else { QL_REQUIRE(usedSpread != Null<Spread>(), "null spread set"); } Leg floatLeg = IborLeg(floatSchedule, iborIndex_) .withNotionals(nominal_) .withPaymentDayCounter(floatDayCount_) .withPaymentAdjustment(floatConvention_) .withFixingDays(iborIndex_->fixingDays()) .withSpreads(usedSpread); boost::shared_ptr<Swap> swap; if (payCms_) swap = boost::shared_ptr<Swap>(new Swap(cmsLeg, floatLeg)); else swap = boost::shared_ptr<Swap>(new Swap(floatLeg, cmsLeg)); swap->setPricingEngine(engine_); return swap; }
AssetSwap::AssetSwap(bool parSwap, const boost::shared_ptr<Bond>& bond, Real bondCleanPrice, Real nonParRepayment, Real gearing, const boost::shared_ptr<IborIndex>& iborIndex, Spread spread, const DayCounter& floatingDayCounter, Date dealMaturity, bool payBondCoupon) : Swap(2), bond_(bond), bondCleanPrice_(bondCleanPrice), nonParRepayment_(nonParRepayment), spread_(spread), parSwap_(parSwap) { Schedule tempSch(bond_->settlementDate(), bond_->maturityDate(), iborIndex->tenor(), iborIndex->fixingCalendar(), iborIndex->businessDayConvention(), iborIndex->businessDayConvention(), DateGeneration::Backward, false); // endOfMonth if (dealMaturity==Date()) dealMaturity = bond_->maturityDate(); QL_REQUIRE(dealMaturity <= tempSch.dates().back(), "deal maturity " << dealMaturity << " cannot be later than (adjusted) bond maturity " << tempSch.dates().back()); // the following might become an input parameter BusinessDayConvention paymentAdjustment = Following; Date finalDate = tempSch.calendar().adjust( dealMaturity, paymentAdjustment); Schedule schedule = tempSch.until(finalDate); // bondCleanPrice must be the (forward) clean price // at the floating schedule start date upfrontDate_ = schedule.startDate(); Real dirtyPrice = bondCleanPrice_ + bond_->accruedAmount(upfrontDate_); Real notional = bond_->notional(upfrontDate_); /* In the market asset swap, the bond is purchased in return for payment of the full price. The notional of the floating leg is then scaled by the full price. */ if (!parSwap_) notional *= dirtyPrice/100.0; if (floatingDayCounter==DayCounter()) legs_[1] = IborLeg(schedule, iborIndex) .withNotionals(notional) .withPaymentAdjustment(paymentAdjustment) .withGearings(gearing) .withSpreads(spread); else legs_[1] = IborLeg(schedule, iborIndex) .withNotionals(notional) .withPaymentDayCounter(floatingDayCounter) .withPaymentAdjustment(paymentAdjustment) .withGearings(gearing) .withSpreads(spread); for (Leg::const_iterator i=legs_[1].begin(); i<legs_[1].end(); ++i) registerWith(*i); const Leg& bondLeg = bond_->cashflows(); Leg::const_iterator i = bondLeg.begin(); // skip bond redemption for (; i<bondLeg.end()-1 && (*i)->date()<=dealMaturity; ++i) { // whatever might be the choice for the discounting engine // bond flows on upfrontDate_ must be discarded bool upfrontDateBondFlows = false; if (!(*i)->hasOccurred(upfrontDate_, upfrontDateBondFlows)) legs_[0].push_back(*i); } // if the first skipped cashflow is not the redemption // and it is a coupon then add the accrued coupon if (i<bondLeg.end()-1) { shared_ptr<Coupon> c = boost::dynamic_pointer_cast<Coupon>(*i); if (c) { shared_ptr<CashFlow> accruedCoupon(new SimpleCashFlow(c->accruedAmount(dealMaturity), finalDate)); legs_[0].push_back(accruedCoupon); } } // add the nonParRepayment_ shared_ptr<CashFlow> nonParRepaymentFlow(new SimpleCashFlow(nonParRepayment_, finalDate)); legs_[0].push_back(nonParRepaymentFlow); QL_REQUIRE(!legs_[0].empty(), "empty bond leg to start with"); // special flows if (parSwap_) { // upfront on the floating leg Real upfront = (dirtyPrice-100.0)/100.0*notional; shared_ptr<CashFlow> upfrontCashFlow(new SimpleCashFlow(upfront, upfrontDate_)); legs_[1].insert(legs_[1].begin(), upfrontCashFlow); // backpayment on the floating leg // (accounts for non-par redemption, if any) Real backPayment = notional; shared_ptr<CashFlow> backPaymentCashFlow(new SimpleCashFlow(backPayment, finalDate)); legs_[1].push_back(backPaymentCashFlow); } else { // final notional exchange shared_ptr<CashFlow> finalCashFlow (new SimpleCashFlow(notional, finalDate)); legs_[1].push_back(finalCashFlow); } QL_REQUIRE(!legs_[0].empty(), "empty bond leg"); for (Leg::const_iterator i=legs_[0].begin(); i<legs_[0].end(); ++i) registerWith(*i); if (payBondCoupon) { payer_[0]=-1.0; payer_[1]=+1.0; } else { payer_[0]=+1.0; payer_[1]=-1.0; } }
AssetSwap::AssetSwap(bool payBondCoupon, const shared_ptr<Bond>& bond, Real bondCleanPrice, const shared_ptr<IborIndex>& iborIndex, Spread spread, const Schedule& floatSchedule, const DayCounter& floatingDayCounter, bool parSwap) : Swap(2), bond_(bond), bondCleanPrice_(bondCleanPrice), nonParRepayment_(100), spread_(spread), parSwap_(parSwap) { Schedule schedule = floatSchedule; if (floatSchedule.empty()) schedule = Schedule(bond_->settlementDate(), bond_->maturityDate(), iborIndex->tenor(), iborIndex->fixingCalendar(), iborIndex->businessDayConvention(), iborIndex->businessDayConvention(), DateGeneration::Backward, false); // endOfMonth // the following might become an input parameter BusinessDayConvention paymentAdjustment = Following; Date finalDate = schedule.calendar().adjust( schedule.endDate(), paymentAdjustment); Date adjBondMaturityDate = schedule.calendar().adjust( bond_->maturityDate(), paymentAdjustment); QL_REQUIRE(finalDate==adjBondMaturityDate, "adjusted schedule end date (" << finalDate << ") must be equal to adjusted bond maturity date (" << adjBondMaturityDate << ")"); // bondCleanPrice must be the (forward) clean price // at the floating schedule start date upfrontDate_ = schedule.startDate(); Real dirtyPrice = bondCleanPrice_ + bond_->accruedAmount(upfrontDate_); Real notional = bond_->notional(upfrontDate_); /* In the market asset swap, the bond is purchased in return for payment of the full price. The notional of the floating leg is then scaled by the full price. */ if (!parSwap_) notional *= dirtyPrice/100.0; if (floatingDayCounter==DayCounter()) legs_[1] = IborLeg(schedule, iborIndex) .withNotionals(notional) .withPaymentAdjustment(paymentAdjustment) .withSpreads(spread); else legs_[1] = IborLeg(schedule, iborIndex) .withNotionals(notional) .withPaymentDayCounter(floatingDayCounter) .withPaymentAdjustment(paymentAdjustment) .withSpreads(spread); for (Leg::const_iterator i=legs_[1].begin(); i<legs_[1].end(); ++i) registerWith(*i); const Leg& bondLeg = bond_->cashflows(); for (Leg::const_iterator i=bondLeg.begin(); i<bondLeg.end(); ++i) { // whatever might be the choice for the discounting engine // bond flows on upfrontDate_ must be discarded bool upfrontDateBondFlows = false; if (!(*i)->hasOccurred(upfrontDate_, upfrontDateBondFlows)) legs_[0].push_back(*i); } QL_REQUIRE(!legs_[0].empty(), "empty bond leg to start with"); // special flows if (parSwap_) { // upfront on the floating leg Real upfront = (dirtyPrice-100.0)/100.0*notional; shared_ptr<CashFlow> upfrontCashFlow(new SimpleCashFlow(upfront, upfrontDate_)); legs_[1].insert(legs_[1].begin(), upfrontCashFlow); // backpayment on the floating leg // (accounts for non-par redemption, if any) Real backPayment = notional; shared_ptr<CashFlow> backPaymentCashFlow(new SimpleCashFlow(backPayment, finalDate)); legs_[1].push_back(backPaymentCashFlow); } else { // final notional exchange shared_ptr<CashFlow> finalCashFlow(new SimpleCashFlow(notional, finalDate)); legs_[1].push_back(finalCashFlow); } QL_REQUIRE(!legs_[0].empty(), "empty bond leg"); for (Leg::const_iterator i=legs_[0].begin(); i<legs_[0].end(); ++i) registerWith(*i); if (payBondCoupon) { payer_[0]=-1.0; payer_[1]=+1.0; } else { payer_[0]=+1.0; payer_[1]=-1.0; } }
FloatingRateBond::FloatingRateBond( Natural settlementDays, Real faceAmount, const Date& startDate, const Date& maturityDate, Frequency couponFrequency, const Calendar& calendar, const ext::shared_ptr<IborIndex>& iborIndex, const DayCounter& accrualDayCounter, BusinessDayConvention accrualConvention, BusinessDayConvention paymentConvention, Natural fixingDays, const std::vector<Real>& gearings, const std::vector<Spread>& spreads, const std::vector<Rate>& caps, const std::vector<Rate>& floors, bool inArrears, Real redemption, const Date& issueDate, const Date& stubDate, DateGeneration::Rule rule, bool endOfMonth) : Bond(settlementDays, calendar, issueDate) { maturityDate_ = maturityDate; Date firstDate, nextToLastDate; switch (rule) { case DateGeneration::Backward: firstDate = Date(); nextToLastDate = stubDate; break; case DateGeneration::Forward: firstDate = stubDate; nextToLastDate = Date(); break; case DateGeneration::Zero: case DateGeneration::ThirdWednesday: case DateGeneration::Twentieth: case DateGeneration::TwentiethIMM: QL_FAIL("stub date (" << stubDate << ") not allowed with " << rule << " DateGeneration::Rule"); default: QL_FAIL("unknown DateGeneration::Rule (" << Integer(rule) << ")"); } Schedule schedule(startDate, maturityDate_, Period(couponFrequency), calendar_, accrualConvention, accrualConvention, rule, endOfMonth, firstDate, nextToLastDate); cashflows_ = IborLeg(schedule, iborIndex) .withNotionals(faceAmount) .withPaymentDayCounter(accrualDayCounter) .withPaymentAdjustment(paymentConvention) .withFixingDays(fixingDays) .withGearings(gearings) .withSpreads(spreads) .withCaps(caps) .withFloors(floors) .inArrears(inArrears); addRedemptionsToCashflows(std::vector<Real>(1, redemption)); QL_ENSURE(!cashflows().empty(), "bond with no cashflows!"); QL_ENSURE(redemptions_.size() == 1, "multiple redemptions created"); registerWith(iborIndex); }
void NonstandardSwap::init() { QL_REQUIRE(fixedNominal_.size() == fixedRate_.size(), "Fixed nominal size (" << fixedNominal_.size() << ") does not match fixed rate size (" << fixedRate_.size() << ")"); QL_REQUIRE(fixedNominal_.size() == fixedSchedule_.size() - 1, "Fixed nominal size (" << fixedNominal_.size() << ") does not match schedule size (" << fixedSchedule_.size() << ") - 1"); QL_REQUIRE(floatingNominal_.size() == floatingSchedule_.size() - 1, "Floating nominal size (" << floatingNominal_.size() << ") does not match schedule size (" << floatingSchedule_.size() << ") - 1"); QL_REQUIRE(floatingNominal_.size() == spread_.size(), "Floating nominal size (" << floatingNominal_.size() << ") does not match spread size (" << spread_.size() << ")"); QL_REQUIRE(floatingNominal_.size() == gearing_.size(), "Floating nominal size (" << floatingNominal_.size() << ") does not match gearing size (" << gearing_.size() << ")"); // if the gearing is zero then the ibor leg will be set up with fixed // coupons which makes trouble here in this context. We therefore use // a dirty trick and enforce the gearing to be non zero. for (Size i = 0; i < gearing_.size(); ++i) { if (close(gearing_[i], 0.0)) gearing_[i] = QL_EPSILON; } legs_[0] = FixedRateLeg(fixedSchedule_) .withNotionals(fixedNominal_) .withCouponRates(fixedRate_, fixedDayCount_) .withPaymentAdjustment(paymentConvention_); legs_[1] = IborLeg(floatingSchedule_, iborIndex_) .withNotionals(floatingNominal_) .withPaymentDayCounter(floatingDayCount_) .withPaymentAdjustment(paymentConvention_) .withSpreads(spread_) .withGearings(gearing_); if (intermediateCapitalExchange_) { for (Size i = 0; i < legs_[0].size() - 1; i++) { Real cap = fixedNominal_[i + 1] - fixedNominal_[i]; if (!close(cap, 0.0)) { std::vector<boost::shared_ptr<CashFlow> >::iterator it1 = legs_[0].begin(); std::advance(it1, i + 1); legs_[0].insert( it1, boost::shared_ptr<CashFlow>( new Redemption(cap, legs_[0][i]->date()))); std::vector<Real>::iterator it2 = fixedNominal_.begin(); std::advance(it2, i + 1); fixedNominal_.insert(it2, fixedNominal_[i]); i++; } } for (Size i = 0; i < legs_[1].size() - 1; i++) { Real cap = floatingNominal_[i + 1] - floatingNominal_[i]; if (!close(cap, 0.0)) { std::vector<boost::shared_ptr<CashFlow> >::iterator it1 = legs_[1].begin(); std::advance(it1, i + 1); legs_[1].insert( it1, boost::shared_ptr<CashFlow>( new Redemption(cap, legs_[1][i]->date()))); std::vector<Real>::iterator it2 = floatingNominal_.begin(); std::advance(it2, i + 1); floatingNominal_.insert(it2, floatingNominal_[i]); i++; } } } if (finalCapitalExchange_) { legs_[0].push_back(boost::shared_ptr<CashFlow>( new Redemption(fixedNominal_.back(), legs_[0].back()->date()))); fixedNominal_.push_back(fixedNominal_.back()); fixedRate_.push_back(0.0); legs_[1].push_back(boost::shared_ptr<CashFlow>(new Redemption( floatingNominal_.back(), legs_[1].back()->date()))); floatingNominal_.push_back(floatingNominal_.back()); } for (Leg::const_iterator i = legs_[1].begin(); i < legs_[1].end(); ++i) registerWith(*i); switch (type_) { case VanillaSwap::Payer: payer_[0] = -1.0; payer_[1] = +1.0; break; case VanillaSwap::Receiver: payer_[0] = +1.0; payer_[1] = -1.0; break; default: QL_FAIL("Unknown nonstandard-swap type"); } }
std::vector<Real> power_spread_swap(Date evaluationDate, Real notional, PowerSpreadSwap::Side side, Rate alpha, Schedule floatingSchedule, Schedule fixedSchedule, DayCounter dayCounter, BusinessDayConvention bdc, std::vector<Real> gearing, std::vector<Real> spread, std::vector<Real> caps, std::vector<Real> floors, bool isAvg, Date firstCallDate, Real pastFixing, Rate floatingFixingRate, Real floatingGearing, DayCounter floatingDayCounter, boost::shared_ptr<StochasticProcess1D> obs1Process, boost::shared_ptr<StochasticProcess1D> obs2Process, YieldCurveParams disc, Real rho12, Real rho1disc, Real rho2disc, Size numSimulation, Size numCalibration) { Date todaysDate = evaluationDate; Settings::instance().evaluationDate() = todaysDate; boost::shared_ptr<IborIndex> index1(new Euribor3M(Handle<YieldTermStructure>( disc.yts ))); boost::shared_ptr<SpreadIndex> index(new SpreadIndex(index1, index1)); boost::shared_ptr<Callability> callability(new Callability(Callability::Price(notional, Callability::Price::Clean), Callability::Call, firstCallDate)); CallabilitySchedule callSchedule; callSchedule.push_back(callability); boost::shared_ptr<StochasticProcess1D> discProcess(new HullWhiteProcess(Handle<YieldTermStructure>(disc.yts), disc.hwParams.a, disc.hwParams.sigma)); /***********************************************************************************/ Leg floatingcashflows = IborLeg(floatingSchedule, index1) .withNotionals(notional) .withPaymentDayCounter(floatingDayCounter) .withPaymentAdjustment(bdc) .withSpreads(alpha) .withGearings(floatingGearing) .withPaymentAdjustment(bdc); PowerSpreadSwap testProduct(0, notional, side, floatingSchedule, floatingcashflows, alpha, fixedSchedule, index, dayCounter, bdc, Null<Natural>(), gearing, spread, caps, floors, isAvg, 100.0, Date(), callSchedule, Exercise::Bermudan); /*****Pricing Engine*****/ std::vector<boost::shared_ptr<StochasticProcess1D> > pros; pros.push_back(discProcess); pros.push_back(obs1Process); pros.push_back(obs2Process); Matrix corr(3,3,1.0); corr[0][1] = corr[1][0] = rho1disc; corr[0][2] = corr[2][0] = rho2disc; corr[1][2] = corr[2][1] = rho12; boost::shared_ptr<StochasticProcessArray> processes(new StochasticProcessArray(pros, corr)); boost::shared_ptr<PricingEngine> engine_lsmc(new MC_PowerSpread_Swap_Engine_LSMC<>(processes, 0.03, //pastFixing 0.03, 256, //seed numSimulation, //required samples numCalibration, //calibration samples true, //antithetic false, //control variate false //brownian bridge )); testProduct.setPricingEngine(engine_lsmc); std::vector<Real> rst; rst.push_back(testProduct.NPV()); rst.push_back(testProduct.errorEstimate()); return rst; }