Technical Analysis Library Examples
Learn how to use VectorAlpha's high-performance technical analysis library with these practical examples.
Installation
Cargo.tomltoml
12345[dependencies] vectoralpha-ta = "0.1.0" # Optional: Enable GPU acceleration vectoralpha-ta = { version = "0.1.0", features = ["cuda"] }
Basic Moving Averages
Calculate simple and exponential moving averages with automatic SIMD optimization:
src/main.rsrust
123456789101112131415161718use vectoralpha_ta::indicators::{sma, ema}; fn main() { let prices = vec![ 100.0, 101.5, 99.8, 102.3, 103.1, 101.7, 104.2, 103.5, 105.0, 104.3 ]; // Simple Moving Average with period 5 let sma_values = sma(&prices, 5)?; println!("SMA(5): {:?}", sma_values); // Exponential Moving Average with period 5 let ema_values = ema(&prices, 5)?; println!("EMA(5): {:?}", ema_values); Ok(()) }
Advanced Indicators
Use more complex indicators like MACD, RSI, and Bollinger Bands:
src/analysis.rsrust
1234567891011121314151617181920212223242526272829303132333435363738394041424344use vectoralpha_ta::indicators::{macd, rsi, bollinger_bands}; use vectoralpha_ta::types::*; fn analyze_security(prices: &[f64]) -> Result<Analysis, TAError> { // MACD with standard parameters (12, 26, 9) let macd_result = macd(prices, 12, 26, 9)?; // RSI with 14-day period let rsi_values = rsi(prices, 14)?; // Bollinger Bands with 20-day MA and 2 standard deviations let bb_result = bollinger_bands(prices, 20, 2.0)?; Ok(Analysis { macd: macd_result, rsi: rsi_values, bollinger_bands: bb_result, }) } // Check for trading signals fn check_signals(analysis: &Analysis) -> Vec<Signal> { let mut signals = Vec::new(); // MACD crossover if analysis.macd.macd.last() > analysis.macd.signal.last() { signals.push(Signal::Buy("MACD bullish crossover")); } // RSI oversold if analysis.rsi.last() < 30.0 { signals.push(Signal::Buy("RSI oversold")); } // Price touching lower Bollinger Band let last_price = analysis.bollinger_bands.close.last(); let lower_band = analysis.bollinger_bands.lower.last(); if last_price <= lower_band * 1.01 { signals.push(Signal::Buy("Price near lower BB")); } signals }
GPU Acceleration
Enable GPU acceleration for massive performance improvements on large datasets:
src/gpu_example.rsrust
12345678910111213141516171819202122232425262728293031323334353637use vectoralpha_ta::gpu::{GpuContext, GpuIndicators}; use vectoralpha_ta::indicators::*; fn main() -> Result<(), Box<dyn std::error::Error>> { // Initialize GPU context let gpu = GpuContext::new()?; // Load large dataset (e.g., 1 million price points) let prices = load_price_data("large_dataset.csv")?; // CPU vs GPU benchmark let start = std::time::Instant::now(); let cpu_sma = sma(&prices, 200)?; let cpu_time = start.elapsed(); let start = std::time::Instant::now(); let gpu_sma = gpu.sma(&prices, 200)?; let gpu_time = start.elapsed(); println!("CPU time: {:?}", cpu_time); println!("GPU time: {:?}", gpu_time); println!("Speedup: {:.2}x", cpu_time.as_secs_f64() / gpu_time.as_secs_f64()); // Batch processing multiple indicators let indicators = gpu.batch_compute(&prices, |data| { BatchIndicators { sma_20: sma(data, 20)?, sma_50: sma(data, 50)?, sma_200: sma(data, 200)?, ema_12: ema(data, 12)?, ema_26: ema(data, 26)?, rsi_14: rsi(data, 14)?, } })?; Ok(()) }
Real-time Streaming Data
Process real-time market data streams efficiently:
src/streaming.rsrust
123456789101112131415161718192021222324252627282930313233343536373839use vectoralpha_ta::streaming::{StreamingIndicator, StreamingEMA}; use tokio::sync::mpsc; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { let (tx, mut rx) = mpsc::channel(100); // Initialize streaming indicator let mut ema = StreamingEMA::new(20); // Spawn market data receiver tokio::spawn(async move { let mut ws = connect_market_data().await?; while let Some(tick) = ws.next().await { tx.send(tick.price).await?; } Ok::<(), Box<dyn std::error::Error>>(()) }); // Process streaming prices while let Some(price) = rx.recv().await { let ema_value = ema.update(price); // Check for trading conditions if should_trade(price, ema_value) { execute_trade(price).await?; } // Log current values println!("Price: {:.2}, EMA(20): {:.2}", price, ema_value); } Ok(()) } fn should_trade(price: f64, ema: f64) -> bool { // Simple strategy: buy when price crosses above EMA price > ema && price < ema * 1.02 }
Custom Indicators
Create your own custom indicators using the library's building blocks:
src/custom_indicator.rsrust
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748use vectoralpha_ta::core::{Indicator, IndicatorResult}; use vectoralpha_ta::math::{std_dev, mean}; /// Custom Volatility-Adjusted Momentum indicator pub struct VAMIndicator { period: usize, volatility_period: usize, } impl VAMIndicator { pub fn new(period: usize, vol_period: usize) -> Self { Self { period, volatility_period: vol_period, } } } impl Indicator for VAMIndicator { fn calculate(&self, data: &[f64]) -> IndicatorResult { let mut result = Vec::with_capacity(data.len()); for i in 0..data.len() { if i < self.period.max(self.volatility_period) { result.push(f64::NAN); continue; } // Calculate momentum let momentum = (data[i] - data[i - self.period]) / data[i - self.period]; // Calculate volatility (standard deviation) let vol_slice = &data[i - self.volatility_period + 1..=i]; let volatility = std_dev(vol_slice); // Adjust momentum by volatility let vam = momentum / volatility.max(0.0001); result.push(vam); } IndicatorResult::new(result) } } // Usage let prices = load_prices()?; let vam = VAMIndicator::new(20, 10); let values = vam.calculate(&prices)?;
Integration with DataFrames
Use with popular Rust DataFrame libraries like Polars:
src/dataframe_integration.rsrust
123456789101112131415161718192021222324use polars::prelude::*; use vectoralpha_ta::indicators::*; fn analyze_dataframe(df: DataFrame) -> Result<DataFrame> { let prices = df.column("close")?.f64()?.to_vec(); // Calculate multiple indicators let sma_20 = sma(&prices, 20)?; let ema_20 = ema(&prices, 20)?; let rsi_14 = rsi(&prices, 14)?; let (bb_upper, bb_middle, bb_lower) = bollinger_bands(&prices, 20, 2.0)?; // Add indicators to DataFrame let df_with_indicators = df .lazy() .with_column(Series::new("sma_20", sma_20)) .with_column(Series::new("ema_20", ema_20)) .with_column(Series::new("rsi_14", rsi_14)) .with_column(Series::new("bb_upper", bb_upper)) .with_column(Series::new("bb_lower", bb_lower)) .collect()?; Ok(df_with_indicators) }