| Crates.io | velora-ta |
| lib.rs | velora-ta |
| version | 0.0.1 |
| created_at | 2025-10-19 17:38:31.759316+00 |
| updated_at | 2025-10-19 17:38:31.759316+00 |
| description | Technical analysis indicators library for Velora - can be used standalone |
| homepage | https://github.com/crabby-ai/velora |
| repository | https://github.com/crabby-ai/velora |
| max_upload_size | |
| id | 1890705 |
| size | 338,840 |
A high-performance, standalone technical analysis library for algorithmic trading in Rust.
Part of the Velora HFT platform, but can be used completely independently.
Add to your Cargo.toml:
[dependencies]
velora-ta = "0.1"
Single Candle: Doji, Hammer, Shooting Star
Two Candle: Bullish Engulfing, Bearish Engulfing
Three Candle: Three White Soldiers, Three Black Crows
use velora_ta::{SMA, EMA, RSI, SingleIndicator};
use chrono::Utc;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create indicators
let mut sma_20 = SMA::new(20)?;
let mut ema_50 = EMA::new(50)?;
let mut rsi_14 = RSI::new(14)?;
// Process live data
loop {
let price = get_latest_price(); // Your data source
let timestamp = Utc::now();
if let Some(sma) = sma_20.update(price, timestamp)? {
println!("SMA(20): {:.2}", sma);
}
if let Some(rsi) = rsi_14.update(price, timestamp)? {
if rsi > 70.0 {
println!("๐ด OVERBOUGHT - Consider selling");
} else if rsi < 30.0 {
println!("๐ข OVERSOLD - Consider buying");
}
}
}
Ok(())
}
use velora_ta::{SMA, MACD, MultiIndicator, SingleIndicator};
use chrono::Utc;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Load historical data
let prices = vec![100.0, 102.0, 101.0, 103.0, 104.0, 106.0, 105.0, 107.0];
// Calculate SMA
let sma = SMA::new(3)?;
let sma_values = sma.calculate(&prices)?;
// Calculate MACD (multi-value indicator)
let macd = MACD::new(12, 26, 9)?;
let timestamp = Utc::now();
for price in &prices {
if let Some(values) = macd.update(*price, timestamp)? {
let macd_line = values[0];
let signal_line = values[1];
let histogram = values[2];
println!("MACD: {:.2}, Signal: {:.2}, Hist: {:.2}",
macd_line, signal_line, histogram);
}
}
Ok(())
}
Some indicators require high/low data:
use velora_ta::{ATR, Stochastic, OhlcBar, SingleIndicator, MultiIndicator};
use chrono::Utc;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut atr = ATR::new(14)?;
let mut stoch = Stochastic::new(14, 3)?;
let timestamp = Utc::now();
// OHLC bar: (open, high, low, close)
let bar = OhlcBar::new(100.0, 105.0, 95.0, 102.0);
// ATR for volatility
if let Some(atr_val) = atr.update_ohlc(&bar, timestamp)? {
println!("ATR(14): {:.2} - Volatility measurement", atr_val);
}
// Stochastic for momentum
if let Some(values) = stoch.update_ohlc(&bar, timestamp)? {
let k = values[0]; // %K
let d = values[1]; // %D
if k > 80.0 {
println!("Stochastic Overbought: %K={:.2}, %D={:.2}", k, d);
}
}
Ok(())
}
use velora_ta::{OBV, VWAP, VolumeIndicator};
use chrono::Utc;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut obv = OBV::new();
let mut vwap = VWAP::new();
let timestamp = Utc::now();
// Price-volume pairs
let data = vec![
(100.0, 1000.0),
(102.0, 1500.0),
(101.0, 1200.0),
];
for (price, volume) in data {
// OBV tracks cumulative volume direction
if let Some(obv_val) = obv.update_with_volume(price, volume, timestamp)? {
println!("OBV: {:.0}", obv_val);
}
// VWAP provides volume-weighted average
if let Some(vwap_val) = vwap.update_with_volume(price, volume, timestamp)? {
println!("VWAP: {:.2}", vwap_val);
}
}
Ok(())
}
| Indicator | Type | Data | Common Use |
|---|---|---|---|
| SMA, EMA | Single | Price | Trend following |
| RSI | Single | Price | Overbought/oversold |
| MACD | Multi | Price | Trend + momentum |
| Bollinger Bands | Multi | Price | Volatility breakouts |
| Stochastic | Multi | OHLC | Momentum oscillator |
| ATR | Single | OHLC | Volatility / stop-loss |
| VWAP | Single | Price+Volume | Intraday benchmark |
| OBV | Single | Price+Volume | Volume confirmation |
By Output Type:
By Data Requirements:
See examples/ directory for complete examples:
sma_ema_demo.rs - Moving averages comparison# Run all tests
cargo test -p velora-ta
# Run specific category
cargo test -p velora-ta trend::
cargo test -p velora-ta momentum::
# Run with output
cargo test -p velora-ta -- --nocapture
# Test coverage
cargo tarpaulin -p velora-ta
Current Coverage: 198 tests, 100% of indicators tested
Benchmarked on Apple M1:
| Indicator | Update Time | Batch (1000 points) |
|---|---|---|
| SMA(20) | ~15ns | ~15ยตs |
| EMA(20) | ~10ns | ~10ยตs |
| RSI(14) | ~25ns | ~25ยตs |
| MACD | ~30ns | ~30ยตs |
| Bollinger Bands | ~40ns | ~40ยตs |
All indicators are O(1) for streaming updates.
All essential indicators for 90%+ of trading strategies
See FUTURE_INDICATORS.md for complete list including:
We welcome contributions! To add a new indicator:
See CONTRIBUTING.md for detailed guidelines.
Trend (14): SMA, EMA, WMA, DEMA, TEMA, HMA, SMMA, VWMA, ADX, Parabolic SAR, SuperTrend, Aroon, KAMA, Vortex
Momentum (8): RSI, MACD, Stochastic, Williams %R, ROC, Momentum, CCI, TSI
Volatility (6): True Range, ATR, StdDev, Bollinger Bands, Keltner Channels, Donchian Channels
Volume (7): OBV, VWAP, AD, CMF, MFI, Force Index, EMV
Bill Williams (3): Awesome Oscillator, Alligator, Fractals
Statistical (3): Linear Regression, Z-Score, Correlation
Patterns (8): Doji, Hammer, Shooting Star, Bullish Engulfing, Bearish Engulfing, Three White Soldiers, Three Black Crows
See FUTURE_INDICATORS.md for the complete roadmap including:
Total Planned: 144+ indicators
pub trait Indicator {
fn name(&self) -> &str;
fn warmup_period(&self) -> usize;
fn is_ready(&self) -> bool;
fn reset(&mut self);
}
pub trait SingleIndicator: Indicator {
fn update(&mut self, price: f64, timestamp: DateTime<Utc>) -> Result<Option<f64>>;
fn current(&self) -> Option<f64>;
fn calculate(&self, prices: &[f64]) -> Result<Vec<Option<f64>>>;
}
pub trait MultiIndicator: Indicator {
fn output_count(&self) -> usize;
fn output_names(&self) -> Vec<&str>;
fn update(&mut self, price: f64, timestamp: DateTime<Utc>) -> Result<Option<Vec<f64>>>;
fn current(&self) -> Option<Vec<f64>>;
}
pub trait VolumeIndicator: Indicator {
fn update_with_volume(&mut self, price: f64, volume: f64, timestamp: DateTime<Utc>)
-> Result<Option<f64>>;
fn calculate_with_volume(&self, prices: &[f64], volumes: &[f64])
-> Result<Vec<Option<f64>>>;
}
use velora_ta::{SMA, EMA, SingleIndicator};
let mut sma_fast = SMA::new(10)?;
let mut sma_slow = SMA::new(30)?;
for price in prices {
let fast = sma_fast.update(price, timestamp)?;
let slow = sma_slow.update(price, timestamp)?;
match (fast, slow) {
(Some(f), Some(s)) if f > s => println!("๐ข Uptrend - Fast > Slow"),
(Some(f), Some(s)) if f < s => println!("๐ด Downtrend - Fast < Slow"),
_ => {}
}
}
use velora_ta::{RSI, BollingerBands, SingleIndicator, MultiIndicator};
let mut rsi = RSI::new(14)?;
let mut bb = BollingerBands::new(20, 2.0)?;
for price in prices {
let rsi_val = rsi.update(price, timestamp)?;
let bb_vals = bb.update(price, timestamp)?;
if let (Some(rsi), Some(bands)) = (rsi_val, bb_vals) {
let upper = bands[0];
let lower = bands[2];
if price < lower && rsi < 30.0 {
println!("๐ข OVERSOLD - Price below lower BB + RSI < 30");
} else if price > upper && rsi > 70.0 {
println!("๐ด OVERBOUGHT - Price above upper BB + RSI > 70");
}
}
}
use velora_ta::{ATR, BollingerBands, OhlcBar};
let mut atr = ATR::new(14)?;
let mut bb = BollingerBands::new(20, 2.0)?;
for bar in ohlc_bars {
let atr_val = atr.update_ohlc(&bar, timestamp)?;
let bb_vals = bb.update(bar.close, timestamp)?;
if let (Some(atr), Some(bands)) = (atr_val, bb_vals) {
let bandwidth = (bands[0] - bands[2]) / bands[1];
if bandwidth < 0.02 && atr < 2.0 {
println!("๐ Low volatility - Breakout imminent");
}
}
}
All indicators support:
// Create indicator
let mut indicator = SMA::new(period)?;
// Check status
indicator.name(); // Get indicator name
indicator.warmup_period(); // Periods needed before output
indicator.is_ready(); // Has enough data?
// Update (streaming)
indicator.update(price, timestamp)?;
// Get current value
indicator.current();
// Batch calculation
indicator.calculate(&prices)?;
// Reset state
indicator.reset();
All indicators have comprehensive tests covering:
# Run all 198 tests
cargo test -p velora-ta
# Run specific indicator tests
cargo test -p velora-ta sma
cargo test -p velora-ta rsi
cargo test -p velora-ta macd
MIT License - see LICENSE for details
Inspired by:
Built with โค๏ธ in Rust
Status: v0.1.0 - Production Ready ๐