Perform the following steps to draw trend lines:
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.
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]
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
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
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:
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()