Last active
March 10, 2023 17:08
-
-
Save soyart/58ad514f8c5902122227963f2e93db28 to your computer and use it in GitHub Desktop.
Draw down, i.e. financial securiry performance indicator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Generic draw down | |
| fn draw_down<T, U>(points: &[T]) -> U | |
| where | |
| T: Clone + Into<U>, | |
| U: Copy + Default + PartialOrd + std::ops::Sub<Output = U>, | |
| { | |
| if points.len() <= 1 { | |
| return U::default(); | |
| } | |
| points | |
| .iter() | |
| .skip(1) | |
| .fold( | |
| (points[0].clone().into(), U::default()), | |
| |(mut max, mut max_down), item| { | |
| let item_u: U = item.clone().into(); | |
| if item_u > max { | |
| max = item_u; | |
| // Return in closure = continue iteration | |
| return (max, max_down); | |
| } | |
| let down = max - item_u; | |
| if down > max_down { | |
| max_down = down; | |
| } | |
| (max, max_down) | |
| }, | |
| ) | |
| .1 | |
| } | |
| // Draw down with f64 result | |
| fn draw_down_f64<T>(points: &[T]) -> f64 | |
| where | |
| T: Into<f64> + Clone, | |
| { | |
| if points.len() <= 1 { | |
| return 0.0; | |
| } | |
| points | |
| .iter() | |
| .skip(1) | |
| .fold( | |
| (points[0].clone().into(), 0.0), | |
| |(mut max, mut max_down), item| { | |
| let item_f64: f64 = item.clone().into(); | |
| if item_f64 > max { | |
| max = item_f64; | |
| // Return in closure = continue iteration | |
| return (max, max_down); | |
| } | |
| let down = max - item_f64; | |
| if down > max_down { | |
| max_down = down; | |
| } | |
| (max, max_down) | |
| }, | |
| ) | |
| .1 | |
| } | |
| #[cfg(test)] | |
| mod test { | |
| #[test] | |
| fn test_draw_down() { | |
| use super::draw_down; | |
| let tests = vec![ | |
| (&[1][..], 0.), | |
| (&[1, 2], 0.), | |
| (&[1, 4, 2, 1], 3.), | |
| (&[1, 10, 12, 14, 7, 4, 20, 9], 11.), | |
| (&[100, 90, 80, 10, 110, 10, 1], 109.), | |
| (&[200, 90, 80, 10, 110, 10, 1], 199.), | |
| (&[7, 8, 9, 1, 10, 8, 6, 11, 200], 8.), | |
| ]; | |
| tests | |
| .into_iter() | |
| .for_each(|test| assert_eq!(draw_down::<i32, f64>(test.0), test.1)) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment