Time for action – drawing trend lines

Perform the following steps to draw trend lines:

  1. First, we need to determine the pivot points. We shall pretend they are equal to the arithmetic mean of the high, low, and close price:
    h, l, c = np.loadtxt('data.csv', delimiter=',', usecols=(4, 5, 6), unpack=True)
    
    pivots = (h + l + c) / 3
    print("Pivots", pivots)

    From the pivots, we can deduce the so-called resistance and support levels. The support level is the lowest level at which the price rebounds. The resistance level is the highest level at which the price bounces back. These are not natural phenomena, they are merely estimates. Based on these estimates, it is possible to draw support and resistance trend lines. We will define the daily spread to be the difference of the high and low price.

  2. Define a function to fit line to data to a line where y = at + b. The function should return a and b. This is another opportunity to apply the lstsq() function of the NumPy linalg package. Rewrite the line equation to y = Ax, where A = [t 1] and x = [a b]. Form A with the NumPy ones_like(), which creates an array, where all the values are equal to 1, using an input array as a template for the array dimensions:
    def fit_line(t, y):
       A = np.vstack([t, np.ones_like(t)]).T
       return np.linalg.lstsq(A, y)[0]
  3. Assuming that support levels are one daily spread below the pivots, and that resistance levels are one daily spread above the pivots, fit the support and resistance trend lines:
    t = np.arange(len(c))
    sa, sb = fit_line(t, pivots - (h - l))
    ra, rb = fit_line(t, pivots + (h - l))
    support = sa * t + sb
    resistance = ra * t + rb
  4. At this juncture, we have all the necessary information to draw the trend lines; however, it is wise to check how many points fall between the support and resistance levels. Obviously, if only a small percentage of the data is between the trend lines, then this setup is of no use to us. Make up a condition for points between the bands and select with the where() function, based on the following condition:
    condition = (c > support) & (c < resistance)
    print("Condition", condition)
    between_bands = np.where(condition)

    These are the printed condition values:

    Condition [False False  True  True  True  True  True False False  True False False
     False False False  True False False False  True  True  True  True False False  True  True  True False  True]
    

    Double-check the values:

    print(support[between_bands])
    print( c[between_bands])
    print( resistance[between_bands])

    The array returned by the where() function has rank 2, so call the ravel() function before calling the len() function:

    between_bands = len(np.ravel(between_bands))
    print("Number points between bands", between_bands)
    print("Ratio between bands", float(between_bands)/len(c))

    You will get the following result:

    Number points between bands 15
    Ratio between bands 0.5
    

    As an extra bonus, we gained a predictive model. Extrapolate the next day resistance and support levels:

    print("Tomorrows support", sa * (t[-1] + 1) + sb)
    print("Tomorrows resistance", ra * (t[-1] + 1) + rb)

    This results in the following output:

    Tomorrows support 349.389157088
    Tomorrows resistance 360.749340996
    

    Another approach to figure out how many points are between the support and resistance estimates is to use [] and intersect1d(). Define selection criteria in the [] operator and intersect the results with the intersect1d() function:

    a1 = c[c > support]
    a2 = c[c < resistance]
    print("Number of points between bands 2nd approach" ,len(np.intersect1d(a1, a2)))

    Not surprisingly, we get:

    Number of points between bands 2nd approach 15
    
  5. Once more, plot the results:
    plt.plot(t, c, label='Data')
    plt.plot(t, support, '--', lw=2.0, label='Support')
    plt.plot(t, resistance, '-.', lw=3.0, label='Resistance')
    plt.title('Trend Lines')
    plt.xlabel('Days')
    plt.ylabel('Price ($)')
    plt.grid()
    plt.legend()
    plt.show()

    In the following plot, we have the price data and the corresponding support and resistance lines:

    Time for action – drawing trend lines

What just happened?

We drew trend lines without having to mess around with rulers, pencils, and paper charts. We defined a function that can fit data to a line with the NumPy vstack(), ones_like(), and lstsq() functions. We fit the data in order to define support and resistance trend lines. Then, we figured out how many points are within the support and resistance range. We did this using two separate methods that produced the same result.

The first method used the where() function with a Boolean condition. The second method made use of the [] operator and the intersect1d() function. The intersect1d() function returns an array of common elements from two arrays (see trendline.py):

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


def fit_line(t, y):
   ''' Fits t to a line y = at + b '''
   A = np.vstack([t, np.ones_like(t)]).T

   return np.linalg.lstsq(A, y)[0]

# Determine pivots
h, l, c = np.loadtxt('data.csv', delimiter=',', usecols=(4, 5, 6), unpack=True)

pivots = (h + l + c) / 3
print("Pivots", pivots)

# Fit trend lines
t = np.arange(len(c))
sa, sb = fit_line(t, pivots - (h - l))
ra, rb = fit_line(t, pivots + (h - l))

support = sa * t + sb
resistance = ra * t + rb
condition = (c > support) & (c < resistance)
print("Condition", condition)
between_bands = np.where(condition)
print(support[between_bands])
print(c[between_bands])
print(resistance[between_bands])
between_bands = len(np.ravel(between_bands))
print("Number points between bands", between_bands)
print("Ratio between bands", float(between_bands)/len(c))

print("Tomorrows support", sa * (t[-1] + 1) + sb)
print("Tomorrows resistance", ra * (t[-1] + 1) + rb)

a1 = c[c > support]
a2 = c[c < resistance]
print("Number of points between bands 2nd approach" ,len(np.intersect1d(a1, a2)))

# Plotting
plt.plot(t, c, label='Data')
plt.plot(t, support, '--', lw=2.0, label='Support')
plt.plot(t, resistance, '-.', lw=3.0, label='Resistance')
plt.title('Trend Lines')
plt.xlabel('Days')
plt.ylabel('Price ($)')
plt.grid()
plt.legend()
plt.show()
..................Content has been hidden....................

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