Compound Ratio Moving Average (CoRa Wave)

Parameters: period = 20 | r_multi = 2 | smooth = true

Overview

The Compound Ratio Moving Average (CoRa Wave) creates an adaptive moving average using geometrically increasing weights that emphasize recent price action. Unlike traditional weighted averages that use linear progression, CoRa Wave applies a compound ratio multiplier to generate exponentially growing weights for more recent data points. The indicator calculates weights using powers of the ratio multiplier, with the newest price receiving the highest weight and older prices receiving progressively smaller weights based on their distance from the current bar. This geometric weighting scheme allows the average to respond quickly to price changes while maintaining smoothness.

An optional smoothing feature applies a weighted moving average with a length equal to the square root of the main period, reducing noise without sacrificing too much responsiveness. The ratio multiplier parameter controls how aggressively weights increase toward recent prices, with higher values creating more reactive averages. Typical multiplier values range from 1.5 to 3.0, with 2.0 providing a balanced response between smoothness and sensitivity. The compound ratio approach makes CoRa Wave particularly effective at tracking trends while filtering out minor retracements.

Traders use CoRa Wave as a trend following tool that adapts better to momentum shifts than simple or exponential moving averages. The indicator excels in trending markets where its geometric weighting helps it stay closer to price during accelerations while avoiding whipsaws during consolidations. Price crossovers with CoRa Wave generate trading signals similar to other moving averages, but with potentially fewer false signals due to the adaptive weighting. Many traders combine CoRa Wave with traditional moving averages to identify convergence and divergence patterns that signal trend changes. The indicator also works well as a dynamic support and resistance level in trending markets.

Implementation Examples

Compute CoRa Wave in a few lines:

use vectorta::indicators::cora_wave::{cora_wave, CoraWaveInput, CoraWaveParams};
use vectorta::utilities::data_loader::{Candles, read_candles_from_csv};

// From a price slice
let prices = vec![100.0, 102.0, 101.5, 103.0, 105.0, 104.5];
let params = CoraWaveParams { period: Some(20), r_multi: Some(2.0), smooth: Some(true) };
let input = CoraWaveInput::from_slice(&prices, params);
let result = cora_wave(&input)?;

// From candles with default params (period=20, r_multi=2.0, smooth=true; source="close")
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let input = CoraWaveInput::with_default_candles(&candles);
let result = cora_wave(&input)?;

// Access values
for v in result.values { println!("CoRa: {}", v); }

API Reference

Input Methods
// From a price slice
CoraWaveInput::from_slice(&[f64], CoraWaveParams) -> CoraWaveInput

// From candles with custom source
CoraWaveInput::from_candles(&Candles, &str, CoraWaveParams) -> CoraWaveInput

// From candles with default params (close, period=20, r_multi=2.0, smooth=true)
CoraWaveInput::with_default_candles(&Candles) -> CoraWaveInput
Parameters Structure
pub struct CoraWaveParams {
    pub period: Option<usize>, // Default: 20
    pub r_multi: Option<f64>,  // Default: 2.0
    pub smooth: Option<bool>,  // Default: true
}
Output Structure
pub struct CoraWaveOutput {
    pub values: Vec<f64>, // CoRa values (WMA-smoothed if enabled)
}
Validation, Warmup & NaNs
  • Errors: EmptyInputData, AllValuesNaN, InvalidPeriod { period, data_len }, NotEnoughValidData { needed, valid }, InvalidRMulti { value }.
  • period must be ≥ 1 and ≤ data length after the first valid value.
  • r_multi must be finite and ≥ 0.
  • Warmup: leading outputs are NaN for warm = first_valid + period − 1 + (smooth ? round(√period) − 1 : 0).
  • Streaming: CoraWaveStream::update returns None until warmup completes; then returns Some(value) per tick.
Error Handling
use vectorta::indicators::cora_wave::{cora_wave, CoraWaveError};

