delta

Black-76

Computes Delta for both call and put options on a future using the Black-76 model (sensitivity to future price change).

Avg. gas

1,915

Max abs. error

1.2e-13

Signature

solidity
function delta(
    uint128 future,
    uint128 strike,
    uint32  timeToExp,
    uint64  volatility,
    uint64  rate
) internal pure returns (int128 deltaCall, int128 deltaPut)

Parameters

NameTypeDescription
futureuint128Current future price in 18-decimal fixed-point format.
strikeuint128Strike price, 18-decimal fixed-point. Precision-tuned for the no-arbitrage band against the future — see Bounds.
timeToExpuint32Time to expiration in seconds. timeToExp == 0 is allowed (handled as expired).
volatilityuint64Annualized implied volatility, 18-decimal fixed-point (e.g. 60% → 6e17).
rateuint64Annualized risk-free (discount) rate, 18-decimal fixed-point.

Returns

NameTypeDescription
deltaCallint128Call delta in 18-decimal fixed-point. δcall ∈ [0, e^(−rτ)].
deltaPutint128Put delta in 18-decimal fixed-point. δput = δcall − e^(−rτ) ∈ [−e^(−rτ), 0].

Bounds

BoundValue
MIN_FUTURE1e-6 smallest allowed future price (1e12)
MAX_FUTURE1e15 largest allowed future price (1e33)
MAX_STSP_RATIO5× (strike must lie within [future/5, future·5])
MAX_EXPIRATION32 years (1,009,152,000 seconds)
MAX_RATE400% annual (4e18)

Behavior

  • Validates all five inputs against module-wide constants and reverts with a typed error on any violation.
  • Returns both call and put delta from a single Φ(d₁) evaluation — δput = δcall − e^(−rτ), so the second value is free.
  • Discounted, unlike Black-Scholes: Black-76 delta is e^(−rτ)·Φ(d₁), bounded to [−e^(−rτ), e^(−rτ)] — so only an absolute error applies.
  • Fast-path on expiration: when timeToExp == 0, delta collapses to its degenerate expiry value (0 or ±1 by moneyness) without running the pricer.
  • Composes four DeFiMath primitives — ln, sqrtTime (specialized sqrt for years), expPositive (the discount factor), and stdNormCDF.
  • Pure internal function; no external calls, no storage. Inlined into the caller's bytecode at compile time.

How it works

delta is the first derivative of option value with respect to the future price. Under Black-76 it is the discounted standard normal CDF of d₁:

δcall=erTΦ(d1),δput=erT(Φ(d1)1)\delta_{call} = e^{-rT}\,\Phi(d_1), \qquad \delta_{put} = e^{-rT}\left(\Phi(d_1) - 1\right)
d1=ln(F/K)+σ22TσTd_1 = \frac{\ln(F/K) + \tfrac{\sigma^2}{2} T}{\sigma \sqrt{T}}

The discount factor e^(−rT) (from Math.expPositive(rT)) is what distinguishes it from the vanilla delta Φ(d₁). Because put delta differs from call delta by exactly the discount factor, both are returned from one stdNormCDF evaluation.

Delta is bounded to [−e^(−rτ), e^(−rτ)] ⊂ [−1, 1], so the suite enforces an absolute error only — 1.2e-13 — with no relative bound. Head-to-head measurements live in defimath-compare.

Errors

ErrorTrigger
FutureLowerBoundErrorfuture ≤ MIN_FUTURE
FutureUpperBoundErrorfuture ≥ MAX_FUTURE
StrikeLowerBoundErrorstrike · 5 < future
StrikeUpperBoundErrorfuture · 5 < strike
TimeToExpiryUpperBoundErrortimeToExp ≥ MAX_EXPIRATION
RateUpperBoundErrorrate ≥ MAX_RATE

Example

solidity
import "defimath-lib/contracts/derivatives/Black76.sol";

(int128 deltaCall, int128 deltaPut) = Black76.delta(
    1000e18,         // future = $1,000
    1050e18,         // strike = $1,050
    90 days,         // 90 days to expiry
    0.60e18,         // 60% annualized vol
    0.05e18          // 5% discount rate
);
// deltaCall ≈ 0.49e18, deltaPut = deltaCall − e^(−rτ) ≈ -0.50e18