Algorithmically Detecting (and Trading) Technical Chart Patterns with Python

Sam Chakerian
Jan 24, 2019 · 4 min read
Image for post
Image for post

Defining Technical Chart Patterns Programmatically

Ever wondered how to programmatically define technical patterns in price data?

At the fundamental level, technical patterns come from local minimum and maximum points in price. From there, the technical patterns may be defined by relative comparisons in these min/max points.

Let’s see if we could have played this by algorithmically identifying any inverse head & shoulders patterns!

Follow along with the notebook here.

The following code can easily be retooled to work as a screener, backtester, or trading algo, with any timeframe or patterns you define.

Disclaimer: this code is intended as a starting point for finding technical patterns, it is for educational purposes only. The framework for this code came from here.

Step 1.) Read in data

I’m reading in data using the Alpaca API (which I’ll also use to place trades later).

I wrote this function to grab data beyond the one request limit of 2,000 minute bars. Later we’ll resample to our timeframe of choice.

We’ll resample data separately, in case we want to try out different timeframes later.

Step 2.) Find minima and maxima

For this step we’ll use a function from scipy’s signal processing library to find peaks in the data.

This code looks complicated, but the point is to return the integer index values with price, for each min/max point.

Let’s plot it with the resampled price data to visually confirm we’re on the right track.

Image for post
Image for post

Step 3.) Find patterns

To find patterns, we simply iterate over all our min max points, and find windows where the points meet some pattern criteria.

Image for post
Image for post

For example, an inverse head and shoulders can roughly be defined as:

C < A, B, D, E

A, E < B, D

To filter for head and shoulders with even necklines:

abs(B-D) < np.mean([B, D])*0.05

(The difference between the necklines must not be more than 5%.)

Here’s the code:

And a plot for visual confirmation:

Image for post
Image for post

As you can see, we are getting more patterns than we need. Our params (smoothing and window range) are too sensitive for this timeframe (60 minutes).

Step 4.) Reorganize and iterate to find best params

In order to find the best params, I reorganized my code into functions and iterated through multiple stocks, smoothing, and window parameters.

Run the above like so:

Image for post
Image for post

Now we can see how our timeframes, patterns, and params are playing out!

Step 5.) Go live!

To use this live, I made the following changes to screener():

def screener(stock_data, ema_list, window_list):

triggers = []

all_results = pd.DataFrame()

for stock in stock_data:
prices = stock_data[stock]

for ema_ in ema_list:
for window_ in window_list:
max_min = get_max_min(prices, smoothing=ema_, window_range=window_)
pat = find_patterns(max_min)

if len(pat) > 0:

return triggers

And ran like so:

stocklist = ['AA', 'AAL', 'AAPL', 'AMZN'] # Long list of stocks herestock_data = get_stock_data(stocklist, 2)resampled_stock_data = resample(stock_data, '360T')ema_list = [5]
window_list = [5]
results = screener(resampled_stock_data, ema_list, window_list)for x in results:
api.submit_order(x, 100, 'buy', 'market', 'day')

Finding the right params for your pattern to play out may take experimentation. See the results() function in the notebook to confirm whether your patterns have a positive edge or not.

Image for post
Image for post

Technology and services are offered by AlpacaDB, Inc. Brokerage services are provided by Alpaca Securities LLC (, member FINRA/SIPC. Alpaca Securities LLC is a wholly-owned subsidiary of AlpacaDB, Inc.

You can find us @AlpacaHQ, if you use twitter.

Automation Generation

News and thought leadership on the changing landscape of…

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store