1
$\begingroup$

I've developed a validator for risk-neutral distributions. I did this for the purpose of testing the risk-neutral distributions generated by a Spectral Analysis risk-neutral density recovery method, implemented in MATLAB here.

My validator calculates the expected payoff for each put option across the provided strike prices, thereby generating a set of theoretical option prices. These are compared against the market's bid and ask prices to assess if the generated prices fall within the acceptable range.

Here is the MATLAB code for the validator:

currentPrice = F * exp(-r * tau);
    
FPrices = currentPrice + currentPrice * result2.returns;

densityR = result2.densityR; 

% Calculate the payoff for each option
optionPrices = [];

% Loop through each strike price in X
for i = 1:length(X)
    % Calculate payoff for the current strike price against all FPrices
    % This calculates the put option payoff: max(0, K - S)
    % FPrices and densityR are extremely dense - array length = 1387
    optionPrices(i) =sum(max(0, X(i) - FPrices) .* densityR)* exp(-r * tau);
end

invalidPricesResult = validatePrices(X, bid, ask, optionPrices);

% Display invalid prices, if any
disp('Invalid Prices for Result:');
disp(invalidPricesResult);


function validationResults = validatePrices(strikePrices, bids, asks, pricesToCheck)
    validationResults = [];
    for i = 1:length(strikePrices)
        K = strikePrices(i);
        bid = bids(i);
        ask = asks(i);
        priceToCheck = pricesToCheck(i);
        isValid = bid <= priceToCheck && priceToCheck <= ask;
        if ~isValid
            validationResults = [validationResults; K, priceToCheck, bid, ask, isValid];
        end
    end
end

The validator code is to be pasted at the end of the spectralExample.m file from the MATLAB project linked above.

However, using this validator, an enormous amount of the risk-neutral-distribution-generated put option prices lie outside the bid-ask spread. Here's a screenshot showing this: the 1st column is the strike, the 2nd column is the generated-price, the 3rd column is the bid, the 4th column is the ask, the 5th column is the outcome of the validation (0 = invalid):

validation result

Therefore, I have to ask - is this a good way to validate a risk-neutral distribution?

If so, does it mean that there is a problem with this risk-neutral-distribution generator?

$\endgroup$
8
  • $\begingroup$ Does your prices only disagree with out of the money options (particularly puts)? I suspect this is due to the "smile" phenomenon where out of the money options trade at higher implied volatility. $\endgroup$
    – AlRacoon
    Commented Feb 19 at 13:22
  • $\begingroup$ @AlRacoon "Does your prices only disagree with out of the money options (particularly puts)? " - No, F (forward price) = 50, currentPrice=49.7506. It is interesting that there are only 2 put options with strike >50 that are outside the bid-ask spread, though, compared with 8 for strike <=50. I suspect that the reason might actually be an error in the implementation, causing a loss of precision for small option prices. Regarding the "smile" - I don't think this can play a role - neither the method nor its implementation refer to B-S in any way - the aim is a model-free RND calculation. $\endgroup$
    – v.y.
    Commented Feb 19 at 14:51
  • $\begingroup$ As far as I remember, the spectral method yields correct results, i.e.: if there exists (at least) one risk neutral distribution that is compatible with observed bid and ask prices, the method will return that density. Did you unit test your inputs and the package that you are using? $\endgroup$ Commented Feb 20 at 12:14
  • 1
    $\begingroup$ Additional thoughts: Are you using the correct return spacing? If I remember correctly, the package uses log returns, not multiplicative returns. $\endgroup$ Commented Feb 20 at 17:04
  • 1
    $\begingroup$ PSA: I am the developer of the Matlab package (not the author of the method, though!). Unfortunately, I cannot explain the details anymore; but I can say that the method itself is tested and sound. I have the feeling that you have errors in your implementation; that's the reason why I am asking for your unit tests. Starting with prices: Are your used (mid) prices free of arbitrage? Does the resulting RND integrate to 1? Does your method recover the input option prices? and so on. $\endgroup$ Commented Feb 21 at 12:41

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.