11use crate :: indicators:: rsi;
2- use crate :: utils:: { calc_mean , find_max , find_min } ;
2+ use crate :: utils:: { rolling_max_min , rolling_mean_strict } ;
33
44pub fn stochrsi (
55 closes : & [ f64 ] ,
@@ -9,45 +9,48 @@ pub fn stochrsi(
99) -> ( Vec < Option < f64 > > , Vec < Option < f64 > > ) {
1010 let len = closes. len ( ) ;
1111 let mut percent_k = vec ! [ None ; len] ;
12- let mut percent_d = vec ! [ None ; len] ;
1312
1413 if len < period_rsi + period_k || period_rsi <= 1 || period_k <= 1 {
15- return ( percent_k, percent_d ) ;
14+ return ( percent_k, vec ! [ None ; len ] ) ;
1615 }
1716
1817 let rsi_values = rsi ( closes, period_rsi) ;
18+ let rsi_values_with_nan: Vec < f64 > = rsi_values
19+ . iter ( )
20+ . map ( |value| value. unwrap_or ( f64:: NAN ) )
21+ . collect ( ) ;
22+ let ( rolling_max, rolling_min) =
23+ rolling_max_min ( & rsi_values_with_nan, & rsi_values_with_nan, period_k) ;
1924
2025 for i in ( period_rsi + period_k - 1 ) ..len {
21- let slice = & rsi_values[ i + 1 - period_k..=i] ;
22- let valid_values: Vec < f64 > = slice. iter ( ) . filter_map ( |& x| x) . collect ( ) ;
26+ let valid_values: Vec < f64 > = rsi_values[ i + 1 - period_k..=i]
27+ . iter ( )
28+ . filter_map ( |& x| x)
29+ . collect ( ) ;
2330
24- if valid_values. len ( ) == period_k {
25- let rsi_max = find_max ( & valid_values) ;
26- let rsi_min = find_min ( & valid_values) ;
27-
28- let k = if rsi_max == rsi_min {
29- None
30- } else {
31- rsi_values[ i] . map ( |rsi| ( ( rsi - rsi_min) / ( rsi_max - rsi_min) ) * 100.0 )
32- } ;
31+ if valid_values. len ( ) != period_k {
32+ continue ;
33+ }
3334
34- percent_k[ i] = k;
35+ let ( Some ( rsi) , Some ( rsi_max) , Some ( rsi_min) ) =
36+ ( rsi_values[ i] , rolling_max[ i] , rolling_min[ i] )
37+ else {
38+ continue ;
39+ } ;
3540
36- if period_d == 1 {
37- percent_d[ i] = k;
38- } else if i >= period_rsi + period_k - 1 + ( period_d - 1 ) {
39- let d_slice = & percent_k[ i + 1 - period_d..=i] ;
40- let valid_d_values: Vec < f64 > = d_slice. iter ( ) . filter_map ( |& x| x) . collect ( ) ;
41- let d = if valid_d_values. len ( ) == period_d {
42- Some ( calc_mean ( & valid_d_values) )
43- } else {
44- None
45- } ;
46- percent_d[ i] = d;
47- }
48- }
41+ percent_k[ i] = if rsi_max == rsi_min {
42+ None
43+ } else {
44+ Some ( ( ( rsi - rsi_min) / ( rsi_max - rsi_min) ) * 100.0 )
45+ } ;
4946 }
5047
48+ let percent_d = if period_d == 1 {
49+ percent_k. clone ( )
50+ } else {
51+ rolling_mean_strict ( & percent_k, period_d)
52+ } ;
53+
5154 ( percent_k, percent_d)
5255}
5356
0 commit comments