## Python Tutorial: Getting Started

Contact: andrewshamlet@gmail.com // @andrewshamlet

Getting Started

Congratulations, and welcome to Stock Technical Analysis in Python!

You have taken your first step towards making smarter, more disciplined trading decisions.

Before diving in, let’s make sure you have everything you may need.

Anaconda 4.4.0

Pandas, Numpy, and MatPlotLib

Anaconda comes pre-loaded with the three modules you will use throughout the course.

Quantopian

You will backtest your strategy using the Quantopian platform.-

StockCharts, Investopedia, and Google Finance

StockCharts, Investopedia, and Google Finance are great resources for financial knowledge.

Stack Overflow

Stack Overflow is a great resource for coding questions.-

You are now ready to dive in!

## Python Tutorial: Query Stock Data, Calculate 30 Day Moving Average

Python streamlines tasks requiring multiple steps in a single block of code. For this reason, it is a great tool for querying and performing analysis on data. In this post we will use Python to pull ticker data for a specific stock and then calculate its 30 day moving average. Here are the steps:

1. Import the pandas modules.

import pandas as pd
import pandas.io.data as web

2. Create a list of the stocks for which you would like to query ticker data. For this example, we will pull ticker data for Facebook, ‘FB’. If you would like to add other stocks, simply add the symbols to the list separated by commas.

stocks = ['FB']

Or

stocks = ['FB','AAPL','GOOG','AMZN']

3. Write function to query data from yahoo finance. The function takes three arguments: the stock, the start date, and the end date. It returns the daily ‘Adj Close’. If you would like to pull a different value, simply switch it for ‘Adj Close’ without the brackets.

def get_stock(stock,start,end):

Or

def get_stock(stock,start,end):
return web.get_data_yahoo(stock,start,end)['Volume']

4. Call function for the date range, 1/1/2016 – 12/31/2016. Use the ‘for n in stocks’ logic in case you have more than one stock for which you would like to pull data. Compile query in DataFrame, saved to variable ‘px’.

px = pd.DataFrame({n: get_stock(n, '1/1/2016', '12/31/2016') for n in stocks})

5. Add new column to DataFrame in which you calculate the 30 day moving average. Call DataFrame to view contents.

px['30 mavg'] = pd.rolling_mean(px, 30)
px

There you have it! We created a DataFrame containing the daily ticker data for a specific stock and then calculated its 30 day moving average. Here is the full code:

import pandas as pd
import pandas.io.data as web

stocks = ['FB']
def get_stock(stock, start, end):
return web.get_data_yahoo(stock, start, end)['Adj Close']
px = pd.DataFrame({n: get_px(n, '1/1/2016', '12/31/2016') for n in names})
px['30 mavg'] = pd.rolling_mean(px, 30)
px

## Python Tutorial: Plot 30 Day Moving Average

Python streamlines tasks requiring multiple steps in a single block of code. For this reason, it is a great tool for querying and performing analysis on data.

Last post we created a DataFrame containing the daily ticker data for a specific stock and calculated its 30 day moving average. In this post, we will take it a step further and plot the DataFrame in order to visualize its contents.

1. Code from last post.

import pandas as pd
import pandas.io.data as web

stocks = ['FB']
def get_stock(stock, start, end):
return web.get_data_yahoo(stock, start, end)['Adj Close']
px = pd.DataFrame({n: get_px(n, '1/1/2016', '12/31/2016') for n in names})
px['30 mavg'] = pd.rolling_mean(px, 30)
px

2. Import the matplotlib modules.

import matplotlib.pyplot as plt
%matplotlib inline

3. Call the plot function.

plt.plot(px)

There you have it! We used matplotlib to visualize our DataFrame. Looks like the stock tanked towards the end of 2016, perhaps due to the US Presidential Election 😉

Here is the full code:

import pandas as pd
import pandas.io.data as web
import matplotlib.pyplot as plt
%matplotlib inline

