Class: BlackScholes
- Inherits:
-
Object
- Object
- BlackScholes
- Defined in:
- lib/black_scholes.rb
Overview
JavaScript adopted from Bernt Arne Odegaard’s Financial Numerical Recipes
http://finance.bi.no/~bernt/gcc_prog/algoritms/algoritms/algoritms.html
by Steve Derezinski, CXWeb, Inc. http://www.cxweb.com
Copyright (C) 1998 Steve Derezinski, Bernt Arne Odegaard
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
http://www.fsf.org/copyleft/gpl.html
Class Method Summary collapse
- .black_scholes(call, s, x, r, v, t) ⇒ Object
- .call_iv(s, x, r, t, o) ⇒ Object
- .n(z) ⇒ Object
- .ndist(z) ⇒ Object
- .option_implied_volatility(call, s, x, r, t, o) ⇒ Object
-
.probability(price, target, days, volatility) ⇒ Object
Returns probability of occuring below and above target price.
- .probability_above(price, target, days, volatility) ⇒ Object
- .probability_below(price, target, days, volatility) ⇒ Object
Class Method Details
.black_scholes(call, s, x, r, v, t) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/black_scholes.rb', line 45 def black_scholes(call,s,x,r,v,t) # call = Boolean (to calc call, call=True, put: call=false) # s = stock prics, x = strike price, r = no-risk interest rate # v = volitility (1 std dev of s for (1 yr? 1 month?, you pick) # t = time to maturity sqt = Math.sqrt(t) d1 = (Math.log(s/x) + r*t)/(v*sqt) + 0.5*(v*sqt) d2 = d1 - (v*sqt) if call delta = n(d1) nd2 = n(d2) else # put delta = -n(-d1) nd2 = -n(-d2) end ert = Math.exp(-r*t) nd1 = ndist(d1) gamma = nd1/(s*v*sqt) vega = s*sqt*nd1 theta = -(s*v*nd1)/(2*sqt) - r*x*ert*nd2 rho = x*t*ert*nd2 s*delta-x*ert*nd2 end |
.call_iv(s, x, r, t, o) ⇒ Object
100 101 102 |
# File 'lib/black_scholes.rb', line 100 def call_iv(s,x,r,t,o) option_implied_volatility(true,s,x,r/100.0,t/365.0,o) end |
.n(z) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/black_scholes.rb', line 22 def n(z) b1 = 0.31938153 b2 = -0.356563782 b3 = 1.781477937 b4 = -1.821255978 b5 = 1.330274429 p = 0.2316419 c2 = 0.3989423 a = z.abs return 1.0 if a > 6.0 t = 1.0/(1.0+a*p) b = c2*Math.exp((-z)*(z/2.0)) n = ((((b5*t+b4)*t+b3)*t+b2)*t+b1)*t n = 1.0-b*n n = 1.0 - n if z < 0.0 n end |
.ndist(z) ⇒ Object
18 19 20 |
# File 'lib/black_scholes.rb', line 18 def ndist(z) (1.0/(Math.sqrt(2*Math::PI)))*Math.exp(-0.5*z) end |
.option_implied_volatility(call, s, x, r, t, o) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/black_scholes.rb', line 75 def option_implied_volatility(call,s,x,r,t,o) # call = Boolean (to calc call, call=True, put: call=false) # s = stock prics, x = strike price, r = no-risk interest rate # t = time to maturity # o = option price sqt = Math.sqrt(t) accuracy = 0.0001 sigma = (o/s)/(0.398*sqt) 100.times do price = black_scholes(call,s,x,r,sigma,t) diff = o-price return sigma if diff.abs < accuracy d1 = (Math.log(s/x) + r*t)/(sigma*sqt) + 0.5*sigma*sqt vega = s*sqt*ndist(d1) sigma = sigma+diff/vega end raise "Failed to converge" end |
.probability(price, target, days, volatility) ⇒ Object
Returns probability of occuring below and above target price.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/black_scholes.rb', line 105 def probability(price, target, days, volatility) p = price.to_f q = target.to_f t = days / 365.0 v = volatility.to_f vt = v*Math.sqrt(t) lnpq = Math.log(q/p) d1 = lnpq / vt y = (1/(1+0.2316419*d1.abs)*100000).floor / 100000.0 z = (0.3989423*Math.exp(-((d1*d1)/2))*100000).floor / 100000.0 y5 = 1.330274*(y**5) y4 = 1.821256*(y**4) y3 = 1.781478*(y**3) y2 = 0.356538*(y**2) y1 = 0.3193815*y x = 1-z*(y5-y4+y3-y2+y1) x = (x*100000).floor / 100000.0 x = 1-x if d1 < 0 pbelow = (x*1000).floor / 10.0 pabove = ((1-x)*1000).floor / 10.0; [pbelow/100,pabove/100]; end |
.probability_above(price, target, days, volatility) ⇒ Object
137 138 139 |
# File 'lib/black_scholes.rb', line 137 def probability_above(price, target, days, volatility) probability(price, target, days, volatility)[1] end |
.probability_below(price, target, days, volatility) ⇒ Object
141 142 143 |
# File 'lib/black_scholes.rb', line 141 def probability_below(price, target, days, volatility) probability(price, target, days, volatility)[0] end |