We will use the hanning()
function to smooth arrays of stock returns, as shown in the following steps:
hanning()
function to compute weights for a certain length window (in this example 8) as follows:N = 8 weights = np.hanning(N) print("Weights", weights)
The weights are as follows:
Weights [ 0. 0.1882551 0.61126047 0.95048443 0.95048443 0.61126047 0.1882551 0. ]
convolve()
with normalized weights:bhp = np.loadtxt('BHP.csv', delimiter=',', usecols=(6,), unpack=True) bhp_returns = np.diff(bhp) / bhp[ : -1] smooth_bhp = np.convolve(weights/weights.sum(), bhp_returns)[N-1:-N+1] vale = np.loadtxt('VALE.csv', delimiter=',', usecols=(6,), unpack=True) vale_returns = np.diff(vale) / vale[ : -1] smooth_vale = np.convolve(weights/weights.sum(), vale_returns)[N-1:-N+1]
matplotlib
using this code:t = np.arange(N - 1, len(bhp_returns)) plt.plot(t, bhp_returns[N-1:], lw=1.0) plt.plot(t, smooth_bhp, lw=2.0) plt.plot(t, vale_returns[N-1:], lw=1.0) plt.plot(t, smooth_vale, lw=2.0) plt.show()
The chart would appear as follows:
The thin lines on the preceding chart are the stock returns and the thick lines are the result of smoothing. As you can see, the lines cross a few times. These points might be important because the trend might have changed there. Or, at least, the relation of BHP to VALE might have changed. These turning inflection points probably occur often, so we might want to project into the future.
K = 8 t = np.arange(N - 1, len(bhp_returns)) poly_bhp = np.polyfit(t, smooth_bhp, K) poly_vale = np.polyfit(t, smooth_vale, K)
polysub()
:poly_sub = np.polysub(poly_bhp, poly_vale) xpoints = np.roots(poly_sub) print("Intersection points", xpoints)
The points are shown as follows:
Intersection points [ 27.73321597+0.j 27.51284094+0.j 24.32064343+0.j 18.86423973+0.j 12.43797190+1.73218179j 12.43797190-1.73218179j 6.34613053+0.62519463j 6.34613053-0.62519463j]
isreal()
function:reals = np.isreal(xpoints) print("Real number?", reals)
The result is as follows:
Real number? [ True True True True False False False False]
Some of the numbers are real, so select them with the select()
function. The select()
function forms an array by taking elements from a list of choices, based on a list of conditions:
xpoints = np.select([reals], [xpoints]) xpoints = xpoints.real print("Real intersection points", xpoints)
The real intersection points are as follows:
Real intersection points [ 27.73321597 27.51284094 24.32064343 18.86423973 0. 0. 0. 0.]
trim_zeros()
function strips the leading and trailing zeroes from a one-dimensional array. Get rid of the zeroes with the trim_zeros()
function:print("Sans 0s", np.trim_zeros(xpoints))
The zeroes are gone, and the output is shown as follows:
Sans 0s [ 27.73321597 27.51284094 24.32064343 18.86423973]
We applied the hanning()
function to smooth arrays containing stock returns. We subtracted two polynomials with the polysub()
function. We then checked for real numbers with the isreal()
function and selected the real numbers with the select()
function. Finally, we stripped zeroes from an array with the trim_zeros()
function (see smoothing.py
):
from __future__ import print_function import numpy as np import matplotlib.pyplot as plt N = 8 weights = np.hanning(N) print("Weights", weights) bhp = np.loadtxt('BHP.csv', delimiter=',', usecols=(6,), unpack=True) bhp_returns = np.diff(bhp) / bhp[ : -1] smooth_bhp = np.convolve(weights/weights.sum(), bhp_returns)[N-1:-N+1] vale = np.loadtxt('VALE.csv', delimiter=',', usecols=(6,), unpack=True) vale_returns = np.diff(vale) / vale[ : -1] smooth_vale = np.convolve(weights/weights.sum(), vale_returns)[N-1:-N+1] K = 8 t = np.arange(N - 1, len(bhp_returns)) poly_bhp = np.polyfit(t, smooth_bhp, K) poly_vale = np.polyfit(t, smooth_vale, K) poly_sub = np.polysub(poly_bhp, poly_vale) xpoints = np.roots(poly_sub) print("Intersection points", xpoints) reals = np.isreal(xpoints) print("Real number?", reals) xpoints = np.select([reals], [xpoints]) xpoints = xpoints.real print("Real intersection points", xpoints) print("Sans 0s", np.trim_zeros(xpoints)) plt.plot(t, bhp_returns[N-1:], lw=1.0, label='BHP returns') plt.plot(t, smooth_bhp, lw=2.0, label='BHP smoothed') plt.plot(t, vale_returns[N-1:], '--', lw=1.0, label='VALE returns') plt.plot(t, smooth_vale, '-.', lw=2.0, label='VALE smoothed') plt.title('Smoothing') plt.xlabel('Days') plt.ylabel('Returns') plt.grid() plt.legend(loc='best') plt.show()