theta
Black-76Computes Theta of the option on a future using the Black-76 model (time decay per day).
Avg. gas
3,255
Max abs. error
1.9e-12
when |θ| < 1
Max rel. error
5e-12
when |θ| ≥ 1
Signature
function theta(
uint128 future,
uint128 strike,
uint32 timeToExp,
uint64 volatility,
uint64 rate
) internal pure returns (int128 thetaCall, int128 thetaPut)Parameters
| Name | Type | Description |
|---|---|---|
| future | uint128 | Current future price in 18-decimal fixed-point format. |
| strike | uint128 | Strike price, 18-decimal fixed-point. Precision-tuned for the no-arbitrage band against the future — see Bounds. |
| timeToExp | uint32 | Time to expiration in seconds. timeToExp == 0 is allowed (handled as expired). |
| volatility | uint64 | Annualized implied volatility, 18-decimal fixed-point (e.g. 60% → 6e17). |
| rate | uint64 | Annualized risk-free (discount) rate, 18-decimal fixed-point. |
Returns
| Name | Type | Description |
|---|---|---|
| thetaCall | int128 | Call theta per day in 18-decimal fixed-point. |
| thetaPut | int128 | Put theta per day in 18-decimal fixed-point. |
Bounds
| Bound | Value |
|---|---|
| MIN_FUTURE | 1e-6 smallest allowed future price (1e12) |
| MAX_FUTURE | 1e15 largest allowed future price (1e33) |
| MAX_STSP_RATIO | 5× (strike must lie within [future/5, future·5]) |
| MAX_EXPIRATION | 32 years (1,009,152,000 seconds) |
| MAX_RATE | 400% annual (4e18) |
Behavior
- Validates all five inputs against module-wide constants and reverts with a typed error on any violation.
- Returns theta per day (the annual figure divided by 365) for both call and put, sharing the common time-decay term across the two.
- Fast-path on expiration: when
timeToExp == 0, returns(0, 0). - Composes five DeFiMath primitives — ln,
sqrtTime,expPositive(the discount factor),exp(the densityφ(d₁)), and stdNormCDF (the carry term). Its higher gas reflects that fuller composition. - Pure
internalfunction; no external calls, no storage. Inlined into the caller's bytecode at compile time.
How it works
theta is the derivative of option value with respect to the passage of time, returned per day (÷365). Under Black-76 the discount factor adds a carry term to the usual time decay:
The shared time-decay term e^(−rT)·F·φ(d₁)·σ / (2√T) is computed once and reused for both call and put; only the sign and the carry term r·price differ (the call and put prices differ, so their carries do too). The density φ(d₁) uses Math.exp, the discount Math.expPositive, the carry CDFs Math.stdNormCDF.
Precision follows the dual-metric rule: a relative bound of 5e-12 where |θ| ≥ 1 and an absolute bound of 1.9e-12 where |θ| < 1, at future = $1,000 — head-to-head measurements live in defimath-compare.
Errors
| Error | Trigger |
|---|---|
| FutureLowerBoundError | future ≤ MIN_FUTURE |
| FutureUpperBoundError | future ≥ MAX_FUTURE |
| StrikeLowerBoundError | strike · 5 < future |
| StrikeUpperBoundError | future · 5 < strike |
| TimeToExpiryUpperBoundError | timeToExp ≥ MAX_EXPIRATION |
| RateUpperBoundError | rate ≥ MAX_RATE |
Example
import "defimath-lib/contracts/derivatives/Black76.sol";
(int128 thetaCall, int128 thetaPut) = Black76.theta(
1000e18, // future = $1,000
1050e18, // strike = $1,050
90 days, // 90 days to expiry
0.60e18, // 60% annualized vol
0.05e18 // 5% discount rate
);
// thetaCall, thetaPut per day (signed)