stocks = ['FB']
def get_stock(stock, start, end):
return web.get_data_yahoo(stock, start, end)['Adj Close']
px = pd.DataFrame({n: get_px(n, '1/1/2016', '12/31/2016') for n in names})
px['30 mavg'] = pd.rolling_mean(px, 30)
plt.plot(px)

## Python Tutorial: MACD (Moving Average Convergence/Divergence)

Python streamlines tasks requiring multiple steps in a single block of code. For this reason, it is a great tool for querying and performing analysis on data.

In this post, we outline steps for calculating a stock’s MACD indicator. But first, what is MACD (Moving Average Convergence/Divergence)?

Developed by Gerald Appel in the late seventies, MACD is one of the simplest and most effective momentum indicators available. MACD turns two trend-following indicators, moving averages, into a momentum oscillator by subtracting the longer moving average from the shorter moving average. As a result, MACD offers the best of both worlds: trend following and momentum.

To calculate MACD, the formula is:

MACD: (12-day EMA - 26-day EMA)

EMA stands for Exponential Moving Average.

With that background, let’s use Python to compute MACD.

1. Start with the 30 Day Moving Average Tutorial code.

import pandas as pd
import pandas.io.data as web

stocks = ['FB']
def get_stock(stock, start, end):
return web.get_data_yahoo(stock, start, end)['Adj Close']
px = pd.DataFrame({n: get_px(n, '1/1/2016', '12/31/2016') for n in names})
px

2. Compute the 26 Day Exponential Moving Average. We must call the column by the stock ticker.

px['26 ema'] = pd.ewma(px["FB"], span=26)

3. Then the 12 Day Exponential Moving Average.

px['12 ema'] = pd.ewma(px["FB"], span=12)

4. Subtract the 26 Day EMA from the 12 Day EMA, arriving at the MACD.

px['MACD'] = (px['12 ema'] - px['26 ema'])

5. Plot close price against MACD.

px.plot(y= ['FB'], title='FB')
px.plot(y= ['MACD'], title='MACD')

There you have it! We created our MACD indicator. Here’s the full code:

import pandas.io.data as web
import pandas as pd
%matplotlib inline
import matplotlib.pyplot as plt

names = ['FB']
def get_px(stock, start, end):
return web.get_data_yahoo(stock, start, end)['Adj Close']
px = pd.DataFrame({n: get_px(n, '1/1/2016', '1/17/2017') for n in names})
px['26 ema'] = pd.ewma(px["FB"], span=26)
px['12 ema'] = pd.ewma(px["FB"], span=12)
px['MACD'] = (px['12 ema'] - px['26 ema'])
px.plot(y= ['FB'], title='FB')
px.plot(y= ['MACD'], title='MACD')

So when would you enter the position 😕 ?

## Update – Python Tutorial: MACD (Moving Average Convergence/Divergence)

Download the accompanying IPython Notebook for this Tutorial from Github.

I received a question from Sam Khorsand about applying the Python Tutorial: MACD (Moving Average Convergence/Divergence) Tutorial   to multiple stocks. The code below will produce yesterday’s MACD Crossover for a list of stocks. Also, by adding ‘to_string(index = False’), you can clean up the date formatting. Enjoy!

import pandas as pd
from pandas_datareader import data as web
import matplotlib.pyplot as plt
import datetime as dt
%matplotlib inline

def MACD(stock, start, end):
df = df.reset_index()
df['30 mavg'] = pd.rolling_mean(df['Close'], 30)
df['26 ema'] = pd.ewma(df['Close'], span=26)
df['12 ema'] = pd.ewma(df['Close'], span=12)
df['MACD'] = (df['12 ema'] - df['26 ema'])
df['Signal'] = pd.ewma(df['MACD'], span=9)
df['Crossover'] = df['MACD'] - df['Signal']
return stock, df['Date'][-1:].to_string(),df['Crossover'][-1:].mean()

stocks = ['FB', 'AAPL', 'GOOG', 'AMZN', 'TSLA']

d = []

