Percentage Price Oscillator (PPO)
Normalize the MACD Spread
Install and import
npm install fintech-algorithmsimport { ppo } from "fintech-algorithms/technical-indicators/trend-systems/percentage-price-oscillator";Signature
ppo(values, fastSpan, slowSpan, signalSpan)MACD expressed as a percentage of the slow EMA rather than in price units, which makes readings comparable across instruments and across time in a way MACD is not.
Parameters
| Name | Type | Notes |
|---|---|---|
values | (number | null)[] | Observation series in chronological order, oldest first. nulls: propagate |
fastSpan | number | Span of the fast EMA. min: 1 · integer: true |
slowSpan | number | Span of the slow EMA; must exceed the fast span. min: 1 · integer: true |
signalSpan | number | Span of the EMA taken over the PPO line itself. min: 1 · integer: true |
Returns
Record<string, (number | null)[]> · length same-as-input
Parallel series: fast_ema, slow_ema, ppo, signal and histogram.
Warm-up
The first slowSpan − 1 for the PPO line, and slowSpan + signalSpan − 2 for the signal and histogram positions are null. As with MACD, the signal line is defined later than the line it smooths.
Errors
- When any span is < 1, is not an integer, or fastSpan ≥ slowSpan — throws RangeError
Complexity: time O(n),
space O(n).
Worked example
executed Captured by running this function on the input its own test provides. Real output of real code — but not asserted against a published figure.
Input
[96.42, 96.948156, 97.568602, 98.255035, 98.973258, 99.68459]Showing 6 of 180 elements.
12269Call
ppo(values, fastSpan, slowSpan, signalSpan)Returns
object with 5 fields: fast_ema, slow_ema, ppo, signal, histogram
{
"fast_ema": [null, null, null, null, null, null],
"slow_ema": [null, null, null, null, null, null],
"ppo": [null, null, null, null, null, null],
"signal": [null, null, null, null, null, null],
"histogram": [null, null, null, null, null, null]
}Diagrams
Calculation flow
Percentage Price Oscillator calculation flow
flowchart LR
A["Validated finalized bar"] --> B["Causal window or recursive state"]
B --> C["Explicit seed and boundary rule"]
C --> D["Aligned Percentage Price Oscillator output"]
D --> E["Diagnostics and audit evidence"]
How it works
This page states the contract — how to call it correctly. The article explains the concept: why it works, and where it breaks.
References
- Gerald Appel's MACD/PPO work — Gerald Appel's MACD/PPO work
- TA-Lib PPO — TA-Lib project or TradingView, as identified by the linked page
- Pinned TA-Lib ta_PPO.c implementation — TA-Lib project or TradingView
- Canonical synthetic fixture and independent arithmetic — The Fintech Builder
- R5 — TA-Lib MACD function documentation — TA-Lib project or TradingView