[Rquantlib-commits] r267 - in pkg/RQuantLib: R man src

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Tue Jul 6 03:20:37 CEST 2010


Author: knguyen
Date: 2010-07-06 03:20:36 +0200 (Tue, 06 Jul 2010)
New Revision: 267

Modified:
   pkg/RQuantLib/R/asian.R
   pkg/RQuantLib/man/AsianOption.Rd
   pkg/RQuantLib/src/asian.cpp
Log:
asian arithmetic

Modified: pkg/RQuantLib/R/asian.R
===================================================================
--- pkg/RQuantLib/R/asian.R	2010-07-01 11:51:44 UTC (rev 266)
+++ pkg/RQuantLib/R/asian.R	2010-07-06 01:20:36 UTC (rev 267)
@@ -23,14 +23,16 @@
 ## MA 02111-1307, USA
 
 AsianOption <- function(averageType, type, underlying, strike, dividendYield,
-                           riskFreeRate, maturity, volatility,
-                           timeSteps=150, gridPoints=151) {
+                        riskFreeRate, maturity, volatility,
+                        first, length, fixings,
+                        timeSteps=150, gridPoints=151) {
     UseMethod("AsianOption")
 }
 
 AsianOption.default <- function(averageType, type, underlying, strike, dividendYield,
-                                   riskFreeRate, maturity, volatility,
-                                   timeSteps=150, gridPoints=151) {
+                                riskFreeRate, maturity, volatility,
+                                first=0, length=0, fixings=0,
+                                timeSteps=150, gridPoints=151) {
     averageType <- match.arg(averageType, c("geometric", "arithmetic"))
     type <- match.arg(type, c("call", "put"))
     val <- .Call("QL_AsianOption",
@@ -42,6 +44,9 @@
                       riskFreeRate=as.double(riskFreeRate),
                       maturity=as.double(maturity),
                       volatility=as.double(volatility),
+                      first=as.double(first),
+                      length=as.double(length),
+                      fixings=as.double(fixings),
                       timeSteps=as.integer(timeSteps),
                       gridPoints=as.integer(gridPoints)),
                  PACKAGE="RQuantLib")

Modified: pkg/RQuantLib/man/AsianOption.Rd
===================================================================
--- pkg/RQuantLib/man/AsianOption.Rd	2010-07-01 11:51:44 UTC (rev 266)
+++ pkg/RQuantLib/man/AsianOption.Rd	2010-07-06 01:20:36 UTC (rev 267)
@@ -12,7 +12,7 @@
 \usage{
 \method{AsianOption}{default}(averageType, type, underlying, strike,
 			                  dividendYield, riskFreeRate, maturity, 
-			                  volatility, timeSteps=150, gridPoints=151)
+			                  volatility, first=0, length=0, fixings=0, timeSteps=150, gridPoints=151)
 \method{plot}{Option}
 \method{print}{Option}
 \method{summary}{Option}
@@ -26,6 +26,9 @@
   \item{riskFreeRate}{Risk-free rate}
   \item{maturity}{Time to maturity (in fractional years)}
   \item{volatility}{Volatility of the underlying stock}
+  \item{first}{to be written}
+  \item{length}{to be written}
+  \item{fixings}{to be written}
   \item{timeSteps}{Time steps for the Finite Differences method, default value is 150}
   \item{gridPoints}{Grid points for the Finite Differences method, default value is 151}
 }
@@ -48,6 +51,9 @@
   \item{parameters}{List with parameters with which object was created}
 }
 \details{
+  
+  When "arithmetic" evaluation is used, only the NPV() is returned.
+  
   The well-known closed-form solution derived by Black, Scholes and
   Merton is used for valuation. Implied volatilities are calculated
   numerically.

Modified: pkg/RQuantLib/src/asian.cpp
===================================================================
--- pkg/RQuantLib/src/asian.cpp	2010-07-01 11:51:44 UTC (rev 266)
+++ pkg/RQuantLib/src/asian.cpp	2010-07-06 01:20:36 UTC (rev 267)
@@ -37,19 +37,12 @@
         Spread dividendYield = Rcpp::as<double>(rparam["dividendYield"]);
         Rate riskFreeRate = Rcpp::as<double>(rparam["riskFreeRate"]);
         Time maturity = Rcpp::as<double>(rparam["maturity"]);
-        int length = int(maturity*360 + 0.5); // FIXME: this could be better
+        //        int length = int(maturity*360 + 0.5); // FIXME: this could be better
         double volatility = Rcpp::as<double>(rparam["volatility"]);
 
         Option::Type optionType = getOptionType(type);
 
-        Average::Type averageType = Average::Geometric;
-        if (avgType=="geometric"){
-            averageType = Average::Geometric;
-        } else if (avgType=="arithmetic"){
-            averageType = Average::Arithmetic;
-        } else {
-            throw std::range_error("Unknown average type " + type);
-        }
+    
         
 
         //from test-suite/asionoptions.cpp
@@ -71,28 +64,74 @@
                                                    Handle<YieldTermStructure>(qTS),
                                                    Handle<YieldTermStructure>(rTS),
                                                    Handle<BlackVolTermStructure>(volTS)));
-        
-        boost::shared_ptr<PricingEngine> 
-            engine(new
-                   AnalyticContinuousGeometricAveragePriceAsianEngine(stochProcess));
 
-
         boost::shared_ptr<StrikedTypePayoff> payoff(new PlainVanillaPayoff(optionType,strike));
 
-        Date exDate = today + length;
+        Date exDate = today + int(maturity * 360 + 0.5);
         boost::shared_ptr<Exercise> exercise(new EuropeanExercise(exDate));
         
-        ContinuousAveragingAsianOption option(averageType, payoff, exercise);
-        option.setPricingEngine(engine);
 
-        Rcpp::List rl = Rcpp::List::create(Rcpp::Named("value") = option.NPV(),
-                                           Rcpp::Named("delta") = option.delta(),
-                                           Rcpp::Named("gamma") = option.gamma(),
-                                           Rcpp::Named("vega") = option.vega(),
-                                           Rcpp::Named("theta") = option.theta(),
-                                           Rcpp::Named("rho") = option.rho(),
-                                           Rcpp::Named("divRho") = option.dividendRho(),
-                                           Rcpp::Named("parameters") = optionParameters);
+        Average::Type averageType = Average::Geometric;
+        Rcpp::List rl = NULL;
+   
+        if (avgType=="geometric"){
+            averageType = Average::Geometric;
+            boost::shared_ptr<PricingEngine> 
+                engine(new
+                       AnalyticContinuousGeometricAveragePriceAsianEngine(stochProcess));        
+            ContinuousAveragingAsianOption option(averageType, payoff, exercise);
+            option.setPricingEngine(engine);
+            
+            rl = Rcpp::List::create(Rcpp::Named("value") = option.NPV(),
+                                    Rcpp::Named("delta") = option.delta(),
+                                    Rcpp::Named("gamma") = option.gamma(),
+                                    Rcpp::Named("vega") = option.vega(),
+                                    Rcpp::Named("theta") = option.theta(),
+                                    Rcpp::Named("rho") = option.rho(),
+                                    Rcpp::Named("divRho") = option.dividendRho(),
+                                    Rcpp::Named("parameters") = optionParameters);
+            
+        } else if (avgType=="arithmetic"){
+            averageType = Average::Arithmetic;
+            boost::shared_ptr<PricingEngine> engine =
+                MakeMCDiscreteArithmeticASEngine<LowDiscrepancy>(stochProcess)
+                .withSeed(3456789)
+                .withSamples(1023);
+            
+            Size fixings = Rcpp::as<double>(rparam["fixings"]);
+            Time length = Rcpp::as<double>(rparam["length"]);
+            Time first = Rcpp::as<double>(rparam["first"]);
+            Time dt = length / (fixings - 1);
+
+            std::vector<Time> timeIncrements(fixings);
+            std::vector<Date> fixingDates(fixings);
+            timeIncrements[0] = first;
+            fixingDates[0] = today + Integer(timeIncrements[0] * 360 + 0.5);
+            for (Size i=1; i<fixings; i++) {
+                timeIncrements[i] = i*dt + first;
+                fixingDates[i] = today + Integer(timeIncrements[i]*360+0.5);
+            }
+            Real runningSum = 0.0;
+            Size pastFixing = 0;
+
+            DiscreteAveragingAsianOption option(Average::Arithmetic, 
+                                                runningSum,
+                                                pastFixing, 
+                                                fixingDates,
+                                                payoff, exercise);
+            option.setPricingEngine(engine);
+            rl = Rcpp::List::create(Rcpp::Named("value") = option.NPV(),
+                                    Rcpp::Named("delta") = 0,
+                                    Rcpp::Named("gamma") = 0,
+                                    Rcpp::Named("vega") = 0,
+                                    Rcpp::Named("theta") = 0 ,
+                                    Rcpp::Named("rho") = 0,
+                                    Rcpp::Named("divRho") = 0,
+                                    Rcpp::Named("parameters") = optionParameters);
+        } else {
+            throw std::range_error("Unknown average type " + type);
+        }      
+    
         return rl;
 
     } catch(std::exception &ex) { 



More information about the Rquantlib-commits mailing list