实现期权定价的快速傅里叶变换

时间:2012-05-05 19:06:29

标签: algorithm fft implementation finance

我需要一些关于我正在做的小项目的提示。我的目标是实现快速傅里叶变换算法(FFT),该算法可以应用于期权的定价。

首先关注:哪个FFT?

有很多不同的FFT算法,其中最着名的是Cooley-Tukey。我对此的看法:我更喜欢最简单的一个,因为这不是论文或大项目,只是关于算法的课程。但它必须与期权定价相兼容(与大多数相比 - 在我们的一般文献中 - 参考图像/声音处理的应用)。所以它取决于提供的输入形式(我需要一些建议)。我熟悉几个改进,如分数FFT,混合基FFT等。但这些看起来相当复杂,并且优化/性能驱动,这与我的项目无关。

第二个问题:哪种定价模式?

我猜布莱克 - 斯科尔斯(BS)有点过于'平坦'而且我知道在BS之后出现的几个模型。因此,与上述目标相同,我最初更喜欢赫斯顿模型。

有很多考虑因素,事实上我只是看不到树木。

一些背景信息

我的背景是数学学士学位(理论),所以我对傅立叶变换有一些了解。

目标是用于计算期权定价的有效FFT实施。它不一定是最快的(没有极端的优化)。目标是尝试理解所选择的FFT并拥有真实的工作应用程序。

那么你能就这些选择提出一些建议吗?

我已经阅读了很多关于FFT +期权定价的论文,比如谷歌前几页所有不错的点击量。但这些研究的写作原因更为“高”。

4 个答案:

答案 0 :(得分:3)

如果您的目标是使用FFT,那么您的选择很差:只有仿射模型能够为您提供足够的信息来获得点密度的傅立叶变换。在实践中,这意味着布莱克 - 斯科尔斯或赫斯顿。也许还有一些,但没有一个“有用的”模型。

赫斯顿的模型具有独特的特征(与其隐含的体积动力学有关),这使得它作为随机体积模型非常无用。我认为这很受欢迎正是因为你可以通过傅立叶变换以半封闭的形式定价香草期权。凭借现代技术,这不再是真正的资产。

如果您对期权定价感兴趣,我建议您不要尝试使用FFT,转而使用PDE或Monte-Carlo方法:您可以使用的模型范围更加有趣(以及如果您有兴趣,可以在就业市场上更有价值。

对于你问题的FFT部分,从头开始实现Cooley-Tukey并不难,你可以从那里开始。当然,在生产代码中,您最好使用固定包(如FFTW)。

答案 1 :(得分:2)

我一直在研究这个话题 - 应用于期权定价的FFT - 几个星期了。事实证明,在这个问题上有大量的工作,所以亚历山大意味着它几乎没有用处。

我发现的最可读的基本论文来自Carr和Madan - www.math.nyu.edu/research/carrp/papers/pdf/jcfpub.pdf - 但还有许多不同层次的细节,谷歌将通过“期权定价傅立叶”搜索找到。

我可能会在不久的将来在R中对此进行编码;我正试图找到一个合适的期权价格数据来源进行测试。

答案 2 :(得分:0)

FFT只是DFT的优化实施。我建议使用现有的FFT库,例如KissFFT,或者如果你真的想从头开始实现这个,那么只需要实现DFT而不是FFT,因为它更简单,性能也不应成为问题除非你有高数据率或大量数据。

答案 3 :(得分:0)

我在Matlab下面提供了 radix-2抽取时间 Cooley-Tukey方案的实现。代码是迭代的,并考虑下图中的方案:

enter image description here

也可以采用递归方法。

正如您将看到的,实现还会计算执行的乘法和加法的数量,并将其与How many FLOPS for FFT?中报告的理论计算进行比较。

代码显然比Matlab利用的高度优化的FFTW慢得多。

另请注意,旋转因子omegaa^(interButterflyIndex * 2^(numStages - p))可以离线计算,然后从查找表中恢复,但在下面的代码中会跳过此点。

% --- 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);