Instantly share code, notes, and snippets.

# nairbv/CallOptionPrice.scala

Last active April 3, 2020 18:26
Show Gist options
• Save nairbv/8726970 to your computer and use it in GitHub Desktop.
Scala script to price a call option using a binomial model. Work backwards from market price (using a solver) to find implied vol.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 import scala.math import scala.util.Random /** * Pricing a call option using a binomial option pricing model. * Formulas from: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.119.9442&rep=rep1&type=pdf */ val r = new Random // the up move in the binomial model def up(sigma:Double, rf:Double, t:Double)= math.exp(sigma * math.sqrt(t)) // probability of an up move def probabilityUp(rf:Double, u:Double,d:Double,t :Double) = (math.exp( t * rf) - d)/(u-d) // time a function and output duration def time( f: => Unit ) { val start = System.currentTimeMillis; f println("time: " + (System.currentTimeMillis - start) ) } def call(undly:Double, strike:Double, toExpiry:Double, n:Int, sigma:Double, rf:Double) = { val t = toExpiry / n val u = up(sigma,rf,t) val d = 1/u val p = probabilityUp(rf, u, d, t) val cache = Array.fill[Double](n+1,n+1)(-10) def f(i:Int,j:Int):Double = { val result = if( cache(i)(j) != -10 ) { cache(i)(j) } else if( i == n ) math.max( undly * math.pow(u,j) * math.pow(d,n-j) - strike, 0d) else { math.max( undly * math.pow(u,j) * math.pow(d,i-j) - strike, math.exp(-rf*t) * p * f(i+1,j+1) + (1-p)*f(i+1,j)) } cache(i)(j)=result result } f(0,0) } // today is jan 30 2013 // looking at Dec 20, 2014 \$130 calls // current price of spy is 179.23 // https://www.google.com/finance?q=NYSEARCA:SPY val price = 179.23 // the 130 calls val strike = 130 // jan 30 2013 -> dec 20 2014 is approximately 11 months to expiry val toExpiry = 11/12.0 // 1 year treasury is .10 as of jan 30 2013. // http://www.treasury.gov/resource-center/data-chart-center/interest-rates/Pages/TextView.aspx?data=yield // subtracting a dividend yield of 1.87% from google finance. val rf = 0.001 - 0.0187 // Using VIX as implied vol since this is SPY. Can use a solver to search for implied vol in: // call(u,s,ex,n,impliedVol,rf)-marketPrice==0 // VIX = 17.29: http://finance.yahoo.com/q?s=%5EVIX val sigma = .1729 // increase for better accuracy, decrease for performance. val n = 100 time { println( call( price, strike, toExpiry, n, sigma, rf) ) } // actual output: // 49.22999999999999 // time: 19 // price of SPY 130 dec 20 2014 calls on google finance are: // 48.15/48.81/49.25 for the last_trade/bid/ask.