kestrel_chartkit/analytics/
mod.rs1mod activity;
7mod cheat_sheet;
8mod fear_gauge;
9mod fear_greed;
10mod price;
11mod regime;
12mod seasonality;
13mod trend;
14mod trend_persistence;
15
16pub use activity::{activity_reading, ActivityReading};
17pub use cheat_sheet::{
18 cheat_sheet, CheatSheetLevel, CheatSheetLevelKind, CheatSheetLevelSide, CheatSheetReading,
19};
20pub use fear_gauge::{fear_gauge_reading, FearGaugeReading, FearGaugeState};
21pub use fear_greed::{fear_greed_reading, FearGreedDriver, FearGreedReading, FearGreedState};
22pub use price::{price_summary, PriceSummary};
23pub use regime::{classify_regime as classify_trend_regime, RegimeReading, RegimeState};
24pub use seasonality::{monthly_seasonality, MonthStatistics, MonthlyReturn, SeasonalityReport};
25pub use trend::{trend_reading, MarketPhase, TrendDirection, TrendReading};
26pub use trend_persistence::{
27 trend_persistence_reading, TrendPersistenceDirection, TrendPersistenceReading,
28 TrendPersistenceSensor, TrendPersistenceState,
29};
30
31fn true_range(bar: &crate::Bar, prev_close: Option<f64>) -> f64 {
35 match prev_close {
36 None => bar.high - bar.low,
37 Some(prev) => (bar.high - bar.low)
38 .max((bar.high - prev).abs())
39 .max((bar.low - prev).abs()),
40 }
41}
42
43fn efficiency_ratio(bars: &[crate::Bar], n: usize) -> Option<f64> {
48 if bars.len() < n + 1 {
49 return None;
50 }
51 let closes = &bars[bars.len() - n - 1..];
52 let net = (closes[closes.len() - 1].close - closes[0].close).abs();
53 let mut volatility = 0.0;
54 for pair in closes.windows(2) {
55 volatility += (pair[1].close - pair[0].close).abs();
56 }
57 if volatility <= 0.0 {
58 return None;
59 }
60 Some(net / volatility)
61}
62
63mod position;
64pub use position::{atr_distance, position_alignment, PositionAlignment};