for stock in stocks:
stock, date, macd = MACD(stock, '1/1/2016', dt.datetime.today())
d.append({'Stock':stock, 'Date':date, 'MACD':macd})

df2 = pd.DataFrame(d)
df2[['Date', 'Stock', 'MACD']]
Date Stock MACD
0 249 2017-09-20 FB -0.211440
1 249 2017-09-20 AAPL -0.828956
2 249 2017-09-20 GOOG -0.069812
3 249 2017-09-20 AMZN 1.028655
4 249 2017-09-20 TSLA 2.287354

## Python Tutorial: MACD Signal Line & Centerline Crossovers

Python streamlines tasks requiring multiple steps in a single block of code. For this reason, it is a great tool for querying and performing analysis on data.

Last post, we outlined steps for calculating a stock’s MACD indicator.

In this post, we take MACD a step further by introducing Signal Line and Centerline Crossovers.

Signal Line Crossovers

Signal Line is defined as:

Signal Line: 9-day EMA of MACD Line

Signal line crossovers are the most common MACD signals. The signal line is a 9-day EMA of the MACD Line. As a moving average of the indicator, it trails the MACD and makes it easier to spot MACD turns. A bullish crossover occurs when the MACD turns up and crosses above the signal line. A bearish crossover occurs when the MACD turns down and crosses below the signal line. Crossovers can last a few days or a few weeks, it all depends on the strength of the move.

Let’s use Python to compute the Signal Line.

1.  Start with the MACD Tutorial code.

import pandas.io.data as web
import pandas as pd
%matplotlib inline
import matplotlib.pyplot as plt

names = ['FB']

def get_px(stock, start, end):
return web.get_data_yahoo(stock, start, end)['Adj Close']
px = pd.DataFrame({n: get_px(n, '1/1/2016', '1/17/2017') for n in names})
px['26 ema'] = pd.ewma(px["FB"], span=26)
px['12 ema'] = pd.ewma(px["FB"], span=12)
px['MACD'] = (px['12 ema'] - px['26 ema'])

2. Compute the 9 Day Exponential Moving Average of MACD.

px['Signal Line'] = pd.ewma(px['MACD'], span=9)

3. Create Signal Line Crossover Indicator. When MACD > Signal Line, 1. When MACD < Signal Line, 0.

px['Signal Line Crossover'] = np.where(px['MACD'] > px['Signal Line'], 1, 0)
px['Signal Line Crossover'] = np.where(px['MACD'] < px['Signal Line'], -1, px['Signal Line Crossover'])

Centerline Crossovers

Centerline crossovers are the next most common MACD signals. A bullish centerline crossover occurs when the MACD Line moves above the zero line to turn positive. This happens when the 12-day EMA of the underlying security moves above the 26-day EMA. A bearish centerline crossover occurs when the MACD moves below the zero line to turn negative. This happens when the 12-day EMA moves below the 26-day EMA.

Centerline crossovers can last a few days or a few months. It all depends on the strength of the trend. The MACD will remain positive as long as there is a sustained uptrend. The MACD will remain negative when there is a sustained downtrend.

4. Create Centerline Crossover Indicator. When MACD > 0, 1. When MACD < 0, 0.

px['Centerline Crossover'] = np.where(px['MACD'] > 0, 1, 0)
px['Centerline Crossover'] = np.where(px['MACD'] < 0, -1, px['Centerline Crossover'])

Plotting Crossovers

Last post, we posed the question: ‘When would you enter the position 😕 ?’

Now that we understand Signal Line Crossovers, let’s propose that we enter the position, ‘buy’, on 1, and we exit the position, ‘sell’, on -1.

5. Create Buy/Sell Indicator, based on Signal Line Crossovers. Multiply by 2 to increase size of indicator when plotted, so ‘buy’ on 2 and ‘sell’ on -2.

px['Buy Sell'] = (2*(np.sign(px['Signal Line Crossover'] - px['Signal Line Crossover'].shift(1))))

6. Plot close price, MACD & Signal Line, and Signal Line & Centerline Crossovers.

