From bdfc85611592f89e33e477f499f189dd55c23b6f Mon Sep 17 00:00:00 2001 From: Benjamin Adovasio Date: Mon, 9 Feb 2026 18:28:53 -0500 Subject: [PATCH] added fair_prob.py --- fair_prob.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 fair_prob.py diff --git a/fair_prob.py b/fair_prob.py new file mode 100644 index 0000000..484c7c0 --- /dev/null +++ b/fair_prob.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +import math + + +def _norm_cdf(z: float) -> float: + # Standard normal CDF via erf (no scipy dependency) + return 0.5 * (1.0 + math.erf(z / math.sqrt(2.0))) + + +def fair_prob_threshold( + *, + spot: float, + strike: float, + sigma_per_second: float, + time_remaining_seconds: float, + resolves_yes_if_spot_ge_strike: bool, +) -> float: + """ + Conservative approximation: + spot(t) ~ Normal(spot, spot*sigma*sqrt(t)) + and compute P(spot_T >= strike) or P(spot_T <= strike). + """ + if spot <= 0 or strike <= 0: + return 0.5 + t = max(1.0, float(time_remaining_seconds)) + sigma = max(1e-9, float(sigma_per_second)) + stdev = spot * sigma * math.sqrt(t) + if stdev <= 0: + return 0.5 + + z = (spot - strike) / stdev + p_ge = _norm_cdf(z) # P(spot_T >= strike) + + fair = p_ge if resolves_yes_if_spot_ge_strike else (1.0 - p_ge) + + # clip away from certainty (tail risk) + return max(0.03, min(0.97, fair))