LIVE·
fetching live quotes from Yahoo Finance…
--:--:--UTC
Learn/Bots/IV Solver (NN)
AI QuantsAIid · ai-iv-solver
ν

IV Solver (NN)

Implied vol from observed option price — no Newton-Raphson needed.

▶ Try it now↗ Browse all 27srcai quants/models/implied_vol/train.pyapi/api/iv
In plain English

When you see an option's price, you can run the math backwards to figure out what volatility the market is implying. The classic way (Newton-Raphson) is finicky and breaks near zero. Our AI does it in a single forward pass — fast and stable.

No jargon. Just what this bot does.
The longer version

Reverse the BS pricer. You have an option's market price and need to back out the implied volatility — what σ makes the formula spit out that price? Classically done with Newton-Raphson, which is fragile near zero vega and can take 20+ iterations. The NN does it in a single forward pass with ~0.9% relative error.

The math
formula
inverse BS surrogate · ≈0.9% relative error
parameters
typeTypechoices: C, Pdefault · C
spotSpot $range — → —default · 100
strikeStrike $range — → —default · 100
daysDays to expiryrange — → —default · 30
rateRate %range — → —default · 4.5
priceObserved $range 0.01 → —default · 4.5
Live demo

Real IV Solver (NN) bot, running on real Yahoo data when the symbol is available. Drag the params — the bot re-runs instantly.

symbolloading…
loading AMZN bars…
Source code · public

This is the actual code the bot runs — not a re-explanation, not a simplified version. Whatever ships here is what executes when you press Run All in the workbench. Read it, copy it, fork it, build a better one.

lib/quant/ai-bots.ts·lines 234321
TypeScript · MIT-licensed
const ivSolver: BotDef = aiBot<IVReq, IVRes>(
  {
    id: "ai-iv-solver",
    name: "IV Solver (NN)",
    category: "ai",
    glyph: "ν",
    tagline: "Implied vol from observed option price — no Newton-Raphson needed.",
    formula: "inverse BS surrogate · ≈0.9% relative error",
    endpoint: "/api/iv",
    module: "ai quants/models/implied_vol/train.py",
    params: [
      { key: "type", label: "Type", kind: "select", default: "C", options: [{ value: "C", label: "Call" }, { value: "P", label: "Put" }] },
      { key: "spot", label: "Spot $", kind: "number", default: 100, step: 0.5 },
      { key: "strike", label: "Strike $", kind: "number", default: 100, step: 0.5 },
      { key: "days", label: "Days to expiry", kind: "number", default: 30, step: 1 },
      { key: "rate", label: "Rate %", kind: "number", default: 4.5, step: 0.1 },
      { key: "price", label: "Observed $", kind: "number", default: 4.5, min: 0.01, step: 0.01, hint: "the option's actual mid price" },
    ],
  },
  {
    request: (ctx, p) => {
      const lastPx = ctx.candles[ctx.candles.length - 1]?.c ?? 100;
      const type = (str(p, "type", "C") === "P" ? "p" : "c") as "c" | "p";
      return {
        price: num(p, "price", 4.5),
        S: num(p, "spot", lastPx),
        K: num(p, "strike", Math.round(lastPx)),
        T: Math.max(0.0005, num(p, "days", 30) / 365),
        r: num(p, "rate", 4.5) / 100,
        flag: type,
      };
    },
    build: (data, ctx, p) => {
      const lastPx = ctx.candles[ctx.candles.length - 1]?.c ?? 100;
      const type = (str(p, "type", "C") === "P" ? "P" : "C") as "C" | "P";
      const spot = num(p, "spot", lastPx);
      const strike = num(p, "strike", Math.round(lastPx));
      const t = Math.max(0.0005, num(p, "days", 30) / 365);
      const rate = num(p, "rate", 4.5) / 100;
      const greeks = priceOption(spot, strike, t, rate, data.sigma, type).greeks;
      return {
        signals: [],
        metrics: [
          { key: "iv", label: "IV", value: `${(data.sigma * 100).toFixed(2)}%`, tone: "info" },
          { key: "vega", label: "ν Vega", value: fmtNum(greeks.vega, 3) },
          { key: "iters", label: "Iterations", value: "1 (NN)", tone: "neutral", hint: "vs ~25 for Newton-Raphson" },
          { key: "err", label: "Surrogate err", value: "≈0.9%", tone: "info" },
        ],
        summary: `Solved IV = ${(data.sigma * 100).toFixed(2)}% in a single forward pass. The python NN replaces Newton-Raphson, which usually takes 20+ iterations and explodes near zero vega.`,
        beginner:
          "Reverse the option pricer — given the price the market is showing, what volatility makes the formula match? The neural net does it in one inference.",
        verdict: { side: "hold", text: `Implied vol ${(data.sigma * 100).toFixed(2)}%.`, confidence: 1 },
      };
    },
    mock: (ctx, p) => {
      const lastPx = ctx.candles[ctx.candles.length - 1]?.c ?? 100;
      const type = (str(p, "type", "C") === "P" ? "P" : "C") as "C" | "P";
      const spot = num(p, "spot", lastPx);
      const strike = num(p, "strike", Math.round(lastPx));
      const days = num(p, "days", 30);
      const rate = num(p, "rate", 4.5) / 100;
      const obs = num(p, "price", 4.5);
      const t = Math.max(0.0005, days / 365);
      let lo = 0.01, hi = 3.0, mid = 0;
      for (let i = 0; i < 50; i++) {
        mid = (lo + hi) / 2;
        const guess = priceOption(spot, strike, t, rate, mid, type).price;
        if (guess > obs) hi = mid;
        else lo = mid;
      }
      const sigma = mid;
      const greeks = priceOption(spot, strike, t, rate, sigma, type).greeks;
      return {
        signals: [],
        metrics: [
          { key: "iv", label: "IV", value: `${(sigma * 100).toFixed(2)}%`, tone: "info" },
          { key: "vega", label: "ν Vega", value: fmtNum(greeks.vega, 3) },
          { key: "iters", label: "Iterations", value: "50 (bisection)", tone: "neutral", hint: "TS fallback" },
          { key: "err", label: "Surrogate err", value: "≈0.9%", tone: "info" },
        ],
        summary: `Solved IV = ${(sigma * 100).toFixed(2)}% via TS bisection (NN unavailable).`,
        beginner:
          "Reverse the option pricer — given the price the market is showing, what volatility makes the formula match?",
        verdict: { side: "hold", text: `Implied vol ${(sigma * 100).toFixed(2)}%.`, confidence: 1 },
      };
    },
  },
);
what each piece means
  • id — unique key the workbench uses to find the bot.
  • params — the sliders + inputs you see on the cell.
  • run(ctx, p) — the function that gets called with candles + your params and returns the verdict.
  • verdict — the BUY / SELL / HOLD pill at the top of the cell.
  • metrics — the small stat boxes shown in the cell body.
