inline void MultiPathGeneratorFixedPath<GSG>::next() const 
	{
        typedef typename GSG::sample_type sequence_type;
        const sequence_type& sequence_ = generator_.nextSequence();

        Size m = process_->size();
        Size n = process_->factors();

        MultiPath& path = *nextPtr_;

        Array asset = process_->initialValues();
        
		for (Size j=0; j<m; j++)
            path[j].front() = asset[j];

        Array temp(n);

        TimeGrid timeGrid = path[0].timeGrid();
        Time t, dt;
        
		for (Size i = 1; i < path.pathSize(); i++) {
            Size offset = (i-1)*n;
            t = timeGrid[i-1];
            dt = timeGrid.dt(i-1);
            
			std::copy(sequence_.value.begin()+offset,
                            sequence_.value.begin()+offset+n,
                            temp.begin());

            asset = process_->evolve(t, asset, dt, temp,i-1);

            for (Size j=0; j<m; j++)
                path[j][i] = asset[j];
		}
    }
PathGeneratorFactory::PathGeneratorFactory(const boost::shared_ptr<StochasticProcessArray>& processes,
										   const TimeGrid& timeGrid)
: processes_(processes), grid_(timeGrid)
{
	unsigned long myseed = static_cast<unsigned long>(1);
	rand_ = std::tr1::mt19937(myseed);

	this->numAssets_ = processes->size();
	this->pathSize_ = timeGrid.size();

	PseudoRandom::rsg_type gen =
		PseudoRandom::make_sequence_generator(numAssets_*(timeGrid.size()-1),1);

	gen_ = boost::shared_ptr<MultiVariate<PseudoRandom>::path_generator_type>(new MultiVariate<PseudoRandom>::path_generator_type(processes,
                                timeGrid, gen, false));
				
	this->next_ = MultiPath(numAssets_,this->grid_);

	S0_ = std::valarray<double>(numAssets_);
	randArrs_ = std::valarray<double>(numAssets_);

	//this->testRandom_ = Array(numAssets_ * pathSize_);
	previousRand_ = Matrix(numAssets_, pathSize_);

	Matrix corr = processes->correlation();
	chol_=CholeskyDecomposition(corr);

	random_ = MultiPath(numAssets_,timeGrid);

	// num - 1
	this->muGrid_ = Matrix(numAssets_, timeGrid.size() - 1);
	this->volGrid_ = Matrix(numAssets_,timeGrid.size() - 1);

	antitheticFlag_ = false;

	for (Size asset = 0 ; asset<numAssets_ ;++asset)
	{
		//초기화 수익률 or 절대값
		S0_[asset] = processes->process(asset)->x0() / processes->process(asset)->basePrice();

		for (Size t = 0 ; t < pathSize_ - 1 ;++t)
		{
			double mu_t = processes->process(asset)->drift(timeGrid[t],1.0);
			double sigma_t = processes->process(asset)->diffusion(timeGrid[t],1.0);
			double dt_t = timeGrid.dt(t);

			// exp( ( mu[t] - 0.5 * vol[t] * vol[t] ) * dt[t] )
			muGrid_[asset][t] = std::exp( ( mu_t - 0.5 * sigma_t * sigma_t ) * dt_t );

			//  vol[t] * sqrt(dt[t]) 
			volGrid_[asset][t] = sigma_t * std::sqrt(dt_t);
		}

	}
}
コード例 #3
0
    Real DigitalPathPricer::operator()(const Path& path) const {
        Size n = path.length();
        QL_REQUIRE(n>1, "the path cannot be empty");

        Real log_asset_price = std::log(path.front());
        Real x, y;
        Volatility vol;
        TimeGrid timeGrid = path.timeGrid();
        Time dt;
        std::vector<Real> u = sequenceGen_.nextSequence().value;
        Real log_strike = std::log(payoff_->strike());

        Size i;
        switch (payoff_->optionType()) {
          case Option::Call:
            for (i=0; i<n-1; i++) {
                x = std::log(path[i+1]/path[i]);
                // terminal or initial vol?
                vol = diffProcess_->diffusion(timeGrid[i+1],
                                              std::exp(log_asset_price));
                // vol = diffProcess_->diffusion(timeGrid[i+2],
                //                               std::exp(log_asset_price+x));
                dt = timeGrid.dt(i);
                y = log_asset_price +
                    0.5*(x + std::sqrt(x*x-2*vol*vol*dt*std::log((1-u[i]))));
                // cross the strike
                if (y >= log_strike) {
                    if (exercise_->payoffAtExpiry()) {
                        return payoff_->cashPayoff() *
                            discountTS_->discount(path.timeGrid().back());
                    } else {
                        // the discount should be calculated at the exercise
                        // time between path.timeGrid()[i+1] and
                        // path.timeGrid()[i+2]
                        return payoff_->cashPayoff() *
                            discountTS_->discount(path.timeGrid()[i+1]);
                    }
                }
                log_asset_price += x;
            }
            break;
          case Option::Put:
            for (i=0; i<n-1; i++) {
                x = std::log(path[i+1]/path[i]);
                // terminal or initial vol?
                // initial (timeGrid[i+1]) for the time being
                vol = diffProcess_->diffusion(timeGrid[i+1],
                                              std::exp(log_asset_price));
                // vol = diffProcess_->diffusion(timeGrid[i+2],
                //                               std::exp(log_asset_price+x));
                dt = timeGrid.dt(i);
                y = log_asset_price +
                    0.5*(x - std::sqrt(x*x - 2*vol*vol*dt*std::log(u[i])));
                if (y <= log_strike) {
                    if (exercise_->payoffAtExpiry()) {
                        return payoff_->cashPayoff() *
                            discountTS_->discount(path.timeGrid().back());
                    } else {
                        // the discount should be calculated at the exercise
                        // time between path.timeGrid()[i+1] and
                        // path.timeGrid()[i+2]
                        return payoff_->cashPayoff() *
                            discountTS_->discount(path.timeGrid()[i+1]);
                    }
                }
                log_asset_price += x;
            }
            break;
          default:
            QL_FAIL("unknown option type");
        }

        return 0.0;
    }