@@ -921,3 +921,57 @@ pub fn t3<T: ToPrimitive>(
921921 . map ( move |( e3, e4, e5, e6) | c1 * e6 + c2 * e5 + c3 * e4 + c4 * e3) ,
922922 )
923923}
924+
925+ /// Fractal Adaptive Moving Average
926+ ///
927+ /// Based on argument that market prices are fractal, this algorithm considers fractal shapes as
928+ /// self-similar because they tend to have the same roughness and sparseness regardless of the
929+ /// magnification used to view them.
930+ ///
931+ /// ## Sources
932+ ///
933+ /// [[1]](https://www.mesasoftware.com/papers/FRAMA.pdf)
934+ ///
935+ /// # Examples
936+ ///
937+ /// ```
938+ /// use traquer::smooth;
939+ ///
940+ /// match smooth::frama(&[1.0,2.0,3.0,4.0,5.0,2.0,3.0,4.0,2.0,3.0,4.0,2.0,3.0,4.0], 3){
941+ /// Ok(iter) => {
942+ /// let ma = iter.collect::<Vec<f64>>();
943+ /// },
944+ /// Err(e) => println!("Error: {}", e),
945+ /// }
946+ /// ```
947+ pub fn frama < T : ToPrimitive > (
948+ data : & [ T ] ,
949+ window : usize ,
950+ ) -> Result < impl Iterator < Item = f64 > + ' _ , & ' static str > {
951+ if window % 2 != 0 {
952+ return Err ( "Window must be an even number" ) ;
953+ }
954+ let mid = window / 2 ;
955+ Ok ( iter:: repeat ( f64:: NAN )
956+ . take ( window - 1 )
957+ . chain ( data. windows ( window) . scan ( 0. , move |state, w| {
958+ let ( hh1, ll1, hh2, ll2) = w. iter ( ) . take ( mid) . zip ( w. iter ( ) . rev ( ) . take ( mid) ) . fold (
959+ ( f64:: MIN , f64:: MAX , f64:: MIN , f64:: MAX ) ,
960+ |( hh1, ll1, hh2, ll2) , ( x1, x2) | {
961+ (
962+ hh1. max ( x1. to_f64 ( ) . unwrap ( ) ) ,
963+ ll1. min ( x1. to_f64 ( ) . unwrap ( ) ) ,
964+ hh2. max ( x2. to_f64 ( ) . unwrap ( ) ) ,
965+ ll2. min ( x2. to_f64 ( ) . unwrap ( ) ) ,
966+ )
967+ } ,
968+ ) ;
969+ let n1 = ( hh1 - ll1) / mid as f64 ;
970+ let n2 = ( hh2 - ll2) / mid as f64 ;
971+ let n3 = ( hh1. max ( hh2) - ll1. min ( ll2) ) / window as f64 ;
972+ let d = ( ( n1 + n2) . ln ( ) - n3. ln ( ) ) / 2_f64 . ln ( ) ;
973+ let alpha = ( -4.6 * ( d - 1. ) ) . exp ( ) . clamp ( 0.01 , 1. ) ;
974+ * state = alpha * w. last ( ) . unwrap ( ) . to_f64 ( ) . unwrap ( ) + ( 1. - alpha) * * state;
975+ Some ( * state)
976+ } ) ) )
977+ }
0 commit comments