JavaFX – Monte Carlo option pricing applet

One of the things I like about JavaFX is that it can be deployed on a lot of platforms, and very easy btw. So in this post I’m going to use the Option Pricing code from previous posts to create a JavaFX application that runs both on desktop and as an applet without any code tweaks. So basically I’ve created two packages:

src/
—— com.breekmd.wordpress.java
———— Main.java
———— MainLayoutController.java
—— com.breekmd.wordpress.rsc
———— application.css
———— MainLayout.fxml

In the java package we’re going to store our Java code, and in the rsc we’re going to store our resources – the .fxml file and the .css file (which is empty on this occasion).

One more thing I love about JavaFX is the Scene Builder which allows to create amazing UIs easily and then just to connect the .fxml file to a java Controller file and ensure the interaction between code and interface.

So here’s the code in each file (remember that application.css is empty):

Main.java:

package com.wordpress.breekmd.java;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

public class Main extends Application {

	private Stage mainStage;

	@Override
	public void start(Stage primaryStage) {
		try {
			this.mainStage = primaryStage;
			FXMLLoader loader = new FXMLLoader();
//			loader.setLocation(getClass().getResource("/com/wordpress/breekmd/rsc/MainLayout.fxml")); -- not the best idea for an applet
			AnchorPane pane = (AnchorPane) loader.load(getClass().getResourceAsStream("/com/wordpress/breekmd/rsc/MainLayout.fxml"));

			Scene mainScene = new Scene(pane);
			mainStage.setTitle("European options price calculator");
			mainStage.setScene(mainScene);
			mainStage.show();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		launch(args);
	}
}

MainLayoutController.java:

package com.wordpress.breekmd.java;

import java.text.DecimalFormat;

import javafx.fxml.FXML;
import javafx.scene.control.TextField;

public class MainLayoutController {

	@FXML
	TextField stepsField;

	@FXML
	TextField simulationsField;

	@FXML
	TextField volatilityField;

	@FXML
	TextField interestField;

	@FXML
	TextField stockField;

	@FXML
	TextField strikeField;

	@FXML
	TextField periodField;

	@FXML
	TextField callField;

	@FXML
	TextField putField;

	public void onCalculate(){
		setPutPrice();
		setCallPrice();
	}

	private void setCallPrice() {
		double S = Double.parseDouble(stockField.getText()); // Stock price
		double P = Double.parseDouble(strikeField.getText());; // Strike price
		double r = (double)Double.parseDouble(interestField.getText())/100; // Interest rate - 8%
		int N = Integer.parseInt(stepsField.getText()); // Number of steps (randomizations)
		double T = (double) Double.parseDouble(periodField.getText())/12; // Number of years until option expiration
		int M = Integer.parseInt(simulationsField.getText()); // Number of computations (number of possible payoffs calculated)
		double sigma = (double)Double.parseDouble(volatilityField.getText())/100; // Volatility - 20%
		double totalPayoff = 0;
		double averagePayoff;
		double compundRate;
		double O; // Premium (option price)
		int m = 0;
		while (m < M) {
			totalPayoff += generateCallPayoffs(N, S, r, T, sigma, P);
			m++;
			}
		averagePayoff = totalPayoff/M;
		compundRate = getCompundCoefficient(r, T, N);
		O = averagePayoff/compundRate;
		DecimalFormat df = new DecimalFormat("##.####");
		callField.setText(df.format(O));
	}

	public static double generatePutPayoffs(int N, double S, double r, double T, double sigma, double P){
		int eta;  // The up-or-down parameter
		int n = 0;
		double tempS = S;
		while (n < N) {
			double rd = Math.random();
			if (rd > 0.5) {
				eta = 1;
			} else {
				eta = -1;
			}
			tempS = tempS + r*tempS*(T/N) + sigma*eta*tempS*Math.sqrt(T/N);
			n++;
		}
		return Math.max(0, P - tempS); // We are going to exercise our right to sell only if P > S
	}

	public static double generateCallPayoffs(int N, double S, double r, double T, double sigma, double P){
		int eta;  // The up-or-down parameter
		int n = 0;
		double tempS = S;
		while (n < N) {
			double rd = Math.random();
			if (rd > 0.5) {
				eta = 1;
			} else {
				eta = -1;
			}
			tempS = tempS + r*tempS*(T/N) + sigma*eta*tempS*Math.sqrt(T/N);
			n++;
		}
		return Math.max(0, tempS - P); // We are going to exercise our right to buy only if S > P
	}

	public static double getCompundCoefficient(double r, double T, int N) {
		double coefficient = Math.pow(1+r*(T/N), (double) N);
		return coefficient;
	}

