# Fourier transform for stock price forecasting

I am trying to forecast stock prices using Fast Fourier Transform, and plot historical, "future" (i.e. real) and forecast prices on the same chart to visually compare the accuracy of the forecasting method. However, I am puzzled as to why the output forecast values are much lower than the last input data of the time series itself.

import numpy as np
import pylab as pl
from numpy import fft

def fourierExtrapolation(x, n_predict):
n = x.size
n_harm = 50
t = np.arange(0, n)
p = np.polyfit(t, x, 1)
x_notrend = x - p[0] * t
x_freqdom = fft.fft(x_notrend)
f = fft.fftfreq(n)
indexes = list(range(n))
indexes.sort(key=lambda i: np.absolute(f[i]))

t = np.arange(0, n + n_predict)
restored_sig = np.zeros(t.size)
for i in indexes[:1 + n_harm * 2]:
ampli = np.absolute(x_freqdom[i]) / n
phase = np.angle(x_freqdom[i])
restored_sig += ampli * np.cos(2 * np.pi * f[i] * t + phase)
return restored_sig + p[0] * t

df = data.DataReader('AAPL', 'yahoo', '2017-01-01', '2021-02-28')

extrapolation = fourierExtrapolation(hist_prices, len(fut_prices)-len(hist_prices))


Now when I print the extrapolated values, they are very low compared to hist_prices and fut_prices which becomes very apparent by running the below code:

pl.plot(fut_prices.index, extrapolation, 'r', label='extrapolation')
pl.plot(hist_prices.index, hist_prices, 'b', label='x_hist', linewidth=1)
pl.plot(fut_prices.index, fut_prices, 'g', label='x_real', linewidth=1)
pl.legend()
pl.show()


What am I missing? Why isn't my forecast series in the same order of magnitude with the input prices?

• I can't run your code due to missing data, but it seems you subtract the trend from your data by doing -p[0]*t, you possibly need to subtract the mean as well. Commented Mar 7, 2021 at 14:22
• You are working with stock price levels, not returns, right? I do not know how well you will be able to extrapolate from levels. Commented Mar 7, 2021 at 19:35

Here's a working example for python3.

import numpy as np
import pylab as pl
from numpy import fft
from datetime import datetime
from pandas_datareader import data as pdr

"""
https://gist.github.com/tartakynov/83f3cd8f44208a1856ce
"""

def fourierExtrapolation(x, n_predict):
n = x.size
n_harm = 50
t = np.arange(0, n)
p = np.polyfit(t, x, 1)
x_notrend = x - p[0] * t
x_freqdom = fft.fft(x_notrend)
f = fft.fftfreq(n)
indexes = list(range(n))
indexes.sort(key=lambda i: np.absolute(f[i]))

#indexes.sort(key=lambda i: np.absolute(x_freqdom[i]))
#indexes.reverse()

t = np.arange(0, n + n_predict)
restored_sig = np.zeros(t.size)
for i in indexes[:1 + n_harm * 2]:
ampli = np.absolute(x_freqdom[i]) / n
phase = np.angle(x_freqdom[i])
restored_sig += ampli * np.cos(2 * np.pi * f[i] * t + phase)
return restored_sig + p[0] * t

data = pdr.get_data_yahoo('AAPL', datetime(2017, 1, 1), datetime(2022, 1, 1))