Time for action – smoothing with the hanning function

We will use the hanning function to smooth arrays of stock returns, as shown in the following steps:

  1. Call the hanning function to compute weights, for a certain N length window (in this example, N is 8):
    N = int(sys.argv[1])
    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.        ]
    
  2. Calculate the stock returns for the BHP and VALE quotes using 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]
  3. Plotting with Matplotlib:
    t = np.arange(N - 1, len(bhp_returns))
    plot(t, bhp_returns[N-1:], lw=1.0)
    plot(t, smooth_bhp, lw=2.0)
    plot(t, vale_returns[N-1:], lw=1.0)
    plot(t, smooth_vale, lw=2.0)
    show()

    The chart would appear as follows:

    Time for action – smoothing with the hanning function

    The thin lines on the 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.

  4. Fit the result of the smoothing step to polynomials:
    K = int(sys.argv[1])
    t = np.arange(N - 1, len(bhp_returns))
    poly_bhp = np.polyfit(t, smooth_bhp, K)
    poly_vale = np.polyfit(t, smooth_vale, K)
  5. Now, we need to compute for a situation where the polynomials we found in the previous step are equal to each other. This boils down to subtracting the polynomials and finding the roots of the resulting polynomial. Subtract the polynomials using 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]
    
  6. The numbers we get are complex; that is not good for us, unless there is such a thing as imaginary time. Check which numbers are real with the 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.]
    
  7. We managed to pick up some zeroes. The trim_zeros function strips the leading and trailing zeros from a one-dimensional array. Get rid of the zeroes with trim_zeros:
    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]
    

What just happened?

We applied the hanning function to smooth arrays containing stock returns. We subtracted two polynomials with the polysub function. We 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 strip_zeroes function (see smoothing.py):

import numpy as np
import sys
from matplotlib.pyplot import plot
from matplotlib.pyplot import show

N = int(sys.argv[1])

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 = int(sys.argv[1])
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)

plot(t, bhp_returns[N-1:], lw=1.0)
plot(t, smooth_bhp, lw=2.0)

plot(t, vale_returns[N-1:], lw=1.0)
plot(t, smooth_vale, lw=2.0)
show()

Have a go hero – smoothing variations

Experiment with the other smoothing functions—hamming , blackman , bartlett , and kaiser . They work more or less in the same way as hanning.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset