Price Exotic & Multi-Asset Trades

Differentiate Through a Recursion, Not Just a Simulation

Java runs the CRR and Leisen–Reimer convergence study, an American put backward induction, and lattice Greeks against the generalized Black–Scholes reference.

Market
Greeks treeOptional

The separate American put example retains its original fixed S=K=40, 20% volatility, 6% rate, 1-year contract, and 2,000-step lattice.

Java source
BinomialLatticeRiskStudio.java

This exact source runs in TeaVM. Form changes update its Java literals and reset manual edits.

import com.nablatensor.lattice.BinomialTree;
import com.nablatensor.lattice.LatticeGreeks;
import com.nablatensor.lattice.LatticePayoff.ExerciseSchedule;
import com.nablatensor.quant.OptionTypeEnum;
import com.nablatensor.quant.analytic.GeneralizedBsm;

public final class BinomialLatticeRiskStudio {
  private BinomialLatticeRiskStudio() {}

  public static void main(String[] args) {
    double spot = 100, strike = 100, rate = 5 / 100.0, dividend = 0 / 100.0, vol = 20 / 100.0, maturity = 1;
    double closed = GeneralizedBsm.of()
        .type(OptionTypeEnum.CALL)
        .spot(spot)
        .strike(strike)
        .maturity(maturity)
        .rate(rate)
        .dividend(dividend)
        .vol(vol)
        .build()
        .price();
    for (int steps : new int[] {
      10, 25, 50, 100, 250, 500
    }) {
      double crr = BinomialTree.of()
          .spot(spot)
          .rate(rate)
          .dividendYield(dividend)
          .vol(vol)
          .maturity(maturity)
          .steps(steps)
          .method(BinomialTree.MethodEnum.CRR)
          .build()
          .priceVanilla(OptionTypeEnum.CALL, strike, ExerciseSchedule.EUROPEAN);
      double lr = BinomialTree.of()
          .spot(spot)
          .rate(rate)
          .dividendYield(dividend)
          .vol(vol)
          .maturity(maturity)
          .steps(steps)
          .method(BinomialTree.MethodEnum.LEISEN_REIMER)
          .build()
          .priceVanilla(OptionTypeEnum.CALL, strike, ExerciseSchedule.EUROPEAN);
      System.out.println("CONV|" + steps + "|" + (crr - closed) + "|" + (lr - closed));
    }
    double euro = BinomialTree.of()
        .spot(40)
        .rate(0.06)
        .dividendYield(0.0)
        .vol(0.2)
        .maturity(1.0)
        .steps(2000)
        .method(BinomialTree.MethodEnum.CRR)
        .build()
        .priceVanilla(OptionTypeEnum.PUT, 40, ExerciseSchedule.EUROPEAN);
    double american = BinomialTree.of()
        .spot(40)
        .rate(0.06)
        .dividendYield(0.0)
        .vol(0.2)
        .maturity(1.0)
        .steps(2000)
        .method(BinomialTree.MethodEnum.CRR)
        .build()
        .priceVanilla(OptionTypeEnum.PUT, 40, ExerciseSchedule.AMERICAN);
    LatticeGreeks g = LatticeGreeks.vanilla(spot, rate, dividend, vol, maturity, 800, BinomialTree.MethodEnum.CRR,
        OptionTypeEnum.CALL, strike, ExerciseSchedule.EUROPEAN);
    GeneralizedBsm b = GeneralizedBsm.of()
        .type(OptionTypeEnum.CALL)
        .spot(spot)
        .strike(strike)
        .maturity(maturity)
        .rate(rate)
        .dividend(dividend)
        .vol(vol)
        .build();
    System.out.println("EARLY|" + euro + "|" + american);
    System.out.println("GREEK|" + closed + "|" + g.delta() + "|" + b.greeks()
        .delta() + "|" + g.gamma() + "|" + g.vega() + "|" + b.greeks()
        .vega());
  }
}
TeaVM compiles and runs the Java source above in this browser.
Implementation guide

Backward induction on a recombining tree

A binomial lattice discretises the underlying evolution and values the trade by working backward from terminal payoffs.

Core mechanism

At each node the continuation value is discounted from up and down successors; for an exercisable product it is compared with immediate exercise. Increasing tree depth reveals convergence behaviour.

Practical workflow

Choose a tree consistent with volatility, rates and time conventions; test depth convergence; compare European results to Black–Scholes; and inspect early-exercise decisions separately.

Key details

*Keywords: binomial tree java, cox ross rubinstein java, leisen reimer java, american option binomial java, backward induction java, richardson extrapolation option java*

Feature F11. Binomial trees and backward induction are a curriculum topic in their own right, and the one valuation the record-and-replay Monte-Carlo engine cannot do. They live in the com.nablatensor.lattice package of nablatensor-quant — plain double, O(n^2), no tape — that exists precisely to cover that material.

A Hull-White trinomial short-rate tree (for the no-arbitrage-model calibration that the curriculum teaches on a trinomial lattice) is a follow-up; the analytic Hull-White model (feature F6) and its Monte-Carlo step block already cover that chapter's pricing.

The Cox–Ross–Rubinstein construction represents one time step with an up move, a down move and a risk-neutral probability chosen so the discounted underlying is a martingale. Backward induction discounts the expected successor value at every node.

A recombining tree has only O(n²) nodes for n steps, which makes it a transparent numerical reference. Comparing a European option as depth rises with Black–Scholes tests convergence; allowing exercise at intermediate nodes changes the recursion into an American or Bermudan valuation.

Scope and review point

Tree convergence can be non-monotonic and slow around payoff features. It remains a numerical approximation, not a universal reference.