Core Java

Geometric Brownian motion with Java

The Wiener process is a continuous-time stochastic process named in honor of Norbert Wiener. It’s commonly used to represent noise or financial development with a random component.

The geometric brownian motion can be calculated to visualize certain bounds (in quantiles) to hint about the absolute range. For calculation following parameters are required:

  • µ (mu): mean percentage
  • σ (sigma): variance
  • t: time period
  • v: Initial value

The extension to the regular calculation uses: m: Value increase per time period (in my case monthly value) breaks: Quantile breaks to calculate the bounds

Code to calculate the values:

import java.time.LocalDate;
import java.util.*;
import static java.lang.Math.sqrt;
import static java.lang.Math.exp;

public class WienerProcess {
    /**
     * Run the Wiener process for a given period and initial amount with a monthly value that is added every month. The
     * code calculates the projection of the value, a set of quantiles and the brownian geometric motion based on a
     * random walk.
     *
     * @param mu mean value (annualized)
     * @param sigma standard deviation (annualized)
     * @param years projection duration in years
     * @param initialValue the initial value
     * @param monthlyValue the value that is added per month
     * @param breaks quantile breaks
     * @return a List of double arrays containing the values per month for the given quantile breaks
     */
    public static List<double[]> getProjection(double mu, double sigma, int years, int initialValue,
        int monthlyValue, double[] breaks) {
        double periodizedMu = mu / 12;
        double periodizedSigma = sigma / Math.sqrt(12);
        int periods = years * 12;

        List<double[]> result = new ArrayList<double[]>();

        for (int i = 0; i < periods; i++) {
            double value = initialValue + (monthlyValue * i);
            NormalDistribution normalDistribution = new NormalDistribution(periodizedMu * (i + 1),
                    periodizedSigma * sqrt(i + 1));
            double bounds[] = new double[breaks.length];
            for (int j = 0; j < breaks.length; j++) {
                double normInv = normalDistribution.inverseCumulativeProbability(breaks[j]);
                bounds[j] = value * exp(normInv);
            }

            result.add(bounds);
        }
        return result;
    }
}

Applying the values:

  • mu: 0.05 (or 5%)
  • sigma: 0.1 (or 10%)
  • initial value: 7000
  • monthly increase: 100
  • time period: 6 years

results in the following chart:

Fig1_50593

Related information

Reference: Geometric Brownian motion with Java from our JCG partner Mark Paluch at the paluch.biz blog.

Mark Paluch

Mark is a software craftsman, did just about every job in IT, open source committer, and is passionate about dev culture. Particularly interested in hardware hacking and internet of things. Mark helps development teams to improve continuously during their software endeavor to achieve outstanding performance.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button