use this code yourself
  1. Copy the whole block above.
  2. On /quant, click + Import your bot in the bot library.
  3. Paste, hit save. It hot-loads into your workspace.
  4. Edit any param defaults or logic to your taste — it's now yours.
Specialty · when it shines, when it fails
✓ Shines when
  • ·Real-time IV updates as the chain ticks. Newton's method has variable latency depending on starting point; the NN is constant-time.
  • ·Building IV surfaces. Need to solve for σ across hundreds of strikes/expiries simultaneously — batch inference shines here.
  • ·Robustness near low vega. Newton blows up when ∂Price/∂σ is small; the NN gracefully degrades instead.
✗ Fails when
  • ·Out-of-distribution. The training set covered 5-200% vol; if the option price implies σ outside that, predictions degrade.
  • ·Pricing arbitrage edge cases. When the market price violates put-call parity, no σ exists — the NN just returns its best guess instead of erroring.
  • ·Deep ITM/OTM at near-zero time-to-expiry. Both Newton and the NN struggle; you need a different algorithm entirely.
How to read its verdict

HOLD always — solver, not a trade signal. The IV it returns is the trade input. Use it as the σ input to the Wheel bot, the BS Solver, or your own pricing logic.

Python service

This bot tries to call the FastAPI service first. When it's up, you get real model output. When it's down, the bot transparently falls back to a deterministic TS surrogate.

FastAPI·http://localhost:8000·/api/ivCHECKING…
data flow
01
BotCell.run()
User clicks Run on this bot in /quant
02
callApi()
POST to localhost:8000/api/iv
03
load_surrogate()
ai quants/models/implied_vol/train.py
04
predict()
Forward pass on the inputs you provided
05
BotResult
JSON returned, card flips green Source: Python NN
spin it upcd "ai quants" && uvicorn serve:app --reload --port 8000
FAQ
Why is the answer slightly different from a Newton-Raphson run?+
Newton finds the exact σ to floating-point precision. The NN is an approximation with ~0.9% mean relative error. For most use cases this is well inside bid-ask noise; for arbitrage strategies you'd still want the exact solver.
Can I trust this when the option is far OTM?+
Below an option price of ~0.05 the function gets flat and any solver becomes unstable. The NN is no exception — its predictions become noisy at deep OTM.