Back to Community
Quick and dirty way to find tops and bottoms of time series

I couldn't find any code to do this, so I wrote a crude way of algorithmically finding "turning" points in time series data.

Summary of the code:

  1. Smooth the time series using curve fitting
  2. Find first derivative using forward difference method
  3. Find bottoms and tops by iterating and looking for crosses in the 1st derivative from - to + and + to -.

This could be extended to automatically detect support and resistance levels in a trading strategy.
Check out the attached notebook!

Loading notebook preview...
Notebook previews are currently unavailable.
4 responses

Another even simpler way of finding turning points is to use "fractals" (a highly misleading name). I have used these in the past to find support/resistance levels in FX market and they work quite well.

Thanks, Mikko. Much easier and more reliable.

Any suggestions on how you go about finding support/resistance? I was thinking of looking at the histogram of the turning points and extracting levels that have lots of points. Then, invalidating the support/resistance points if they've already been broken.

Loading notebook preview...
Notebook previews are currently unavailable.

Hey guys, this is very cool but the Notebook doesn't work, I am getting this error

IndexErrorTraceback (most recent call last)  
<ipython-input-36-a8992727d9f0> in <module>()  
----> 1 bottoms, tops = plotTurningPoints(asset, 1)

<ipython-input-35-a12f49a2439b> in plotTurningPoints(price_series, n)  
     14     ax.plot(price_series)  
     15     ticks = ax.get_xticks()  
---> 16     ax.set_xticklabels([price_series.index[i].date() for i in ticks[:-1]]) # Label x-axis with dates  
     17     ax.set_title('Share Price with Turning Points')  
     18     ax.plot([b[0] for b in bottoms], price_series[[b[0] for b in bottoms]], 'gD')

/usr/local/lib/python2.7/dist-packages/pandas/tseries/base.pyc in __getitem__(self, key)
    190         getitem = self._data.__getitem__  
    191         if lib.isscalar(key):  
--> 192             val = getitem(key)  
    193             return self._box_func(val)  
    194         else:

IndexError: index 735842 is out of bounds for axis 0 with size 160  

Found this - haven't tested it tho. It's from2015, might need reformatting: