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; mind you, 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 between 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
and vstack
functions.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 that condition.condition = (c > support) & (c < resistance) print "Condition", condition between_bands = np.where(condition)
The following are the 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:
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 the following:
Number of points between bands 2nd approach 15
plot(t, c) plot(t, support) plot(t, resistance) show()
We will get the following plot in which 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
, 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
).
import numpy as np from matplotlib.pyplot import plot from matplotlib.pyplot import show def fit_line(t, y): A = np.vstack([t, np.ones_like(t)]).T return np.linalg.lstsq(A, y)[0] h, l, c = np.loadtxt('data.csv', delimiter=',', usecols=(4, 5, 6), unpack=True) pivots = (h + l + c) / 3 print "Pivots", pivots 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)) plot(t, c) plot(t, support) plot(t, resistance) show()