Support and resistance indicators

In the first chapter, we explained the principle of the evolution of prices based on supply and demand. The price decreases when there is an increase in supply, and the price increases when demand rises. When there is a fall in price, we expect the price fall to pause due to a concentration of demands. This virtual limit will be referred to as a support line. Since the price becomes lower, it is more likely to find buyers. Inversely, when the price starts rising, we expect a pause in this increase due to a concentration of supplies. This is referred to as the resistance line. It is based on the same principle, showing that a high price leads sellers to sell. This exploits the market psychology of investors following this trend of buying when the price is low and selling when the price is high.

To illustrate an example of a technical indicator (in this part, support and resistance), we will use the Google data from the first chapter. Since you will use the data for testing many times, you should store this data frame to your disk. Doing this will help you save time when you want to replay the data. To avoid complications with stock split, we will only take dates without splits. Therefore, we will keep only 620 days. Let's have a look at the following code:

import pandas as pd
from pandas_datareader import data

start_date = '2014-01-01'
end_date = '2018-01-01'
SRC_DATA_FILENAME='goog_data.pkl'

try:
goog_data2 = pd.read_pickle(SRC_DATA_FILENAME)
except FileNotFoundError:
goog_data2 = data.DataReader('GOOG', 'yahoo', start_date, end_date)
goog_data2.to_pickle(SRC_DATA_FILENAME)

goog_data=goog_data2.tail(620)
lows=goog_data['Low']
highs=goog_data['High']

import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111, ylabel='Google price in $')
highs.plot(ax=ax1, color='c', lw=2.)
lows.plot(ax=ax1, color='y', lw=2.)
plt.hlines(highs.head(200).max(),lows.index.values[0],lows.index.values[-1],linewidth=2, color='g')
plt.hlines(lows.head(200).min(),lows.index.values[0],lows.index.values[-1],linewidth=2, color='r')
plt.axvline(linewidth=2,color='b',x=lows.index.values[200],linestyle=':')
plt.show()

In this code, the following applies:

  • This retrieves the financial data from the Yahoo finance website between January 1, 2014 and January 1, 2018.
  • We used the maximum and minimum values to create the support and the resistance limits, as shown in the following plot:

In this plot, the following applies:

  • We draw the highs and lows of the GOOG price.
  • The green line represents the resistance level, and the red line represents the support level.
  • To build these lines, we use the maximum value of the GOOG price and the minimum value of the GOOG price stored daily.
  • After the 200th day (dotted vertical blue line), we will buy when we reach the support line, and sell when we reach the resistance line. In this example, we used 200 days so that we have sufficient data points to get an estimate of the trend.
  • It is observed that the GOOG price will reach the resistance line around August 2016. This means that we have a signal to enter a short position (sell). 
  • Once traded, we will wait to get out of this short position when the GOOG price will reach the support line.
  • With this historical data, it is easily noticeable that this condition will not happen.
  • This will result in carrying a short position in a rising market without having any signal to sell it, thereby resulting in a huge loss.
  • This means that, even if the trading idea based on support/resistance has strong grounds in terms of economical behavior, in reality, we will need to modify this trading strategy to make it work.
  • Moving the support/resistance line to adapt to the market evolution will be key to the trading strategy efficiency.

In the middle of the following chart, we show three fixed-size time windows. We took care of adding the tolerance margin that we will consider to be sufficiently close to the limits (support and resistance):

If we take a new 200-day window after the first one, the support/resistance levels will be recalculated. We observe that the trading strategy will not get rid of the GOOG position (while the market keeps raising) since the price does not go back to the support level.

Since the algorithm cannot get rid of a position, we will need to add more parameters to change the behavior in order to enter a position. The following parameters can be added to the algorithm to change its position:

  • There can be a shorter rolling window.
  • We can count the number of times the price reaches a support or resistance line.
  • A tolerance margin can be added to consider that a support or resistance value can attain around a certain percentage of this value.

This phase is critical when creating your trading strategy. You will start by observing how your trading idea will perform using historical data, and then you will increase the number of parameters of this strategy to adjust to more realistic test cases.

In our example, we can introduce two further parameters:

  • The minimum number of times that a price needs to reach the support/resistance level.
  • We will define the tolerance margin of what we consider being close to the support/resistance level.

