Core mechanism
The example replaces a hard indicator with a controllable smooth approximation. As the width narrows, the price approaches the discontinuous payoff while the Greek becomes less stable.
Java runs smoothed barrier and cash digital payoffs through NablaTensor's differentiable product API; each width uses the same seed.
Five smoothing widths and the digital are run 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.ExoticProducts;
import com.nablatensor.quant.MonteCarlo;
import com.nablatensor.quant.OptionTypeEnum;
import com.nablatensor.quant.Product;
public final class BarriersDigitalsRiskStudio {
private BarriersDigitalsRiskStudio() {}
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();
double barrier = 120;
int steps = 24;
long scenarios = 20000L, seed = 42L;
double[] widths = {
5.0, 2.0, 1.0, 0.5, 0.25
};
for (double width : widths) {
Product<EquityMarket> product = ExoticProducts.BarrierOption.of()
.type(OptionTypeEnum.CALL)
.kind(ExoticProducts.BarrierEnum.UP_OUT)
.barrier(barrier)
.width(width)
.build();
try (MonteCarlo<EquityMarket> mc = MonteCarlo.of(product)
.market(market)
.steps(steps)
.fp64()
.greeks()
.on("cpu")
.build()) {
Nabla.TypedValuation<EquityMarket> v = mc.run(scenarios, seed);
System.out.println("BARRIER|" + width + "|" + v.price() + "|" + v.greek(EquityMarket::spot));
}
}
Product<EquityMarket> digital = ExoticProducts.DigitalCash.of()
.type(OptionTypeEnum.CALL)
.cash(10)
.width(0.5)
.build();
try (MonteCarlo<EquityMarket> mc = MonteCarlo.of(digital)
.market(market)
.steps(1)
.fp64()
.greeks()
.on("cpu")
.build()) {
Nabla.TypedValuation<EquityMarket> v = mc.run(scenarios, seed);
System.out.println("DIGITAL|" + v.price() + "|" + v.greek(EquityMarket::spot));
}
}
}
Barriers and digitals expose the tension between a contract's discontinuous payoff and the smoothness needed for stable pathwise sensitivity estimation.
The example replaces a hard indicator with a controllable smooth approximation. As the width narrows, the price approaches the discontinuous payoff while the Greek becomes less stable.
Run a width sweep, quantify price bias and Greek variation, select a method consistent with the risk use case, and validate against independent estimators or repricing.
*Keywords: barrier option greeks monte carlo, digital option delta adjoint, smoothed payoff automatic differentiation, knock-out delta java*
A knock-out delta or a digital delta by bump-and-revalue is notoriously noisy: the payoff has a jump, so a finite bump straddles it and the estimate has huge variance. The Phase-1 answer is nablatensor-ops' smoothed indicator — a logistic STEP built from primitive nodes — so the whole payoff is differentiable and one adjoint sweep gives a genuine (mollified) delta.
The engine tape has one output, so this builds one kernel per metric and replays them at a common seed. A single tape with multiple named outputs — one forward sweep, N reverse seeds — is the next engine feature; MultiMetric is its drop-in-compatible stand-in.
A hard barrier crossing or cash-or-nothing payoff changes abruptly at a threshold. In Monte Carlo, a tiny spot change can switch a path from zero to full payoff, so a pathwise derivative may be zero on most paths and unstable near the barrier.
Smoothing replaces the step with a differentiable transition. The width is therefore a bias–variance control: a wider transition changes the contract more but stabilises the Greek; a narrower transition reduces payoff bias but can restore estimator noise. The width sweep on this page makes that trade-off inspectable.
There is no universally correct smoothing width. It is a model/numerical choice that must be documented and monitored.