Start Here — Price, Then Differentiate

Price a Vanilla Option and Get Every Greek

A Java European call, priced and differentiated in one TeaVM CPU sweep, with the result checked against Black–Scholes.

Trade details
Generated
Market data
Engine & simulationOptional

TeaVM currently runs the portable CPU engine. Trade metadata and day-count are included in the source; the European pricer uses maturity in years.

Java source
VanillaEuropeanGreeks.java

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

import com.nablatensor.engine.Nabla;
import com.nablatensor.quant.BlackScholes;
import com.nablatensor.quant.EquityMarket;
import com.nablatensor.quant.MonteCarlo;
import com.nablatensor.quant.OptionTypeEnum;
import com.nablatensor.quant.Products;

public final class VanillaEuropeanGreeks {
  private VanillaEuropeanGreeks() {}

  public static void main(String[] args) {
    String tradeId = "EQ-OPT-83866";
    String book = "EQD-FLOW-01";
    String valuationDate = "2026-09-24";
    String currency = "USD";
    String dayCount = "ACT/365";
    double notional = 1000000;
    EquityMarket market = EquityMarket.of()
        .spot(100)
        .strike(100)
        .vol(20 / 100.0)
        .rate(3 / 100.0)
        .maturity(1)
        .build();
    try (MonteCarlo<EquityMarket> pricer = MonteCarlo.of(Products.europeanCall())
        .market(market)
        .steps(1)
        .fp64()
        .greeks()
        .on("cpu")
        .build()) {
      Nabla.TypedValuation<EquityMarket> value = pricer.run(20000L, 42L);
      BlackScholes reference = BlackScholes.of(OptionTypeEnum.CALL, market);
      System.out.println("TRADE|" + tradeId + "|" + book + "|" + valuationDate + "|" + currency + "|"
          + dayCount + "|" + notional);
      row("price", value.price(), reference.price());
      row("delta", value.greek(EquityMarket::spot), reference.delta());
      row("vega", value.greek(EquityMarket::vol), reference.vega());
      row("rho", value.greek(EquityMarket::rate), reference.rho());
      row("dV/dK", value.greek(EquityMarket::strike), reference.strikeSensitivity());
      System.out.println("META|" + pricer.nodes() + "|" + pricer.recordSeconds() + "|" + value.seconds()
          + "|" + value.scenariosPerSecond() + "|" + value.standardError());
    }
  }

  private static void row(String name, double measured, double reference) {
    System.out.println("ROW|" + name + "|" + measured + "|" + reference);
  }
}
TeaVM compiles and runs the Java source above in this browser.
Implementation guide

Vanilla Greeks as a controlled benchmark

A European option provides a compact comparison between a simulated adjoint valuation and a well-known closed-form reference.

Core mechanism

The same recorded payoff returns price, delta, vega, rho and strike sensitivity by differentiating with respect to the relevant active inputs. The Black–Scholes value is an independent reference under its own modelling assumptions.

Practical workflow

Start with stable market inputs and enough paths for the desired error tolerance. Compare Monte-Carlo price and Greeks to the analytic result, then use the same recording pattern for path-dependent trades without a closed form.

Key details

*Keywords: java monte carlo option pricing, adjoint algorithmic differentiation java, java automatic differentiation, black scholes greeks java*

A European call, priced by Monte Carlo, with delta, vega, rho and strike sensitivity from one reverse sweep — no bumping. The closed form is right there for comparison.

The adjoint Greeks track Black-Scholes to Monte-Carlo error. The reverse sweep costs a small constant on top of the price — it does not scale with the number of risk factors, which is the whole point.

The Black–Scholes comparison is useful because it separates two questions. First, does the simulation converge to the price under the same constant-volatility assumptions? Second, do the adjoint derivatives converge to the closed-form delta, vega, rho and strike sensitivity? A price match alone is not enough evidence that the factor mapping or derivative propagation is correct.

The closed form assumes a frictionless setting with a lognormal underlying, constant volatility and rate, and a European exercise right. The browser control panel deliberately exposes spot, strike, volatility, rate and maturity because those are the model inputs that drive the reference value and its first-order Greeks.

Scope and review point

The browser output uses a simplified market and a ported CPU engine. Production valuation also needs conventions, dividends, curves, volatility surfaces and independent model validation.