Class TouchOption

java.lang.Object
com.quantfinlib.pricing.TouchOption

public final class TouchOption extends Object
One-touch and no-touch options (pay-at-expiry) under continuously monitored geometric Brownian motion — with the barrier-hitting probability itself exposed, since desks quote one-touches as (roughly) discounted hit probabilities.

With log-drift m = r − q − σ²/2 and barrier log-distance h = ln(H/S), the reflection principle gives the probability of touching an upper barrier (h > 0) by expiry:

  P = N((−h + mT)/σ√T) + e^{2mh/σ²} · N((−h − mT)/σ√T)

and symmetrically for a lower barrier. A one-touch paying at expiry is payout·e^{−rT}·P; a no-touch is the complement. Conventions match BlackScholes: carry is the continuous yield (foreign rate for FX).

Pay-at-hit one-touches (rebate paid immediately on touch) discount to the hitting time instead: oneTouchPayAtHit(double, double, double, double, double, double, double). Double no-touch and double one-touch (two barriers, pay at expiry) are doubleNoTouch(double, double, double, double, double, double, double, double) and doubleOneTouch(double, double, double, double, double, double, double, double).

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final int
    Number of image terms on each side used by doubleNoTouchProbability(double, double, double, double, double, double, double): the series runs over n = -N..N.
  • Method Summary

    Modifier and Type
    Method
    Description
    static double
    doubleNoTouch(double spot, double lower, double upper, double rate, double carry, double vol, double timeYears, double payout)
    Double no-touch: pays payout at expiry if spot never touches lower or upper.
    static double
    doubleNoTouchProbability(double spot, double lower, double upper, double rate, double carry, double vol, double timeYears)
    Probability that spot stays strictly inside (lower, upper) until timeYears under GBM with continuous monitoring.
    static double
    doubleOneTouch(double spot, double lower, double upper, double rate, double carry, double vol, double timeYears, double payout)
    Double one-touch paying at expiry: pays payout if either barrier is touched before expiry.
    static double
    hitProbability(double spot, double barrier, double rate, double carry, double vol, double timeYears)
    Probability that spot touches barrier at least once before timeYears, under GBM with the given rate/carry/vol.
    static double
    noTouch(double spot, double barrier, double rate, double carry, double vol, double timeYears, double payout)
    Pays payout at expiry if the barrier never traded.
    static double
    oneTouch(double spot, double barrier, double rate, double carry, double vol, double timeYears, double payout)
    Pays payout at expiry if the barrier traded at any point.
    static double
    oneTouchPayAtHit(double spot, double barrier, double rate, double carry, double vol, double timeYears, double payout)
    One-touch paying payout at the moment the barrier is first touched (American digital, "rebate at hit").

    Methods inherited from class Object

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

    • DOUBLE_TOUCH_SERIES_TERMS

      public static final int DOUBLE_TOUCH_SERIES_TERMS
      Number of image terms on each side used by doubleNoTouchProbability(double, double, double, double, double, double, double): the series runs over n = -N..N. Term n is bounded by exp(-2 n^2 l^2 / (vol^2 T)) times a factor of order exp(2 |mu| n l), with l = ln(U/L); for l / (vol sqrt T) >= 0.1 the omitted tail is below 1e-15 of the payout (checked against the eigenfunction series in the tests).
      See Also:
  • Method Details

    • hitProbability

      public static double hitProbability(double spot, double barrier, double rate, double carry, double vol, double timeYears)
      Probability that spot touches barrier at least once before timeYears, under GBM with the given rate/carry/vol.
    • oneTouch

      public static double oneTouch(double spot, double barrier, double rate, double carry, double vol, double timeYears, double payout)
      Pays payout at expiry if the barrier traded at any point.
    • noTouch

      public static double noTouch(double spot, double barrier, double rate, double carry, double vol, double timeYears, double payout)
      Pays payout at expiry if the barrier never traded.
    • oneTouchPayAtHit

      public static double oneTouchPayAtHit(double spot, double barrier, double rate, double carry, double vol, double timeYears, double payout)
      One-touch paying payout at the moment the barrier is first touched (American digital, "rebate at hit"). Closed form of Reiner and Rubinstein (1991, "Breaking down the barriers", Risk 4(8)), as printed in Haug (2007, The Complete Guide to Option Pricing Formulas, 2nd ed., section 4.17.3, rebate term F). With b = rate - carry,
        mu     = (b - vol^2/2) / vol^2
        lambda = sqrt(mu^2 + 2 rate / vol^2)
        z      = ln(H/S) / (vol sqrt T) + lambda vol sqrt T
        price  = payout [ (H/S)^(mu+lambda) N(eta z) + (H/S)^(mu-lambda) N(eta z - 2 eta lambda vol sqrt T) ]
      

      with eta = +1 for a lower barrier (H < S) and eta = -1 for an upper one. The formula is the Laplace transform E[e^{-rate tau} 1{tau <= T}] of the first-passage time tau, so rate discounts from the hitting time, not from expiry. For FX, rate is the domestic rate and carry the foreign rate, and the payout is in domestic currency. With rate = 0 it equals oneTouch(double, double, double, double, double, double, double) (tested). Requires mu^2 + 2 rate / vol^2 >= 0; a more negative domestic rate has no real lambda and is rejected.

      Parameters:
      barrier - the touch level; above spot is an up-touch, below a down-touch
      Returns:
      present value in the payout currency; payout if spot is at the barrier
    • doubleNoTouchProbability

      public static double doubleNoTouchProbability(double spot, double lower, double upper, double rate, double carry, double vol, double timeYears)
      Probability that spot stays strictly inside (lower, upper) until timeYears under GBM with continuous monitoring. Image-sum series of Ikeda and Kunitomo (1992, "Pricing options with curved boundaries", Mathematical Finance 2(4)) with flat boundaries, written in log space with x = ln(S/L), l = ln(U/L), m = rate - carry - vol^2/2, a = m / vol^2, s = vol sqrt T:
        P = sum_{n=-N..N} e^{-2 a n l}     [N((l - x + 2nl - mT)/s) - N((2nl - x - mT)/s)]
                        - e^{-2 a (x + n l)} [N((l + x + 2nl - mT)/s) - N((x + 2nl - mT)/s)]
      

      with N = DOUBLE_TOUCH_SERIES_TERMS. Returns 0 when spot is on or outside a barrier.

    • doubleNoTouch

      public static double doubleNoTouch(double spot, double lower, double upper, double rate, double carry, double vol, double timeYears, double payout)
      Double no-touch: pays payout at expiry if spot never touches lower or upper. Equals payout e^{-rate T} doubleNoTouchProbability(...); rate is the domestic rate and carry the foreign rate for FX.
    • doubleOneTouch

      public static double doubleOneTouch(double spot, double lower, double upper, double rate, double carry, double vol, double timeYears, double payout)
      Double one-touch paying at expiry: pays payout if either barrier is touched before expiry. The complement of doubleNoTouch(double, double, double, double, double, double, double, double).