upProbability function
P(settle > strike) — the UP digital, with the SVI skew correction.
inputs.svi is the already-rolled surface (no roll-down applied here).
strike shares units with inputs.forward. Returns a probability in
[0, 1].
Implementation
double upProbability(PricerInputs inputs, double strike) {
final forward = inputs.forward;
final svi = inputs.svi;
if (!(forward > 0)) return 0;
if (strike <= 0) return 1; // neg-inf limit
final k = math.log(strike / forward);
final km = k - svi.m;
final root = math.sqrt(km * km + svi.sigma * svi.sigma);
final inner = svi.rho * km + root; // >= 0 for |rho| <= 1
final w = svi.a + svi.b * inner; // total variance
// The chain guarantees w > 0 at every strike
// (assert_min_total_variance_positive at load time), so this branch is
// unreachable in practice; return the variance→0 tail limit rather than
// throw, so a UI never crashes on a degenerate snapshot.
if (w <= 0) return k < 0 ? 1 : 0;
final sq = math.sqrt(w);
final d2 = _clampD2(-((k + w / 2) / sq));
final nd2 = _normalCdf(d2);
final wPrime = svi.b * (svi.rho + km / root); // SVI slope × b
final price = nd2 - (_normalPdf(d2) * wPrime) / (2 * sq); // skew correction
return price < 0
? 0
: price > 1
? 1
: price;
}