CallSpecifiedMultiProduct::CallSpecifiedMultiProduct( const Clone<MarketModelMultiProduct>& underlying, const Clone<ExerciseStrategy<CurveState> >& strategy, const Clone<MarketModelMultiProduct>& rebate) : underlying_(underlying), strategy_(strategy), rebate_(rebate), callable_(true) { Size products = underlying_->numberOfProducts(); EvolutionDescription d1 = underlying->evolution(); const std::vector<Time>& rateTimes1 = d1.rateTimes(); const std::vector<Time>& evolutionTimes1 = d1.evolutionTimes(); const std::vector<Time>& exerciseTimes = strategy->exerciseTimes(); if (!rebate_.empty()) { EvolutionDescription d2 = rebate_->evolution(); const std::vector<Time>& rateTimes2 = d2.rateTimes(); QL_REQUIRE(rateTimes1.size() == rateTimes2.size() && std::equal(rateTimes1.begin(), rateTimes1.end(), rateTimes2.begin()), "incompatible rate times"); } else { EvolutionDescription description(rateTimes1, exerciseTimes); Matrix amounts(products, exerciseTimes.size(), 0.0); rebate_ = MarketModelCashRebate(description, exerciseTimes, amounts, products); } std::vector<Time> mergedEvolutionTimes; std::vector<std::vector<Time> > allEvolutionTimes(4); allEvolutionTimes[0] = evolutionTimes1; allEvolutionTimes[1] = exerciseTimes; allEvolutionTimes[2] = rebate_->evolution().evolutionTimes(); allEvolutionTimes[3] = strategy->relevantTimes(); mergeTimes(allEvolutionTimes, mergedEvolutionTimes, isPresent_); // TODO: add relevant rates evolution_ = EvolutionDescription(rateTimes1, mergedEvolutionTimes); cashFlowTimes_ = underlying_->possibleCashFlowTimes(); rebateOffset_ = cashFlowTimes_.size(); const std::vector<Time> rebateTimes = rebate_->possibleCashFlowTimes(); cashFlowTimes_.insert(cashFlowTimes_.end(), rebateTimes.begin(), rebateTimes.end()); dummyCashFlowsThisStep_ = std::vector<Size>(products, 0); Size n = rebate_->maxNumberOfCashFlowsPerProductPerStep(); dummyCashFlowsGenerated_ = std::vector<std::vector<CashFlow> >(products, std::vector<CashFlow>(n)); }
void ceil_out (Quality const& q, In1 in, Out1 out, Int limit, In2 in_expected, Out2 out_expected) { auto const expect_result (amounts (in_expected, out_expected)); auto const actual_result (q.ceil_out (amounts(in, out), amount(limit))); expect (actual_result == expect_result); }
void ceil_in (Quality const& q, In1 in, Out1 out, Int limit, In2 in_expected, Out2 out_expected) { auto expect_result (amounts (in_expected, out_expected)); auto actual_result (q.ceil_in ( amounts (in, out), amount (limit))); BEAST_EXPECT(actual_result == expect_result); }
void JamshidianSwaptionEngine::calculate() const { QL_REQUIRE(arguments_.settlementType==Settlement::Physical, "cash-settled swaptions not priced by Jamshidian engine"); QL_REQUIRE(arguments_.exercise->type() == Exercise::European, "cannot use the Jamshidian decomposition " "on exotic swaptions"); QL_REQUIRE(arguments_.swap->spread() == 0.0, "non zero spread (" << arguments_.swap->spread() << ") not allowed"); // PC Date referenceDate; DayCounter dayCounter; boost::shared_ptr<TermStructureConsistentModel> tsmodel = boost::dynamic_pointer_cast<TermStructureConsistentModel>(*model_); if (tsmodel) { referenceDate = tsmodel->termStructure()->referenceDate(); dayCounter = tsmodel->termStructure()->dayCounter(); } else { referenceDate = termStructure_->referenceDate(); dayCounter = termStructure_->dayCounter(); } std::vector<Real> amounts(arguments_.fixedCoupons); amounts.back() += arguments_.nominal; Real maturity = dayCounter.yearFraction(referenceDate, arguments_.exercise->date(0)); std::vector<Time> fixedPayTimes(arguments_.fixedPayDates.size()); Time valueTime = dayCounter.yearFraction(referenceDate,arguments_.fixedResetDates[0]); for (Size i=0; i<fixedPayTimes.size(); i++) fixedPayTimes[i] = dayCounter.yearFraction(referenceDate, arguments_.fixedPayDates[i]); rStarFinder finder(*model_, arguments_.nominal, maturity, valueTime, fixedPayTimes, amounts); Brent s1d; Rate minStrike = -10.0; Rate maxStrike = 10.0; s1d.setMaxEvaluations(10000); s1d.setLowerBound(minStrike); s1d.setUpperBound(maxStrike); Rate rStar = s1d.solve(finder, 1e-8, 0.05, minStrike, maxStrike); Option::Type w = arguments_.type==VanillaSwap::Payer ? Option::Put : Option::Call; Size size = arguments_.fixedCoupons.size(); Real value = 0.0; for (Size i=0; i<size; i++) { Real fixedPayTime = dayCounter.yearFraction(referenceDate, arguments_.fixedPayDates[i]); Real strike = model_->discountBond(maturity, fixedPayTime, rStar) / model_->discountBond(maturity,valueTime,rStar); Real dboValue = model_->discountBondOption( w, strike, maturity, valueTime, fixedPayTime); value += amounts[i]*dboValue; } results_.value = value; }
void optimize() { if(size.x == 0 || size.y == 0) return; boost::shared_ptr<filesystem::MemoryStreamBuffer> streamBuffer(new filesystem::MemoryStreamBuffer()); filesystem::OutputStream outputStream; outputStream.setBuffer(streamBuffer); filesystem::InputStream inputStream; inputStream.setBuffer(streamBuffer); for(int yb = 0; yb < blockAmount.y; ++yb) for(int xb = 0; xb < blockAmount.x; ++xb) { int xo = xb * (BLOCK_SIZE - 1); int yo = yb * (BLOCK_SIZE - 1); // Collect texture influences std::vector<OptimizeLayer> amounts(blendings.size()); { for(unsigned int i = 0; i < blendings.size(); ++i) { amounts[i].index = i; BlendStorage &blend = blendings[i]; for(int y = 0; y < BLOCK_SIZE; ++y) for(int x = 0; x < BLOCK_SIZE; ++x) { int index = (yo + y) * size.x + xo + x; int value = blend.weights[index]; /* if(value < 50) { value = 0; blend.weights[index] = 0; } */ amounts[i].order += value; } } std::sort(amounts.begin(), amounts.end(), OptimizeLayerSorter()); } // Normalize out all others { for(int y = 0; y < BLOCK_SIZE; ++y) for(int x = 0; x < BLOCK_SIZE; ++x) { int xp = xo + x; int yp = yo + y; if(xp < 0 || yp < 0 || xp >= size.x || yp >= size.y) continue; int index = yp * size.x + xp; int layerAmount = min(MAX_OPTIMIZE_LAYERS, int(amounts.size())); if(!layerAmount) continue; // Find highest amount of used textures (default 0) and normalize by // adding missing blend weights to it int highest = amounts[0].index; int highestAmount = blendings[highest].weights[index]; int combined = 0; if(highestAmount < 255) int a = 0; int i = 0; for(i = 0; i < layerAmount; ++i) { int current = blendings[amounts[i].index].weights[index]; combined += current; if(current > highestAmount) { highest = amounts[i].index; highestAmount = current; } } for(i = layerAmount; i < int(amounts.size()); ++i) blendings[amounts[i].index].weights[index] = 0; blendings[highest].weights[index] += 255 - combined; } } } /* // highest weight, texture index pairs for normalization std::vector<std::pair<int, int> > weights; // Amount of weights removed from given pixel std::vector<unsigned char> weightSub; weights.resize(size.x * size.y, std::pair<int, int> (-1, 0)); weightSub.resize(size.x * size.y); for(unsigned int i = 0; i < blendings.size(); ++i) { BlendStorage &blend = blendings[i]; for(unsigned int j = 0; j < blend.weights.size(); ++j) { std::pair<int, int> currentWeight(blend.weights[j], i); weights[j] = std::max(weights[j], currentWeight); if(blend.weights[j] < 75) { weightSub[j] += blend.weights[j]; blend.weights[j] = 0; } } } // Normalize for(unsigned int j = 0; j < weightSub.size(); ++j) { std::pair<int, int> ¤tWeight = weights[j]; if(currentWeight.second < 0) continue; blendings[currentWeight.second].weights[j] += weightSub[j]; } */ write(outputStream); read(inputStream); }
void Gaussian1dJamshidianSwaptionEngine::calculate() const { QL_REQUIRE(arguments_.settlementType == Settlement::Physical, "cash-settled swaptions not priced by Jamshidian engine"); QL_REQUIRE(arguments_.exercise->type() == Exercise::European, "cannot use the Jamshidian decomposition " "on exotic swaptions"); QL_REQUIRE(arguments_.swap->spread() == 0.0, "non zero spread (" << arguments_.swap->spread() << ") not allowed"); // PC Date referenceDate; DayCounter dayCounter; referenceDate = model_->termStructure()->referenceDate(); dayCounter = model_->termStructure()->dayCounter(); std::vector<Real> amounts(arguments_.fixedCoupons); amounts.back() += arguments_.nominal; Size startIndex = std::upper_bound(arguments_.fixedResetDates.begin(), arguments_.fixedResetDates.end(), arguments_.exercise->date(0) - 1) - arguments_.fixedResetDates.begin(); // only consider coupons with start date >= exercise dates rStarFinder finder(*model_, arguments_.nominal, arguments_.exercise->date(0), arguments_.fixedResetDates[startIndex], arguments_.fixedPayDates, amounts, startIndex); Brent s1d; Rate minStrike = -8.0; Rate maxStrike = 8.0; s1d.setMaxEvaluations(10000); s1d.setLowerBound(minStrike); s1d.setUpperBound(maxStrike); Rate rStar = s1d.solve(finder, 1e-8, 0.00, minStrike, maxStrike); // this is actually yStar Option::Type w = arguments_.type == VanillaSwap::Payer ? Option::Put : Option::Call; Size size = arguments_.fixedCoupons.size(); Real value = 0.0; for (Size i = startIndex; i < size; i++) { // Real fixedPayTime = // dayCounter.yearFraction(referenceDate,arguments_.fixedPayDates[i]); Real strike = model_->zerobond(arguments_.fixedPayDates[i], arguments_.exercise->date(0), rStar) / model_->zerobond(arguments_.fixedResetDates[startIndex], arguments_.exercise->date(0), rStar); Real dboValue = model_->zerobondOption(w, arguments_.exercise->date(0), arguments_.fixedResetDates[startIndex], arguments_.fixedPayDates[i], strike); value += amounts[i] * dboValue; } results_.value = value; }