px.plot(y=['FB'], title='Close')
px.plot(y= ['MACD', 'Signal Line'], title='MACD & Signal Line')
px.plot(y= ['Centerline Crossover', 'Buy Sell'], title='Signal Line & Centerline Crossovers', ylim=(-3,3))

There you have it! We created MACD Signal Line and Centerline Crossovers, and based on the Crossovers, plotted ‘buy’ and ‘sell’ indicators.

Based on the entry and exit points, can you calculate the P&L? Stay tuned to find out.

Here’s the full code:

import pandas.io.data as web
import pandas as pd
%matplotlib inline
import matplotlib.pyplot as plt

names = ['FB']

def get_px(stock, start, end):
return web.get_data_yahoo(stock, start, end)['Adj Close']
px = pd.DataFrame({n: get_px(n, '1/1/2016', '1/17/2017') for n in names})
px['26 ema'] = pd.ewma(px["FB"], span=26)
px['12 ema'] = pd.ewma(px["FB"], span=12)
px['MACD'] = (px['12 ema'] - px['26 ema'])
px['Signal Line'] = pd.ewma(px['MACD'], span=9)
px['Signal Line Crossover'] = np.where(px['MACD'] > px['Signal Line'], 1, 0)
px['Signal Line Crossover'] = np.where(px['MACD'] < px['Signal Line'], -1, px['Signal Line Crossover'])
px['Centerline Crossover'] = np.where(px['MACD'] > 0, 1, 0)
px['Centerline Crossover'] = np.where(px['MACD'] < 0, -1, px['Centerline Crossover'])
px['Buy Sell'] = (2*(np.sign(px['Signal Line Crossover'] - px['Signal Line Crossover'].shift(1))))

px.plot(y=['FB'], title='Close')
px.plot(y= ['MACD', 'Signal Line'], title='MACD & Signal Line')
px.plot(y= ['Centerline Crossover', 'Buy Sell'], title='Signal Line & Centerline Crossovers', ylim=(-3,3))

## Python Tutorial – Future Returns

Download the accompanying IPython Notebook for this Tutorial from Github.

Last Tutorial, we outlined steps for calculating the Stochastic Oscillator.

In this Tutorial, we walk through calculating 5-day, 10-day, and 20-day future returns, from historical data.

Caculating 5-day, 10-day, and 20-day future returns will allow us to identify relationships between current technical indicators and future returns.

Let’s use Python to compute the 5-day, 10-day, and 20-day future returns.

1.) Import modules.

import pandas as pd
import numpy as np
from pandas_datareader import data as web
import matplotlib.pyplot as plt
%matplotlib inline

2.) Define function for querying daily close.

def get_stock(stock,start,end):

3.) Define function for calculating the 5-day future return.

def fiveday(close):
fiveday = ((close.shift(-5) - close) / close) * 100
return fiveday

4.) Define function for calculating 10-day future return.

def tenday(close):
tenday = ((close.shift(-10) - close) / close) * 100
return tenday

5.) Define function for calculating 20-day future return.

def twentyday(close):
twentyday = ((close.shift(-20) - close) / close) * 100
return twentyday

6.) Query daily close.

df = pd.DataFrame(get_stock('FB', '1/1/2016', '12/31/2016'))

7.) Run daily close through fiveday, tenday, and twentday functions. Save series to new columns in dataframe.

df['5 day'] = fiveday(df['Close'])
df['10 day'] = tenday(df['Close'])
df['20 day'] = twentyday(df['Close'])
df = df.dropna()
df.tail()

8.) Plot average 5-day, 10-day, and 20-day future returns.

df2 = df[['5 day', '10 day', '20 day']].mean()
df2.plot(kind='bar')

There you have it! We calculated 5-day, 10-day, and 20-day future returns. Here’s the full code:

import pandas as pd
import numpy as np
from pandas_datareader import data as web
import matplotlib.pyplot as plt
%matplotlib inline

def get_stock(stock,start,end):

