augment_stochastic_oscillator

augment_stochastic_oscillator(
    data,
    date_column,
    high_column,
    low_column,
    close_column,
    k_periods=14,
    d_periods=3,
    reduce_memory=False,
    engine='pandas',
)

The augment_stochastic_oscillator function calculates the Stochastic Oscillator (%K and %D) for a financial instrument using either pandas or polars engine, and returns the augmented DataFrame.

Parameters

Name Type Description Default
data Union[pd.DataFrame, pd.core.groupby.generic.DataFrameGroupBy] The input data can be a pandas DataFrame or a pandas DataFrameGroupBy object containing the time series data for Stochastic Oscillator calculations. required
date_column str The name of the column containing dates or timestamps. required
high_column str The column containing high prices for the financial instrument. required
low_column str The column containing low prices for the financial instrument. required
close_column str The column containing closing prices for the financial instrument. required
k_periods Union[int, Tuple[int, int], List[int]] The number of periods for calculating %K (fast stochastic). Can be an integer, a tuple of two integers (start and end periods), or a list of integers. Default is 14. 14
d_periods int The number of periods for calculating %D (slow stochastic), typically a moving average of %K. Default is 3. 3
reduce_memory bool If True, reduces memory usage of the DataFrame before calculation. Default is False. False
engine str The computation engine to use: ‘pandas’ or ‘polars’. Default is ‘pandas’. 'pandas'

Returns

Name Type Description
pd.DataFrame A pandas DataFrame augmented with columns: - {close_column}stoch_k{k_period}: Stochastic Oscillator %K for each k_period - {close_column}stoch_d{k_period}_{d_period}: Stochastic Oscillator %D for each k_period

Notes

The Stochastic Oscillator is a momentum indicator that compares a security’s closing price to its price range over a specific period, developed by George Lane. It consists of two lines:

  • %K: Measures the current close relative to the high-low range over k_periods.
  • %D: A moving average of %K over d_periods, smoothing the %K line.

Key interpretations:

  • Values above 80 indicate overbought conditions, suggesting a potential price reversal downward.
  • Values below 20 indicate oversold conditions, suggesting a potential price reversal upward.
  • Crossovers of %K and %D can signal buy/sell opportunities.
  • Divergences between price and the oscillator can indicate trend reversals.

Formula:

  • %K = 100 * (Close - Lowest Low in k_periods) / (Highest High in k_periods - Lowest Low in k_periods)
  • %D = Moving average of %K over d_periods

References:

  • https://www.investopedia.com/terms/s/stochasticoscillator.asp

Examples

import pandas as pd
import pytimetk as tk

df = tk.load_dataset('stocks_daily', parse_dates=['date'])

# Example 1 - Single stock stochastic oscillator
stoch_df = (
    df.query("symbol == 'AAPL'")
    .augment_stochastic_oscillator(
        date_column='date',
        high_column='high',
        low_column='low',
        close_column='close',
        k_periods=[14, 28],
        d_periods=3
    )
)
stoch_df.head()
symbol date open high low close volume adjusted close_stoch_k_14 close_stoch_d_14_3 close_stoch_k_28 close_stoch_d_28_3
5398 AAPL 2013-01-02 19.779285 19.821428 19.343929 19.608213 560518000 16.791180 55.347578 55.347578 55.347578 55.347578
5399 AAPL 2013-01-03 19.567142 19.631071 19.321428 19.360714 352965200 16.579241 7.857132 31.602355 7.857132 31.602355
5400 AAPL 2013-01-04 19.177500 19.236786 18.779642 18.821428 594333600 16.117437 4.011014 22.405241 4.011014 22.405241
5401 AAPL 2013-01-07 18.642857 18.903570 18.400000 18.710714 484156400 16.022623 21.859325 11.242491 21.859325 11.242491
5402 AAPL 2013-01-08 18.900356 18.996071 18.616072 18.761070 458707200 16.065746 25.401952 17.090764 25.401952 17.090764
# Example 2 - Multiple stocks with groupby
stoch_df = (
    df.groupby('symbol')
    .augment_stochastic_oscillator(
        date_column='date',
        high_column='high',
        low_column='low',
        close_column='close',
        k_periods=14,
        d_periods=3
    )
)
stoch_df.groupby('symbol').tail(1)
symbol date open high low close volume adjusted close_stoch_k_14 close_stoch_d_14_3
2698 META 2023-09-21 295.700012 300.260010 293.269989 295.730011 21300500 295.730011 16.997631 38.434278
5397 AMZN 2023-09-21 131.940002 132.240005 129.309998 129.330002 70234800 129.330002 0.120872 17.363105
8096 AAPL 2023-09-21 174.550003 176.300003 173.860001 173.929993 63047900 173.929993 2.372259 15.957065
10795 NFLX 2023-09-21 386.500000 395.899994 383.420013 384.149994 5547900 384.149994 1.042383 3.574762
13494 NVDA 2023-09-21 415.829987 421.000000 409.799988 410.170013 44893000 410.170013 0.419530 7.552880
16193 GOOG 2023-09-21 132.389999 133.190002 131.089996 131.360001 22042700 131.360001 3.054348 31.727204
# Example 3 - Polars engine for single stock
stoch_df = (
    df.query("symbol == 'AAPL'")
    .augment_stochastic_oscillator(
        date_column='date',
        high_column='high',
        low_column='low',
        close_column='close',
        k_periods=[14, 28],
        d_periods=3,
        engine='polars'
    )
)
stoch_df.head()
symbol date open high low close volume adjusted close_stoch_k_14 close_stoch_k_28 close_stoch_d_14_3 close_stoch_d_28_3
5398 AAPL 2013-01-02 19.779285 19.821428 19.343929 19.608213 560518000 16.791180 NaN NaN NaN NaN
5399 AAPL 2013-01-03 19.567142 19.631071 19.321428 19.360714 352965200 16.579241 NaN NaN NaN NaN
5400 AAPL 2013-01-04 19.177500 19.236786 18.779642 18.821428 594333600 16.117437 NaN NaN NaN NaN
5401 AAPL 2013-01-07 18.642857 18.903570 18.400000 18.710714 484156400 16.022623 NaN NaN NaN NaN
5402 AAPL 2013-01-08 18.900356 18.996071 18.616072 18.761070 458707200 16.065746 NaN NaN NaN NaN

Example 4 - Polars engine with groupby

stoch_df = ( df.groupby(‘symbol’) .augment_stochastic_oscillator( date_column=‘date’, high_column=‘high’, low_column=‘low’, close_column=‘close’, k_periods=14, d_periods=3, engine=‘polars’ ) ) stoch_df.groupby(‘symbol’).tail(1)