// Copyright Matthew Pulver 2018 - 2019. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // https://www.boost.org/LICENSE_1_0.txt) #include #include #include using namespace boost::math::constants; using namespace boost::math::differentiation; // Equations and function/variable names are from // https://en.wikipedia.org/wiki/Greeks_(finance)#Formulas_for_European_option_Greeks // Standard normal cumulative distribution function template X Phi(X const& x) { return 0.5 * erfc(-one_div_root_two() * x); } enum class CP { call, put }; // Assume zero annual dividend yield (q=0). template promote black_scholes_option_price(CP cp, double K, Price const& S, Sigma const& sigma, Tau const& tau, Rate const& r) { using namespace std; auto const d1 = (log(S / K) + (r + sigma * sigma / 2) * tau) / (sigma * sqrt(tau)); auto const d2 = (log(S / K) + (r - sigma * sigma / 2) * tau) / (sigma * sqrt(tau)); switch (cp) { case CP::call: return S * Phi(d1) - exp(-r * tau) * K * Phi(d2); case CP::put: return exp(-r * tau) * K * Phi(-d2) - S * Phi(-d1); default: throw std::runtime_error("Invalid CP value."); } } int main() { double const K = 100.0; // Strike price. auto const S = make_fvar(105); // Stock price. double const sigma = 5; // Volatility. double const tau = 30.0 / 365; // Time to expiration in years. (30 days). double const r = 1.25 / 100; // Interest rate. auto const call_price = black_scholes_option_price(CP::call, K, S, sigma, tau, r); auto const put_price = black_scholes_option_price(CP::put, K, S, sigma, tau, r); std::cout << "black-scholes call price = " << call_price.derivative(0) << '\n' << "black-scholes put price = " << put_price.derivative(0) << '\n' << "call delta = " << call_price.derivative(1) << '\n' << "put delta = " << put_price.derivative(1) << '\n' << "call gamma = " << call_price.derivative(2) << '\n' << "put gamma = " << put_price.derivative(2) << '\n'; return 0; } /* Output: black-scholes call price = 56.5136 black-scholes put price = 51.4109 call delta = 0.773818 put delta = -0.226182 call gamma = 0.00199852 put gamma = 0.00199852 **/