## 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.

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: https://www.learnpythonwithrune.org/free-ebook-2/.

Cheers, Rune