• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //           Copyright Matthew Pulver 2018 - 2019.
2 // Distributed under the Boost Software License, Version 1.0.
3 //      (See accompanying file LICENSE_1_0.txt or copy at
4 //           https://www.boost.org/LICENSE_1_0.txt)
5 
6 #include <boost/math/differentiation/autodiff.hpp>
7 #include <iostream>
8 #include <stdexcept>
9 
10 using namespace boost::math::constants;
11 using namespace boost::math::differentiation;
12 
13 // Equations and function/variable names are from
14 // https://en.wikipedia.org/wiki/Greeks_(finance)#Formulas_for_European_option_Greeks
15 
16 // Standard normal cumulative distribution function
17 template <typename X>
Phi(X const & x)18 X Phi(X const& x) {
19   return 0.5 * erfc(-one_div_root_two<X>() * x);
20 }
21 
22 enum class CP { call, put };
23 
24 // Assume zero annual dividend yield (q=0).
25 template <typename Price, typename Sigma, typename Tau, typename Rate>
black_scholes_option_price(CP cp,double K,Price const & S,Sigma const & sigma,Tau const & tau,Rate const & r)26 promote<Price, Sigma, Tau, Rate> black_scholes_option_price(CP cp,
27                                                             double K,
28                                                             Price const& S,
29                                                             Sigma const& sigma,
30                                                             Tau const& tau,
31                                                             Rate const& r) {
32   using namespace std;
33   auto const d1 = (log(S / K) + (r + sigma * sigma / 2) * tau) / (sigma * sqrt(tau));
34   auto const d2 = (log(S / K) + (r - sigma * sigma / 2) * tau) / (sigma * sqrt(tau));
35   switch (cp) {
36     case CP::call:
37       return S * Phi(d1) - exp(-r * tau) * K * Phi(d2);
38     case CP::put:
39       return exp(-r * tau) * K * Phi(-d2) - S * Phi(-d1);
40     default:
41       throw std::runtime_error("Invalid CP value.");
42   }
43 }
44 
main()45 int main() {
46   double const K = 100.0;                    // Strike price.
47   auto const S = make_fvar<double, 2>(105);  // Stock price.
48   double const sigma = 5;                    // Volatility.
49   double const tau = 30.0 / 365;             // Time to expiration in years. (30 days).
50   double const r = 1.25 / 100;               // Interest rate.
51   auto const call_price = black_scholes_option_price(CP::call, K, S, sigma, tau, r);
52   auto const put_price = black_scholes_option_price(CP::put, K, S, sigma, tau, r);
53 
54   std::cout << "black-scholes call price = " << call_price.derivative(0) << '\n'
55             << "black-scholes put  price = " << put_price.derivative(0) << '\n'
56             << "call delta = " << call_price.derivative(1) << '\n'
57             << "put  delta = " << put_price.derivative(1) << '\n'
58             << "call gamma = " << call_price.derivative(2) << '\n'
59             << "put  gamma = " << put_price.derivative(2) << '\n';
60   return 0;
61 }
62 /*
63 Output:
64 black-scholes call price = 56.5136
65 black-scholes put  price = 51.4109
66 call delta = 0.773818
67 put  delta = -0.226182
68 call gamma = 0.00199852
69 put  gamma = 0.00199852
70 **/
71