	public void setPutPrice(){
		double S = Double.parseDouble(stockField.getText()); // Stock price
		double P = Double.parseDouble(strikeField.getText());; // Strike price
		double r = (double)Double.parseDouble(interestField.getText())/100; // Interest rate - 8%
		int N = Integer.parseInt(stepsField.getText()); // Number of steps (randomizations)
		double T = (double) Double.parseDouble(periodField.getText())/12; // Number of years until option expiration
		int M = Integer.parseInt(simulationsField.getText()); // Number of computations (number of possible payoffs calculated)
		double sigma = (double)Double.parseDouble(volatilityField.getText())/100; // Volatility - 20%
		double totalPayoff = 0;
		double averagePayoff;
		double compundRate;
		double O; // Premium (option price)
		int m = 0;
		while (m < M) {
			totalPayoff += generatePutPayoffs(N, S, r, T, sigma, P);
			m++;
			}
		averagePayoff = totalPayoff/M;
		compundRate = getCompundCoefficient(r, T, N);
		O = averagePayoff/compundRate;
		DecimalFormat df = new DecimalFormat("##.####");
		putField.setText(df.format(O));
	}

}

Yes, the code does get repetitive and could be done a lot shorter, but I just want to keep things as simple as possible so you could understand how JavaFX works and how to deploy as an web applet without getting your attention split to other stuff.

MainLayout.fxml (created totally in Scene Builder, so it is not very much to explain, except the fact that you HAVE!!! to specify in the .fxml file the controller class – MainLayoutController.java in this case):

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane fx:id="anchorPane" prefHeight="375.0" prefWidth="590.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.wordpress.breekmd.java.MainLayoutController">
   <children>
      <VBox layoutX="51.0" layoutY="43.0" prefWidth="181.0" spacing="13.0" AnchorPane.leftAnchor="51.0" AnchorPane.topAnchor="40.0">
         <children>
            <Label layoutX="50.0" layoutY="35.0" prefHeight="21.0" prefWidth="134.0" text="Number of steps" />
            <Label layoutX="50.0" layoutY="75.0" prefHeight="21.0" prefWidth="134.0" text="Number of simulations" />
            <Label layoutX="50.0" layoutY="115.0" prefHeight="21.0" prefWidth="134.0" text="Volatility (%)" />
            <Label layoutX="50.0" layoutY="125.0" prefHeight="21.0" prefWidth="134.0" text="Risk-free interest rate (%)" />
            <Label layoutX="50.0" layoutY="155.0" prefHeight="21.0" prefWidth="134.0" text="Stock price" />
            <Label layoutX="50.0" layoutY="185.0" prefHeight="21.0" prefWidth="134.0" text="Strike price" />
            <Label layoutX="50.0" layoutY="215.0" prefHeight="21.0" prefWidth="181.0" text="Number of months till expiration" />
         </children>
      </VBox>
      <VBox layoutX="277.0" layoutY="35.0" prefHeight="241.0" prefWidth="149.0" spacing="9.5" AnchorPane.leftAnchor="277.0" AnchorPane.rightAnchor="82.0" AnchorPane.topAnchor="35.0">
         <children>
            <TextField fx:id="stepsField" layoutX="277.0" layoutY="33.0" prefHeight="16.0" prefWidth="149.0" />
            <TextField fx:id="simulationsField" layoutX="277.0" layoutY="77.0" />
            <TextField fx:id="volatilityField" layoutX="277.0" layoutY="112.0" />
            <TextField fx:id="interestField" layoutX="277.0" layoutY="143.0" />
            <TextField fx:id="stockField" layoutX="277.0" layoutY="177.0" />
            <TextField fx:id="strikeField" layoutX="277.0" layoutY="211.0" />
            <TextField fx:id="periodField" layoutX="277.0" layoutY="243.0" prefHeight="17.0" prefWidth="149.0" />
         </children>
      </VBox>
      <Button layoutX="443.0" layoutY="308.0" maxHeight="25.0" maxWidth="65.0" mnemonicParsing="false" onMouseClicked="#onCalculate" text="Calculate" AnchorPane.rightAnchor="82.0" AnchorPane.topAnchor="308.0" />
      <HBox layoutX="65.0" layoutY="308.0" spacing="30.0" AnchorPane.leftAnchor="65.0" AnchorPane.rightAnchor="179.0">
         <children>
            <Label layoutX="65.0" layoutY="312.0" text="Put price" />
            <TextField fx:id="putField" editable="false" layoutX="135.0" layoutY="308.0" prefHeight="25.0" prefWidth="80.0" />
            <Label layoutX="250.0" layoutY="312.0" text="Call price" />
            <TextField fx:id="callField" editable="false" layoutX="320.0" layoutY="308.0" prefHeight="25.0" prefWidth="80.0" />
         </children>
      </HBox>
   </children>
</AnchorPane>

Basically,

loader.setLocation(getClass().getResource("/com/wordpress/breekmd/rsc/MainLayout.fxml"));

is not okay, because if you try and run this as an web applet you will get the error that “Location not set.”, meaning that the app did not find the specified .fxml file, because it is stored in a .jar file and it can not be accessed as a file anymore, but it has to be accessed as an InputStream! I can not stress enough the importance of this piece of code, because if you do a mistake here all you’re going to see when you run your .jar file is going to be a grey box.

The app is going to look like that:

optionpricingonline

 

Be advised that I did not not implement any input checking methods, so it is possible to input negative values, letters or nothing, but the program will not run (for the sake of simplicity).

Now, you just have to edit your build.fxbuild file and input any information that is mandatory – this is a very simple task. Then, click on: Generate ant build.xml and run.

It is important to go to Control Panel/Java and add “file:///” (if you plan to run this from your computer) to the exception site list, otherwise you will not be able to run the applet.

Now, just go to the folder where your project has been deployed and run the .html file and this what you’re going to see (yes, allow the plugin to run on this page):

optionpricingonline

 

I did not change the html template so this is the default html template when deploying an web JavaFX applet. If you want to check this app online just go to: http://infinitymobile.comoj.com/OnlineOptionPricing.html and allow to run the java plug-in (remember to add this site to the site exception list in Java settings).

One comment

Leave a comment