diff --git a/DESCRIPTION b/DESCRIPTION index 9f9ea6c..d84bca0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: greeks Title: Sensitivities of Prices of Financial Options and Implied Volatilities -Version: 1.3.3 +Version: 1.3.4 Authors@R: person(given = "Anselm", family = "Hudde", diff --git a/src/Binomial_American_Greeks.cpp b/src/Binomial_American_Greeks.cpp index 7bb66df..83f6c59 100644 --- a/src/Binomial_American_Greeks.cpp +++ b/src/Binomial_American_Greeks.cpp @@ -7,12 +7,12 @@ using std::string; using std::max; -double american_call(double x, double price, double exercise_price) { - return max(x, price - exercise_price); +double american_call(double price, double exercise_price) { + return max(0.0, price - exercise_price); } -double american_put(double x, double price, double exercise_price) { - return max(x, exercise_price - price); +double american_put(double price, double exercise_price) { + return max(0.0, exercise_price - price); } // [[Rcpp::export]] @@ -26,7 +26,7 @@ NumericVector Binomial_American_Greeks_cpp(double initial_price = 100, const int steps = 1000) { // payoff_function - double (*payoff_function)(double x, double price, double exercise_price); + double (*payoff_function)(double price, double exercise_price); // iterators int i; @@ -42,7 +42,7 @@ NumericVector Binomial_American_Greeks_cpp(double initial_price = 100, const double down = exp(-volatility * sqrt(dt)); const double p = (exp((r-dividend_yield)*dt) - down)/(up-down); const double q = (1 - p); - const double exp_min_r_dt = exp(-r*dt); + const double exp_min_r_steps_dt = exp(-r*steps*dt); // generate the price vector NumericVector price(2*steps+1); @@ -62,17 +62,20 @@ NumericVector Binomial_American_Greeks_cpp(double initial_price = 100, } for(i = 0; i <= steps; i++) { - american_value(i) = payoff_function(0.0, price(2*steps - 2*i), exercise_price); + european_value(i) = + exp_min_r_steps_dt * payoff_function(price(2*steps - 2*i), exercise_price); } - european_value = clone(american_value); + american_value = clone(european_value); for(j = steps-1; j >= 0; j--) { for(i = 0; i <= j; i++) { - american_value(i) = payoff_function( - exp_min_r_dt * (p*american_value(i) + q*american_value(i+1)), - price(2*steps - 2*i + j - steps), exercise_price); european_value(i) = p * european_value(i) + q * european_value(i+1); + american_value(i) = p * american_value(i) + q * american_value(i+1); + american_value(i) = max( + exp(-(r-dividend_yield)*j*dt) * + payoff_function(price(2*steps - 2*i + j - steps), exercise_price), + american_value(i)); } }