Exemple #1
0
 //! discount factor implied by the rate compounded between two dates
 DiscountFactor discountFactor(const Date& d1,
                               const Date& d2,
                               const Date& refStart = Date(),
                               const Date& refEnd = Date()) const {
     QL_REQUIRE(d2>=d1,
                "d1 (" << d1 << ") "
                "later than d2 (" << d2 << ")");
     Time t = dc_.yearFraction(d1, d2, refStart, refEnd);
     return discountFactor(t);
 }
Exemple #2
0
	Real LiborCurve::swapAnnuity(Size reference, Size fixing, Size length, Size payFreq) {
		QL_REQUIRE(reference<=fixing,"reference index " << reference << " must be leq fixing " << fixing);
		Size pf = payFreq;
		double sum=0.0;
		double p=1.0;
		for(int j=fixing;j<fixing+length;j++) {
			p*=1.0/(1.0+(rateTimes_[j+1]-rateTimes_[j])*rates_[j]);
			if(--pf == 0) { sum+=p*(rateTimes_[j+1]-rateTimes_[j+1-payFreq]); pf=payFreq; }
		}
		//printf("swap Annuity=%1.11f\n",discountFactor(reference,fixing)*sum);
		return discountFactor(reference,fixing)*sum;
	}
Exemple #3
0
    void FFTEngine::precalculate(const std::vector<boost::shared_ptr<Instrument> >& optionList) {
        // Group payoffs by expiry date
        // as with FFT we can compute a bunch of these at once
        resultMap_.clear();

        typedef std::vector<boost::shared_ptr<StrikedTypePayoff> > PayoffList;
        typedef std::map<Date, PayoffList> PayoffMap;
        PayoffMap payoffMap;
        
        for (std::vector<boost::shared_ptr<Instrument> >::const_iterator optIt = optionList.begin();
            optIt != optionList.end(); optIt++)
        {
            boost::shared_ptr<VanillaOption> option = boost::dynamic_pointer_cast<VanillaOption>(*optIt);
            QL_REQUIRE(option, "instrument must be option");
            QL_REQUIRE(option->exercise()->type() == Exercise::European,
                "not an European Option");

            boost::shared_ptr<StrikedTypePayoff> payoff =
                boost::dynamic_pointer_cast<StrikedTypePayoff>(option->payoff());
            QL_REQUIRE(payoff, "non-striked payoff given");

            payoffMap[option->exercise()->lastDate()].push_back(payoff);
        }

        std::complex<Real> i1(0, 1);
        Real alpha = 1.25;

        for (PayoffMap::const_iterator payIt = payoffMap.begin(); payIt != payoffMap.end(); payIt++)
        {
            Date expiryDate = payIt->first;

            // Calculate n large enough for maximum strike, and round up to a power of 2
            Real maxStrike = 0.0;
            for (PayoffList::const_iterator it = payIt->second.begin();
                it != payIt->second.end(); it++)
            {
                boost::shared_ptr<StrikedTypePayoff> payoff = *it;

                if (payoff->strike() > maxStrike)
                    maxStrike = payoff->strike();
            }
            Real nR = 2.0 * (std::log(maxStrike) + lambda_) / lambda_;
      Size log2_n = (static_cast<Size>((std::log(nR) / std::log(2.0))) + 1);
            Size n = 1 << log2_n;

            // Strike range (equation 19,20)
            Real b = n * lambda_ / 2.0;

            // Grid spacing (equation 23)
            Real eta = 2.0 * M_PI / (lambda_ * n);

            // Discount factor
            Real df = discountFactor(expiryDate);
            Real div = dividendYield(expiryDate);

            // Input to fourier transform
            std::vector<std::complex<Real> > fti;
            fti.resize(n);

            // Precalculate any discount factors etc.
            precalculateExpiry(expiryDate);

            for (Size i=0; i<n; i++)
            {
                Real k_u = -b + lambda_ * i;
                Real v_j = eta * i;
                Real sw = eta * (3.0 + ((i % 2) == 0 ? -1.0 : 1.0) - ((i == 0) ? 1.0 : 0.0)) / 3.0; 

                std::complex<Real> psi = df * complexFourierTransform(v_j - (alpha + 1)* i1);
                psi = psi / (alpha*alpha + alpha - v_j*v_j + i1 * (2 * alpha + 1.0) * v_j);

                fti[i] = std::exp(i1 * b * v_j)  * sw * psi;
            }

            // Perform fft
            std::vector<std::complex<Real> > results(n);
            FastFourierTransform fft(log2_n);
            fft.transform(fti.begin(), fti.end(), results.begin());

            // Call prices
            std::vector<Real> prices, strikes;
            prices.resize(n);
            strikes.resize(n);
            for (Size i=0; i<n; i++)
            {
                Real k_u = -b + lambda_ * i;
                prices[i] = (std::exp(-alpha * k_u) / M_PI) * results[i].real();
                strikes[i] = std::exp(k_u);
            }

            for (PayoffList::const_iterator it = payIt->second.begin();
                it != payIt->second.end(); it++)
            {
                boost::shared_ptr<StrikedTypePayoff> payoff = *it;

                Real callPrice = LinearInterpolation(strikes.begin(), strikes.end(), prices.begin())(payoff->strike());
                switch (payoff->optionType())
                {
                case Option::Call:
                    resultMap_[expiryDate][payoff] = callPrice;
                    break;
                case Option::Put:
                    resultMap_[expiryDate][payoff] = callPrice - process_->x0() * div + payoff->strike() * df;
                    break;
                default:
                    QL_FAIL("Invalid option type");
                }
            }
        }
    }
Exemple #4
0
	Real LiborCurve::swap2TerminalMeasure(Size reference, Size fixing, Size delay, Size length, Size payFreq) {
		return discountFactor(reference,fixing+delay)/discountFactorT0(0,fixing+delay) *
				  swapAnnuityT0(fixing,length,payFreq)/swapAnnuity(reference,fixing,length,payFreq);
	}
Exemple #5
0
	Real LiborCurve::rRate(Size reference, Size fixing, Size delay, Size length, Size payFreq) {
		QL_REQUIRE(reference<=fixing,"reference index " << reference << " must be leq fixing " << fixing);
		double sumD=rateTimes_[fixing+length]-rateTimes_[fixing];
		return swapAnnuityT0(fixing,length,payFreq)/(discountFactorT0(0,fixing+delay)*sumD)*
			(discountFactor(reference,fixing+delay)*sumD/swapAnnuity(reference,fixing,length,payFreq)-1.0);
	}
double CCRate::forwardRate(double t1, double t2) {
	double f = 1.0 / (t2 - t1) *
		(discountFactor(t1)
			/ discountFactor(t2) - 1);
	return f;
}