So I’ve been busy lately and haven’t had the time to write any new blog posts, but I can’t let all of February go past without posting anything. So I might as well write a post related to what I’m currently working on. And that would be pricing an Asian Option.
But in stead of just posting some of the MATLAB code we’re currently working on, I thought I’d do it in Java. Why Java? Well, two reasons:
 It’s way faster than MATLAB
 Since we’re all getting more and more cores in our computers I might as well do it multithreaded
Although there are faster ways of doing this than using Monte Carlo simulations, that’s what I’ve gone for. Had I gone for a stochastic calculus solution it would be sort of pointless doing a multithreaded implementation, right?
I don’t guarantee any of the results, as I might have easily screwed up some of the formulas (I’m still learning this stuff..)
So without further ado, here’s the code:
 package asianoption;

 import java.text.DecimalFormat;
 import java.util.Random;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.CountDownLatch;

 /**
 * @author Christian Felde (cfelde AT cfelde DOT com)
 *
 * Copyrighted me, no guaranties given..
 */
 public class PriceAsianOption implements Runnable {
 private final CountDownLatch latch;
 private final ConcurrentMap<String, Double> results;
 private final double T, r, vol, dt, S0, K;
 private final int sims, threads;

 public static void main(String... args) throws InterruptedException {
 double T = 1.0; // 1 year terminal time
 double r = 0.02; // 2% annual risk free rate
 double vol = 0.4; // 40% annual volatility
 double dt = 1.0/250.0; // Time step of one day (given 250 trading days)
 double S0 = 100.0; // Initial stock price
 double K = 100.0; // Option strike price

 // Define number of concurrent simulations
 // and number of simulation pr thread.
 int threadCount = Runtime.getRuntime().availableProcessors();
 int simsPrThread = 100000;

 System.out.print("Running " + threadCount + " threads ");
 System.out.println("with " + simsPrThread + " sims in each thread..");

 DecimalFormat formatter = new DecimalFormat("#.######");
 PriceAsianOption pao = new PriceAsianOption(T, r, vol, dt,
 S0, K, threadCount, simsPrThread);
 System.out.println("Option price: "
 + formatter.format(pao.getPrice()));
 }

 public PriceAsianOption(double T, double r, double vol, double dt,
 double S0, double K, int threadCount, int simsPrThread) {
 results = new ConcurrentHashMap<String, Double>();

 // Set up latch
 latch = new CountDownLatch(threadCount);
 this.threads = threadCount;

 // Global read vars
 this.T = T;
 this.r = r;
 this.vol = vol;
 this.dt = dt;
 this.S0 = S0;
 this.K = K;
 this.sims = simsPrThread;
 }

 /**
 * Calculate the price of an asian option using
 * multi threaded Monte Carlo simulations
 *
 * @return Asian option price
 */
 public double getPrice() throws InterruptedException {
 long start = System.currentTimeMillis();
 for (int i = 0; i < threads; i++) {
 new Thread(this).start();
 }

 latch.await();
 long end = System.currentTimeMillis();

 System.out.println("Run time in millis: " + (endstart));

 DecimalFormat formatter = new DecimalFormat("#.######");
 double result = 0.0;
 for (String name : results.keySet()) {
 System.out.println(name + ": "
 + formatter.format(results.get(name)));
 result += results.get(name);
 }

 return result/threads;
 }

 /**
 * This is where we run the monte carlo sims..
 */
 public void run() {
 Random random = new Random();

 // For the purpose of being efficient, let's define our constants
 // outside the main loop
 double a = (r  (0.5*Math.pow(vol, 2)))*dt;
 double b = vol*Math.sqrt(dt);

 double result = 0.0;
 for (int i = 0; i < sims; i++) {
 double avgPrice = 0.0;
 int steps = 0;
 double lastPrice = S0;
 for (double t = dt; t <= T; t += dt) {
 // This is our Geometric Brownian motion..
 lastPrice = lastPrice*Math.exp(a
 + (b*random.nextGaussian()));
 avgPrice += lastPrice;
 steps++;
 }
 avgPrice = avgPrice/steps; // This is the average stock price
 result += Math.max(0, avgPriceK);
 }
 result = result/sims; // This is the mean forward option price
 result = result*Math.exp(r*T); // Now it's discounted..

 results.put(Thread.currentThread().getName(), result);

 latch.countDown();
 }
 }
On my 2 year old dual core MacBook Pro this is the output I get when running it:
Running 2 threads with 100000 sims in each thread..
Run time in millis: 4463
Thread0: 9.590498
Thread1: 9.614967
Option price: 9.602732
Hope you find it helpful 🙂
Hi.
Nice Blog!! I suggest instead of storing the values in the current thread you could use Future Callable implementation. I guess it would be much Clearer.
Thank,
Vikas
Thanks for the comment, and yes, absolutely room for design improvements but hopefully it serves as a decent example 😉
Hi,
Very impressive. May I ask what method you use for pricing the options?
Just Monte Carlo with a simple GBM.