// [[Rcpp::export]] Rcpp::List europeanOptionArraysEngine(std::string type, Rcpp::NumericMatrix par) { QuantLib::Option::Type optionType = getOptionType(type); int n = par.nrow(); Rcpp::NumericVector value(n), delta(n), gamma(n), vega(n), theta(n), rho(n), divrho(n); QuantLib::Date today = QuantLib::Date::todaysDate(); QuantLib::Settings::instance().evaluationDate() = today; QuantLib::DayCounter dc = QuantLib::Actual360(); for (int i=0; i<n; i++) { double underlying = par(i, 0); // first column double strike = par(i, 1); // second column QuantLib::Spread dividendYield = par(i, 2); // third column QuantLib::Rate riskFreeRate = par(i, 3); // fourth column QuantLib::Time maturity = par(i, 4); // fifth column #ifdef QL_HIGH_RESOLUTION_DATE // in minutes boost::posix_time::time_duration length = boost::posix_time::minutes(boost::uint64_t(maturity * 360 * 24 * 60)); #else int length = int(maturity*360 + 0.5); // FIXME: this could be better #endif double volatility = par(i, 5); // sixth column boost::shared_ptr<QuantLib::SimpleQuote> spot(new QuantLib::SimpleQuote( underlying )); boost::shared_ptr<QuantLib::SimpleQuote> vol(new QuantLib::SimpleQuote( volatility )); boost::shared_ptr<QuantLib::BlackVolTermStructure> volTS = flatVol(today, vol, dc); boost::shared_ptr<QuantLib::SimpleQuote> qRate(new QuantLib::SimpleQuote( dividendYield )); boost::shared_ptr<QuantLib::YieldTermStructure> qTS = flatRate(today, qRate, dc); boost::shared_ptr<QuantLib::SimpleQuote> rRate(new QuantLib::SimpleQuote( riskFreeRate )); boost::shared_ptr<QuantLib::YieldTermStructure> rTS = flatRate(today, rRate, dc); #ifdef QL_HIGH_RESOLUTION_DATE QuantLib::Date exDate(today.dateTime() + length); #else QuantLib::Date exDate = today + length; #endif boost::shared_ptr<QuantLib::Exercise> exercise(new QuantLib::EuropeanExercise(exDate)); boost::shared_ptr<QuantLib::StrikedTypePayoff> payoff(new QuantLib::PlainVanillaPayoff(optionType, strike)); boost::shared_ptr<QuantLib::VanillaOption> option = makeOption(payoff, exercise, spot, qTS, rTS, volTS); value[i] = option->NPV(); delta[i] = option->delta(); gamma[i] = option->gamma(); vega[i] = option->vega(); theta[i] = option->theta(); rho[i] = option->rho(); divrho[i] = option->dividendRho(); } return Rcpp::List::create(Rcpp::Named("value") = value, Rcpp::Named("delta") = delta, Rcpp::Named("gamma") = gamma, Rcpp::Named("vega") = vega, Rcpp::Named("theta") = theta, Rcpp::Named("rho") = rho, Rcpp::Named("divRho") = divrho); }
// dumped core when we tried last // no longer under 0.3.10 and g++ 4.0.1 (Aug 2005) // [[Rcpp::export]] double binaryOptionImpliedVolatilityEngine(std::string type, double value, double underlying, double strike, double dividendYield, double riskFreeRate, double maturity, double volatility, double cashPayoff) { #ifdef QL_HIGH_RESOLUTION_DATE // in minutes boost::posix_time::time_duration length = boost::posix_time::minutes(maturity * 360 * 24 * 60); #else int length = int(maturity*360 + 0.5); // FIXME: this could be better #endif QuantLib::Option::Type optionType = getOptionType(type); // updated again for QuantLib 0.9.0, // cf QuantLib-0.9.0/test-suite/digitaloption.cpp QuantLib::Date today = QuantLib::Date::todaysDate(); QuantLib::Settings::instance().evaluationDate() = today; QuantLib::DayCounter dc = QuantLib::Actual360(); boost::shared_ptr<QuantLib::SimpleQuote> spot(new QuantLib::SimpleQuote(underlying)); boost::shared_ptr<QuantLib::SimpleQuote> qRate(new QuantLib::SimpleQuote(dividendYield)); boost::shared_ptr<QuantLib::YieldTermStructure> qTS = flatRate(today, qRate, dc); boost::shared_ptr<QuantLib::SimpleQuote> rRate(new QuantLib::SimpleQuote(riskFreeRate)); boost::shared_ptr<QuantLib::YieldTermStructure> rTS = flatRate(today, rRate, dc); boost::shared_ptr<QuantLib::SimpleQuote> vol(new QuantLib::SimpleQuote(volatility)); boost::shared_ptr<QuantLib::BlackVolTermStructure> volTS = flatVol(today, vol, dc); boost::shared_ptr<QuantLib::StrikedTypePayoff> payoff(new QuantLib::CashOrNothingPayoff(optionType, strike, cashPayoff)); #ifdef QL_HIGH_RESOLUTION_DATE QuantLib::Date exDate(today.dateTime() + length); #else QuantLib::Date exDate = today + length; #endif boost::shared_ptr<QuantLib::Exercise> exercise(new QuantLib::EuropeanExercise(exDate)); boost::shared_ptr<QuantLib::BlackScholesMertonProcess> stochProcess(new QuantLib::BlackScholesMertonProcess(QuantLib::Handle<QuantLib::Quote>(spot), QuantLib::Handle<QuantLib::YieldTermStructure>(qTS), QuantLib::Handle<QuantLib::YieldTermStructure>(rTS), QuantLib::Handle<QuantLib::BlackVolTermStructure>(volTS))); //boost::shared_ptr<PricingEngine> engine(new AnalyticEuropeanEngine(stochProcess)); boost::shared_ptr<QuantLib::PricingEngine> engine(new QuantLib::AnalyticBarrierEngine(stochProcess)); QuantLib::VanillaOption opt(payoff, exercise); opt.setPricingEngine(engine); return opt.impliedVolatility(value, stochProcess); }
// [[Rcpp::export]] double europeanOptionImpliedVolatilityEngine(std::string type, double value, double underlying, double strike, double dividendYield, double riskFreeRate, double maturity, double volatility) { const QuantLib::Size maxEvaluations = 100; const double tolerance = 1.0e-6; int length = int(maturity*360 + 0.5); // FIXME: this could be better QuantLib::Option::Type optionType = getOptionType(type); QuantLib::Date today = QuantLib::Date::todaysDate(); QuantLib::Settings::instance().evaluationDate() = today; // new framework as per QuantLib 0.3.5 // updated for 0.3.7 QuantLib::DayCounter dc = QuantLib::Actual360(); boost::shared_ptr<QuantLib::SimpleQuote> spot(new QuantLib::SimpleQuote(underlying)); boost::shared_ptr<QuantLib::SimpleQuote> vol(new QuantLib::SimpleQuote(volatility)); boost::shared_ptr<QuantLib::BlackVolTermStructure> volTS = flatVol(today, vol, dc); boost::shared_ptr<QuantLib::SimpleQuote> qRate(new QuantLib::SimpleQuote(dividendYield)); boost::shared_ptr<QuantLib::YieldTermStructure> qTS = flatRate(today,qRate,dc); boost::shared_ptr<QuantLib::SimpleQuote> rRate(new QuantLib::SimpleQuote(riskFreeRate)); boost::shared_ptr<QuantLib::YieldTermStructure> rTS = flatRate(today,rRate,dc); QuantLib::Date exDate = today + length; boost::shared_ptr<QuantLib::Exercise> exercise(new QuantLib::EuropeanExercise(exDate)); boost::shared_ptr<QuantLib::StrikedTypePayoff> payoff(new QuantLib::PlainVanillaPayoff(optionType, strike)); boost::shared_ptr<QuantLib::VanillaOption> option = makeOption(payoff, exercise, spot, qTS, rTS, volTS, Analytic, QuantLib::Null<QuantLib::Size>(), QuantLib::Null<QuantLib::Size>()); boost::shared_ptr<QuantLib::GeneralizedBlackScholesProcess> process = makeProcess(spot, qTS, rTS,volTS); double volguess = volatility; vol->setValue(volguess); return option->impliedVolatility(value, process, tolerance, maxEvaluations); }
int ScripMasterDataRequest::serialize(char *buf) { int bytes = 0; UNSIGNED_INTEGER tmp = 0; UNSIGNED_SHORT tmpShort = 0; UNSIGNED_CHARACTER tmpChar = 0; UNSIGNED_LONG tmpLong = 0; bytes = sizeof(UNSIGNED_SHORT); // Leave 2 bytes for packet size // Put category of command SERIALIZE_8(tmpChar, (UNSIGNED_CHARACTER)(CMD::CommandCategory_SEND_SCRIP_MASTER_DATA), buf, bytes); //Command Category // Put fields of this class SERIALIZE_8(tmpChar, getScripMasterDataRequestType(), buf, bytes); SERIALIZE_32(tmp, getClientId(), buf, bytes); SERIALIZE_64(tmpLong, getRecordNumber(), buf, bytes); SERIALIZE_64(tmpLong, getSecurityId(), buf, bytes); SERIALIZE_64(tmpLong, getSymbolId(), buf, bytes); SERIALIZE_16(tmpShort, getExchangeId(), buf, bytes); memcpy(buf + bytes, getSymbol(), SYMBOL_SIZE); bytes += SYMBOL_SIZE; memcpy(buf + bytes, getSeries(), SERIES_SIZE); bytes += SERIES_SIZE; memcpy(buf + bytes, getMarketName(), SERIES_SIZE); bytes += MARKET_NAME_SIZE; SERIALIZE_8(tmpChar, getOptionType(), buf, bytes); SERIALIZE_8(tmpChar, getOptionMode(), buf, bytes); SERIALIZE_8(tmpChar, getSecurityType(), buf, bytes); SERIALIZE_64(tmpLong, getStrikePrice(), buf, bytes); SERIALIZE_32(tmp, getExpiryYearMon(), buf, bytes); SERIALIZE_32(tmp, getExpiryDate(), buf, bytes); SERIALIZE_32(tmp, getNumberOfRecords(), buf, bytes); memcpy(buf + bytes, getSymbolAlias(), SYMBOL_ALIAS_SIZE); bytes += SYMBOL_ALIAS_SIZE; UNSIGNED_SHORT dummyBytes = 0; // Put size as the first field after deducting 2 bytes reserved for size SERIALIZE_16(tmpShort, (UNSIGNED_SHORT)(bytes-sizeof(UNSIGNED_SHORT)), buf, dummyBytes); return bytes; }
void ScripMasterDataRequest::dump() { std::cout << "ScripMasterDataRequest dump : " << std::endl; std::cout << getScripMasterDataRequestType() << std::endl; std::cout << getClientId() << std::endl; std::cout << getRecordNumber() << std::endl; std::cout << getSecurityId() << std::endl; std::cout << getSymbolId() << std::endl; std::cout << getExchangeId() << std::endl; std::cout << getSymbol() << std::endl; std::cout << getSeries() << std::endl; std::cout << getMarketName() << std::endl; std::cout << getOptionType() << std::endl; std::cout << getOptionMode() << std::endl; std::cout << getSecurityType() << std::endl; std::cout << getStrikePrice() << std::endl; std::cout << getExpiryYearMon() << std::endl; std::cout << getExpiryDate() << std::endl; std::cout << getNumberOfRecords() << std::endl; std::cout << getSymbolAlias() << std::endl; std::cout << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n" << std::endl; }
// [[Rcpp::export]] Rcpp::List binaryOptionEngine(std::string binType, std::string type, std::string excType, double underlying, double strike, double dividendYield, double riskFreeRate, double maturity, double volatility, double cashPayoff) { #ifdef QL_HIGH_RESOLUTION_DATE // in minutes boost::posix_time::time_duration length = boost::posix_time::minutes(maturity * 360 * 24 * 60); #else int length = int(maturity*360 + 0.5); // FIXME: this could be better, but same rounding in QL #endif QuantLib::Option::Type optionType = getOptionType(type); // new QuantLib 0.3.5 framework: digitals, updated for 0.3.7 // updated again for QuantLib 0.9.0, // cf QuantLib-0.9.0/test-suite/digitaloption.cpp QuantLib::Date today = QuantLib::Date::todaysDate(); QuantLib::Settings::instance().evaluationDate() = today; QuantLib::DayCounter dc = QuantLib::Actual360(); boost::shared_ptr<QuantLib::SimpleQuote> spot(new QuantLib::SimpleQuote(underlying)); boost::shared_ptr<QuantLib::SimpleQuote> qRate(new QuantLib::SimpleQuote(dividendYield)); boost::shared_ptr<QuantLib::YieldTermStructure> qTS = flatRate(today,qRate,dc); boost::shared_ptr<QuantLib::SimpleQuote> rRate(new QuantLib::SimpleQuote(riskFreeRate)); boost::shared_ptr<QuantLib::YieldTermStructure> rTS = flatRate(today,rRate,dc); boost::shared_ptr<QuantLib::SimpleQuote> vol(new QuantLib::SimpleQuote(volatility)); boost::shared_ptr<QuantLib::BlackVolTermStructure> volTS = flatVol(today, vol, dc); boost::shared_ptr<QuantLib::StrikedTypePayoff> payoff; if (binType=="cash") { boost::shared_ptr<QuantLib::StrikedTypePayoff> con(new QuantLib::CashOrNothingPayoff(optionType, strike, cashPayoff)); payoff = con; } else if (binType=="asset") { boost::shared_ptr<QuantLib::StrikedTypePayoff> aon(new QuantLib::AssetOrNothingPayoff(optionType, strike)); payoff = aon; } else if (binType=="gap") { boost::shared_ptr<QuantLib::StrikedTypePayoff> gap(new QuantLib::GapPayoff(optionType, strike, cashPayoff)); payoff = gap; } else { throw std::range_error("Unknown binary option type " + binType); } #ifdef QL_HIGH_RESOLUTION_DATE QuantLib::Date exDate(today.dateTime() + length); #else QuantLib::Date exDate = today + length; #endif boost::shared_ptr<QuantLib::Exercise> exercise; if (excType=="american") { boost::shared_ptr<QuantLib::Exercise> amEx(new QuantLib::AmericanExercise(today, exDate)); exercise = amEx; } else if (excType=="european") { boost::shared_ptr<QuantLib::Exercise> euEx(new QuantLib::EuropeanExercise(exDate)); exercise = euEx; } else { throw std::range_error("Unknown binary exercise type " + excType); } boost::shared_ptr<QuantLib::BlackScholesMertonProcess> stochProcess(new QuantLib::BlackScholesMertonProcess(QuantLib::Handle<QuantLib::Quote>(spot), QuantLib::Handle<QuantLib::YieldTermStructure>(qTS), QuantLib::Handle<QuantLib::YieldTermStructure>(rTS), QuantLib::Handle<QuantLib::BlackVolTermStructure>(volTS))); boost::shared_ptr<QuantLib::PricingEngine> engine; if (excType=="american") { boost::shared_ptr<QuantLib::PricingEngine> amEng(new QuantLib::AnalyticDigitalAmericanEngine(stochProcess)); engine = amEng; } else if (excType=="european") { boost::shared_ptr<QuantLib::PricingEngine> euEng(new QuantLib::AnalyticEuropeanEngine(stochProcess)); engine = euEng; } else { throw std::range_error("Unknown binary exercise type " + excType); } QuantLib::VanillaOption opt(payoff, exercise); opt.setPricingEngine(engine); Rcpp::List rl = Rcpp::List::create(Rcpp::Named("value") = opt.NPV(), Rcpp::Named("delta") = opt.delta(), Rcpp::Named("gamma") = opt.gamma(), Rcpp::Named("vega") = (excType=="european") ? opt.vega() : R_NaN, Rcpp::Named("theta") = (excType=="european") ? opt.theta() : R_NaN, Rcpp::Named("rho") = (excType=="european") ? opt.rho() : R_NaN, Rcpp::Named("divRho") = (excType=="european") ? opt.dividendRho() : R_NaN); return rl; }
// [[Rcpp::export]] Rcpp::List barrierOptionEngine(std::string barrType, std::string type, double underlying, double strike, double dividendYield, double riskFreeRate, double maturity, double volatility, double barrier, double rebate) { #ifdef QL_HIGH_RESOLUTION_DATE // in minutes boost::posix_time::time_duration length = boost::posix_time::minutes(maturity * 360 * 24 * 60); #else int length = int(maturity*360 + 0.5); // FIXME: this could be better #endif QuantLib::Barrier::Type barrierType = QuantLib::Barrier::DownIn; if (barrType=="downin") { barrierType = QuantLib::Barrier::DownIn; } else if (barrType=="upin") { barrierType = QuantLib::Barrier::UpIn; } else if (barrType=="downout") { barrierType = QuantLib::Barrier::DownOut; } else if (barrType=="upout") { barrierType = QuantLib::Barrier::UpOut; } else { throw std::range_error("Unknown barrier type " + type); } QuantLib::Option::Type optionType = getOptionType(type); // new QuantLib 0.3.5 framework, updated for 0.3.7 // updated again for QuantLib 0.9.0, // cf QuantLib-0.9.0/test-suite/barrieroption.cpp QuantLib::Date today = QuantLib::Date::todaysDate(); QuantLib::Settings::instance().evaluationDate() = today; QuantLib::DayCounter dc = QuantLib::Actual360(); boost::shared_ptr<QuantLib::SimpleQuote> spot(new QuantLib::SimpleQuote(underlying)); boost::shared_ptr<QuantLib::SimpleQuote> qRate(new QuantLib::SimpleQuote(dividendYield)); boost::shared_ptr<QuantLib::YieldTermStructure> qTS = flatRate(today, qRate, dc); boost::shared_ptr<QuantLib::SimpleQuote> rRate(new QuantLib::SimpleQuote(riskFreeRate)); boost::shared_ptr<QuantLib::YieldTermStructure> rTS = flatRate(today,rRate,dc); boost::shared_ptr<QuantLib::SimpleQuote> vol(new QuantLib::SimpleQuote(volatility)); boost::shared_ptr<QuantLib::BlackVolTermStructure> volTS = flatVol(today, vol, dc); #ifdef QL_HIGH_RESOLUTION_DATE QuantLib::Date exDate(today.dateTime() + length); #else QuantLib::Date exDate = today + length; #endif boost::shared_ptr<QuantLib::Exercise> exercise(new QuantLib::EuropeanExercise(exDate)); boost::shared_ptr<QuantLib::StrikedTypePayoff> payoff(new QuantLib::PlainVanillaPayoff(optionType, strike)); boost::shared_ptr<QuantLib::BlackScholesMertonProcess> stochProcess(new QuantLib::BlackScholesMertonProcess(QuantLib::Handle<QuantLib::Quote>(spot), QuantLib::Handle<QuantLib::YieldTermStructure>(qTS), QuantLib::Handle<QuantLib::YieldTermStructure>(rTS), QuantLib::Handle<QuantLib::BlackVolTermStructure>(volTS))); // Size timeSteps = 1; // bool antitheticVariate = false; // bool controlVariate = false; // Size requiredSamples = 10000; // double requiredTolerance = 0.02; // Size maxSamples = 1000000; // bool isBiased = false; boost::shared_ptr<QuantLib::PricingEngine> engine(new QuantLib::AnalyticBarrierEngine(stochProcess)); // need to explicitly reference BarrierOption from QuantLib here QuantLib::BarrierOption barrierOption(barrierType, barrier, rebate, payoff, exercise); barrierOption.setPricingEngine(engine); Rcpp::List rl = Rcpp::List::create(Rcpp::Named("value") = barrierOption.NPV(), Rcpp::Named("delta") = R_NaReal, Rcpp::Named("gamma") = R_NaReal, Rcpp::Named("vega") = R_NaReal, Rcpp::Named("theta") = R_NaReal, Rcpp::Named("rho") = R_NaReal, Rcpp::Named("divRho") = R_NaReal); return rl; }
// [[Rcpp::export]] Rcpp::List asianOptionEngine(std::string averageType, std::string type, double underlying, double strike, double dividendYield, double riskFreeRate, double maturity, double volatility, double first, double length, size_t fixings) { QuantLib::Option::Type optionType = getOptionType(type); //from test-suite/asionoptions.cpp QuantLib::DayCounter dc = QuantLib::Actual360(); QuantLib::Date today = QuantLib::Date::todaysDate(); QuantLib::Settings::instance().evaluationDate() = today; QuantLib::ext::shared_ptr<QuantLib::SimpleQuote> spot(new QuantLib::SimpleQuote(underlying)); QuantLib::ext::shared_ptr<QuantLib::SimpleQuote> qRate(new QuantLib::SimpleQuote(dividendYield)); QuantLib::ext::shared_ptr<QuantLib::YieldTermStructure> qTS = flatRate(today, qRate, dc); QuantLib::ext::shared_ptr<QuantLib::SimpleQuote> rRate(new QuantLib::SimpleQuote(riskFreeRate)); QuantLib::ext::shared_ptr<QuantLib::YieldTermStructure> rTS = flatRate(today, rRate, dc); QuantLib::ext::shared_ptr<QuantLib::SimpleQuote> vol(new QuantLib::SimpleQuote(volatility)); QuantLib::ext::shared_ptr<QuantLib::BlackVolTermStructure> volTS = flatVol(today, vol, dc); QuantLib::ext::shared_ptr<QuantLib::BlackScholesMertonProcess> stochProcess(new QuantLib::BlackScholesMertonProcess(QuantLib::Handle<QuantLib::Quote>(spot), QuantLib::Handle<QuantLib::YieldTermStructure>(qTS), QuantLib::Handle<QuantLib::YieldTermStructure>(rTS), QuantLib::Handle<QuantLib::BlackVolTermStructure>(volTS))); QuantLib::ext::shared_ptr<QuantLib::StrikedTypePayoff> payoff(new QuantLib::PlainVanillaPayoff(optionType,strike)); Rcpp::List rl = R_NilValue; if (averageType=="geometric"){ QuantLib::ext::shared_ptr<QuantLib::PricingEngine> engine(new QuantLib::AnalyticContinuousGeometricAveragePriceAsianEngine(stochProcess)); #ifdef QL_HIGH_RESOLUTION_DATE // in minutes QuantLib::Date exDate(today.dateTime() + boost::posix_time::minutes(boost::uint64_t(maturity * 360 * 24 * 60))); #else QuantLib::Date exDate = today + int(maturity * 360 + 0.5); #endif boost::shared_ptr<QuantLib::Exercise> exercise(new QuantLib::EuropeanExercise(exDate)); QuantLib::ContinuousAveragingAsianOption option(QuantLib::Average::Geometric, 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()); } else if (averageType=="arithmetic") { // TODO: check fixings > 1, first, length if (first < 0) Rcpp::stop("Parameter 'first' must be non-negative."); if (length < 0) Rcpp::stop("Parameter 'length' must be non-negative."); if (fixings <= 1) Rcpp::stop("Parameter 'fixings' must be larger than one."); boost::shared_ptr<QuantLib::PricingEngine> engine = QuantLib::MakeMCDiscreteArithmeticAPEngine<QuantLib::LowDiscrepancy>(stochProcess) .withSamples(2047) .withControlVariate(); //boost::shared_ptr<PricingEngine> engine = // MakeMCDiscreteArithmeticASEngine<LowDiscrepancy>(stochProcess) // .withSeed(3456789) // .withSamples(1023); QuantLib::Time dt = length / (fixings - 1); std::vector<QuantLib::Time> timeIncrements(fixings); std::vector<QuantLib::Date> fixingDates(fixings); timeIncrements[0] = first; fixingDates[0] = today + QuantLib::Integer(timeIncrements[0] * 360 + 0.5); for (QuantLib::Size i=1; i<fixings; i++) { timeIncrements[i] = i*dt + first; #ifdef QL_HIGH_RESOLUTION_DATE fixingDates[i]= QuantLib::Date(today.dateTime() + boost::posix_time::minutes(boost::uint64_t(timeIncrements[i] * 360 * 24 * 60))); #else fixingDates[i] = today + QuantLib::Integer(timeIncrements[i]*360+0.5); #endif } QuantLib::Real runningSum = 0.0; QuantLib::Size pastFixing = 0; boost::shared_ptr<QuantLib::Exercise> exercise(new QuantLib::EuropeanExercise(fixingDates[fixings-1])); QuantLib::DiscreteAveragingAsianOption option(QuantLib::Average::Arithmetic, runningSum, pastFixing, fixingDates, payoff, exercise); option.setPricingEngine(engine); rl = Rcpp::List::create(Rcpp::Named("value") = option.NPV(), Rcpp::Named("delta") = R_NaReal, Rcpp::Named("gamma") = R_NaReal, Rcpp::Named("vega") = R_NaReal, Rcpp::Named("theta") = R_NaReal, Rcpp::Named("rho") = R_NaReal, Rcpp::Named("divRho") = R_NaReal); } return rl; }
RcppExport SEXP AsianOption(SEXP optionParameters){ try{ Rcpp::List rparam(optionParameters); std::string avgType = Rcpp::as<std::string>(rparam["averageType"]); std::string type = Rcpp::as<std::string>(rparam["type"]); double underlying = Rcpp::as<double>(rparam["underlying"]); double strike = Rcpp::as<double>(rparam["strike"]); QuantLib::Spread dividendYield = Rcpp::as<double>(rparam["dividendYield"]); QuantLib::Rate riskFreeRate = Rcpp::as<double>(rparam["riskFreeRate"]); QuantLib::Time maturity = Rcpp::as<double>(rparam["maturity"]); // int length = int(maturity*360 + 0.5); // FIXME: this could be better double volatility = Rcpp::as<double>(rparam["volatility"]); QuantLib::Option::Type optionType = getOptionType(type); //from test-suite/asionoptions.cpp QuantLib::DayCounter dc = QuantLib::Actual360(); QuantLib::Date today = QuantLib::Date::todaysDate(); QuantLib::Settings::instance().evaluationDate() = today; boost::shared_ptr<QuantLib::SimpleQuote> spot(new QuantLib::SimpleQuote(underlying)); boost::shared_ptr<QuantLib::SimpleQuote> qRate(new QuantLib::SimpleQuote(dividendYield)); boost::shared_ptr<QuantLib::YieldTermStructure> qTS = flatRate(today, qRate, dc); boost::shared_ptr<QuantLib::SimpleQuote> rRate(new QuantLib::SimpleQuote(riskFreeRate)); boost::shared_ptr<QuantLib::YieldTermStructure> rTS = flatRate(today, rRate, dc); boost::shared_ptr<QuantLib::SimpleQuote> vol(new QuantLib::SimpleQuote(volatility)); boost::shared_ptr<QuantLib::BlackVolTermStructure> volTS = flatVol(today, vol, dc); boost::shared_ptr<QuantLib::BlackScholesMertonProcess> stochProcess(new QuantLib::BlackScholesMertonProcess(QuantLib::Handle<QuantLib::Quote>(spot), QuantLib::Handle<QuantLib::YieldTermStructure>(qTS), QuantLib::Handle<QuantLib::YieldTermStructure>(rTS), QuantLib::Handle<QuantLib::BlackVolTermStructure>(volTS))); boost::shared_ptr<QuantLib::StrikedTypePayoff> payoff(new QuantLib::PlainVanillaPayoff(optionType,strike)); QuantLib::Average::Type averageType = QuantLib::Average::Geometric; Rcpp::List rl = R_NilValue; if (avgType=="geometric"){ averageType = QuantLib::Average::Geometric; boost::shared_ptr<QuantLib::PricingEngine> engine(new QuantLib::AnalyticContinuousGeometricAveragePriceAsianEngine(stochProcess)); QuantLib::Date exDate = today + int(maturity * 360 + 0.5); boost::shared_ptr<QuantLib::Exercise> exercise(new QuantLib::EuropeanExercise(exDate)); QuantLib::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 = QuantLib::Average::Arithmetic; boost::shared_ptr<QuantLib::PricingEngine> engine = QuantLib::MakeMCDiscreteArithmeticAPEngine<QuantLib::LowDiscrepancy>(stochProcess) .withSamples(2047) .withControlVariate(); //boost::shared_ptr<PricingEngine> engine = // MakeMCDiscreteArithmeticASEngine<LowDiscrepancy>(stochProcess) // .withSeed(3456789) // .withSamples(1023); QuantLib::Size fixings = Rcpp::as<double>(rparam["fixings"]); QuantLib::Time length = Rcpp::as<double>(rparam["length"]); QuantLib::Time first = Rcpp::as<double>(rparam["first"]); QuantLib::Time dt = length / (fixings - 1); std::vector<QuantLib::Time> timeIncrements(fixings); std::vector<QuantLib::Date> fixingDates(fixings); timeIncrements[0] = first; fixingDates[0] = today + QuantLib::Integer(timeIncrements[0] * 360 + 0.5); for (QuantLib::Size i=1; i<fixings; i++) { timeIncrements[i] = i*dt + first; fixingDates[i] = today + QuantLib::Integer(timeIncrements[i]*360+0.5); } QuantLib::Real runningSum = 0.0; QuantLib::Size pastFixing = 0; boost::shared_ptr<QuantLib::Exercise> exercise(new QuantLib::EuropeanExercise(fixingDates[fixings-1])); QuantLib::DiscreteAveragingAsianOption option(QuantLib::Average::Arithmetic, runningSum, pastFixing, fixingDates, payoff, exercise); option.setPricingEngine(engine); rl = Rcpp::List::create(Rcpp::Named("value") = option.NPV(), Rcpp::Named("delta") = R_NaN, Rcpp::Named("gamma") = R_NaN, Rcpp::Named("vega") = R_NaN, Rcpp::Named("theta") = R_NaN, Rcpp::Named("rho") = R_NaN, Rcpp::Named("divRho") = R_NaN, Rcpp::Named("parameters") = optionParameters); } else { throw std::range_error("Unknown average type " + type); } return rl; } catch(std::exception &ex) { forward_exception_to_r(ex); } catch(...) { ::Rf_error("c++ exception (unknown reason)"); } return R_NilValue; }
std::string OptionsFunctionalityNode::getOptionTypeName(const std::string &name) const { return GenericType::get_type_description(getOptionType(name)); }
// [[Rcpp::export]] Rcpp::List europeanOptionEngine(std::string type, double underlying, double strike, double dividendYield, double riskFreeRate, double maturity, double volatility, Rcpp::Nullable<Rcpp::NumericVector> discreteDividends, Rcpp::Nullable<Rcpp::NumericVector> discreteDividendsTimeUntil) { #ifdef QL_HIGH_RESOLUTION_DATE // in minutes boost::posix_time::time_duration length = boost::posix_time::minutes(boost::uint64_t(maturity * 360 * 24 * 60)); #else int length = int(maturity*360 + 0.5); // FIXME: this could be better #endif QuantLib::Option::Type optionType = getOptionType(type); QuantLib::Date today = QuantLib::Date::todaysDate(); QuantLib::Settings::instance().evaluationDate() = today; // new framework as per QuantLib 0.3.5 QuantLib::DayCounter dc = QuantLib::Actual360(); boost::shared_ptr<QuantLib::SimpleQuote> spot(new QuantLib::SimpleQuote( underlying )); boost::shared_ptr<QuantLib::SimpleQuote> vol(new QuantLib::SimpleQuote( volatility )); boost::shared_ptr<QuantLib::BlackVolTermStructure> volTS = flatVol(today, vol, dc); boost::shared_ptr<QuantLib::SimpleQuote> qRate(new QuantLib::SimpleQuote( dividendYield )); boost::shared_ptr<QuantLib::YieldTermStructure> qTS = flatRate(today, qRate, dc); boost::shared_ptr<QuantLib::SimpleQuote> rRate(new QuantLib::SimpleQuote( riskFreeRate )); boost::shared_ptr<QuantLib::YieldTermStructure> rTS = flatRate(today, rRate, dc); bool withDividends = discreteDividends.isNotNull() && discreteDividendsTimeUntil.isNotNull(); #ifdef QL_HIGH_RESOLUTION_DATE QuantLib::Date exDate(today.dateTime() + length); #else QuantLib::Date exDate = today + length; #endif boost::shared_ptr<QuantLib::Exercise> exercise(new QuantLib::EuropeanExercise(exDate)); boost::shared_ptr<QuantLib::StrikedTypePayoff> payoff(new QuantLib::PlainVanillaPayoff(optionType, strike)); if (withDividends) { Rcpp::NumericVector divvalues(discreteDividends), divtimes(discreteDividendsTimeUntil); int n = divvalues.size(); std::vector<QuantLib::Date> discDivDates(n); std::vector<double> discDividends(n); for (int i = 0; i < n; i++) { #ifdef QL_HIGH_RESOLUTION_DATE boost::posix_time::time_duration discreteDividendLength = boost::posix_time::minutes(boost::uint64_t(divtimes[i] * 360 * 24 * 60)); discDivDates[i] = QuantLib::Date(today.dateTime() + discreteDividendLength); #else discDivDates[i] = today + int(divtimes[i] * 360 + 0.5); #endif discDividends[i] = divvalues[i]; } boost::shared_ptr<QuantLib::BlackScholesMertonProcess> stochProcess(new QuantLib::BlackScholesMertonProcess(QuantLib::Handle<QuantLib::Quote>(spot), QuantLib::Handle<QuantLib::YieldTermStructure>(qTS), QuantLib::Handle<QuantLib::YieldTermStructure>(rTS), QuantLib::Handle<QuantLib::BlackVolTermStructure>(volTS))); boost::shared_ptr<QuantLib::PricingEngine> engine(new QuantLib::AnalyticDividendEuropeanEngine(stochProcess)); QuantLib::DividendVanillaOption option(payoff, exercise, discDivDates, discDividends); option.setPricingEngine(engine); return 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") = R_NaReal); } else { boost::shared_ptr<QuantLib::VanillaOption> option = makeOption(payoff, exercise, spot, qTS, rTS, volTS); return 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::export]] Rcpp::List americanOptionEngine(std::string type, double underlying, double strike, double dividendYield, double riskFreeRate, double maturity, double volatility, int timeSteps, int gridPoints, std::string engine, Rcpp::Nullable<Rcpp::NumericVector> discreteDividends, Rcpp::Nullable<Rcpp::NumericVector> discreteDividendsTimeUntil) { #ifdef QL_HIGH_RESOLUTION_DATE // in minutes boost::posix_time::time_duration length = boost::posix_time::minutes(boost::uint64_t(maturity * 360 * 24 * 60)); #else int length = int(maturity * 360 + 0.5); // FIXME: this could be better #endif QuantLib::Option::Type optionType = getOptionType(type); // new framework as per QuantLib 0.3.5, updated for 0.3.7 // updated again for 0.9.0, see eg test-suite/americanoption.cpp QuantLib::Date today = QuantLib::Date::todaysDate(); QuantLib::Settings::instance().evaluationDate() = today; QuantLib::DayCounter dc = QuantLib::Actual360(); boost::shared_ptr<QuantLib::SimpleQuote> spot(new QuantLib::SimpleQuote(underlying)); boost::shared_ptr<QuantLib::SimpleQuote> qRate(new QuantLib::SimpleQuote(dividendYield)); boost::shared_ptr<QuantLib::YieldTermStructure> qTS = flatRate(today,qRate,dc); boost::shared_ptr<QuantLib::SimpleQuote> rRate(new QuantLib::SimpleQuote(riskFreeRate)); boost::shared_ptr<QuantLib::YieldTermStructure> rTS = flatRate(today,rRate,dc); boost::shared_ptr<QuantLib::SimpleQuote> vol(new QuantLib::SimpleQuote(volatility)); boost::shared_ptr<QuantLib::BlackVolTermStructure> volTS = flatVol(today, vol, dc); bool withDividends = discreteDividends.isNotNull() && discreteDividendsTimeUntil.isNotNull(); #ifdef QL_HIGH_RESOLUTION_DATE QuantLib::Date exDate(today.dateTime() + length); #else QuantLib::Date exDate = today + length; #endif boost::shared_ptr<QuantLib::StrikedTypePayoff> payoff(new QuantLib::PlainVanillaPayoff(optionType, strike)); boost::shared_ptr<QuantLib::Exercise> exercise(new QuantLib::AmericanExercise(today, exDate)); boost::shared_ptr<QuantLib::BlackScholesMertonProcess> stochProcess(new QuantLib::BlackScholesMertonProcess(QuantLib::Handle<QuantLib::Quote>(spot), QuantLib::Handle<QuantLib::YieldTermStructure>(qTS), QuantLib::Handle<QuantLib::YieldTermStructure>(rTS), QuantLib::Handle<QuantLib::BlackVolTermStructure>(volTS))); if (withDividends) { Rcpp::NumericVector divvalues(discreteDividends), divtimes(discreteDividendsTimeUntil); int n = divvalues.size(); std::vector<QuantLib::Date> discDivDates(n); std::vector<double> discDividends(n); for (int i = 0; i < n; i++) { #ifdef QL_HIGH_RESOLUTION_DATE boost::posix_time::time_duration discreteDividendLength = boost::posix_time::minutes(boost::uint64_t(divtimes[i] * 360 * 24 * 60)); discDivDates[i] = QuantLib::Date(today.dateTime() + discreteDividendLength); #else discDivDates[i] = today + int(divtimes[i] * 360 + 0.5); #endif discDividends[i] = divvalues[i]; } QuantLib::DividendVanillaOption option(payoff, exercise, discDivDates, discDividends); if (engine=="BaroneAdesiWhaley") { Rcpp::warning("Discrete dividends, engine switched to CrankNicolson"); engine = "CrankNicolson"; } if (engine=="CrankNicolson") { // FDDividendAmericanEngine only works with CrankNicolson // suggestion by Bryan Lewis: use CrankNicolson for greeks boost::shared_ptr<QuantLib::PricingEngine> fdcnengine(new QuantLib::FDDividendAmericanEngine<QuantLib::CrankNicolson>(stochProcess, timeSteps, gridPoints)); option.setPricingEngine(fdcnengine); return Rcpp::List::create(Rcpp::Named("value") = option.NPV(), Rcpp::Named("delta") = option.delta(), Rcpp::Named("gamma") = option.gamma(), Rcpp::Named("vega") = R_NaReal, Rcpp::Named("theta") = R_NaReal, Rcpp::Named("rho") = R_NaReal, Rcpp::Named("divRho") = R_NaReal); } else { throw std::range_error("Unknown engine " + engine); } } else { QuantLib::VanillaOption option(payoff, exercise); if (engine=="BaroneAdesiWhaley") { // new from 0.3.7 BaroneAdesiWhaley boost::shared_ptr<QuantLib::PricingEngine> engine(new QuantLib::BaroneAdesiWhaleyApproximationEngine(stochProcess)); option.setPricingEngine(engine); return Rcpp::List::create(Rcpp::Named("value") = option.NPV(), Rcpp::Named("delta") = R_NaReal, Rcpp::Named("gamma") = R_NaReal, Rcpp::Named("vega") = R_NaReal, Rcpp::Named("theta") = R_NaReal, Rcpp::Named("rho") = R_NaReal, Rcpp::Named("divRho") = R_NaReal); } else if (engine=="CrankNicolson") { // suggestion by Bryan Lewis: use CrankNicolson for greeks boost::shared_ptr<QuantLib::PricingEngine> fdcnengine(new QuantLib::FDAmericanEngine<QuantLib::CrankNicolson>(stochProcess, timeSteps, gridPoints)); option.setPricingEngine(fdcnengine); return Rcpp::List::create(Rcpp::Named("value") = option.NPV(), Rcpp::Named("delta") = option.delta(), Rcpp::Named("gamma") = option.gamma(), Rcpp::Named("vega") = R_NaReal, Rcpp::Named("theta") = R_NaReal, Rcpp::Named("rho") = R_NaReal, Rcpp::Named("divRho") = R_NaReal); } else { throw std::range_error("Unknown engine " + engine); } } }
static int parseOneOption (char *opt, char* const argv[], const int argc, int *pos) { if (strcmp(opt,"-activate") == 0) { ASSERT_HAS_NEXT(); char *o = argv[++(*pos)]; if (!hasCommandOption(o)) { errorMessage = o; return 1; } (*pos)++; (*pos) -= 2; setBoolOption(o,TRUE); return 0; } else if (strcmp(opt,"-deactivate") == 0) { ASSERT_HAS_NEXT(); char *o = argv[++(*pos)]; if (!hasCommandOption(o)) { errorMessage = o; return 1; } (*pos)++; (*pos) -= 2; setBoolOption(o,FALSE); return 0; } else if (hasCommandOption(opt)) { char *o = commandOptionGetOption(opt); (*pos)++; switch(getOptionType(o)) { case OPTION_INT: { ASSERT_HAS_NEXT(); int val = atoi(argv[*pos]); setIntOption(o,val); (*pos)++; (*pos) -= 2; } break; case OPTION_STRING: { ASSERT_HAS_NEXT(); setStringOption(o,strdup(argv[*pos])); (*pos)++; (*pos) -= 2; } break; case OPTION_FLOAT: { ASSERT_HAS_NEXT(); //TODO (*pos)++; (*pos) -= 2; } break; case OPTION_BOOL: // if user has given value as separate argument if (*pos < argc && !isOption(argv[*pos])) { char *bVal = argv[*pos]; if (streq(bVal,"TRUE") || streq(bVal,"t") || streq(bVal,"1") || streq(bVal,"true")) setBoolOption(o,TRUE); else setBoolOption(o,FALSE); } // otherwise mentioning an option sets it to TRUE else { setBoolOption(o, TRUE); (*pos) -= 1; } break; } return 0; } else { errorMessage = opt; return 1; } }
static Bool initOptionFromMetadataPath (CompDisplay *d, CompMetadata *metadata, CompOption *option, const xmlChar *path) { CompXPath xPath, xDefaultPath; xmlNodePtr node, defaultNode; xmlDocPtr defaultDoc; xmlChar *name, *type; char *value; CompActionState state = 0; Bool helper = FALSE; if (!initXPathFromMetadataPath (&xPath, metadata, path)) return FALSE; node = *xPath.obj->nodesetval->nodeTab; type = xmlGetProp (node, BAD_CAST "type"); if (type) { option->type = getOptionType ((char *) type); xmlFree (type); } else { option->type = CompOptionTypeBool; } name = xmlGetProp (node, BAD_CAST "name"); option->name = strdup ((char *) name); xmlFree (name); if (initXPathFromMetadataPathElement (&xDefaultPath, metadata, path, BAD_CAST "default")) { defaultDoc = xDefaultPath.doc; defaultNode = *xDefaultPath.obj->nodesetval->nodeTab; } else { defaultDoc = NULL; defaultNode = NULL; } switch (option->type) { case CompOptionTypeBool: initBoolValue (&option->value, defaultDoc, defaultNode); break; case CompOptionTypeInt: initIntRestriction (metadata, &option->rest, (char *) path); initIntValue (&option->value, &option->rest, defaultDoc, defaultNode); break; case CompOptionTypeFloat: initFloatRestriction (metadata, &option->rest, (char *) path); initFloatValue (&option->value, &option->rest, defaultDoc, defaultNode); break; case CompOptionTypeString: initStringValue (&option->value, &option->rest, defaultDoc, defaultNode); break; case CompOptionTypeColor: initColorValue (&option->value, defaultDoc, defaultNode); break; case CompOptionTypeAction: initActionState (metadata, option->type, &state, (char *) path); initActionValue (d, &option->value, state, defaultDoc, defaultNode); break; case CompOptionTypeKey: initActionState (metadata, option->type, &state, (char *) path); initKeyValue (d, &option->value, state, defaultDoc, defaultNode); break; case CompOptionTypeButton: initActionState (metadata, option->type, &state, (char *) path); initButtonValue (d, &option->value, state, defaultDoc, defaultNode); break; case CompOptionTypeEdge: initActionState (metadata, option->type, &state, (char *) path); initEdgeValue (d, &option->value, state, defaultDoc, defaultNode); break; case CompOptionTypeBell: initActionState (metadata, option->type, &state, (char *) path); initBellValue (d, &option->value, state, defaultDoc, defaultNode); break; case CompOptionTypeMatch: helper = boolFromMetadataPathElement (metadata, (char *) path, "helper", FALSE); initMatchValue (d, &option->value, helper, defaultDoc, defaultNode); break; case CompOptionTypeList: value = stringFromMetadataPathElement (metadata, (char *) path, "type"); if (value) { option->value.list.type = getOptionType ((char *) value); free (value); } else { option->value.list.type = CompOptionTypeBool; } switch (option->value.list.type) { case CompOptionTypeInt: initIntRestriction (metadata, &option->rest, (char *) path); break; case CompOptionTypeFloat: initFloatRestriction (metadata, &option->rest, (char *) path); break; case CompOptionTypeAction: case CompOptionTypeKey: case CompOptionTypeButton: case CompOptionTypeEdge: case CompOptionTypeBell: initActionState (metadata, option->value.list.type, &state, (char *) path); break; case CompOptionTypeMatch: helper = boolFromMetadataPathElement (metadata, (char *) path, "helper", FALSE); default: break; } initListValue (d, &option->value, &option->rest, state, helper, defaultDoc, defaultNode); break; } if (defaultDoc) finiXPath (&xDefaultPath); finiXPath (&xPath); return TRUE; }