I ran an FFT on real financial monthly time series data. If I plot the FFT frequency domain output on the interval $[0, f_s)$, the dominant frequency pair peaks occur at $f_{A1}$ $\approx$ $0.02 \ month^{-1}$ and $f_{A2} \approx 0.98 \ month^{-1}$. If I plot the FFT frequency domain output on the interval $[-f_s/2, f_s/2)$ instead, then they occur at $f_{B1} \approx -0.48 \ month^{-1}$ and $f_{B2} \approx 0.48 \ month^{-1}$.
Because the original time domain data is real with no imaginary component, I think that it would make sense to plot the FFT frequency domain data on the interval $[0, f_s/2)$ and ignore the negative frequencies (as discussed in a related question I posted: "Binning and Frequency for FFT on Financial Time Series Data"). However, if I ignore the negative frequencies and plot only $[0, f_s/2)$, I think the FFT might not reflect the original time series as I'll explain below.
When I eyeball the original time series data, I see what looks like a predominant cycle period that repeats roughly every $T_{eyeball} \approx 36 \ months$, give or take. I thought that this should roughly correspond to the peak frequencies in the frequency domain, which should be about $f_{eyeball} \approx 1/T_{eyeball} = 1/(36 month) = 0.028 \ month^{-1}$. $f_{eyeball}$ is close to $f_{A1} \approx 0.02 \ month^{-1}$, the first peak frequency if I plot my frequency domain data on the interval $[0, f_s)$ as described in the first paragraph above. $f_{eyeball}$ is not close to the peak frequencies $f_{B1}$ and $f_{B2}$ that result from plotting the frequency domain on the interval $[-f_s/2, f_s/2)$. So, while it makes conceptual sense to me to plot the FFT on the $[0, f_s/2)$ interval because my time series data is real, that seems to be at odds with the nature of the time series.
If I were to plot on $[0, f_s)$ thus capturing the whole spectrum, it would seem like I'm double-counting frequencies because of the symmetry of FFT. Could the solution be to take the data on $[0, f_s/2)$? This would capture the peak frequency that seems to fit the data, but it seems like an arbitrary choice.
Could it be possible that this is an artifact of how scipy.fft
organizes positive an negative frequencies? The scipy.fft` documentation states:
"For N even, the elements $y[1] ... y[N/2 - 1]$ contain the positive-frequency terms, and the elements $y[N/2] ... y[N - 1]$ contain the negative-frequency terms, in order of decreasingly negative frequency. For N odd, the elements $y[1] ... y[(N - 1)/2]$ contain the positive-frequency terms, and the elements $y[(N+1)/2] ... y[N - 1]$ contain the negative-frequency terms, in order of decreasingly negative frequency."
If I'm understanding this correctly, this would mean that scipy.fft
bins positive frequencies on the $[0, f_s/2)$ interval and the negative frequencies on the interval $[f_s/2, f_s)$. This would mean that choosing $[0, f_s/2)$ is the right way to go for me and that would be consistent with the correct peak frequency $f_{A1}$ $\approx$ $0.02 \ month^{-1} \approx f_{eyeball} \approx 0.028 \ month^{-1}$
Or could it be something else that I'm missing?