Implementing a Fast Fourier Transform for Option Pricing

僤鯓⒐⒋嵵緔 提交于 2019-12-06 16:27:48

I've been researching this topic - FFTs applied to options pricing - for a few weeks now. It turns out there's an extensive body of work on the subject, so it's hardly futile as Alexandre implies.

The most readable basic paper I've found is from Carr and Madan - www.math.nyu.edu/research/carrp/papers/pdf/jcfpub.pdf - but there are many others in varying levels of detail, which Google will find via "option pricing Fourier" search.

I may be coding this up in R in the near future; I'm trying to locate a decent source of options price data for testing.

If your goal is to make some use of the FFT, then your choices are poor: only affine models give you enough information to obtain the Fourier transform of the spot density. In practice, this means Black-Scholes, or Heston. Perhaps a few more, but none of the "useful" models.

Heston's model has peculiar features (pertaining to its implied vol dynamics) which makes it quite useless as a stochastic vol model. I suppose it is popular precisely because of the fact that you can price vanilla options in semi-closed form, through Fourier transforms. With modern technology, this is no longer a real asset.

If you are interested in option pricing, I'd therefore suggest you don't try too hard with FFT, and turn to PDE or Monte-Carlo methods: the range of models you can play with are much more interesting (and much more valuable on the job market, in case you're interested).

For the FFT part of your question, implementing Cooley-Tukey from scratch is not hard, and you can start there. Of course, in production code, you are better using a canned package (like FFTW).

An FFT is just an optimised implementation of the DFT. I suggest either using an existing FFT library, such as KissFFT, or if you really want to implement this from scratch then just implement the DFT rather than an FFT, since it is much simpler, and performance should not be an issue unless you have high data rates or large amounts of data.

JackOLantern

I'm providing below the implementation of the radix-2 Decimation In Time Cooley-Tukey scheme in Matlab. The code is an iterative one and considers the scheme in the following figure:

A recursive approach is also possible.

As you will see, the implementation calculates also the number of performed multiplications and additions and compares it with the theoretical calculations reported in How many FLOPS for FFT?.

The code is obviously much slower than the highly optimized FFTW exploited by Matlab.

Note also that the twiddle factors omegaa^(interButterflyIndex * 2^(numStages - p)) can be calculated off-line and then restored from a lookup table, but this point is skipped in the code below.

% --- Radix-2 Decimation In Time - Iterative approach

clear all
close all
clc

N = 32;

x = randn(1, N);
xoriginal = x;
x = bitrevorder(x);
xhat = zeros(1, N);

numStages = log2(N);

omegaa = exp(-1i * 2 * pi / N);

mulCount = 0;
sumCount = 0;
tic
for p = 1 : numStages
    alpha = 2^(p - 1);
    butterflyStart = 1;
    while (butterflyStart <= (N - alpha))
        for interButterflyIndex = 0 : alpha - 1
            xhat(butterflyStart)          = x(butterflyStart) + x(butterflyStart + alpha) * omegaa^(interButterflyIndex * 2^(numStages - p)); 
            xhat(butterflyStart + alpha)  = x(butterflyStart) - x(butterflyStart + alpha) * omegaa^(interButterflyIndex * 2^(numStages - p));
            mulCount = mulCount + 4;
            sumCount = sumCount + 6;
            butterflyStart = butterflyStart + 1;
            if (interButterflyIndex == (alpha - 1))
                butterflyStart=butterflyStart + alpha;
            end;
        end;
    end;
    x = xhat;
end;
timeCooleyTukey = toc;

tic
xhatcheck = fft(xoriginal, N);
timeFFTW = toc;

rms = 100 * sqrt(sum(sum(abs(xhat - xhatcheck).^2)) / sum(sum(abs(xhat).^2)));

fprintf('Time Cooley-Tukey = %f; \t Time FFTW = %f\n\n', timeCooleyTukey, timeFFTW);
fprintf('Theoretical multiplications count \t = %i; \t Actual multiplications count \t = %i\n', ...
         2 * N * log2(N), mulCount);
fprintf('Theoretical additions count \t\t = %i; \t Actual additions count \t\t = %i\n\n', ...
         3 * N * log2(N), sumCount);
fprintf('Root mean square with FFTW implementation = %.10e\n', rms);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!