Time for action – enveloping with Bollinger Bands

We already know how to calculate the SMA. So, if you need to refresh your memory, please review the Time for action – computing the simple average section in this chapter. This example will introduce the NumPy fill() function. The fill() function sets the value of an array to a scalar value. The function should be faster than array.flat = scalar or setting the values of the array one-by-one in a loop. Perform the following steps to envelope with the Bollinger Bands:

  1. Starting with an array called sma that contains the moving average values, we will loop through all the datasets corresponding to those values. After forming the dataset, calculate the standard deviation. Note that at a certain point, it will be necessary to calculate the difference between each data point and the corresponding average value. If we do not have NumPy, we will loop through these points and subtract each of the values one-by-one from the corresponding average. However, the NumPy fill() function allows us to construct an array that has elements set to the same value. This enables us to save on one loop and subtract arrays in one go:
    deviation = []
    C = len(c)
    
    for i in range(N - 1, C):
       if i + N < C:
          dev = c[i: i + N]
       else:
          dev = c[-N:]
       
       averages = np.zeros(N)
       averages.fill(sma[i - N - 1])
       dev = dev - averages
       dev = dev ** 2
       dev = np.sqrt(np.mean(dev))
       deviation.append(dev)
    
    deviation = 2 * np.array(deviation)
    print(len(deviation), len(sma))
    upperBB = sma + deviation
    lowerBB = sma - deviation
  2. To plot, we will use the following code (don't worry about it now; we will see how this works in Chapter 9, Plotting with matplotlib):
    t = np.arange(N - 1, C)
    plt.plot(t, c_slice, lw=1.0, label='Data')
    plt.plot(t, sma, '--', lw=2.0, label='Moving Average')
    plt.plot(t, upperBB, '-.', lw=3.0, label='Upper Band')
    plt.plot(t, lowerBB, ':', lw=4.0, label='Lower Band')
    plt.title('Bollinger Bands')
    plt.xlabel('Days')
    plt.ylabel('Price ($)')
    plt.grid()
    plt.legend()
    plt.show()

    Following is a chart showing the Bollinger Bands for our data. The jagged thin line in the middle represents the close price, and the dashed, smoother line crossing it is the moving average:

    Time for action – enveloping with Bollinger Bands

What just happened?

We worked out the Bollinger Bands that envelope the close price of our data. More importantly, we got acquainted with the NumPy fill() function. This function fills an array with a scalar value. This is the only parameter of the fill() function (see bollingerbands.py):

from __future__ import print_function
import numpy as np
import matplotlib.pyplot as plt

N = 5

weights = np.ones(N) / N
print("Weights", weights)

c = np.loadtxt('data.csv', delimiter=',', usecols=(6,), unpack=True)
sma = np.convolve(weights, c)[N-1:-N+1]
deviation = []
C = len(c)

for i in range(N - 1, C):
   if i + N < C:
      dev = c[i: i + N]
   else:
      dev = c[-N:]
   
   averages = np.zeros(N)
   averages.fill(sma[i - N - 1])
   dev = dev - averages
   dev = dev ** 2
   dev = np.sqrt(np.mean(dev))
   deviation.append(dev)

deviation = 2 * np.array(deviation)
print(len(deviation), len(sma))
upperBB = sma + deviation
lowerBB = sma - deviation

c_slice = c[N-1:]
between_bands = np.where((c_slice < upperBB) & (c_slice > lowerBB))

print(lowerBB[between_bands])
print(c[between_bands])
print(upperBB[between_bands])
between_bands = len(np.ravel(between_bands))
print("Ratio between bands", float(between_bands)/len(c_slice))

t = np.arange(N - 1, C)
plt.plot(t, c_slice, lw=1.0, label='Data')
plt.plot(t, sma, '--', lw=2.0, label='Moving Average')
plt.plot(t, upperBB, '-.', lw=3.0, label='Upper Band')
plt.plot(t, lowerBB, ':', lw=4.0, label='Lower Band')
plt.title('Bollinger Bands')
plt.xlabel('Days')
plt.ylabel('Price ($)')
plt.grid()
plt.legend()
plt.show()

Have a go hero – switching to Exponential Moving Average

It is customary to choose the SMA to center the Bollinger Band on. The second most popular choice is the EMA, so try that as an exercise. You can find a suitable example in this chapter, if you need pointers.

Check whether the fill() function is faster or is as fast as array.flat = scalar, or setting the value in a loop.

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

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