Skip to content

Commit 8c957da

Browse files
committed
EuOptImplied switched to using either time-to-expiry or expiry date
By changing the C++ signature and using Nullable we skip second function
1 parent 0a39f1d commit 8c957da

8 files changed

Lines changed: 68 additions & 153 deletions

File tree

ChangeLog

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
2026-03-04 Dirk Eddelbuettel <edd@debian.org>
2+
3+
* src/implieds.cpp (europeanOptionImpliedVolatilityEngine): Use new
4+
helper function with two Nullable<> args, remove alternate function
5+
* src/utils.cpp (getFutureDate): Helper function for expiry date
6+
given either maturity as fractional year or actual dates
7+
* R/implied.R (EuropeanOptionImpliedVolatility.default): Use simpler
8+
interface testing for either fractional time, or Date type
9+
* inst/include/rquantlib_internal.h: Declare it
10+
* inst/include/RQuantLib_RcppExports.h: Regenerated
11+
* src/RcppExports.cpp: Idem
12+
* R/RcppExports.R: Idem
13+
114
2026-03-03 Dirk Eddelbuettel <edd@debian.org>
215

316
* src/implieds.cpp (americanOptionImpliedVolatilityEngine): Use

R/RcppExports.R

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,8 @@ calibrateHullWhiteUsingSwapsEngine <- function(termStrcDateVec, termStrcZeroVec,
185185
.Call(`_RQuantLib_calibrateHullWhiteUsingSwapsEngine`, termStrcDateVec, termStrcZeroVec, swapDF, iborDateVec, iborZeroVec, iborType, evalDate)
186186
}
187187

