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 StressTestingRiskStudio {
static final String[] MACRO = {
"baseline", "adverse", "severely adverse"
}, HORIZON = {
"Q0", "Q1", "Q2", "Q3"
};
static final double[] SPOT_SHOCK = {
0, -0.2, -0.4
}, VOL_SHOCK = {
0, 0.05, 0.15
}, RATE_SHOCK = {
0, -0.0075, -0.015
}, TIME_SHOCK = {
0, -0.25, -0.5, -0.75
};
public static void main(String[] a) {
double s0 = 100, k = 100, v0 = 20 / 100.0, r0 = 3 / 100.0, t0 = 1;
double callUnits = 5000000 / s0, putUnits = 3000000 / s0;
long paths = 100000L, seed = 42L;
EquityMarket base = market(s0, k, v0, r0, t0);
try (MonteCarlo<EquityMarket> call = MonteCarlo.of(Products.europeanCall())
.market(base)
.steps(1)
.fp64()
.priceOnly()
.on("cpu")
.build(); MonteCarlo<EquityMarket> put = MonteCarlo.of(Products.europeanPut())
.market(base)
.steps(1)
.fp64()
.priceOnly()
.on("cpu")
.build(); MonteCarlo<EquityMarket> callGreek = MonteCarlo.of(Products.europeanCall())
.market(base)
.steps(1)
.fp64()
.greeks()
.on("cpu")
.build()) {
double[] basePv = new double[4];
for (int h = 0; h < 4; h++) {
EquityMarket m = shocked(s0, k, v0, r0, t0, 0, h);
basePv[h] = callUnits * call.run(m, paths, seed)
.price() - putUnits * put.run(m, paths, seed)
.price();
}
double worst = Double.POSITIVE_INFINITY, worstDelta = 0;
int wi = 0, wh = 0;
for (int x = 0; x < 3; x++) for (int h = 0; h < 4; h++) {
EquityMarket m = shocked(s0, k, v0, r0, t0, x, h);
double pv = callUnits * call.run(m, paths, seed)
.price() - putUnits * put.run(m, paths, seed)
.price();
double loss = pv - basePv[h];
System.out.println("GRID|" + MACRO[x] + "|" + HORIZON[h] + "|" + loss);
if (loss < worst) {
worst = loss;
wi = x;
wh = h;
worstDelta = callGreek.run(m, paths, seed)
.greek(EquityMarket::spot);
}
}
System.out.println("WORST|" + MACRO[wi] + "|" + HORIZON[wh] + "|" + worst + "|" + worstDelta);
}
}
static EquityMarket market(double s, double k, double v, double r, double t) {
return EquityMarket.of()
.spot(s)
.strike(k)
.vol(v)
.rate(r)
.maturity(t)
.build();
}
static EquityMarket shocked(double s, double k, double v, double r, double t, int x, int h) {
return market(s * (1 + SPOT_SHOCK[x]), k, Math.max(0.001, v + VOL_SHOCK[x]), r + RATE_SHOCK[x],
Math.max(0.01, t + TIME_SHOCK[h]));
}
}