What is the Stochastic Oscillator Indicator for a stock?
A stochastic oscillator is a momentum indicator comparing a particular closing price of a security to a range of its prices over a certain period of time.
https://www.investopedia.com/terms/s/stochasticoscillator.asp
The stochastic oscillator is an indicator for the speed and momentum of the price. The indicator changes direction before the price does and is therefore a leading indicator.
Step 1: Get stock data to do the calculations on
In this tutorial we will use the Apple stock as example, which has ticker AAPL. You can change to any other stock of your interest by changing the ticker below. To find the ticker of your favorite company/stock you can use Yahoo! Finance ticker lookup.
To get some time series of stock data we will use the Pandas-datareader library to collect it from Yahoo! Finance.
import pandas_datareader as pdr
import datetime as dt
ticker = pdr.get_data_yahoo("AAPL", dt.datetime(2020, 1, 1), dt.datetime.now())
print(ticker)
Where we only focus on data from 2020 until today.
High Low ... Volume Adj Close
Date ...
2020-01-02 300.600006 295.190002 ... 33870100.0 298.292145
2020-01-03 300.579987 296.500000 ... 36580700.0 295.392120
2020-01-06 299.959991 292.750000 ... 29596800.0 297.745880
2020-01-07 300.899994 297.480011 ... 27218000.0 296.345581
2020-01-08 304.440002 297.160004 ... 33019800.0 301.112640
... ... ... ... ... ...
2020-08-05 441.570007 435.589996 ... 30498000.0 439.457642
2020-08-06 457.649994 439.190002 ... 50607200.0 454.790009
2020-08-07 454.700012 441.170013 ... 49453300.0 444.450012
2020-08-10 455.100006 440.000000 ... 53100900.0 450.910004
2020-08-11 449.929993 436.429993 ... 46871100.0 437.500000
[154 rows x 6 columns]
The output does not show all the columns, which are: High, Low, Open, Close, Volume, and Adj Close.
Step 2: Understand the calculation of Stochastic Oscillator Indicator
The Stochastic Oscillator Indicator consists of two values calculated as follows.
%K = (Last Close – Lowest low) / (Highest high – Lowest low)
%D = Simple Moving Average of %K
What %K looks at is the Lowest low and Highest high in a window of some days. The default is 14 days, but can be changed. I’ve seen others use 20 days, as the stock market is open 20 days per month. The original definition set it to 14 days. The simple moving average was set to 3 days.
The numbers are converted to percentage, hence the indicators are in the range of 0% to 100%.
The idea is that if the indicators are above 80%, it is considered to be in the overbought range. While if it is below 20%, then it is considered to be oversold.
Step 3: Calculate the Stochastic Oscillator Indicator
With the above description it is straight forward to do.
import pandas_datareader as pdr
import datetime as dt
ticker = pdr.get_data_yahoo("AAPL", dt.datetime(2020, 1, 1), dt.datetime.now())
ticker['14-high'] = ticker['High'].rolling(14).max()
ticker['14-low'] = ticker['Low'].rolling(14).min()
ticker['%K'] = (ticker['Close'] - ticker['14-low'])*100/(ticker['14-high'] - ticker['14-low'])
ticker['%D'] = ticker['%K'].rolling(3).mean()
print(ticker)
Resulting in the following output.
High Low ... %K %D
Date ...
2020-01-02 300.600006 295.190002 ... NaN NaN
2020-01-03 300.579987 296.500000 ... NaN NaN
2020-01-06 299.959991 292.750000 ... NaN NaN
2020-01-07 300.899994 297.480011 ... NaN NaN
2020-01-08 304.440002 297.160004 ... NaN NaN
... ... ... ... ... ...
2020-08-05 441.570007 435.589996 ... 92.997680 90.741373
2020-08-06 457.649994 439.190002 ... 97.981589 94.069899
2020-08-07 454.700012 441.170013 ... 86.939764 92.639677
2020-08-10 455.100006 440.000000 ... 93.331365 92.750906
2020-08-11 449.929993 436.429993 ... 80.063330 86.778153
[154 rows x 10 columns]
Please notice that we have not included all columns here. Also, see the the %K and %D are not available for the first days, as it needs 14 days of data to be calculated.
Step 4: Plotting the data on a graph
We will combine two graphs in one. This can be easily obtained using Pandas DataFrames plot function. The argument secondary_y can be used to plot up against two y-axis.
The two lines %K and %D are both on the same scale 0-100, while the stock prices are on a different scale depending on the specific stock.
To keep things simple, we also want to plot a line indicator of the 80% high line and 20% low line. This can be done by using the axhline from the Axis object that plot returns.
The full code results in the following.
import pandas_datareader as pdr
import datetime as dt
import matplotlib.pyplot as plt
ticker = pdr.get_data_yahoo("AAPL", dt.datetime(2020, 1, 1), dt.datetime.now())
ticker['14-high'] = ticker['High'].rolling(14).max()
ticker['14-low'] = ticker['Low'].rolling(14).min()
ticker['%K'] = (ticker['Close'] - ticker['14-low'])*100/(ticker['14-high'] - ticker['14-low'])
ticker['%D'] = ticker['%K'].rolling(3).mean()
ax = ticker[['%K', '%D']].plot()
ticker['Adj Close'].plot(ax=ax, secondary_y=True)
ax.axhline(20, linestyle='--', color="r")
ax.axhline(80, linestyle="--", color="r")
plt.show()
Resulting in the following graph.

