Fourier transform for stock price forecasting
Fourier transform for stock price forecasting
Loading saved threads...
lazarea · External communityPost link
External question — Quantitative Finance Stack Exchange
Author: lazarea
Original post: https://quant.stackexchange.com/questions/61565
License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/
Adaptation: HTML converted to plain text; contact email addresses removed.
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
from pandas_datareader import data
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')
hist_prices = df.loc[:'2020-11-01','Adj Close']
fut_prices = df.loc['2020-11-01':,'Adj Close']
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?
Quote
Report
Sergei Rodionov · External communityPost link
External answer — Quantitative Finance Stack Exchange
Author: Sergei Rodionov
Original post: https://quant.stackexchange.com/a/61577
License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/
Adaptation: HTML converted to plain text; contact email addresses removed.
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))
hist = data.loc[:,'Adj Close'].values
train = data.loc[:'2020-11-01','Adj Close'].values
n_predict = len(hist) - len(train)
extrapolation = fourierExtrapolation(train, n_predict)
pl.plot(np.arange(0, hist.size), hist, 'b', label = 'Data', linewidth = 3)
pl.plot(np.arange(0, train.size), train, 'c', label = 'Train', linewidth = 2)
pl.plot(np.arange(0, extrapolation.size), extrapolation, 'r', label = 'Predict', linewidth = 1)
pl.legend()
pl.show()
Quote
Report
qwertydotplus · External communityPost link
External answer — Quantitative Finance Stack Exchange
Author: qwertydotplus
Original post: https://quant.stackexchange.com/a/85850
License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/
Adaptation: HTML converted to plain text; contact email addresses removed.
because the Fourier Transform takes as input one period of a periodic waveform, thus an extrapolation from any modification of the FT will "try to be" periodic with a period equal to your input data (the "extrapolation" will end up being approximately a shifted copy of your input regardless of how you massage the data). you should read up on how the FT works and try to make your model look further into the future. your "extrapolation" will almost certainly better match the "training" data than the future data.
Quote
Report
Post Reply
Checking account access…