Core mechanism
The valuation accumulates a path average before applying the payoff. The tape captures each fixing's contribution, allowing the reverse pass to return Greeks through the same path computation.
The Java Asian call prices the path average and differentiates the same recorded tape for spot and volatility.
The browser workload defaults to 20,000 scenarios on the portable CPU engine.
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.EquityMarket;
import com.nablatensor.quant.MonteCarlo;
import com.nablatensor.quant.Products;
public final class AsianOptionRiskStudio {
private AsianOptionRiskStudio() {}
public static void main(String[] args) {
EquityMarket market = EquityMarket.of()
.spot(100)
.strike(100)
.vol(20 / 100.0)
.rate(3 / 100.0)
.maturity(1)
.build();
int steps = 60;
long scenarios = 20000L;
long seed = 42L;
try (MonteCarlo<EquityMarket> pricer = MonteCarlo.of(Products.asianCall())
.market(market)
.steps(steps)
.fp64()
.greeks()
.on("cpu")
.build()) {
Nabla.TypedValuation<EquityMarket> v = pricer.run(scenarios, seed);
System.out.println("RESULT|" + v.price() + "|" + v.standardError() + "|" + v.greek(EquityMarket::spot)
+ "|" + v.greek(EquityMarket::vol) + "|" + pricer.nodes() + "|" + v.seconds());
}
}
}
An Asian option depends on a sequence of fixings, so its risk reflects the entire simulated path rather than only terminal price.
The valuation accumulates a path average before applying the payoff. The tape captures each fixing's contribution, allowing the reverse pass to return Greeks through the same path computation.
Set the observation schedule and averaging convention explicitly, use convergence diagnostics for paths and time steps, and compare selected cases to an analytic approximation or independent engine.
*Keywords: asian option monte carlo java, gpu monte carlo greeks, java vector api monte carlo, adjoint aad asian option*
An arithmetic-average Asian call has no closed form, so its risk is normally a bump-and-revalue grid. Here it is one recording, one adjoint sweep, replayed on every backend the machine has — same tape, same seed, same numbers to Monte-Carlo noise; only throughput changes.
Every engine agrees on price and Greeks to the digits shown; cpu-jit reproduces the scalar cpu oracle bit-for-bit (see validation). This box has an AMD APU, so rocm runs a real HIP GPU kernel at fp64; on an APU that is only ~1.2× the SIMD path — a discrete card, or the fp32 shaders below, is where the GPU pulls ahead.
The AadEngines.available(...) filter above is fp64, so vulkan and cuda (both fp32-only) don't appear. At fp32 the picture on this box:
cuda has no device on this box. On a Colab Tesla T4, notebooks/engine-benchmark.ipynb — a heavier workload (a 4057-node barrier tape, not this 1536-node Asian) — runs cuda at 1.3×10⁷ value+5-Greeks scenarios/s (≈ 1.4× the same T4's opencl), i.e. in the vulkan / rocm tier. Not directly comparable to the rows above; re-run the notebook on a GPU runtime for the exact figure.
The demonstration uses stylised GBM and a simple schedule. Contractual averaging, corporate actions and volatility-surface dynamics need fuller treatment in production.