Phil Cooper / Sep 21 2023
Greeks
Black-Scholes formula
See related python article.
{:deps {org.clojure/clojure {:mvn/version "1.10.3"}
;; complient is used for autocompletion
;; add your libs here (and restart the runtime to pick up changes)
compliment/compliment {:mvn/version "0.3.9"}}}
Extensible Data Notation
The Cumulativ Normal Distrubution (cdf) and Probablity Distribution Functions (pdf) can also be found in kixi-stats or apache.math but are provided here to limit dependencies.
(defn cdf
"Cumulative Normal Distribution function"
[X]
(let [a1 0.31938153, a2 -0.356563782, a3 1.781477937, a4 -1.821255978, a5 1.330274429
L (Math/abs X)
K (/ 1 (+ 1 (* 0.2316419 L)))
w (- 1 (* (/ 1 (Math/sqrt (* 2 Math/PI))) (Math/exp (- (* L L 0.5)))
(+ (* a1 K) (* a2 K K) (* a3 K K K) (* a4 K K K K) (* a5 K K K K K))))]
(if (< X 0) (- 1 w) w)))
(defn pdf
"Probability Distribution Function"
[x & {:keys [mean sd] :or {mean 0 sd 1}}]
(* (/ 1.0 (Math/sqrt (* 2 3.14159265358979 (Math/pow sd 2))))
(* (Math/exp (* -0.5 (Math/pow (/ (- x mean) sd) 2))))))
0.0s
; Black-Scholes in Clojure
; The direct translation of Black-Scholes in C++ by Espen Gaarder Haug
; http://www.espenhaug.com/black_scholes.html
(defn- d1* [S X T r v]
(/ (+ (Math/log (/ S X)) (* (+ r (* v v 0.5)) T)) (* v (Math/sqrt T))))
0.0s
; The Black and Scholes (1973) Stock option formula
(defn black-scholes [put-call-flag S X T r v]
(let [d1 (d1* S X T r v)
d2 (- d1 (* v (Math/sqrt T)))]
(case put-call-flag
:call (- (* S (cdf d1)) (* X (Math/exp (* (- r) T)) (cdf d2)))
:put (- (* X (Math/exp (* (- r) T)) (cdf (- d2))) (* S (cdf (- d1))))
(throw (Exception. "BAD put-call-flag")))))
0.0s
Calculation of a put or call option.
[(black-scholes :call 408.67 370 0.7014 0.04 0.2343)
(black-scholes :put 408.67 370 0.7014 0.04 0.2343)]
0.0s
Calculate Greeks on the options
(defn delta [put-call-flag S K T r sigma]
(case put-call-flag
:call (cdf (d1* S,K,T,r,sigma))
:put (* -1 (cdf (* -1 (d1* S,K,T,r,sigma))))
(throw (Exception. "BAD put-call-flag"))))
(defn gamma [_put-call-flag S K T r sigma]
(/ (pdf (d1* S K T r sigma)) (* S sigma (Math/sqrt T))))
(defn vega [_put-call-flag S K T r sigma]
(-> (pdf (d1* S K T r sigma))
(* 0.01 S (Math/sqrt T))))
(defn theta [put-call-flag S K T r sigma]
(let [d1 (d1* S K T r sigma)
d2 (- d1 (* sigma (Math/sqrt T)))
put-call-sign (case put-call-flag :call 1 :put -1 (throw (Exception. "BAD put-call-flag ")))]
(- (/ (* -0.01 S (pdf d1) sigma) 2 (Math/sqrt T))
(* 0.01 put-call-sign r K (Math/exp (* -1 r T)) (cdf (* put-call-sign d2))))))
(defn rho [put-call-flag S K T r sigma]
(let [d1 (d1* S K T r sigma)
d2 (- d1 (* sigma (Math/sqrt T)))
put-call-sign (case put-call-flag :call 1 :put -1 (throw (Exception. "BAD put-call-flag ")))]
(* 0.01 put-call-sign K T (Math/exp (* -1 r T)) (cdf (* put-call-sign d2)))))
0.1s
[(delta :call 408.67 370 0.7014 0.04 0.2343),(delta :put 408.67 370 0.7014 0.04 0.2343)]
0.0s
[(gamma :call 408.67 370 0.7014 0.04 0.2343), (gamma :put 408.67 370 0.7014 0.04 0.2343)]
0.0s
[(vega :call 408.67 370 0.7014 0.04 0.2343), (vega :put 408.67 370 0.7014 0.04 0.2343)]
0.0s
[(theta :call 408.67 370 0.7014 0.04 0.2343), (theta :put 408.67 370 0.7014 0.04 0.2343)]
0.0s
[(rho :call 408.67 370 0.7014 0.04 0.2343), (rho :put 408.67 370 0.7014 0.04 0.2343)]
0.0s
(black-scholes :put 408.67 370 0.7014 0.04 0.2343)
0.0s
0.0s