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));
    }
Exemple #2
0
    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);
    }
Exemple #3
0
    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> &currentWeight = 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;
    }