1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4pub use use_bar as bar;
11pub use use_drawdown as drawdown;
12pub use use_factor as factor;
13pub use use_market_price as market_price;
14pub use use_portfolio_weight as portfolio_weight;
15pub use use_price_series as price_series;
16pub use use_return as return_;
17pub use use_risk as risk;
18pub use use_signal_score as signal_score;
19pub use use_tick as tick;
20pub use use_volatility as volatility;
21
22pub mod prelude {
24 pub use crate::bar::{BarInterval, BarTime, OhlcBar, OhlcvBar};
25 pub use crate::drawdown::{Drawdown, DrawdownPoint, DrawdownWindow};
26 pub use crate::factor::{FactorExposure, FactorLoading, FactorModelName, FactorName};
27 pub use crate::market_price::{MarketPrice, PriceKind, PriceQuote};
28 pub use crate::portfolio_weight::{AssetWeight, PortfolioWeight, WeightSet};
29 pub use crate::price_series::{PricePoint, PriceSeries, SeriesName};
30 pub use crate::return_::{LogReturn, ReturnKind, ReturnValue, SimpleReturn};
31 pub use crate::risk::{RiskBudget, RiskLevel, RiskLimit, RiskMeasure};
32 pub use crate::signal_score::{SignalDirection, SignalName, SignalScore, SignalStrength};
33 pub use crate::tick::{QuoteTick, Tick, TickKind, TradeTick};
34 pub use crate::volatility::{Volatility, VolatilityKind, VolatilityWindow};
35}
36
37#[cfg(test)]
38mod tests {
39 use super::{
40 bar, drawdown, factor, market_price, portfolio_weight, price_series, return_, risk,
41 signal_score, tick, volatility,
42 };
43
44 #[test]
45 fn facade_exposes_composable_quant_primitives() -> Result<(), Box<dyn std::error::Error>> {
46 let close = market_price::MarketPrice::new(101.25)?;
47 let simple_return = return_::SimpleReturn::from_prices(100.0, close.value())?;
48 let bar = bar::OhlcvBar::from_values(
49 bar::BarTime::new("2026-05-17")?,
50 bar::BarInterval::Day,
51 100.0,
52 102.0,
53 99.5,
54 close.value(),
55 42_000.0,
56 )?;
57 let trade = tick::TradeTick::new(close).with_size(100.0)?;
58 let mut series = price_series::PriceSeries::new();
59 series.push(price_series::PricePoint::new(
60 market_price::MarketPrice::new(100.0)?,
61 ));
62 series.push(price_series::PricePoint::new(close));
63 let volatility = volatility::Volatility::new(0.20)?;
64 let drawdown = drawdown::Drawdown::from_peak_current(105.0, close.value())?;
65 let weight = portfolio_weight::AssetWeight::new(
66 "ABC",
67 portfolio_weight::PortfolioWeight::new(0.25)?,
68 )?;
69 let exposure = factor::FactorExposure::new(factor::FactorName::new("momentum")?, 0.7)?;
70 let signal =
71 signal_score::SignalScore::new(signal_score::SignalName::new("quality-score")?, 1.2)?;
72 let limit = risk::RiskLimit::new(risk::RiskMeasure::Volatility, 0.20)?;
73
74 assert!((simple_return.value() - 0.0125).abs() < 1.0e-12);
75 assert!((bar.bar().close().value() - 101.25).abs() < f64::EPSILON);
76 assert_eq!(trade.tick().size(), Some(100.0));
77 assert_eq!(series.len(), 2);
78 assert!((volatility.value() - 0.20).abs() < f64::EPSILON);
79 assert!(drawdown.value() <= 0.0);
80 assert_eq!(weight.asset_id(), "ABC");
81 assert_eq!(exposure.factor().as_str(), "momentum");
82 assert!((signal.score() - 1.2).abs() < f64::EPSILON);
83 assert_eq!(limit.measure(), &risk::RiskMeasure::Volatility);
84 Ok(())
85 }
86}