Indicators
The SDK includes common technical indicators. All implement the Indicator trait:
rust
pub trait Indicator {
fn update(&mut self, value: f64);
fn value(&self) -> f64;
fn ready(&self) -> bool;
}Call .update(value) to feed data, .value() to get the current result, and .ready() to check if enough samples have been collected.
Simple Moving Average (Sma)
rust
let mut sma = Sma::new(20);
sma.update(price);
if sma.ready() {
let value = sma.value();
}Exponential Moving Average (Ema)
rust
let mut ema = Ema::new(12);
ema.update(price);
if ema.ready() {
let value = ema.value();
}Relative Strength Index (Rsi)
rust
let mut rsi = Rsi::new(14);
rsi.update(price);
if rsi.ready() {
let value = rsi.value(); // 0-100
}Bollinger Bands
rust
let mut bb = BollingerBands::new(20, 2.0);
bb.update(price);
if bb.ready() {
let mid = bb.value(); // Middle band (SMA)
let upper = bb.upper(); // Upper band
let lower = bb.lower(); // Lower band
}MACD
rust
let mut macd = Macd::new(12, 26, 9);
macd.update(price);
if macd.ready() {
let macd_line = macd.value();
let signal = macd.signal();
let histogram = macd.histogram();
}Average True Range (Atr)
rust
let mut atr = Atr::new(14);
atr.update_hlc(high, low, close); // Use HLC data for accuracy
if atr.ready() {
let value = atr.value();
}The standard .update(value) method also works but uses the value as-is (less accurate without high/low).
Standard Deviation (StdDev)
rust
let mut std = StdDev::new(20);
std.update(price);
if std.ready() {
let value = std.value();
}Volume-Weighted Average Price (Vwap)
rust
let mut vwap = Vwap::new();
vwap.update_pv(price, volume); // Feed price and volume
let value = vwap.value();
vwap.reset(); // Reset at session boundariesCustom Indicators
Build your own by implementing the Indicator trait or using a ring buffer:
rust
pub struct MyIndicator {
buffer: Vec<f64>,
period: usize,
}
impl MyIndicator {
pub fn new(period: usize) -> Self {
Self {
buffer: Vec::with_capacity(period),
period,
}
}
}
impl Indicator for MyIndicator {
fn update(&mut self, value: f64) {
if self.buffer.len() >= self.period {
self.buffer.remove(0);
}
self.buffer.push(value);
}
fn value(&self) -> f64 {
self.buffer.iter().sum::<f64>() / self.buffer.len() as f64
}
fn ready(&self) -> bool {
self.buffer.len() >= self.period
}
}