Step 5: Interpreting the signals.
First a word of warning. Most advice from only using one indicator alone as a buy-sell signal. This also holds for the Stochastic Oscillator indicator. As the name suggest, it is only an indicator, not a predictor.
The indicator signals buy or sell when the two lines crosses each other. If the %K is above the %D then it signals buy and when it crosses below, it signals sell.
Looking at the graph it makes a lot of signals (every time the two lines crosses each other). This is a good reason to have other indicators to rely on.
An often misconception is that it should only be used when it is in the regions of 20% low or 80% high. But it is often that low and high can be for quite some time. Hence, selling if we reach the 80% high in this case, we would miss a great opportunity of a big gain.
12% Investment Solution
Would you like to get 12% in return of your investments?
D. A. Carter promises and shows how his simple investment strategy will deliver that in the book The 12% Solution. The book shows how to test this statement by using backtesting.
Did Carter find a strategy that will consistently beat the market?
Actually, it is not that hard to use Python to validate his calculations. But we can do better than that. If you want to work smarter than traditional investors then continue to read here.
Python for Finance: Unlock Financial Freedom and Build Your Dream Life
Discover the key to financial freedom and secure your dream life with Python for Finance!
Say goodbye to financial anxiety and embrace a future filled with confidence and success. If you’re tired of struggling to pay bills and longing for a life of leisure, it’s time to take action.
Imagine breaking free from that dead-end job and opening doors to endless opportunities. With Python for Finance, you can acquire the invaluable skill of financial analysis that will revolutionize your life.
Make informed investment decisions, unlock the secrets of business financial performance, and maximize your money like never before. Gain the knowledge sought after by companies worldwide and become an indispensable asset in today’s competitive market.
Don’t let your dreams slip away. Master Python for Finance and pave your way to a profitable and fulfilling career. Start building the future you deserve today!
Python for Finance a 21 hours course that teaches investing with Python.
Learn pandas, NumPy, Matplotlib for Financial Analysis & learn how to Automate Value Investing.
“Excellent course for anyone trying to learn coding and investing.” – Lorenzo B.

Thanks Rune, fantastic job! I’d like to develop a Strategic (backtesting) where we buy in 30 and sell when go down 70, but I’m not getting😔. Could you give me the key to get it?
Hi Mark,
A great resource for backtesting is to check out the eBook on the subject. It is free and is available here: http://www.learnpythonwithrune.org/free-ebook-2/.
Cheers, Rune
Dear Rune. I use this medium because I have not seen any other way of being able to communicate to you what may be an anomaly in the operation of this website.
I have been accessing this link “backtesting-a-trading-strategy-with-pandas-and-python” normally. Recently this access is malfunctioning. ¿The access has been closed or it is some anomaly of the Web?.
Thank you for everything you share with us. Best regards
Hi Enrique,
Thanks for reaching out to me. I have tried to test it and it seems to work from my connection. So I am not sure what is wrong.
Please let me know, if you have any suggestions.
Just to make sure – you refer to this page? https://www.learnpythonwithrune.org/backtesting-a-trading-strategy-with-pandas-and-python/
BR Rune