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):
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?