Algorithmically Detecting (and Trading) Technical Chart Patterns with PythonSam ChakerianBlockedUnblockFollowFollowingJan 24Defining Technical Chart Patterns ProgrammaticallyEver 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.
samchaaa/alpaca_tech_screenerContribute to samchaaa/alpaca_tech_screener development by creating an account on GitHub.
comThe 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.
An Empirical Algorithmic Evaluation of Technical AnalysisAt a recent meeting of the Quantopian staff journal club, I presented a paper by Andrew Lo, Harry Mamaysky, and Jiang…www.
) Read in dataI’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.
) Find minima and maximaFor 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.
) Find patternsTo find patterns, we simply iterate over all our min max points, and find windows where the points meet some pattern criteria.
For example, an inverse head and shoulders can roughly be defined as:C < A, B, D, EA, E < B, DTo filter for head and shoulders with even necklines:abs(B-D) < np.
05(The difference between the necklines must not be more than 5%.
)Here’s the code:And a plot for visual confirmation: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).
) Reorganize and iterate to find best paramsIn 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: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: triggers.
append(stock) return triggersAnd 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 = window_list = 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.
Technology and services are offered by AlpacaDB, Inc.
Brokerage services are provided by Alpaca Securities LLC (alpaca.
markets), member FINRA/SIPC.
Alpaca Securities LLC is a wholly-owned subsidiary of AlpacaDB, Inc.
You can find us @AlpacaHQ, if you use twitter.
Follow Automation Generation, a Medium’s publication created for developers/makers in trading and fintech.