Price Moving Average Ratio Percentile

Parameters: ma_length = 20 | ma_type = vwma | pmarp_lookback = 350 | signal_ma_length = 20 | signal_ma_type = sma | line_mode = pmarp

Overview

Price Moving Average Ratio Percentile computes a price-to-moving-average ratio, then evaluates how stretched that ratio is relative to a longer historical window. That gives you both the raw PMAR reading and the percentile-style PMARP reading, along with a plot line, signal line, upper and lower context bands, and a scaled ratio series.

VectorTA lets you choose the moving-average families independently for the base ratio and the signal line. The indicator can run on candle data with a chosen source or on direct price and volume slices, which is useful when you want VWMA behavior without building a candle wrapper around your data first.

Defaults: `ma_length = 20`, `ma_type = "vwma"`, `pmarp_lookback = 350`, `signal_ma_length = 20`, `signal_ma_type = "sma"`, and `line_mode = "pmarp"`.

Implementation Examples

Run PMARP from candles with a selected source or from direct price and volume slices.

use vector_ta::indicators::price_moving_average_ratio_percentile::{
    price_moving_average_ratio_percentile,
    PriceMovingAverageRatioPercentileInput,
    PriceMovingAverageRatioPercentileMaType,
    PriceMovingAverageRatioPercentileLineMode,
    PriceMovingAverageRatioPercentileParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};

let direct = price_moving_average_ratio_percentile(
    &PriceMovingAverageRatioPercentileInput::from_slices(
        &close,
        &volume,
        PriceMovingAverageRatioPercentileParams {
            ma_length: Some(20),
            ma_type: Some(PriceMovingAverageRatioPercentileMaType::Vwma),
            pmarp_lookback: Some(350),
            signal_ma_length: Some(20),
            signal_ma_type: Some(PriceMovingAverageRatioPercentileMaType::Sma),
            line_mode: Some(PriceMovingAverageRatioPercentileLineMode::Pmarp),
        },
    ),
)?;

let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let from_candles = price_moving_average_ratio_percentile(
    &PriceMovingAverageRatioPercentileInput::from_candles(
        &candles,
        "close",
        PriceMovingAverageRatioPercentileParams::default(),
    ),
)?;

println!("pmarp = {:?}", direct.pmarp.last());
println!("signal = {:?}", from_candles.signal.last());

API Reference

Input Methods
PriceMovingAverageRatioPercentileInput::from_candles(&Candles, "close", params)
    -> PriceMovingAverageRatioPercentileInput

PriceMovingAverageRatioPercentileInput::from_slices(&[f64], &[f64], params)
    -> PriceMovingAverageRatioPercentileInput

PriceMovingAverageRatioPercentileInput::with_default_candles(&Candles)
    -> PriceMovingAverageRatioPercentileInput
Parameters Structure
pub struct PriceMovingAverageRatioPercentileParams {
    pub ma_length: Option<usize>,             // default 20
    pub ma_type: Option<...>,                 // sma, ema, hma, rma, vwma
    pub pmarp_lookback: Option<usize>,        // default 350
    pub signal_ma_length: Option<usize>,      // default 20
    pub signal_ma_type: Option<...>,          // sma, ema, hma, rma, vwma
    pub line_mode: Option<...>,               // pmar or pmarp
}
Output Structure
pub struct PriceMovingAverageRatioPercentileOutput {
    pub pmar: Vec<f64>,
    pub pmarp: Vec<f64>,
    pub plotline: Vec<f64>,
    pub signal: Vec<f64>,
    pub pmar_high: Vec<f64>,
    pub pmar_low: Vec<f64>,
    pub scaled_pmar: Vec<f64>,
}
Validation, Modes & Warmup
  • Price and volume inputs must be non-empty, finite enough to compute the chosen averages, and equal in length.
  • ma_length, pmarp_lookback, and signal_ma_length must all be greater than 0.
  • The supported moving-average types are sma, ema, hma, rma, and vwma.
  • The supported line modes are pmar and pmarp.
  • The stream warmup reported by get_warmup_period() is the maximum of ma_length and signal_ma_length.
  • Batch mode validates each numeric sweep and rejects non-batch kernels.
Builder, Streaming & Batch APIs
PriceMovingAverageRatioPercentileBuilder::new()
    .source("close")
    .ma_length(usize)
    .ma_type(...)
    .pmarp_lookback(usize)
    .signal_ma_length(usize)
    .signal_ma_type(...)
    .line_mode(...)
    .kernel(Kernel)
    .apply(&Candles)
    .apply_slices(&[f64], &[f64])
    .into_stream()

PriceMovingAverageRatioPercentileStream::try_new(params)
stream.update(price, volume) -> (f64, f64, f64, f64, f64, f64, f64)
stream.get_warmup_period() -> usize

PriceMovingAverageRatioPercentileBatchBuilder::new()
    .ma_length_range(start, end, step)
    .pmarp_lookback_range(start, end, step)
    .signal_ma_length_range(start, end, step)
    .ma_type(...)
    .signal_ma_type(...)
    .line_mode(...)
    .kernel(Kernel)
    .apply_slices(&[f64], &[f64])

Python Bindings

Python exposes a scalar function returning a dictionary of seven NumPy arrays, a stream class returning the latest seven-field point as a dictionary, and a batch helper returning reshaped matrices.

from vector_ta import (
    price_moving_average_ratio_percentile,
    price_moving_average_ratio_percentile_batch,
    PriceMovingAverageRatioPercentileStream,
)

out = price_moving_average_ratio_percentile(
    close,
    volume,
    ma_length=20,
    ma_type="vwma",
    pmarp_lookback=350,
    signal_ma_length=20,
    signal_ma_type="sma",
    line_mode="pmarp",
)

stream = PriceMovingAverageRatioPercentileStream()
point = stream.update(close[-1], volume[-1])

batch = price_moving_average_ratio_percentile_batch(
    close,
    volume,
    ma_length_range=(10, 30, 10),
    pmarp_lookback_range=(200, 400, 100),
    signal_ma_length_range=(10, 20, 10),
    ma_type="vwma",
    signal_ma_type="sma",
    line_mode="pmarp",
)

print(out["pmarp"][-1])
print(batch["rows"], batch["cols"])

JavaScript/WASM Bindings

The WASM layer exposes scalar and batch object-returning helpers plus low-level allocation and into-buffer entry points for host-managed memory.

import init, {
  price_moving_average_ratio_percentile_js,
  price_moving_average_ratio_percentile_batch_js,
  price_moving_average_ratio_percentile_alloc,
  price_moving_average_ratio_percentile_free,
  price_moving_average_ratio_percentile_into,
  price_moving_average_ratio_percentile_batch_into,
} from "vector-ta-wasm";

await init();

const single = price_moving_average_ratio_percentile_js(
  close,
  volume,
  20,
  "vwma",
  350,
  20,
  "sma",
  "pmarp",
);

const batch = price_moving_average_ratio_percentile_batch_js(close, volume, {
  ma_length_range: [10, 30, 10],
  pmarp_lookback_range: [200, 400, 100],
  signal_ma_length_range: [10, 20, 10],
  ma_type: "vwma",
  signal_ma_type: "sma",
  line_mode: "pmarp",
});

CUDA Bindings (Rust)

Additional details for the CUDA bindings can be found inside the VectorTA repository.

Performance Analysis

Comparison:
View:
Placeholder data (no recorded benchmarks for this indicator)

Across sizes, Rust CPU runs about 1.14× faster than Tulip C in this benchmark.

Loading chart...

AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU)

Related Indicators