Class VolSurface

java.lang.Object
com.quantfinlib.pricing.VolSurface

public final class VolSurface extends Object
Implied volatility surface built from (expiry, strike, vol) pillar quotes — or directly from market option prices via implied-vol inversion.

Interpolation:

  • Within a smile — linear in vol across strikes, flat extrapolation beyond the quoted wings.
  • Across expiries — linear in total variance w = σ²T. When a forward is supplied for every expiry (VolSurface.Builder.forward(double, double)), the interpolation is at fixed log-moneyness ln(K/F(t)), with F(t) log-linear in t; this is the convention under which a smile that rolls with the forward stays calendar-arbitrage-free (Gatheral 2006, The Volatility Surface, chapter 3). Without forwards it falls back to fixed strike. Flat vol outside the quoted expiry range.

Nothing in the construction enforces absence of arbitrage. Two checks are provided: calendarViolations(int) (total variance must not fall with expiry at fixed moneyness) and minimumDensity(double, double, int) (the butterfly condition ∂²C/∂K² >= 0 on one smile). Linear interpolation with flat wings puts a concave kink at the outermost pillar of any skewed smile, and the density check reports it there; a smooth parametric smile (SABR, SabrModel) avoids that. For an arbitrage-free parametric surface use SsviSurface or SviSurface; Dupire local vol is DupireLocalVol.

Immutable and thread-safe once built.
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static final class 
     
    static final record 
    Total variance falls between two expiries at this log-moneyness.
  • Method Summary

    Modifier and Type
    Method
    Description
    double
    atmVol(double expiryYears, double forward)
    ATM vol, taking the forward (or spot) as the at-the-money strike.
     
    calendarViolations(int gridPoints)
    Calendar-arbitrage scan: for each pair of consecutive quoted expiries, total variance at gridPoints log-moneyness values spanning both smiles' quoted range must not decrease.
     
    double
    forwardAt(double expiryYears)
    Forward at an expiry, log-linear between pillars and flat outside.
    double
    minimumDensity(double expiryYears, double forward, int n)
    Smallest butterfly density ∂²C/∂K² (undiscounted Black call on the interpolated smile, central second difference) over n strikes across the quoted range of pillar expiry expiryYears.
    double
    price(BlackScholes.OptionType type, double spot, double strike, double rate, double carry, double expiryYears)
    Option price using the surface vol at (expiry, strike).
    double
    skew(double expiryYears, double strikeLow, double strikeHigh)
    Chord slope of the smile between two strikes, in decimal vol per unit of strike.
    strikes(double expiryYears)
     
    double
    vol(double expiryYears, double strike)
    Interpolated implied volatility at any (expiry, strike).

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • builder

      public static VolSurface.Builder builder()
    • vol

      public double vol(double expiryYears, double strike)
      Interpolated implied volatility at any (expiry, strike).
    • forwardAt

      public double forwardAt(double expiryYears)
      Forward at an expiry, log-linear between pillars and flat outside.
      Throws:
      IllegalStateException - if the surface was built without forwards
    • calendarViolations

      public List<VolSurface.CalendarViolation> calendarViolations(int gridPoints)
      Calendar-arbitrage scan: for each pair of consecutive quoted expiries, total variance at gridPoints log-moneyness values spanning both smiles' quoted range must not decrease. Returns every violation found (empty when clean). Without forwards, moneyness is ln(K) at fixed strike.
    • minimumDensity

      public double minimumDensity(double expiryYears, double forward, int n)
      Smallest butterfly density ∂²C/∂K² (undiscounted Black call on the interpolated smile, central second difference) over n strikes across the quoted range of pillar expiry expiryYears. Negative means the smile admits a butterfly arbitrage. Kinks of the linear interpolation show up as spikes, not as negative density, unless the slope change itself is arbitrageable.
    • atmVol

      public double atmVol(double expiryYears, double forward)
      ATM vol, taking the forward (or spot) as the at-the-money strike.
    • price

      public double price(BlackScholes.OptionType type, double spot, double strike, double rate, double carry, double expiryYears)
      Option price using the surface vol at (expiry, strike).
    • skew

      public double skew(double expiryYears, double strikeLow, double strikeHigh)
      Chord slope of the smile between two strikes, in decimal vol per unit of strike.
    • expiries

      public NavigableSet<Double> expiries()
    • strikes

      public NavigableSet<Double> strikes(double expiryYears)