12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- // 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 <boost/math/differentiation/autodiff.hpp>
- #include <iostream>
- #include <stdexcept>
- 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 <typename X>
- X Phi(X const& x) {
- return 0.5 * erfc(-one_div_root_two<X>() * x);
- }
- enum class CP { call, put };
- // Assume zero annual dividend yield (q=0).
- template <typename Price, typename Sigma, typename Tau, typename Rate>
- promote<Price, Sigma, Tau, Rate> 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<double, 2>(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
- **/
|