fix: input range of current Math.cdf implementation #40
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
With the current implementation of
cdf
andncdf
, the input range with correct output is a bit small due to overflows and the algorithm to calculate exponentials inoptimalExp
. This pull request fixes the problems and the modifiedcdf
will return good results for all possible inputs with reasonable precision.Problem
rvol/contracts/libraries/Math.sol
Line 247 in ee066ee
In Math.sol L247 and L267, the calculation of variable
exp
overflows whenx
is 127-bit binary fixed-point, the actual range iswhich means the function can only return correct results for
x < 2.82
, approximately:In rvol we normally pass the Black-Scholes parameters
d1
andd2
to the CDF functions. They are calculated from spot price, strike, volatility and time to expire of the option or underlying asset. With a reasonable set of these parameterswe get
d1
= 3.408 approximately, which is far larger than the 2.82 limit. Socdf
can give wrong answers sometimes in options-related contexts.Solution
First we replace the$$x\lt\sqrt{32}\approx5.6568542$$ (will explain it later)
uint256 exp = ((x / 2) * x) / FIXED_1;
linewith
uint256 exp = (x * (x >> 3)) / (FIXED_1 >> 2);
The 3-bit shift is enough to prevent overflow for
After this modification the output of
cdf
is likeNow the input range extends to ~5 and it's enough for real options calculations. But we go a step further to make the CDF functions better.
rvol/contracts/libraries/Math.sol
Line 181 in ee066ee
This time the periodic falls are due to the algorithm to implement
optimalExp
. After get Taylor series of small residuals it elaborates the exponential for x bit by bit but only to the 131st bit, which corresbonds to the 2^3 bit - sooptimalExp
will return periodic results with 16 as the period (in fixed-point).Since the argument we pass to$\frac{x^2}{2}$ , the output falls at $$\frac{x^2}{2}=16\cdot n\quad(n=1,2,3,\ldots)$$ $$x_1=\sqrt{32}$$
optimalExp
isthus the first falling point
the actual CDF value (0.9999999...) has been very close to 1 since long before this point so we let the functions return 1 if input is greater than it (5.656854)
from previous discussions we know the input
exp
will not overflow either within this range socdf
can return good results now:One more thing
rvol/contracts/libraries/Math.sol
Line 83 in ee066ee
the constant in L83 in
sqrt
should be0x4
for the last bit in the guess of initial value.