/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl This file is part of QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ QuantLib is free software: you can redistribute it and/or modify it under the terms of the QuantLib license. You should have received a copy of the license along with this program; if not, please email . The license is also available online at . This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ #include #include #include #include #include namespace QuantLib { namespace { class HimalayaPathPricer : public PathPricer { public: HimalayaPathPricer(Real strike, DiscountFactor discount) : strike_(strike), discount_(discount) { QL_REQUIRE(strike>=0.0, "negative strike given"); } Real operator()(const MultiPath& multiPath) const { Size numAssets = multiPath.assetNumber(); Size numNodes = multiPath.pathSize(); QL_REQUIRE(numAssets>0, "no asset given"); Size i, j; std::vector prices(numAssets); for (j=0; j remainingAssets(numAssets, true); Real averagePrice = 0.0; Real bestPrice; Size removeAsset; Size fixings = numNodes-1; if (multiPath[0].timeGrid().mandatoryTimes()[0] == 0.0) { bestPrice = 0.0; // dummy assignement to avoid compiler warning removeAsset=0; for (j = 0; j < numAssets; j++) { if (prices[j] >= bestPrice) { bestPrice = prices[j]; removeAsset = j; } } remainingAssets[removeAsset] = false; averagePrice += bestPrice; fixings = numNodes; } for (i = 1; i < numNodes; i++) { bestPrice = 0.0; // dummy assignement to avoid compiler warning removeAsset=0; for (j = 0; j < numAssets; j++) { if (remainingAssets[j]) { prices[j] = multiPath[j][i]; if (prices[j] >= bestPrice) { bestPrice = prices[j]; removeAsset = j; } } } remainingAssets[removeAsset] = false; averagePrice += bestPrice; } averagePrice /= std::min(fixings, numAssets); Real optPrice = std::max(averagePrice - strike_, 0.0); return discount_ * optPrice; } private: Real strike_; DiscountFactor discount_; }; } McHimalaya::McHimalaya( const std::vector& underlying, const std::vector >& dividendYield, const Handle& riskFreeRate, const std::vector >& volatilities, const Matrix& correlation, Real strike, const std::vector