Let's now have a look at the code:

import pandas as pd
import numpy as np
from pandas_datareader import data

start_date = '2014-01-01'
end_date = '2018-01-01'
SRC_DATA_FILENAME='goog_data.pkl'

try:
goog_data = pd.read_pickle(SRC_DATA_FILENAME)
print('File data found...reading GOOG data')
except FileNotFoundError:
print('File not found...downloading the GOOG data')
goog_data = data.DataReader('GOOG', 'yahoo', start_date, end_date)
goog_data.to_pickle(SRC_DATA_FILENAME)

goog_data_signal = pd.DataFrame(index=goog_data.index)
goog_data_signal['price'] = goog_data['Adj Close']

In the code, the data is collected by using the pandas_datareader library and by using the class. Now, let's have a look at the other part of the code where we will implement the trading strategy:

def trading_support_resistance(data, bin_width=20):
data['sup_tolerance'] = pd.Series(np.zeros(len(data)))
data['res_tolerance'] = pd.Series(np.zeros(len(data)))
data['sup_count'] = pd.Series(np.zeros(len(data)))
data['res_count'] = pd.Series(np.zeros(len(data)))
data['sup'] = pd.Series(np.zeros(len(data)))
data['res'] = pd.Series(np.zeros(len(data)))
data['positions'] = pd.Series(np.zeros(len(data)))
data['signal'] = pd.Series(np.zeros(len(data)))
in_support=0
in_resistance=0

for x in range((bin_width - 1) + bin_width, len(data)):
data_section = data[x - bin_width:x + 1]
support_level=min(data_section['price'])
resistance_level=max(data_section['price'])
range_level=resistance_level-support_level
data['res'][x]=resistance_level
data['sup'][x]=support_level
data['sup_tolerance'][x]=support_level + 0.2 * range_level
data['res_tolerance'][x]=resistance_level - 0.2 * range_level

if data['price'][x]>=data['res_tolerance'][x] and
data['price'][x] <= data['res'][x]:
in_resistance+=1
data['res_count'][x]=in_resistance
elif data['price'][x] <= data['sup_tolerance'][x] and
data['price'][x] >= data['sup'][x]:
in_support += 1
data['sup_count'][x] = in_support
else:
in_support=0
in_resistance=0
if in_resistance>2:
data['signal'][x]=1
elif in_support>2:
data['signal'][x]=0
else:
data['signal'][x] = data['signal'][x-1]

data['positions']=data['signal'].diff()

trading_support_resistance(goog_data_signal)

In the preceding code, the following applies:

  • The trading_support_resistance function defines the time window in the price that is used to calculate the resistance and support levels.
  • The level of support and resistance is calculated by taking the maximum and minimum price and then subtracting and adding a 20% margin.
  • We used diff to know when we place the orders.
  • When the price is below/above the support/resistance, we will enter a long/short position. For that, we will have 1 for a long position and 0 for a short position.

The code will print the chart representing the time when orders go out:


import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111, ylabel='Google price in $')
goog_data_signal['sup'].plot(ax=ax1, color='g', lw=2.)
goog_data_signal['res'].plot(ax=ax1, color='b', lw=2.)
goog_data_signal['price'].plot(ax=ax1, color='r', lw=2.)
ax1.plot(goog_data_signal.loc[goog_data_signal.positions == 1.0].index,
goog_data_signal.price[goog_data_signal.positions == 1.0],
'^', markersize=7, color='k',label='buy')
ax1.plot(goog_data_signal.loc[goog_data_signal.positions == -1.0].index,
goog_data_signal.price[goog_data_signal.positions == -1.0],
'v', markersize=7, color='k',label='sell')
plt.legend()
plt.show()

The codes will return the following output. The plot shows a 20-day rolling window calculating resistance and support:

From this plot, it is observed that a buy order is sent when a price stays in the resistance tolerance margin for 2 consecutive days, and that a sell order is sent when a price stays in the support tolerance margin for 2 consecutive days.

In this section, we learned the difference between trend and momentum trading strategies, and we implemented a very well used momentum trading strategy based on support and resistance levels. We will now explore new ideas to create trading strategies by using more technical analysis.

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

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