def fiveday(close):
fiveday = ((close.shift(-5) - close) / close) * 100
return fiveday

def tenday(close):
tenday = ((close.shift(-10) - close) / close) * 100
return tenday

def twentyday(close):
twentyday = ((close.shift(-20) - close) / close) * 100
return twentyday

df = pd.DataFrame(get_stock('FB', '1/1/2016', '12/31/2016'))
df['5 day'] = fiveday(df['Close'])
df['10 day'] = tenday(df['Close'])
df['20 day'] = twentyday(df['Close'])
df = df.dropna()
df.tail()

## Python Tutorial: Stochastic Oscillator

Download the accompanying IPython Notebook for this Tutorial from Github.

Last Tutorial, we outlined steps for calculating the Mass Index.

In this Tutorial, we introduce a new technical indicator, the Stochastic Oscillator.

Developed by George C. Lane in the late 1950s, the Stochastic Oscillator is a momentum indicator that shows the location of the close relative to the high-low range over a set number of periods.

The Stochastic Oscillator is calculated as follows:

%K = (Current Close - Lowest Low)/(Highest High - Lowest Low) * 100
%D = 3-day SMA of %K

Lowest Low = lowest low for the look-back period
Highest High = highest high for the look-back period

The default setting for the Stochastic Oscillator is 14 periods, which can be days, weeks, months or an intraday timeframe. A 14-period %K would use the most recent close, the highest high over the last 14 periods and the lowest low over the last 14 periods. %D is a 3-day simple moving average of %K.

As a bound oscillator, the Stochastic Oscillator makes it easy to identify overbought and oversold levels. The oscillator ranges from zero to one hundred. No matter how fast a security advances or declines, the Stochastic Oscillator will always fluctuate within this range. Traditional settings use 80 as the overbought threshold and 20 as the oversold threshold. These levels can be adjusted to suit analytical needs and security characteristics. Readings above 80 for the 20-day Stochastic Oscillator would indicate that the underlying security was trading near the top of its 20-day high-low range. Readings below 20 occur when a security is trading at the low end of its high-low range.

Before looking at some chart examples, it is important to note that overbought readings are not necessarily bearish. Securities can become overbought and remain overbought during a strong uptrend. Closing levels that are consistently near the top of the range indicate sustained buying pressure. In a similar vein, oversold readings are not necessarily bullish. Securities can also become oversold and remain oversold during a strong downtrend. Closing levels consistently near the bottom of the range indicate sustained selling pressure. It is, therefore, important to identify the bigger trend and trade in the direction of this trend. Look for occasional oversold readings in an uptrend and ignore frequent overbought readings. Similarly, look for occasional overbought readings in a strong downtrend and ignore frequent oversold readings.

Let’s use Python to compute the Stochastic Oscillator.

1.) Import modules.

import pandas as pd
import numpy as np
from pandas_datareader import data as web
import matplotlib.pyplot as plt
%matplotlib inline

2.a.) Define function for querying daily close.

def get_stock(stock,start,end):

2.b.) Define function for querying daily high.

def get_high(stock,start,end):

2.c.) Define function for querying daily low.

def get_low(stock,start,end):

3.) Define function for the Stochastic Oscillator, both %K and %D.

def STOK(close, low, high, n):
STOK = ((close - pd.rolling_min(low, n)) / (pd.rolling_max(high, n) - pd.rolling_min(low, n))) * 100
return STOK

def STOD(close, low, high, n):
STOK = ((close - pd.rolling_min(low, n)) / (pd.rolling_max(high, n) - pd.rolling_min(low, n))) * 100
STOD = pd.rolling_mean(STOK, 3)
return STOD

How does the Stochastic Oscillator function work?

3.a.) To calculate %K, we find the difference between the current close and the lowest low for the look-back period, n. We then find the difference between the highest high for the look-back period, n, and the lowest low for the same look-back period. Dividing these two values and multiplying the result by 100, we arrive at %K, which we set to variable STOK.

