import pandas as pd
import polars as pl
import pytimetk as tk
df = tk.load_dataset("stocks_daily", parse_dates=["date"])
# Pandas example (engine inferred)
ppo_pd = (
df.groupby("symbol")
.augment_ppo(
date_column="date",
close_column="close",
fast_period=12,
slow_period=26,
)
)
# Polars example using the tk accessor
ppo_pl = (
pl.from_pandas(df.query("symbol == 'AAPL'"))
.tk.augment_ppo(
date_column="date",
close_column="close",
fast_period=12,
slow_period=26,
)
)augment_ppo
augment_ppo(
data,
date_column,
close_column,
fast_period=12,
slow_period=26,
reduce_memory=False,
engine='auto',
)Calculate the Percentage Price Oscillator (PPO) for pandas or polars data.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| data | DataFrame or GroupBy(pandas or polars) | Financial data to augment with PPO values. Grouped inputs are processed per group before the indicator columns are appended. | required |
| date_column | str | Name of the column containing date information. | required |
| close_column | str | Name of the closing price column. | required |
| fast_period | int | Lookback window for the fast EMA. | 12 |
| slow_period | int | Lookback window for the slow EMA. | 26 |
| reduce_memory | bool | Attempt to reduce memory usage when operating on pandas data. | False |
| engine | (auto, pandas, polars) | Execution engine. Defaults to inferring from the input data type. | "auto" |
Returns
| Name | Type | Description |
|---|---|---|
| DataFrame | DataFrame with PPO values appended. Matches the backend of the input data. |
Notes
The PPO is computed as the percentage difference between a fast and a slow exponential moving average (EMA):
PPO = (EMA_fast - EMA_slow) / EMA_slow * 100
The implementation follows the common convention of using min_periods=0 on the EMA calculations to accumulate values from the beginning of the series. Division-by-zero scenarios yield NaN to align with pandasβ behaviour.