Files
wickra/docs/wiki/indicators/volume/Indicator-VolumePriceTrend.md
T
kingchenc d2f99efd78 F13c: restructure the indicator catalogue into eight families
The original taxonomy was four classical families plus a statistics group,
with the F1-F12 expansion slotted in as sub-categories. This regroups the
whole 71-indicator catalogue into eight top-level families, each with at
least five members:

  Moving Averages (12), Momentum Oscillators (13), Trend & Directional (9),
  Price Oscillators (5), Volatility & Bands (12), Trailing Stops (5),
  Volume (9), Price Statistics (7).

- Wiki: docs/wiki/indicators/ reorganised into eight family folders; all 71
  indicator pages moved with `git mv`. Every internal cross-link is
  normalised to `../<family>/Indicator-X.md`, each page's `Family` field is
  set to its new family, and two pre-existing `../Indicator-Chaining.md`
  links (should have been `../../`) are corrected. A link check confirms
  every relative wiki link resolves.
- Indicators-Overview.md fully rewritten around the eight families;
  Home.md indicator reference and the README family table follow suit.
- Warmup-Periods.md gains the eight F13 indicators; CHANGELOG records the
  46-indicator expansion (25 -> 71) and the eight-family taxonomy.
- Tests: Node indicators.test.js and Python test_new_indicators.py cover
  all eight new indicators (Node 91/91, Python 117/117 green).

cargo fmt + clippy (core/wickra/data/wasm/node) clean; 508 core tests,
25 data tests and 74 doctests green.
2026-05-22 21:21:56 +02:00

161 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# VolumePriceTrend
> Volume-Price Trend (VPT) — a cumulative volume line where each bar's
> contribution is scaled by its percentage price change.
## Quick reference
| Field | Value |
|-------|-------|
| Family | Volume |
| Input type | `Candle` (uses `close`, `volume`) |
| Output type | `f64` |
| Output range | unbounded (drifts with cumulative volume) |
| Default parameters | none (no parameters) |
| Warmup period | `1` |
| Interpretation | Running volume flow; slope and divergence matter. |
## Formula
```
VPT_t = VPT_{t1} + volume_t · (close_t close_{t1}) / close_{t1}
```
VPT is a close relative of [`Obv`](../volume/Indicator-Obv.md). Where OBV adds the
*entire* bar volume on any up-close, VPT adds volume scaled by the **size**
of the move: a 2 % gain on a given volume moves the line twice as far as a
1 % gain on the same volume. That makes VPT more sensitive to the
conviction behind a move. The first bar establishes the baseline at `0`.
## Parameters
`VolumePriceTrend` takes **no parameters**`VolumePriceTrend::new()` in
Rust, `wickra.VolumePriceTrend()` in Python, `new ta.VolumePriceTrend()`
in Node.
## Inputs / Outputs
From `crates/wickra-core/src/indicators/vpt.rs`:
```rust
impl Indicator for VolumePriceTrend {
type Input = Candle;
type Output = f64;
// update(&mut self, input: Candle) -> Option<f64>
}
```
`VolumePriceTrend` is a **candle-input** indicator: it reads `close` and
`volume`. In Python the streaming `update` accepts a 6-tuple or a dict;
the batch helper takes `close` and `volume` numpy arrays. Node and WASM
expose `update(close, volume)` and `batch(close, volume)`.
## Warmup
`warmup_period() == 1`. VPT is cumulative — it emits the baseline `0` from
the first candle, then accumulates from the second onward.
## Edge cases
- **Constant close.** With no price change every bar contributes `0`, so
the line stays flat regardless of volume
(`constant_close_keeps_line_flat` pins this).
- **First bar.** The first candle has no previous close; VPT emits the
baseline `0.0` (`emits_from_first_candle_at_zero` pins this).
- **Zero previous close.** A percentage change against a `0.0` prior
close is undefined and is treated as `0`.
- **Candle validation.** `Candle::new` rejects invalid bars upstream.
- **Reset.** `vpt.reset()` returns the running total to `0`.
## Examples
### Rust
```rust
use wickra::{BatchExt, Candle, Indicator, VolumePriceTrend};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut vpt = VolumePriceTrend::new();
// closes 10 -> 11 -> 9, volumes 100, 200, 300.
let out = vpt.batch(&[
Candle::new(10.0, 10.0, 10.0, 10.0, 100.0, 0)?,
Candle::new(11.0, 11.0, 11.0, 11.0, 200.0, 1)?,
Candle::new(9.0, 9.0, 9.0, 9.0, 300.0, 2)?,
]);
println!("{:?}", out);
Ok(())
}
```
Output:
```
[Some(0.0), Some(20.0), Some(-34.54545454545455)]
```
Bar 1 is the baseline `0`. Bar 2 adds `200 · (1110)/10 = 20`. Bar 3 adds
`300 · (911)/11 = 600/11`, leaving `20 600/11 ≈ 34.545`. This matches
the `reference_values` test in `crates/wickra-core/src/indicators/vpt.rs`.
### Python
```python
import numpy as np
import wickra as ta
vpt = ta.VolumePriceTrend()
close = np.array([10.0, 11.0, 9.0])
volume = np.array([100.0, 200.0, 300.0])
print(vpt.batch(close, volume))
```
Output:
```
[ 0. 20. -34.54545455]
```
### Node
```javascript
const ta = require('wickra');
const vpt = new ta.VolumePriceTrend();
console.log(vpt.batch([10, 11, 9], [100, 200, 300]));
```
Output:
```
[ 0, 20, -34.54545454545455 ]
```
## Interpretation
`VolumePriceTrend` is read like OBV — by **slope** and by **divergence**,
never by absolute level. A VPT rising in step with price confirms the
trend is volume-supported; VPT flattening or falling while price climbs
is a bearish divergence warning that the move lacks participation. Versus
OBV, VPT gives proportionally more weight to large moves and less to a
string of tiny up-closes, so it tracks the *magnitude* of conviction, not
just its direction.
## Common pitfalls
- **Reading the absolute value.** Only slope and divergences carry
meaning; the level depends on the stream's start point.
- **Expecting OBV-identical behaviour.** VPT scales by percentage change,
so the two lines diverge — especially across large single-bar moves.
## References
The Volume-Price Trend (also "Price-Volume Trend") is a standard
cumulative volume study; the `volume · ROC` accumulation here matches the
common definition.
## See also
- [Indicator-Obv.md](../volume/Indicator-Obv.md) — cumulative signed volume, the
closest relative.
- [Indicator-Adl.md](../volume/Indicator-Adl.md) — cumulative range-weighted volume.
- [Indicators-Overview.md](../../Indicators-Overview.md) — the full taxonomy.