volas
English | 简体中文
A Rust-backed, OHLCV-shaped DataFrame for candlestick / market time-series, with a
technical-indicator directive engine.
volas is intentionally narrow — not a general-purpose DataFrame. It targets live OHLCV
pipelines: compute an indicator by naming its directive ("ma:20", "macd.signal",
"close > open"), and resample / cumulate bars to a coarser time frame.
[]
= "1"
There is also a Python package named
volas— the same Rust kernels exposed via PyO3. See the volas Python project on GitHub andvolason PyPI. It is a separate distribution from this crate; the directive vocabulary is identical across both.
Quick start
use ;
use ;
// Build a frame from named columns (here just `close`).
let df = new.unwrap;
// Compute an indicator by its directive string. `ma:2` is the 2-period SMA.
let directive = parse.unwrap;
let ma = execute.unwrap;
assert!; // the warm-up row is NA (no value yet)
assert_eq!; // (3.0 + 4.0) / 2
The data model
A DataFrame is a set of equal-length, named, typed Columns over a shared row
Index. A Column is a contiguous typed buffer; any cell can be NA (missing)
independently of its value — see Missing values below.
use ;
let df = new.unwrap;
assert_eq!;
assert_eq!;
assert_eq!;
let close = df.column.unwrap; // -> &Column
assert_eq!;
assert_eq!; // owned Vec<f64>
assert_eq!; // borrowed slice (F64 only)
Column constructors: Column::f64, Column::i64, Column::bool,
Column::str. Read values with Column::to_f64_vec (owned), Column::as_f64
(borrowed, None for non-f64), Column::is_valid (per-cell NA check),
Column::len, and Column::dtype.
Missing values (NA)
A cell can be missing independently of its value. Float columns use NaN as the NA
marker; integer / bool / string columns carry an explicit validity mask. Check
missingness per cell with is_valid, and count it with null_count.
use Column;
use Validity;
// Float columns: NaN is the missing marker.
let prices = f64;
assert_eq!;
assert!;
assert!; // cell 1 is NA
assert!; // reading an NA f64 yields NaN
// Integer / bool / string columns carry a validity mask instead of a sentinel.
let volume = i64_with;
assert_eq!;
assert!;
Indicator warm-up rows are NA too — e.g. a 2-period SMA has one NA row at the head:
use ;
use ;
let df = new.unwrap;
let ma = execute.unwrap;
assert!; // the warm-up row is NA
assert_eq!;
Indicators via directives
The directive engine is the primary way to compute indicators: parse a directive
string into an Ast, then execute it against a DataFrame to get a Column. This
covers every built-in indicator uniformly — see the full reference of all
directives in
INDICATORS.md.
use ;
use ;
let n = 40;
let df = new.unwrap;
// Single-output directive -> one Column.
let rsi = execute.unwrap;
assert_eq!;
// Multi-output indicator: address each line by its sub-command.
let macd = execute.unwrap;
let signal = execute.unwrap;
let hist = execute.unwrap;
assert_eq!;
// A comparison directive -> a Bool column (usable as a row mask).
let bullish = execute.unwrap;
assert_eq!;
// `@`-suffix picks input columns; canonical form drops a default input.
let ast = parse.unwrap;
assert_eq!;
A directive has the shape name:arg0,arg1,...@col0,col1,... — name is the indicator,
: arguments are its parameters, and @ columns are the inputs (each with a sensible
default, e.g. close). Multi-output indicators expose each line as name.subcommand
(macd.signal, boll.upper, kdj.k). The exact arguments, defaults, and sub-commands
for all directives are in
INDICATORS.md.
Warm-up length (rows before the first valid value) is available without computing:
use ;
let ast = parse.unwrap;
assert_eq!; // a 20-period SMA has 19 warm-up rows
Raw kernels (advanced)
The directive engine is the recommended API. For direct, DataFrame-free access, the
compute module exposes the numeric kernels as pure functions over slices
(&[f64] -> Vec<f64>); most users should prefer directives, which are stable, complete,
and identical to the Python surface.
Reading CSV
use ;
// Defaults: comma-separated, the first row is the header, standard NA tokens.
let df = read_csv.unwrap;
println!;
path is any AsRef<Path> (&str, String, PathBuf). Tune parsing via
ReadCsvOptions (delimiter, has_header, na_values, keep_default_na).
Time-frame cumulation (OHLCV resampling)
Aggregate finer bars into a coarser TimeFrame (the source must have a
DatetimeIndex). The default OHLCV spec is open=first, high=max, low=min,
close=last, volume=sum.
use ;
use ;
// In practice `df` has a 1-minute DatetimeIndex; this is a placeholder frame.
let df = new.unwrap;
// Resample to 5-minute bars.
let five_min = cumulate.unwrap;
let _ = five_min;
TimeFrame is an enum (Min1, Min5, Hour1, Day1, …) and also parses a label via
TimeFrame::from_label("5m").
Error handling
Fallible functions return Result<_, VolasError> (a single error enum) — no panics on
bad input. An unknown or malformed directive is reported at parse:
use VolasError;
use parse;
let ok = parse;
assert!;
let bad: = parse;
assert!;
Crate layout
- top level — the data model (
DataFrame,Series,Column,Index,DType,Scalar,Tz,Result,VolasError), plusread_csvandTimeFrame; directive—parse/execute/stringify/lookback, and theAst;compute— numeric kernels and technical indicators (pure functions);time— time-frame cumulation (OHLCV resampling);core— the fullvolas-coresurface, for the less-common types.
This crate is a thin facade re-exporting the volas workspace (volas-core,
volas-compute, volas-directive, volas-time, volas-io) behind one dependency.