kestrel_chartkit/engine/
liquidity_path.rs1#[cfg(feature = "serde")]
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Copy, PartialEq)]
14#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
15pub struct FreeSpaceScore {
16 pub score: f64,
18 pub lvn_width_atr: f64,
19 pub distance_to_hvn_atr: f64,
20 pub volume_density: f64,
21}
22
23pub fn build_free_space_score(
24 lvn_width_atr: f64,
25 distance_to_hvn_atr: f64,
26 volume_density: f64,
27) -> FreeSpaceScore {
28 let density_component = (1.0 - volume_density.clamp(0.0, 1.0)) * 40.0;
29 let width_component = lvn_width_atr.clamp(0.0, 3.0) / 3.0 * 30.0;
30 let distance_component = distance_to_hvn_atr.clamp(0.0, 3.0) / 3.0 * 30.0;
31 let score = (density_component + width_component + distance_component).clamp(0.0, 100.0);
32 FreeSpaceScore {
33 score,
34 lvn_width_atr,
35 distance_to_hvn_atr,
36 volume_density,
37 }
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43
44 #[test]
45 fn thin_wide_far_book_scores_high() {
46 let out = build_free_space_score(3.0, 3.0, 0.0);
47 assert!((out.score - 100.0).abs() < 1e-9);
48 }
49
50 #[test]
51 fn dense_narrow_close_book_scores_low() {
52 let out = build_free_space_score(0.0, 0.0, 1.0);
53 assert!(out.score.abs() < 1e-9);
54 }
55}