#STOK = ((close - pd.rolling_min(low, n)) / (pd.rolling_max(high, n) - pd.rolling_min(low, n))) * 100

3.b.) Function returns STOK.

#return STOK

3.c.) To calculate %D, we first calculate %K.

#STOK = ((close - pd.rolling_min(low, n)) / (pd.rolling_max(high, n) - pd.rolling_min(low, n))) * 100

3.d.) Then we take the 3 day moving average of %K, and set the value to variable STOD.

#STOD = pd.rolling_mean(STOK, 3)

3.e.) Function returns STOD.

#return STOD

4.) Query daily close, high, and low for ‘FB’ during 2016.

df = pd.DataFrame(get_stock('FB', '1/1/2016', '12/31/2016'))
df['High'] = get_high('FB', '1/1/2016', '12/31/2016')
df['Low'] = get_low('FB', '1/1/2016', '12/31/2016')

5.) Run daily close, low, and high through %K and %D functions. Save series to new columns in dataframe.

df['%K'] = STOK(df['Close'], df['Low'], df['High'], 14)
df['%D'] = STOD(df['Close'], df['Low'], df['High'], 14)
df.tail()

6.) Plot daily close, %K, and %D.

df.plot(y=['Close'], figsize = (20, 5))
df.plot(y=['%K', '%D'], figsize = (20, 5))

There you have it! We created our Stochastic Oscillator indicator. Here’s the full code:

import pandas as pd
import numpy as np
from pandas_datareader import data as web
import matplotlib.pyplot as plt
%matplotlib inline

def get_stock(stock,start,end):

def get_high(stock,start,end):

def get_low(stock,start,end):

def STOK(close, low, high, n):
STOK = ((close - pd.rolling_min(low, n)) / (pd.rolling_max(high, n) - pd.rolling_min(low, n))) * 100
return STOK

def STOD(close, low, high, n):
STOK = ((close - pd.rolling_min(low, n)) / (pd.rolling_max(high, n) - pd.rolling_min(low, n))) * 100
STOD = pd.rolling_mean(STOK, 3)
return STOD

df = pd.DataFrame(get_stock('FB', '1/1/2016', '12/31/2016'))
df['High'] = get_high('FB', '1/1/2016', '12/31/2016')
df['Low'] = get_low('FB', '1/1/2016', '12/31/2016')
df['%K'] = STOK(df['Close'], df['Low'], df['High'], 14)
df['%D'] = STOD(df['Close'], df['Low'], df['High'], 14)
df.tail()

## Python Tutorial: Mass Index

Download the accompanying IPython Notebook for this Tutorial from Github.

Python streamlines tasks requiring multiple steps in a single block of code. For this reason, it is a great tool for querying and performing analysis on data.

Last Tutorial, we outlined steps for calculating Commodity Channel Index (CCI).

In this Tutorial, we introduce a new technical indicator, the Mass Index.

Developed by Donald Dorsey, the Mass Index uses the high-low range to identify trend reversals based on range expansions. In this sense, the Mass Index is a volatility indicator that does not have a directional bias. Instead, the Mass Index identifies range bulges that can foreshadow a reversal of the current trend.

The Mass Index is calculated as follows:

Single EMA = 9-period exponential moving average (EMA) of the high-low differential

Double EMA = 9-period EMA of the 9-period EMA of the high-low differential

EMA Ratio = Single EMA divided by Double EMA

Mass Index = 25-period sum of the EMA Ratio

First, the Single EMA provides the average for the high-low range.

Second, the Double EMA provides a second smoothing of this volatility measure.

Using a ratio of these two exponential moving averages normalizes the data series. This ratio shows when the Single EMA becomes large relative to the Double EMA.

The final step, a 25-period summation, acts like a moving average to further smooth the data series.

Overall, the Mass Index rises as the high-low range widens and falls as the high-low range narrows.