match cora_wave(&input) {
    Ok(out) => consume(out),
    Err(CoraWaveError::EmptyInputData) => log::error!("no data provided"),
    Err(CoraWaveError::AllValuesNaN) => log::warn!("all inputs are NaN"),
    Err(CoraWaveError::InvalidPeriod &#123; period, data_len &#125;) =>
        eprintln!("invalid period {period} for length {data_len}"),
    Err(CoraWaveError::NotEnoughValidData &#123; needed, valid &#125;) =>
        eprintln!("need {needed} valid values, only {valid} available"),
    Err(CoraWaveError::InvalidRMulti &#123; value &#125;) =>
        eprintln!("invalid r_multi: {value}"),
}

Python Bindings

Basic Usage

Call CoRa Wave on NumPy arrays:

import numpy as np
from vectorta import cora_wave

prices = np.asarray([100.0, 102.0, 101.5, 103.0, 105.0], dtype=np.float64)

values = cora_wave(prices, period=20, r_multi=2.0, smooth=True, kernel="auto")
print("CoRa values", values)
Streaming Real-time Updates

Maintain a rolling CoRa Wave stream:

from vectorta import CoraWaveStream

stream = CoraWaveStream(period=20, r_multi=2.0, smooth=True)

for price in price_feed:
    y = stream.update(price)
    if y is not None:
        use(y)
Batch Parameter Optimization

Evaluate multiple period and r_multi combinations:

import numpy as np
from vectorta import cora_wave_batch

prices = np.asarray([...], dtype=np.float64)

result = cora_wave_batch(
    prices,
    period_range=(20, 60, 5),
    r_multi_range=(1.0, 3.0, 0.5),
    smooth=True,
    kernel="auto",
)

values = result["values"]  # shape: [rows, len(prices)]
periods = result["periods"]
r_multis = result["r_multis"]
smooth = result["smooth"]
CUDA Acceleration

CUDA support for CoRa Wave is currently under development. The API will follow the same pattern as other CUDA-enabled indicators.

# Coming soon: CUDA-accelerated CoRa Wave calculations
# from vectorta import cora_wave_cuda_batch, cora_wave_cuda_many_series_one_param
# import numpy as np
# ...

JavaScript/WASM Bindings

Basic Usage

Calculate CoRa Wave in JS/TS:

import { cora_wave_js } from 'vectorta-wasm';

const prices = new Float64Array([100.0, 102.0, 101.5, 103.0, 105.0]);

// Args: data, period, r_multi, smooth
const values = cora_wave_js(prices, 20, 2.0, true);
console.log('CoRa values:', values);
Memory-Efficient Operations

Use zero-copy allocations for large datasets:

import { cora_wave_alloc, cora_wave_free, cora_wave_into, memory } from 'vectorta-wasm';

const len = prices.length;
const inPtr = cora_wave_alloc(len);
const outPtr = cora_wave_alloc(len);

new Float64Array(memory.buffer, inPtr, len).set(prices);

// in_ptr, out_ptr, len, period, r_multi, smooth
cora_wave_into(inPtr, outPtr, len, 20, 2.0, true);

const out = new Float64Array(memory.buffer, outPtr, len).slice();

cora_wave_free(inPtr, len);
cora_wave_free(outPtr, len);

console.log('CoRa values:', out);
Batch Processing

Evaluate many parameter combinations at once:

import { cora_wave_batch } from 'vectorta-wasm';

const prices = new Float64Array([/* historical prices */]);

const result = cora_wave_batch(prices, {
  period_range: [20, 60, 5],
  r_multi_range: [1.0, 3.0, 0.5],
  smooth: true,
});

// result: { values: Float64Array, combos: CoraWaveParams[], rows: number, cols: number }
console.log(result.rows, result.cols);
// Flattened values can be reshaped by rows x cols as needed

Performance Analysis

Comparison:
View:
Loading chart...

AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU) | Benchmarks: 2026-01-05

Related Indicators