188-
europeanOptionImpliedVolatilityEngine <- function(type, value, underlying, strike, dividendYield, riskFreeRate, maturity, volatility, dayCounter) {
189-
.Call(`_RQuantLib_europeanOptionImpliedVolatilityEngine`, type, value, underlying, strike, dividendYield, riskFreeRate, maturity, volatility, dayCounter)
190-
}
191-
192-
europeanOptionImpliedVolatilityEngineByDate <- function(type, value, underlying, strike, dividendYield, riskFreeRate, exDate, volatility, dayCounter) {
193-
.Call(`_RQuantLib_europeanOptionImpliedVolatilityEngineByDate`, type, value, underlying, strike, dividendYield, riskFreeRate, exDate, volatility, dayCounter)
188+
europeanOptionImpliedVolatilityEngine <- function(type, value, underlying, strike, dividendYield, riskFreeRate, maturity_, exDate_, volatility, dayCounter) {
189+
.Call(`_RQuantLib_europeanOptionImpliedVolatilityEngine`, type, value, underlying, strike, dividendYield, riskFreeRate, maturity_, exDate_, volatility, dayCounter)
194190
}
195191

196192
americanOptionImpliedVolatilityEngine <- function(type, value, underlying, strike, dividendYield, riskFreeRate, maturity_, exDate_, volguess, timesteps, gridpoints, dayCounter) {

R/implied.R

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## RQuantLib -- R interface to the QuantLib libraries
22
##
3-
## Copyright (C) 2002 - 2026 Dirk Eddelbuettel <edd@debian.org>
3+
## Copyright (C) 2002-2026 Dirk Eddelbuettel <edd@debian.org>
44
##
55
## This file is part of RQuantLib.
66
##
@@ -31,15 +31,11 @@ EuropeanOptionImpliedVolatility.default <- function(type, value, underlying,
3131
riskFreeRate, maturity,
3232
volatility, dayCounter=0) {
3333

34-
if (inherits(maturity, "Date")) {
35-
val <- europeanOptionImpliedVolatilityEngineByDate(type, value, underlying, strike,
36-
dividendYield, riskFreeRate,
37-
maturity, volatility, dayCounter)
38-
} else {
39-
val <- europeanOptionImpliedVolatilityEngine(type, value, underlying, strike,
40-
dividendYield, riskFreeRate,
41-
maturity, volatility, dayCounter)
42-
}
34+
val <- europeanOptionImpliedVolatilityEngine(type, value, underlying, strike,
35+
dividendYield, riskFreeRate,
36+
if (inherits(maturity, "numeric")) maturity else NULL,
37+
if (inherits(maturity, "Date")) maturity else NULL,
38+
volatility, dayCounter)
4339
class(val) <- c("EuropeanOptionImpliedVolatility","ImpliedVolatility")
4440
val
4541
}

inst/include/RQuantLib_RcppExports.h

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -486,38 +486,17 @@ namespace RQuantLib {
486486
return Rcpp::as<bool >(rcpp_result_gen);
487487
}
488488

489-
inline double europeanOptionImpliedVolatilityEngine(std::string type, double value, double underlying, double strike, double dividendYield, double riskFreeRate, double maturity, double volatility, int dayCounter) {
490-
typedef SEXP(*Ptr_europeanOptionImpliedVolatilityEngine)(SEXP,SEXP,SEXP,SEXP,SEXP,SEXP,SEXP,SEXP,SEXP);
489+
inline double europeanOptionImpliedVolatilityEngine(std::string type, double value, double underlying, double strike, double dividendYield, double riskFreeRate, Rcpp::Nullable<double> maturity_, Rcpp::Nullable<QuantLib::Date> exDate_, double volatility, int dayCounter) {
490+
typedef SEXP(*Ptr_europeanOptionImpliedVolatilityEngine)(SEXP,SEXP,SEXP,SEXP,SEXP,SEXP,SEXP,SEXP,SEXP,SEXP);
491491
static Ptr_europeanOptionImpliedVolatilityEngine p_europeanOptionImpliedVolatilityEngine = NULL;
492492
if (p_europeanOptionImpliedVolatilityEngine == NULL) {
493-
validateSignature("double(*europeanOptionImpliedVolatilityEngine)(std::string,double,double,double,double,double,double,double,int)");
493+
validateSignature("double(*europeanOptionImpliedVolatilityEngine)(std::string,double,double,double,double,double,Rcpp::Nullable<double>,Rcpp::Nullable<QuantLib::Date>,double,int)");
494494
p_europeanOptionImpliedVolatilityEngine = (Ptr_europeanOptionImpliedVolatilityEngine)R_GetCCallable("RQuantLib", "_RQuantLib_europeanOptionImpliedVolatilityEngine");
495495
}
496496
RObject rcpp_result_gen;
497497
{
498498
RNGScope RCPP_rngScope_gen;
499-
rcpp_result_gen = p_europeanOptionImpliedVolatilityEngine(Shield<SEXP>(Rcpp::wrap(type)), Shield<SEXP>(Rcpp::wrap(value)), Shield<SEXP>(Rcpp::wrap(underlying)), Shield<SEXP>(Rcpp::wrap(strike)), Shield<SEXP>(Rcpp::wrap(dividendYield)), Shield<SEXP>(Rcpp::wrap(riskFreeRate)), Shield<SEXP>(Rcpp::wrap(maturity)), Shield<SEXP>(Rcpp::wrap(volatility)), Shield<SEXP>(Rcpp::wrap(dayCounter)));
500-
}
501-
if (rcpp_result_gen.inherits("interrupted-error"))
502-
throw Rcpp::internal::InterruptedException();
503-
if (Rcpp::internal::isLongjumpSentinel(rcpp_result_gen))
504-
throw Rcpp::LongjumpException(rcpp_result_gen);
505-
if (rcpp_result_gen.inherits("try-error"))
506-
throw Rcpp::exception(Rcpp::as<std::string>(rcpp_result_gen).c_str());
507-
return Rcpp::as<double >(rcpp_result_gen);
508-
}
509-
510-
inline double europeanOptionImpliedVolatilityEngineByDate(std::string type, double value, double underlying, double strike, double dividendYield, double riskFreeRate, QuantLib::Date exDate, double volatility, int dayCounter) {
511-
typedef SEXP(*Ptr_europeanOptionImpliedVolatilityEngineByDate)(SEXP,SEXP,SEXP,SEXP,SEXP,SEXP,SEXP,SEXP,SEXP);
512-
static Ptr_europeanOptionImpliedVolatilityEngineByDate p_europeanOptionImpliedVolatilityEngineByDate = NULL;
513-
if (p_europeanOptionImpliedVolatilityEngineByDate == NULL) {
514-
validateSignature("double(*europeanOptionImpliedVolatilityEngineByDate)(std::string,double,double,double,double,double,QuantLib::Date,double,int)");
515-
p_europeanOptionImpliedVolatilityEngineByDate = (Ptr_europeanOptionImpliedVolatilityEngineByDate)R_GetCCallable("RQuantLib", "_RQuantLib_europeanOptionImpliedVolatilityEngineByDate");
516-
}
517-
RObject rcpp_result_gen;
518-
{
519-
RNGScope RCPP_rngScope_gen;
520-
rcpp_result_gen = p_europeanOptionImpliedVolatilityEngineByDate(Shield<SEXP>(Rcpp::wrap(type)), Shield<SEXP>(Rcpp::wrap(value)), Shield<SEXP>(Rcpp::wrap(underlying)), Shield<SEXP>(Rcpp::wrap(strike)), Shield<SEXP>(Rcpp::wrap(dividendYield)), Shield<SEXP>(Rcpp::wrap(riskFreeRate)), Shield<SEXP>(Rcpp::wrap(exDate)), Shield<SEXP>(Rcpp::wrap(volatility)), Shield<SEXP>(Rcpp::wrap(dayCounter)));
499+
rcpp_result_gen = p_europeanOptionImpliedVolatilityEngine(Shield<SEXP>(Rcpp::wrap(type)), Shield<SEXP>(Rcpp::wrap(value)), Shield<SEXP>(Rcpp::wrap(underlying)), Shield<SEXP>(Rcpp::wrap(strike)), Shield<SEXP>(Rcpp::wrap(dividendYield)), Shield<SEXP>(Rcpp::wrap(riskFreeRate)), Shield<SEXP>(Rcpp::wrap(maturity_)), Shield<SEXP>(Rcpp::wrap(exDate_)), Shield<SEXP>(Rcpp::wrap(volatility)), Shield<SEXP>(Rcpp::wrap(dayCounter)));
521500
}
522501
if (rcpp_result_gen.inherits("interrupted-error"))
523502
throw Rcpp::internal::InterruptedException();

inst/include/rquantlib_internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ QuantLib::Date advanceDate(QuantLib::Date issueDate, int days);
200200

201201
// utils.cpp
202202
QuantLib::Date getFutureDate(const QuantLib::Date today, double maturity);
203+
QuantLib::Date getFutureDate(const QuantLib::Date today,
204+
Rcpp::Nullable<double> maturity,
205+
Rcpp::Nullable<QuantLib::Date> exDate);
203206

204207
// convenience namespace shortcut
205208
namespace qlext = QuantLib::ext;

src/RcppExports.cpp

Lines changed: 9 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,8 +1268,8 @@ BEGIN_RCPP
12681268
END_RCPP
12691269
}
12701270
// europeanOptionImpliedVolatilityEngine
1271-
double europeanOptionImpliedVolatilityEngine(std::string type, double value, double underlying, double strike, double dividendYield, double riskFreeRate, double maturity, double volatility, int dayCounter);
1272-
static SEXP _RQuantLib_europeanOptionImpliedVolatilityEngine_try(SEXP typeSEXP, SEXP valueSEXP, SEXP underlyingSEXP, SEXP strikeSEXP, SEXP dividendYieldSEXP, SEXP riskFreeRateSEXP, SEXP maturitySEXP, SEXP volatilitySEXP, SEXP dayCounterSEXP) {
1271+
double europeanOptionImpliedVolatilityEngine(std::string type, double value, double underlying, double strike, double dividendYield, double riskFreeRate, Rcpp::Nullable<double> maturity_, Rcpp::Nullable<QuantLib::Date> exDate_, double volatility, int dayCounter);
1272+
static SEXP _RQuantLib_europeanOptionImpliedVolatilityEngine_try(SEXP typeSEXP, SEXP valueSEXP, SEXP underlyingSEXP, SEXP strikeSEXP, SEXP dividendYieldSEXP, SEXP riskFreeRateSEXP, SEXP maturity_SEXP, SEXP exDate_SEXP, SEXP volatilitySEXP, SEXP dayCounterSEXP) {
12731273
BEGIN_RCPP
12741274
Rcpp::RObject rcpp_result_gen;
12751275
Rcpp::traits::input_parameter< std::string >::type type(typeSEXP);
@@ -1278,60 +1278,19 @@ BEGIN_RCPP
12781278
Rcpp::traits::input_parameter< double >::type strike(strikeSEXP);
12791279
Rcpp::traits::input_parameter< double >::type dividendYield(dividendYieldSEXP);
12801280
Rcpp::traits::input_parameter< double >::type riskFreeRate(riskFreeRateSEXP);
1281-
Rcpp::traits::input_parameter< double >::type maturity(maturitySEXP);
1282-
Rcpp::traits::input_parameter< double >::type volatility(volatilitySEXP);
1283-
Rcpp::traits::input_parameter< int >::type dayCounter(dayCounterSEXP);
1284-
rcpp_result_gen = Rcpp::wrap(europeanOptionImpliedVolatilityEngine(type, value, underlying, strike, dividendYield, riskFreeRate, maturity, volatility, dayCounter));
1285-
return rcpp_result_gen;
1286-
END_RCPP_RETURN_ERROR
1287-
}
1288-
RcppExport SEXP _RQuantLib_europeanOptionImpliedVolatilityEngine(SEXP typeSEXP, SEXP valueSEXP, SEXP underlyingSEXP, SEXP strikeSEXP, SEXP dividendYieldSEXP, SEXP riskFreeRateSEXP, SEXP maturitySEXP, SEXP volatilitySEXP, SEXP dayCounterSEXP) {
1289-
SEXP rcpp_result_gen;
1290-
{
1291-
Rcpp::RNGScope rcpp_rngScope_gen;
1292-
rcpp_result_gen = PROTECT(_RQuantLib_europeanOptionImpliedVolatilityEngine_try(typeSEXP, valueSEXP, underlyingSEXP, strikeSEXP, dividendYieldSEXP, riskFreeRateSEXP, maturitySEXP, volatilitySEXP, dayCounterSEXP));
1293-
}
1294-
Rboolean rcpp_isInterrupt_gen = Rf_inherits(rcpp_result_gen, "interrupted-error");
1295-
if (rcpp_isInterrupt_gen) {
1296-
UNPROTECT(1);
1297-
Rf_onintr();
1298-
}
1299-
bool rcpp_isLongjump_gen = Rcpp::internal::isLongjumpSentinel(rcpp_result_gen);
1300-
if (rcpp_isLongjump_gen) {
1301-
Rcpp::internal::resumeJump(rcpp_result_gen);
1302-
}
1303-
Rboolean rcpp_isError_gen = Rf_inherits(rcpp_result_gen, "try-error");
1304-
if (rcpp_isError_gen) {
1305-
SEXP rcpp_msgSEXP_gen = Rf_asChar(rcpp_result_gen);
1306-
UNPROTECT(1);
1307-
(Rf_error)("%s", CHAR(rcpp_msgSEXP_gen));
1308-
}
1309-
UNPROTECT(1);
1310-
return rcpp_result_gen;
1311-
}
1312-
// europeanOptionImpliedVolatilityEngineByDate
1313-
double europeanOptionImpliedVolatilityEngineByDate(std::string type, double value, double underlying, double strike, double dividendYield, double riskFreeRate, QuantLib::Date exDate, double volatility, int dayCounter);
1314-
static SEXP _RQuantLib_europeanOptionImpliedVolatilityEngineByDate_try(SEXP typeSEXP, SEXP valueSEXP, SEXP underlyingSEXP, SEXP strikeSEXP, SEXP dividendYieldSEXP, SEXP riskFreeRateSEXP, SEXP exDateSEXP, SEXP volatilitySEXP, SEXP dayCounterSEXP) {
1315-
BEGIN_RCPP
1316-
Rcpp::RObject rcpp_result_gen;
1317-
Rcpp::traits::input_parameter< std::string >::type type(typeSEXP);
1318-
Rcpp::traits::input_parameter< double >::type value(valueSEXP);
1319-
Rcpp::traits::input_parameter< double >::type underlying(underlyingSEXP);
1320-
Rcpp::traits::input_parameter< double >::type strike(strikeSEXP);
1321-
Rcpp::traits::input_parameter< double >::type dividendYield(dividendYieldSEXP);
1322-
Rcpp::traits::input_parameter< double >::type riskFreeRate(riskFreeRateSEXP);
1323-
Rcpp::traits::input_parameter< QuantLib::Date >::type exDate(exDateSEXP);
1281+
Rcpp::traits::input_parameter< Rcpp::Nullable<double> >::type maturity_(maturity_SEXP);
1282+
Rcpp::traits::input_parameter< Rcpp::Nullable<QuantLib::Date> >::type exDate_(exDate_SEXP);
13241283
Rcpp::traits::input_parameter< double >::type volatility(volatilitySEXP);
13251284
Rcpp::traits::input_parameter< int >::type dayCounter(dayCounterSEXP);
1326-
rcpp_result_gen = Rcpp::wrap(europeanOptionImpliedVolatilityEngineByDate(type, value, underlying, strike, dividendYield, riskFreeRate, exDate, volatility, dayCounter));
1285+
rcpp_result_gen = Rcpp::wrap(europeanOptionImpliedVolatilityEngine(type, value, underlying, strike, dividendYield, riskFreeRate, maturity_, exDate_, volatility, dayCounter));
13271286
return rcpp_result_gen;
13281287
END_RCPP_RETURN_ERROR
13291288
}
1330-
RcppExport SEXP _RQuantLib_europeanOptionImpliedVolatilityEngineByDate(SEXP typeSEXP, SEXP valueSEXP, SEXP underlyingSEXP, SEXP strikeSEXP, SEXP dividendYieldSEXP, SEXP riskFreeRateSEXP, SEXP exDateSEXP, SEXP volatilitySEXP, SEXP dayCounterSEXP) {
1289+
RcppExport SEXP _RQuantLib_europeanOptionImpliedVolatilityEngine(SEXP typeSEXP, SEXP valueSEXP, SEXP underlyingSEXP, SEXP strikeSEXP, SEXP dividendYieldSEXP, SEXP riskFreeRateSEXP, SEXP maturity_SEXP, SEXP exDate_SEXP, SEXP volatilitySEXP, SEXP dayCounterSEXP) {
13311290
SEXP rcpp_result_gen;
13321291
{
13331292
Rcpp::RNGScope rcpp_rngScope_gen;
1334-
rcpp_result_gen = PROTECT(_RQuantLib_europeanOptionImpliedVolatilityEngineByDate_try(typeSEXP, valueSEXP, underlyingSEXP, strikeSEXP, dividendYieldSEXP, riskFreeRateSEXP, exDateSEXP, volatilitySEXP, dayCounterSEXP));
1293+
rcpp_result_gen = PROTECT(_RQuantLib_europeanOptionImpliedVolatilityEngine_try(typeSEXP, valueSEXP, underlyingSEXP, strikeSEXP, dividendYieldSEXP, riskFreeRateSEXP, maturity_SEXP, exDate_SEXP, volatilitySEXP, dayCounterSEXP));
13351294
}
13361295
Rboolean rcpp_isInterrupt_gen = Rf_inherits(rcpp_result_gen, "interrupted-error");
13371296
if (rcpp_isInterrupt_gen) {
@@ -1694,8 +1653,7 @@ static int _RQuantLib_RcppExport_validate(const char* sig) {
16941653
signatures.insert("std::vector<double>(*dayCount)(std::vector<QuantLib::Date>,std::vector<QuantLib::Date>,std::vector<double>)");
16951654
signatures.insert("std::vector<double>(*yearFraction)(std::vector<QuantLib::Date>,std::vector<QuantLib::Date>,std::vector<double>)");
16961655
signatures.insert("bool(*setEvaluationDate)(QuantLib::Date)");
1697-
signatures.insert("double(*europeanOptionImpliedVolatilityEngine)(std::string,double,double,double,double,double,double,double,int)");
1698-
signatures.insert("double(*europeanOptionImpliedVolatilityEngineByDate)(std::string,double,double,double,double,double,QuantLib::Date,double,int)");
1656+
signatures.insert("double(*europeanOptionImpliedVolatilityEngine)(std::string,double,double,double,double,double,Rcpp::Nullable<double>,Rcpp::Nullable<QuantLib::Date>,double,int)");
16991657
signatures.insert("double(*americanOptionImpliedVolatilityEngine)(std::string,double,double,double,double,double,Rcpp::Nullable<double>,Rcpp::Nullable<QuantLib::Date>,double,int,int,int)");
17001658
signatures.insert("Rcpp::DateVector(*CreateSchedule)(Rcpp::List)");
17011659
signatures.insert("std::string(*getQuantLibVersion)()");
@@ -1732,7 +1690,6 @@ RcppExport SEXP _RQuantLib_RcppExport_registerCCallable() {
17321690
R_RegisterCCallable("RQuantLib", "_RQuantLib_yearFraction", (DL_FUNC)_RQuantLib_yearFraction_try);
17331691
R_RegisterCCallable("RQuantLib", "_RQuantLib_setEvaluationDate", (DL_FUNC)_RQuantLib_setEvaluationDate_try);
17341692
R_RegisterCCallable("RQuantLib", "_RQuantLib_europeanOptionImpliedVolatilityEngine", (DL_FUNC)_RQuantLib_europeanOptionImpliedVolatilityEngine_try);
1735-
R_RegisterCCallable("RQuantLib", "_RQuantLib_europeanOptionImpliedVolatilityEngineByDate", (DL_FUNC)_RQuantLib_europeanOptionImpliedVolatilityEngineByDate_try);
17361693
R_RegisterCCallable("RQuantLib", "_RQuantLib_americanOptionImpliedVolatilityEngine", (DL_FUNC)_RQuantLib_americanOptionImpliedVolatilityEngine_try);
17371694
R_RegisterCCallable("RQuantLib", "_RQuantLib_CreateSchedule", (DL_FUNC)_RQuantLib_CreateSchedule_try);
17381695
R_RegisterCCallable("RQuantLib", "_RQuantLib_getQuantLibVersion", (DL_FUNC)_RQuantLib_getQuantLibVersion_try);
@@ -1794,8 +1751,7 @@ static const R_CallMethodDef CallEntries[] = {
17941751
{"_RQuantLib_discountCurveEngine", (DL_FUNC) &_RQuantLib_discountCurveEngine, 4},
17951752
{"_RQuantLib_calibrateHullWhiteUsingCapsEngine", (DL_FUNC) &_RQuantLib_calibrateHullWhiteUsingCapsEngine, 7},
17961753
{"_RQuantLib_calibrateHullWhiteUsingSwapsEngine", (DL_FUNC) &_RQuantLib_calibrateHullWhiteUsingSwapsEngine, 7},
1797-
{"_RQuantLib_europeanOptionImpliedVolatilityEngine", (DL_FUNC) &_RQuantLib_europeanOptionImpliedVolatilityEngine, 9},
1798-
{"_RQuantLib_europeanOptionImpliedVolatilityEngineByDate", (DL_FUNC) &_RQuantLib_europeanOptionImpliedVolatilityEngineByDate, 9},
1754+
{"_RQuantLib_europeanOptionImpliedVolatilityEngine", (DL_FUNC) &_RQuantLib_europeanOptionImpliedVolatilityEngine, 10},
17991755
{"_RQuantLib_americanOptionImpliedVolatilityEngine", (DL_FUNC) &_RQuantLib_americanOptionImpliedVolatilityEngine, 12},
18001756
{"_RQuantLib_sabrengine", (DL_FUNC) &_RQuantLib_sabrengine, 9},
18011757
{"_RQuantLib_CreateSchedule", (DL_FUNC) &_RQuantLib_CreateSchedule, 1},

0 commit comments

Comments
 (0)