Donald Dorsey looked for “reversal bulges” to signal a trend reversal. According to Dorsey, a bulge occurs when the Mass Index moves above 27. This initial bulge does not complete the signal though. Dorsey waited for this bulge to reverse with a move back below 26.50. Once the reversal bulge is complete, traders should use other analysis techniques to determine the direction of the next move. Ideally, a downtrend followed by a reversal bulge would suggest a bullish trend reversal. Conversely, an uptrend followed by a reversal bulge would suggest a bearish trend reversal.

Let’s use Python to compute the Mass Index.

1.) Import modules.

import pandas as pd
import numpy as np
from pandas_datareader import data as web
import matplotlib.pyplot as plt
%matplotlib inline

2.a.) Define function for querying daily close.

def get_stock(stock,start,end):

2.b.) Define function for querying daily high.

def get_high(stock,start,end):

2.c.) Define function for querying daily low.

def get_low(stock,start,end):

3.) Define function for Mass Index.

def MassIndex(high, low):
Range = high - low
EX1 = pd.ewma(Range, span = 9, min_periods = 8)
EX2 = pd.ewma(EX1, span = 9, min_periods = 8)
Mass = EX1 / EX2
MassIndex = pd.Series(pd.rolling_sum(Mass, 25), name = 'Mass Index')
return MassIndex

How does the Mass Index function work?

3.a.) Function calculates the difference between the high and the low, and sets this value to variable Range.

#Range = high - low

3.b.) Function takes a 9 period Exponential Moving Average of the Range, and sets this value to variable EX1.

#EX1 = pd.ewma(Range, span = 9, min_periods = 8)

3.c.) Function takes a 9 period Exponential Moving Average of the EX1, to smooth volatility, and sets this value to variable EX2.

#EX2 = pd.ewma(EX1, span = 9, min_periods = 8)

3.d.) Function takes the ratio of EX1 to EX2, and sets this value to variable Mass.

#Mass = EX1 / EX2

3.e.) Function calculates the 25 period rolling sum of Mass, and sets this value to variable MassIndex.

#MassIndex = pd.Series(pd.rolling_sum(Mass, 25), name = 'Mass Index')

3.f.) Function returns MassIndex.

#return MassIndex

4.) Query daily close, high, and low for ‘FB’ during 2016.

df = pd.DataFrame(get_stock('FB', '1/1/2016', '12/31/2016'))
df['High'] = get_high('FB', '1/1/2016', '12/31/2016')
df['Low'] = get_low('FB', '1/1/2016', '12/31/2016')

5.) Run daily high and low through Mass Index function. Save series to new column in dataframe.

df['MassIndex'] = MassIndex(df['High'], df['Low'])
df.tail()

6.) Plot daily close and Mass Index.

df.plot(y=['Close'])
df.plot(y=['MassIndex'])

There you have it! We created our Mass Index indicator. Here’s the full code:

import pandas as pd
import numpy as np
from pandas_datareader import data as web
import matplotlib.pyplot as plt
%matplotlib inline

def get_stock(stock,start,end):

def get_high(stock,start,end):

def get_low(stock,start,end):

def MassIndex(high, low):
Range = high - low
EX1 = pd.ewma(Range, span = 9, min_periods = 8)
EX2 = pd.ewma(EX1, span = 9, min_periods = 8)
Mass = EX1 / EX2
MassIndex = pd.Series(pd.rolling_sum(Mass, 25), name = 'Mass Index')
return MassIndex

df = pd.DataFrame(get_stock('FB', '1/1/2016', '12/31/2016'))
df['High'] = get_high('FB', '1/1/2016', '12/31/2016')
df['Low'] = get_low('FB', '1/1/2016', '12/31/2016')
df['MassIndex'] = MassIndex(df['High'], df['Low'])
df.tail()

## Python Tutorial: CCI

Download the accompanying IPython Notebook for this Tutorial from Github.

Python streamlines tasks requiring multiple steps in a single block of code. For this reason, it is a great tool for querying and performing analysis on data.

Last Tutorial, we outlined steps for calculating Rate of Change (ROC).

In this Tutorial, we introduce a new technical indicator, the Commodity Channel Index (CCI).

