Compound Ratio Moving Average (CoRa Wave)
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 }. periodmust be ≥ 1 and ≤ data length after the first valid value.r_multimust be finite and ≥ 0.- Warmup: leading outputs are
NaNforwarm = first_valid + period − 1 + (smooth ? round(√period) − 1 : 0). - Streaming:
CoraWaveStream::updatereturnsNoneuntil warmup completes; then returnsSome(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 { period, data_len }) =>
eprintln!("invalid period {period} for length {data_len}"),
Err(CoraWaveError::NotEnoughValidData { needed, valid }) =>
eprintln!("need {needed} valid values, only {valid} available"),
Err(CoraWaveError::InvalidRMulti { value }) =>
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
AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU) | Benchmarks: 2026-01-05
Related Indicators
Arnaud Legoux Moving Average
Moving average indicator
Centered Weighted Moving Average
Moving average indicator
Double Exponential Moving Average
Moving average indicator
Ehlers Distance Coefficient Filter
Moving average indicator
Ehlers Error-Correcting EMA (ECEMA)
Moving average indicator
Ehlers Instantaneous Trendline
Moving average indicator