Class VarianceSwap

java.lang.Object
com.quantfinlib.pricing.VarianceSwap

public final class VarianceSwap extends Object
VARIANCE SWAP analytics — the cleanest pure-volatility trade there is: at expiry the swap pays notional × (realized variance − strike), no delta, no path-dependent barriers, no vega decay games. The remarkable fact (Demeterfi-Derman-Kamal-Zou 1999) is that its fair strike is MODEL-FREE: a static portfolio of OTM options weighted 1/K² replicates the log contract, so the strike is readable off the option chain with no volatility model at all — the same integral a VIX-style index computes. fairVariance(double[], double[], double[], double, double, double) therefore delegates to VolatilityIndex and squares it: a VIX of 20 IS a variance-swap strike of 0.04. One number, two names.

The two quantities a desk actually books:

  • Variance vs vega notional — dealers quote in VEGA (P&L per vol point) but settle in VARIANCE units; the bridge is varianceNotional = vegaNotional / (2·K_vol), the linearization of variance in vol at the strike. Get this wrong and every P&L number is off by a factor of 2·K_vol.
  • Mark-to-market of a seasoned swap — variance is ADDITIVE in time, so a swap part-way through its life is just realized variance so far (locked in) blended with the fair strike for the remaining leg, discounted: MTM = e^{-r·(T-t)} · [ (t/T)·realized + ((T-t)/T)·K_rem − K_0 ] per unit of variance notional. No model here either — that is why variance swaps mark cleanly and volatility swaps (square root of this payoff) do not.

Conventions, stated: variance in annualized decimal² (0.04 = 20 vol), time in years, realized variance supplied by the caller (use volatility.HarRv/realized estimators — this class does not choose your sampling convention for you). The replication carries the discretization bias documented on VolatilityIndex (~+5e-4 in variance for a coarse chain) and, like all 1/K² replication, prices CONTINUOUS variance — jump risk is why dealers cap payoffs in practice; the cap is not modeled here, stated. Research lane.

  • Method Summary

    Modifier and Type
    Method
    Description
    static double
    fairVariance(double[] strikes, double[] putMids, double[] callMids, double forward, double rate, double tYears)
    Model-free fair strike (annualized VARIANCE, e.g. 0.04) replicated from one expiry's option chain — parameters exactly as VolatilityIndex.index(double[], double[], double[], double, double, double).
    static double
    markToMarket(double strikeVariance, double realizedVariance, double remainingFair, double tElapsedYears, double tTotalYears, double rate)
    Mark-to-market of a seasoned variance swap per unit of variance notional (multiply by varianceNotional(double, double) for money).
    static double
    varianceNotional(double vegaNotional, double strikeVol)
    Variance notional from a vega-notional quote: vegaNotional / (2 · strikeVol).
    static double
    volSwapStrike(double fairVariance, double varianceOfVariance)
    VOLATILITY swap fair strike via the Brockhaus-Long convexity correction: E[√V] ≈ √E[V] − Var(V) / (8·E[V]^{3/2}).

    Methods inherited from class java.lang.Object

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

    • fairVariance

      public static double fairVariance(double[] strikes, double[] putMids, double[] callMids, double forward, double rate, double tYears)
      Model-free fair strike (annualized VARIANCE, e.g. 0.04) replicated from one expiry's option chain — parameters exactly as VolatilityIndex.index(double[], double[], double[], double, double, double).
    • volSwapStrike

      public static double volSwapStrike(double fairVariance, double varianceOfVariance)
      VOLATILITY swap fair strike via the Brockhaus-Long convexity correction: E[√V] ≈ √E[V] − Var(V) / (8·E[V]^{3/2}). A vol swap strike is always BELOW the square root of the variance strike (Jensen: √ is concave), and by how much depends on the variance of variance — which is a model input, not chain-readable; that is exactly why vol swaps are not model-free while variance swaps are.
      Parameters:
      fairVariance - E[V], the variance-swap strike, > 0
      varianceOfVariance - Var(V) under your vol-of-vol model, ≥ 0
    • varianceNotional

      public static double varianceNotional(double vegaNotional, double strikeVol)
      Variance notional from a vega-notional quote: vegaNotional / (2 · strikeVol).
      Parameters:
      vegaNotional - P&L per 1.00 of volatility (per "100 vol points")
      strikeVol - the strike in VOL terms (0.20, not 0.04), > 0
    • markToMarket

      public static double markToMarket(double strikeVariance, double realizedVariance, double remainingFair, double tElapsedYears, double tTotalYears, double rate)
      Mark-to-market of a seasoned variance swap per unit of variance notional (multiply by varianceNotional(double, double) for money).
      Parameters:
      strikeVariance - original strike K₀ (variance units, > 0)
      realizedVariance - annualized variance realized over [0, t], ≥ 0
      remainingFair - current fair strike for [t, T] (variance), ≥ 0
      tElapsedYears - elapsed time t, ≥ 0
      tTotalYears - total life T, > 0, ≥ t
      rate - cc discount rate to expiry