Developed by Donald Lambert, the Commodity Channel Index (CCI) is a versatile indicator that can be used to identify a new trend or warn of extreme conditions. CCI measures the current price level relative to an average price level over a given period of time. CCI is relatively high when prices are far above their average. CCI is relatively low when prices are far below their average. In this manner, CCI can be used to identify overbought and oversold levels.

The Commodity Channel Index (CCI) is calculated as follows:

CCI = (Typical Price  -  n-period SMA of TP) / (Constant x Mean Deviation)

Typical Price (TP) = (High + Low + Close)/3

Constant = .015

Lambert set the Constant at .015 to ensure that approximately 70 to 80 percent of CCI values would fall between -100 and +100. This percentage also depends on the look-back period. A shorter CCI (10 periods) will be more volatile with a smaller percentage of values between +100 and -100. Conversely, a longer CCI (40 periods) will have a higher percentage of values between +100 and -100.

Lambert set the Constant at .015 to ensure that approximately 70 to 80 percent of CCI values would fall between -100 and +100. This percentage also depends on the look-back period. A shorter CCI (10 periods) will be more volatile with a smaller percentage of values between +100 and -100. Conversely, a longer CCI (40 periods) will have a higher percentage of values between +100 and -100.

The Commodity Channel Index (CCI) can be used as either a coincident or leading indicator. As a coincident indicator, surges above +100 reflect strong price action that can signal the start of an uptrend. Plunges below -100 reflect weak price action that can signal the start of a downtrend.

As a leading indicator, chartists can look for overbought or oversold conditions that may foreshadow a mean reversion. Similarly, bullish and bearish divergences can be used to detect early momentum shifts and anticipate trend reversals.

Let’s use Python to compute the Commodity Channel Index (CCI).

1.) Import modules.

import pandas as pd
import numpy as np
from pandas_datareader import data as web
import matplotlib.pyplot as plt
%matplotlib inline

2.a.) Define function for querying daily close.

def get_stock(stock,start,end):

2.b.) Define function for querying daily high.

def get_high(stock,start,end):

2.c.) Define function for querying daily low.

def get_low(stock,start,end):

3.) Define function for Commodity Channel Index (CCI).

def CCI(close, high, low, n, constant):
TP = (high + low + close) / 3
CCI = pd.Series((TP - pd.rolling_mean(TP, n)) / (constant * pd.rolling_std(TP, n)), name = 'CCI_' + str(n))
return CCI

How does the CCI function work?

3.a.) Function calculates Typical Price as the sum of the (High, Low, and Close) divided by three. The function sets this value to variable TP.

#TP = (high + low + close) / 3

3.b.) Function subtracts n period simple moving average of the Typical Price from the current Typical Price. The difference is divided by the n period standard deviation of the Typical Price multiplied by the constant. The function sets this value to variable CCI.

#CCI = pd.Series((TP - pd.rolling_mean(TP, n)) / (constant * pd.rolling_std(TP, n)), name = 'CCI_' + str(n))

3.c.) Function returns CCI

#return CCI

4.) Query daily close, high, and low for ‘FB’ during 2016.

df = pd.DataFrame(get_stock('FB', '1/1/2016', '12/31/2016'))
df['High'] = get_high('FB', '1/1/2016', '12/31/2016')
df['Low'] = get_low('FB', '1/1/2016', '12/31/2016')

5.) Run daily close, high, and low through CCI function. Save series to new column in dataframe.

df['CCI'] = CCI(df['Close'], df['High'], df['Low'], 20, 0.015)
df.tail()

6.) Plot daily close and CCI.

df.plot(y=['Close'])
df.plot(y=['CCI'])

There you have it! We created our CCI indicator. Here’s the full code:

import pandas as pd
import numpy as np
from pandas_datareader import data as web
import matplotlib.pyplot as plt
%matplotlib inline

def get_stock(stock,start,end):

def get_high(stock,start,end):

def get_low(stock,start,end):