1#![allow(missing_docs)]
18
19use crate::backtesting::strategy::StrategyContext;
20use crate::indicators::Indicator;
21
22use super::IndicatorRef;
23
24#[derive(Debug, Clone)]
30pub struct SmaRef {
31 pub period: usize,
32 key: String,
33}
34
35impl IndicatorRef for SmaRef {
36 fn key(&self) -> &str {
37 &self.key
38 }
39
40 fn required_indicators(&self) -> Vec<(String, Indicator)> {
41 vec![(self.key.clone(), Indicator::Sma(self.period))]
42 }
43
44 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
45 ctx.indicator(self.key())
46 }
47
48 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
49 ctx.indicator_prev(self.key())
50 }
51}
52
53#[inline]
64pub fn sma(period: usize) -> SmaRef {
65 SmaRef {
66 period,
67 key: format!("sma_{period}"),
68 }
69}
70
71#[derive(Debug, Clone)]
73pub struct EmaRef {
74 pub period: usize,
75 key: String,
76}
77
78impl IndicatorRef for EmaRef {
79 fn key(&self) -> &str {
80 &self.key
81 }
82
83 fn required_indicators(&self) -> Vec<(String, Indicator)> {
84 vec![(self.key.clone(), Indicator::Ema(self.period))]
85 }
86
87 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
88 ctx.indicator(self.key())
89 }
90
91 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
92 ctx.indicator_prev(self.key())
93 }
94}
95
96#[inline]
98pub fn ema(period: usize) -> EmaRef {
99 EmaRef {
100 period,
101 key: format!("ema_{period}"),
102 }
103}
104
105#[derive(Debug, Clone)]
107pub struct WmaRef {
108 pub period: usize,
109 key: String,
110}
111
112impl IndicatorRef for WmaRef {
113 fn key(&self) -> &str {
114 &self.key
115 }
116
117 fn required_indicators(&self) -> Vec<(String, Indicator)> {
118 vec![(self.key.clone(), Indicator::Wma(self.period))]
119 }
120
121 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
122 ctx.indicator(self.key())
123 }
124
125 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
126 ctx.indicator_prev(self.key())
127 }
128}
129
130#[inline]
132pub fn wma(period: usize) -> WmaRef {
133 WmaRef {
134 period,
135 key: format!("wma_{period}"),
136 }
137}
138
139#[derive(Debug, Clone)]
141pub struct DemaRef {
142 pub period: usize,
143 key: String,
144}
145
146impl IndicatorRef for DemaRef {
147 fn key(&self) -> &str {
148 &self.key
149 }
150
151 fn required_indicators(&self) -> Vec<(String, Indicator)> {
152 vec![(self.key.clone(), Indicator::Dema(self.period))]
153 }
154
155 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
156 ctx.indicator(self.key())
157 }
158
159 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
160 ctx.indicator_prev(self.key())
161 }
162}
163
164#[inline]
166pub fn dema(period: usize) -> DemaRef {
167 DemaRef {
168 period,
169 key: format!("dema_{period}"),
170 }
171}
172
173#[derive(Debug, Clone)]
175pub struct TemaRef {
176 pub period: usize,
177 key: String,
178}
179
180impl IndicatorRef for TemaRef {
181 fn key(&self) -> &str {
182 &self.key
183 }
184
185 fn required_indicators(&self) -> Vec<(String, Indicator)> {
186 vec![(self.key.clone(), Indicator::Tema(self.period))]
187 }
188
189 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
190 ctx.indicator(self.key())
191 }
192
193 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
194 ctx.indicator_prev(self.key())
195 }
196}
197
198#[inline]
200pub fn tema(period: usize) -> TemaRef {
201 TemaRef {
202 period,
203 key: format!("tema_{period}"),
204 }
205}
206
207#[derive(Debug, Clone)]
209pub struct HmaRef {
210 pub period: usize,
211 key: String,
212}
213
214impl IndicatorRef for HmaRef {
215 fn key(&self) -> &str {
216 &self.key
217 }
218
219 fn required_indicators(&self) -> Vec<(String, Indicator)> {
220 vec![(self.key.clone(), Indicator::Hma(self.period))]
221 }
222
223 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
224 ctx.indicator(self.key())
225 }
226
227 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
228 ctx.indicator_prev(self.key())
229 }
230}
231
232#[inline]
234pub fn hma(period: usize) -> HmaRef {
235 HmaRef {
236 period,
237 key: format!("hma_{period}"),
238 }
239}
240
241#[derive(Debug, Clone)]
243pub struct VwmaRef {
244 pub period: usize,
245 key: String,
246}
247
248impl IndicatorRef for VwmaRef {
249 fn key(&self) -> &str {
250 &self.key
251 }
252
253 fn required_indicators(&self) -> Vec<(String, Indicator)> {
254 vec![(self.key.clone(), Indicator::Vwma(self.period))]
255 }
256
257 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
258 ctx.indicator(self.key())
259 }
260
261 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
262 ctx.indicator_prev(self.key())
263 }
264}
265
266#[inline]
268pub fn vwma(period: usize) -> VwmaRef {
269 VwmaRef {
270 period,
271 key: format!("vwma_{period}"),
272 }
273}
274
275#[derive(Debug, Clone)]
277pub struct McginleyDynamicRef {
278 pub period: usize,
279 key: String,
280}
281
282impl IndicatorRef for McginleyDynamicRef {
283 fn key(&self) -> &str {
284 &self.key
285 }
286
287 fn required_indicators(&self) -> Vec<(String, Indicator)> {
288 vec![(self.key.clone(), Indicator::McginleyDynamic(self.period))]
289 }
290
291 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
292 ctx.indicator(self.key())
293 }
294
295 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
296 ctx.indicator_prev(self.key())
297 }
298}
299
300#[inline]
302pub fn mcginley(period: usize) -> McginleyDynamicRef {
303 McginleyDynamicRef {
304 period,
305 key: format!("mcginley_{period}"),
306 }
307}
308
309#[derive(Debug, Clone)]
315pub struct RsiRef {
316 pub period: usize,
317 key: String,
318}
319
320impl IndicatorRef for RsiRef {
321 fn key(&self) -> &str {
322 &self.key
323 }
324
325 fn required_indicators(&self) -> Vec<(String, Indicator)> {
326 vec![(self.key.clone(), Indicator::Rsi(self.period))]
327 }
328
329 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
330 ctx.indicator(self.key())
331 }
332
333 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
334 ctx.indicator_prev(self.key())
335 }
336}
337
338#[inline]
350pub fn rsi(period: usize) -> RsiRef {
351 RsiRef {
352 period,
353 key: format!("rsi_{period}"),
354 }
355}
356
357#[derive(Debug, Clone)]
359pub struct CciRef {
360 pub period: usize,
361 key: String,
362}
363
364impl IndicatorRef for CciRef {
365 fn key(&self) -> &str {
366 &self.key
367 }
368
369 fn required_indicators(&self) -> Vec<(String, Indicator)> {
370 vec![(self.key.clone(), Indicator::Cci(self.period))]
371 }
372
373 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
374 ctx.indicator(self.key())
375 }
376
377 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
378 ctx.indicator_prev(self.key())
379 }
380}
381
382#[inline]
384pub fn cci(period: usize) -> CciRef {
385 CciRef {
386 period,
387 key: format!("cci_{period}"),
388 }
389}
390
391#[derive(Debug, Clone)]
393pub struct WilliamsRRef {
394 pub period: usize,
395 key: String,
396}
397
398impl IndicatorRef for WilliamsRRef {
399 fn key(&self) -> &str {
400 &self.key
401 }
402
403 fn required_indicators(&self) -> Vec<(String, Indicator)> {
404 vec![(self.key.clone(), Indicator::WilliamsR(self.period))]
405 }
406
407 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
408 ctx.indicator(self.key())
409 }
410
411 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
412 ctx.indicator_prev(self.key())
413 }
414}
415
416#[inline]
418pub fn williams_r(period: usize) -> WilliamsRRef {
419 WilliamsRRef {
420 period,
421 key: format!("williams_r_{period}"),
422 }
423}
424
425#[derive(Debug, Clone)]
427pub struct CmoRef {
428 pub period: usize,
429 key: String,
430}
431
432impl IndicatorRef for CmoRef {
433 fn key(&self) -> &str {
434 &self.key
435 }
436
437 fn required_indicators(&self) -> Vec<(String, Indicator)> {
438 vec![(self.key.clone(), Indicator::Cmo(self.period))]
439 }
440
441 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
442 ctx.indicator(self.key())
443 }
444
445 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
446 ctx.indicator_prev(self.key())
447 }
448}
449
450#[inline]
452pub fn cmo(period: usize) -> CmoRef {
453 CmoRef {
454 period,
455 key: format!("cmo_{period}"),
456 }
457}
458
459#[derive(Debug, Clone)]
465pub struct MomentumRef {
466 pub period: usize,
467 key: String,
468}
469
470impl IndicatorRef for MomentumRef {
471 fn key(&self) -> &str {
472 &self.key
473 }
474
475 fn required_indicators(&self) -> Vec<(String, Indicator)> {
476 vec![(self.key.clone(), Indicator::Momentum(self.period))]
477 }
478
479 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
480 ctx.indicator(self.key())
481 }
482
483 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
484 ctx.indicator_prev(self.key())
485 }
486}
487
488#[inline]
490pub fn momentum(period: usize) -> MomentumRef {
491 MomentumRef {
492 period,
493 key: format!("momentum_{period}"),
494 }
495}
496
497#[derive(Debug, Clone)]
499pub struct RocRef {
500 pub period: usize,
501 key: String,
502}
503
504impl IndicatorRef for RocRef {
505 fn key(&self) -> &str {
506 &self.key
507 }
508
509 fn required_indicators(&self) -> Vec<(String, Indicator)> {
510 vec![(self.key.clone(), Indicator::Roc(self.period))]
511 }
512
513 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
514 ctx.indicator(self.key())
515 }
516
517 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
518 ctx.indicator_prev(self.key())
519 }
520}
521
522#[inline]
524pub fn roc(period: usize) -> RocRef {
525 RocRef {
526 period,
527 key: format!("roc_{period}"),
528 }
529}
530
531#[derive(Debug, Clone)]
537pub struct AdxRef {
538 pub period: usize,
539 key: String,
540}
541
542impl IndicatorRef for AdxRef {
543 fn key(&self) -> &str {
544 &self.key
545 }
546
547 fn required_indicators(&self) -> Vec<(String, Indicator)> {
548 vec![(self.key.clone(), Indicator::Adx(self.period))]
549 }
550
551 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
552 ctx.indicator(self.key())
553 }
554
555 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
556 ctx.indicator_prev(self.key())
557 }
558}
559
560#[inline]
571pub fn adx(period: usize) -> AdxRef {
572 AdxRef {
573 period,
574 key: format!("adx_{period}"),
575 }
576}
577
578#[derive(Debug, Clone)]
584pub struct AtrRef {
585 pub period: usize,
586 key: String,
587}
588
589impl IndicatorRef for AtrRef {
590 fn key(&self) -> &str {
591 &self.key
592 }
593
594 fn required_indicators(&self) -> Vec<(String, Indicator)> {
595 vec![(self.key.clone(), Indicator::Atr(self.period))]
596 }
597
598 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
599 ctx.indicator(self.key())
600 }
601
602 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
603 ctx.indicator_prev(self.key())
604 }
605}
606
607#[inline]
609pub fn atr(period: usize) -> AtrRef {
610 AtrRef {
611 period,
612 key: format!("atr_{period}"),
613 }
614}
615
616#[derive(Debug, Clone, Copy)]
622pub struct ObvRef;
623
624impl IndicatorRef for ObvRef {
625 fn key(&self) -> &str {
626 "obv"
627 }
628
629 fn required_indicators(&self) -> Vec<(String, Indicator)> {
630 vec![("obv".to_string(), Indicator::Obv)]
631 }
632
633 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
634 ctx.indicator(self.key())
635 }
636
637 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
638 ctx.indicator_prev(self.key())
639 }
640}
641
642#[inline]
644pub fn obv() -> ObvRef {
645 ObvRef
646}
647
648#[derive(Debug, Clone, Copy)]
650pub struct VwapRef;
651
652impl IndicatorRef for VwapRef {
653 fn key(&self) -> &str {
654 "vwap"
655 }
656
657 fn required_indicators(&self) -> Vec<(String, Indicator)> {
658 vec![("vwap".to_string(), Indicator::Vwap)]
659 }
660
661 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
662 ctx.indicator(self.key())
663 }
664
665 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
666 ctx.indicator_prev(self.key())
667 }
668}
669
670#[inline]
672pub fn vwap() -> VwapRef {
673 VwapRef
674}
675
676#[derive(Debug, Clone)]
678pub struct MfiRef {
679 pub period: usize,
680 key: String,
681}
682
683impl IndicatorRef for MfiRef {
684 fn key(&self) -> &str {
685 &self.key
686 }
687
688 fn required_indicators(&self) -> Vec<(String, Indicator)> {
689 vec![(self.key.clone(), Indicator::Mfi(self.period))]
690 }
691
692 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
693 ctx.indicator(self.key())
694 }
695
696 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
697 ctx.indicator_prev(self.key())
698 }
699}
700
701#[inline]
703pub fn mfi(period: usize) -> MfiRef {
704 MfiRef {
705 period,
706 key: format!("mfi_{period}"),
707 }
708}
709
710#[derive(Debug, Clone)]
712pub struct CmfRef {
713 pub period: usize,
714 key: String,
715}
716
717impl IndicatorRef for CmfRef {
718 fn key(&self) -> &str {
719 &self.key
720 }
721
722 fn required_indicators(&self) -> Vec<(String, Indicator)> {
723 vec![(self.key.clone(), Indicator::Cmf(self.period))]
724 }
725
726 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
727 ctx.indicator(self.key())
728 }
729
730 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
731 ctx.indicator_prev(self.key())
732 }
733}
734
735#[inline]
737pub fn cmf(period: usize) -> CmfRef {
738 CmfRef {
739 period,
740 key: format!("cmf_{period}"),
741 }
742}
743
744#[derive(Debug, Clone, Copy)]
752pub struct MacdConfig {
753 pub fast: usize,
755 pub slow: usize,
757 pub signal: usize,
759}
760
761impl MacdConfig {
762 pub fn line(&self) -> MacdLineRef {
764 MacdLineRef::new(self.fast, self.slow, self.signal)
765 }
766
767 pub fn signal_line(&self) -> MacdSignalRef {
769 MacdSignalRef::new(self.fast, self.slow, self.signal)
770 }
771
772 pub fn histogram(&self) -> MacdHistogramRef {
774 MacdHistogramRef::new(self.fast, self.slow, self.signal)
775 }
776}
777
778#[inline]
790pub fn macd(fast: usize, slow: usize, signal: usize) -> MacdConfig {
791 MacdConfig { fast, slow, signal }
792}
793
794#[derive(Debug, Clone)]
796pub struct MacdLineRef {
797 pub fast: usize,
799 pub slow: usize,
801 pub signal: usize,
803 key: String,
804}
805
806impl MacdLineRef {
807 fn new(fast: usize, slow: usize, signal: usize) -> Self {
808 Self {
809 fast,
810 slow,
811 signal,
812 key: format!("macd_line_{fast}_{slow}_{signal}"),
813 }
814 }
815}
816
817impl IndicatorRef for MacdLineRef {
818 fn key(&self) -> &str {
819 &self.key
820 }
821
822 fn required_indicators(&self) -> Vec<(String, Indicator)> {
823 vec![(
824 self.key.clone(),
825 Indicator::Macd {
826 fast: self.fast,
827 slow: self.slow,
828 signal: self.signal,
829 },
830 )]
831 }
832
833 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
834 ctx.indicator(self.key())
835 }
836
837 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
838 ctx.indicator_prev(self.key())
839 }
840}
841
842#[derive(Debug, Clone)]
844pub struct MacdSignalRef {
845 pub fast: usize,
847 pub slow: usize,
849 pub signal: usize,
851 key: String,
852}
853
854impl MacdSignalRef {
855 fn new(fast: usize, slow: usize, signal: usize) -> Self {
856 Self {
857 fast,
858 slow,
859 signal,
860 key: format!("macd_signal_{fast}_{slow}_{signal}"),
861 }
862 }
863}
864
865impl IndicatorRef for MacdSignalRef {
866 fn key(&self) -> &str {
867 &self.key
868 }
869
870 fn required_indicators(&self) -> Vec<(String, Indicator)> {
871 vec![(
872 self.key.clone(),
873 Indicator::Macd {
874 fast: self.fast,
875 slow: self.slow,
876 signal: self.signal,
877 },
878 )]
879 }
880
881 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
882 ctx.indicator(self.key())
883 }
884
885 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
886 ctx.indicator_prev(self.key())
887 }
888}
889
890#[derive(Debug, Clone)]
892pub struct MacdHistogramRef {
893 pub fast: usize,
895 pub slow: usize,
897 pub signal: usize,
899 key: String,
900}
901
902impl MacdHistogramRef {
903 fn new(fast: usize, slow: usize, signal: usize) -> Self {
904 Self {
905 fast,
906 slow,
907 signal,
908 key: format!("macd_histogram_{fast}_{slow}_{signal}"),
909 }
910 }
911}
912
913impl IndicatorRef for MacdHistogramRef {
914 fn key(&self) -> &str {
915 &self.key
916 }
917
918 fn required_indicators(&self) -> Vec<(String, Indicator)> {
919 vec![(
920 self.key.clone(),
921 Indicator::Macd {
922 fast: self.fast,
923 slow: self.slow,
924 signal: self.signal,
925 },
926 )]
927 }
928
929 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
930 ctx.indicator(self.key())
931 }
932
933 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
934 ctx.indicator_prev(self.key())
935 }
936}
937
938#[derive(Debug, Clone, Copy)]
942pub struct BollingerConfig {
943 pub period: usize,
945 pub std_dev: f64,
947}
948
949impl BollingerConfig {
950 pub fn upper(&self) -> BollingerUpperRef {
952 BollingerUpperRef::new(self.period, self.std_dev)
953 }
954
955 pub fn middle(&self) -> BollingerMiddleRef {
957 BollingerMiddleRef::new(self.period, self.std_dev)
958 }
959
960 pub fn lower(&self) -> BollingerLowerRef {
962 BollingerLowerRef::new(self.period, self.std_dev)
963 }
964}
965
966#[inline]
978pub fn bollinger(period: usize, std_dev: f64) -> BollingerConfig {
979 BollingerConfig { period, std_dev }
980}
981
982#[derive(Debug, Clone)]
984pub struct BollingerUpperRef {
985 pub period: usize,
987 pub std_dev: f64,
989 key: String,
990}
991
992impl BollingerUpperRef {
993 fn new(period: usize, std_dev: f64) -> Self {
994 Self {
995 period,
996 std_dev,
997 key: format!("bollinger_upper_{period}_{std_dev}"),
998 }
999 }
1000}
1001
1002impl IndicatorRef for BollingerUpperRef {
1003 fn key(&self) -> &str {
1004 &self.key
1005 }
1006
1007 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1008 vec![(
1009 self.key.clone(),
1010 Indicator::Bollinger {
1011 period: self.period,
1012 std_dev: self.std_dev,
1013 },
1014 )]
1015 }
1016
1017 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1018 ctx.indicator(self.key())
1019 }
1020
1021 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1022 ctx.indicator_prev(self.key())
1023 }
1024}
1025
1026#[derive(Debug, Clone)]
1028pub struct BollingerMiddleRef {
1029 pub period: usize,
1031 pub std_dev: f64,
1033 key: String,
1034}
1035
1036impl BollingerMiddleRef {
1037 fn new(period: usize, std_dev: f64) -> Self {
1038 Self {
1039 period,
1040 std_dev,
1041 key: format!("bollinger_middle_{period}_{std_dev}"),
1042 }
1043 }
1044}
1045
1046impl IndicatorRef for BollingerMiddleRef {
1047 fn key(&self) -> &str {
1048 &self.key
1049 }
1050
1051 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1052 vec![(
1053 self.key.clone(),
1054 Indicator::Bollinger {
1055 period: self.period,
1056 std_dev: self.std_dev,
1057 },
1058 )]
1059 }
1060
1061 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1062 ctx.indicator(self.key())
1063 }
1064
1065 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1066 ctx.indicator_prev(self.key())
1067 }
1068}
1069
1070#[derive(Debug, Clone)]
1072pub struct BollingerLowerRef {
1073 pub period: usize,
1075 pub std_dev: f64,
1077 key: String,
1078}
1079
1080impl BollingerLowerRef {
1081 fn new(period: usize, std_dev: f64) -> Self {
1082 Self {
1083 period,
1084 std_dev,
1085 key: format!("bollinger_lower_{period}_{std_dev}"),
1086 }
1087 }
1088}
1089
1090impl IndicatorRef for BollingerLowerRef {
1091 fn key(&self) -> &str {
1092 &self.key
1093 }
1094
1095 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1096 vec![(
1097 self.key.clone(),
1098 Indicator::Bollinger {
1099 period: self.period,
1100 std_dev: self.std_dev,
1101 },
1102 )]
1103 }
1104
1105 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1106 ctx.indicator(self.key())
1107 }
1108
1109 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1110 ctx.indicator_prev(self.key())
1111 }
1112}
1113
1114#[derive(Debug, Clone, Copy)]
1118pub struct DonchianConfig {
1119 pub period: usize,
1120}
1121
1122impl DonchianConfig {
1123 pub fn upper(&self) -> DonchianUpperRef {
1125 DonchianUpperRef::new(self.period)
1126 }
1127
1128 pub fn middle(&self) -> DonchianMiddleRef {
1130 DonchianMiddleRef::new(self.period)
1131 }
1132
1133 pub fn lower(&self) -> DonchianLowerRef {
1135 DonchianLowerRef::new(self.period)
1136 }
1137}
1138
1139#[inline]
1141pub fn donchian(period: usize) -> DonchianConfig {
1142 DonchianConfig { period }
1143}
1144
1145#[derive(Debug, Clone)]
1147pub struct DonchianUpperRef {
1148 pub period: usize,
1149 key: String,
1150}
1151
1152impl DonchianUpperRef {
1153 fn new(period: usize) -> Self {
1154 Self {
1155 period,
1156 key: format!("donchian_upper_{period}"),
1157 }
1158 }
1159}
1160
1161impl IndicatorRef for DonchianUpperRef {
1162 fn key(&self) -> &str {
1163 &self.key
1164 }
1165
1166 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1167 vec![(self.key.clone(), Indicator::DonchianChannels(self.period))]
1168 }
1169
1170 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1171 ctx.indicator(self.key())
1172 }
1173
1174 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1175 ctx.indicator_prev(self.key())
1176 }
1177}
1178
1179#[derive(Debug, Clone)]
1181pub struct DonchianMiddleRef {
1182 pub period: usize,
1183 key: String,
1184}
1185
1186impl DonchianMiddleRef {
1187 fn new(period: usize) -> Self {
1188 Self {
1189 period,
1190 key: format!("donchian_middle_{period}"),
1191 }
1192 }
1193}
1194
1195impl IndicatorRef for DonchianMiddleRef {
1196 fn key(&self) -> &str {
1197 &self.key
1198 }
1199
1200 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1201 vec![(self.key.clone(), Indicator::DonchianChannels(self.period))]
1202 }
1203
1204 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1205 ctx.indicator(self.key())
1206 }
1207
1208 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1209 ctx.indicator_prev(self.key())
1210 }
1211}
1212
1213#[derive(Debug, Clone)]
1215pub struct DonchianLowerRef {
1216 pub period: usize,
1217 key: String,
1218}
1219
1220impl DonchianLowerRef {
1221 fn new(period: usize) -> Self {
1222 Self {
1223 period,
1224 key: format!("donchian_lower_{period}"),
1225 }
1226 }
1227}
1228
1229impl IndicatorRef for DonchianLowerRef {
1230 fn key(&self) -> &str {
1231 &self.key
1232 }
1233
1234 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1235 vec![(self.key.clone(), Indicator::DonchianChannels(self.period))]
1236 }
1237
1238 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1239 ctx.indicator(self.key())
1240 }
1241
1242 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1243 ctx.indicator_prev(self.key())
1244 }
1245}
1246
1247#[derive(Debug, Clone, Copy)]
1251pub struct SupertrendConfig {
1252 pub period: usize,
1253 pub multiplier: f64,
1254}
1255
1256impl SupertrendConfig {
1257 pub fn value(&self) -> SupertrendValueRef {
1259 SupertrendValueRef::new(self.period, self.multiplier)
1260 }
1261
1262 pub fn uptrend(&self) -> SupertrendUptrendRef {
1264 SupertrendUptrendRef::new(self.period, self.multiplier)
1265 }
1266}
1267
1268#[inline]
1270pub fn supertrend(period: usize, multiplier: f64) -> SupertrendConfig {
1271 SupertrendConfig { period, multiplier }
1272}
1273
1274#[derive(Debug, Clone)]
1276pub struct SupertrendValueRef {
1277 pub period: usize,
1278 pub multiplier: f64,
1279 key: String,
1280}
1281
1282impl SupertrendValueRef {
1283 fn new(period: usize, multiplier: f64) -> Self {
1284 Self {
1285 period,
1286 multiplier,
1287 key: format!("supertrend_value_{period}_{multiplier}"),
1288 }
1289 }
1290}
1291
1292impl IndicatorRef for SupertrendValueRef {
1293 fn key(&self) -> &str {
1294 &self.key
1295 }
1296
1297 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1298 vec![(
1299 self.key.clone(),
1300 Indicator::Supertrend {
1301 period: self.period,
1302 multiplier: self.multiplier,
1303 },
1304 )]
1305 }
1306
1307 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1308 ctx.indicator(self.key())
1309 }
1310
1311 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1312 ctx.indicator_prev(self.key())
1313 }
1314}
1315
1316#[derive(Debug, Clone)]
1319pub struct SupertrendUptrendRef {
1320 pub period: usize,
1321 pub multiplier: f64,
1322 key: String,
1323}
1324
1325impl SupertrendUptrendRef {
1326 fn new(period: usize, multiplier: f64) -> Self {
1327 Self {
1328 period,
1329 multiplier,
1330 key: format!("supertrend_uptrend_{period}_{multiplier}"),
1331 }
1332 }
1333}
1334
1335impl IndicatorRef for SupertrendUptrendRef {
1336 fn key(&self) -> &str {
1337 &self.key
1338 }
1339
1340 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1341 vec![(
1342 self.key.clone(),
1343 Indicator::Supertrend {
1344 period: self.period,
1345 multiplier: self.multiplier,
1346 },
1347 )]
1348 }
1349
1350 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1351 ctx.indicator(self.key())
1352 }
1353
1354 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1355 ctx.indicator_prev(self.key())
1356 }
1357}
1358
1359#[derive(Debug, Clone, Copy)]
1363pub struct StochasticConfig {
1364 pub k_period: usize,
1365 pub k_slow: usize,
1366 pub d_period: usize,
1367}
1368
1369impl StochasticConfig {
1370 pub fn k(&self) -> StochasticKRef {
1372 StochasticKRef::new(self.k_period, self.k_slow, self.d_period)
1373 }
1374
1375 pub fn d(&self) -> StochasticDRef {
1377 StochasticDRef::new(self.k_period, self.k_slow, self.d_period)
1378 }
1379}
1380
1381#[inline]
1383pub fn stochastic(k_period: usize, k_slow: usize, d_period: usize) -> StochasticConfig {
1384 StochasticConfig {
1385 k_period,
1386 k_slow,
1387 d_period,
1388 }
1389}
1390
1391#[derive(Debug, Clone)]
1393pub struct StochasticKRef {
1394 pub k_period: usize,
1395 pub k_slow: usize,
1396 pub d_period: usize,
1397 key: String,
1398}
1399
1400impl StochasticKRef {
1401 fn new(k_period: usize, k_slow: usize, d_period: usize) -> Self {
1402 Self {
1403 k_period,
1404 k_slow,
1405 d_period,
1406 key: format!("stochastic_k_{k_period}_{k_slow}_{d_period}"),
1407 }
1408 }
1409}
1410
1411impl IndicatorRef for StochasticKRef {
1412 fn key(&self) -> &str {
1413 &self.key
1414 }
1415
1416 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1417 vec![(
1418 self.key.clone(),
1419 Indicator::Stochastic {
1420 k_period: self.k_period,
1421 k_slow: self.k_slow,
1422 d_period: self.d_period,
1423 },
1424 )]
1425 }
1426
1427 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1428 ctx.indicator(self.key())
1429 }
1430
1431 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1432 ctx.indicator_prev(self.key())
1433 }
1434}
1435
1436#[derive(Debug, Clone)]
1438pub struct StochasticDRef {
1439 pub k_period: usize,
1440 pub k_slow: usize,
1441 pub d_period: usize,
1442 key: String,
1443}
1444
1445impl StochasticDRef {
1446 fn new(k_period: usize, k_slow: usize, d_period: usize) -> Self {
1447 Self {
1448 k_period,
1449 k_slow,
1450 d_period,
1451 key: format!("stochastic_d_{k_period}_{k_slow}_{d_period}"),
1452 }
1453 }
1454}
1455
1456impl IndicatorRef for StochasticDRef {
1457 fn key(&self) -> &str {
1458 &self.key
1459 }
1460
1461 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1462 vec![(
1463 self.key.clone(),
1464 Indicator::Stochastic {
1465 k_period: self.k_period,
1466 k_slow: self.k_slow,
1467 d_period: self.d_period,
1468 },
1469 )]
1470 }
1471
1472 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1473 ctx.indicator(self.key())
1474 }
1475
1476 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1477 ctx.indicator_prev(self.key())
1478 }
1479}
1480
1481#[derive(Debug, Clone, Copy)]
1485pub struct AroonConfig {
1486 pub period: usize,
1487}
1488
1489impl AroonConfig {
1490 pub fn up(&self) -> AroonUpRef {
1492 AroonUpRef::new(self.period)
1493 }
1494
1495 pub fn down(&self) -> AroonDownRef {
1497 AroonDownRef::new(self.period)
1498 }
1499}
1500
1501#[inline]
1503pub fn aroon(period: usize) -> AroonConfig {
1504 AroonConfig { period }
1505}
1506
1507#[derive(Debug, Clone)]
1509pub struct AroonUpRef {
1510 pub period: usize,
1511 key: String,
1512}
1513
1514impl AroonUpRef {
1515 fn new(period: usize) -> Self {
1516 Self {
1517 period,
1518 key: format!("aroon_up_{period}"),
1519 }
1520 }
1521}
1522
1523impl IndicatorRef for AroonUpRef {
1524 fn key(&self) -> &str {
1525 &self.key
1526 }
1527
1528 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1529 vec![(self.key.clone(), Indicator::Aroon(self.period))]
1530 }
1531
1532 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1533 ctx.indicator(self.key())
1534 }
1535
1536 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1537 ctx.indicator_prev(self.key())
1538 }
1539}
1540
1541#[derive(Debug, Clone)]
1543pub struct AroonDownRef {
1544 pub period: usize,
1545 key: String,
1546}
1547
1548impl AroonDownRef {
1549 fn new(period: usize) -> Self {
1550 Self {
1551 period,
1552 key: format!("aroon_down_{period}"),
1553 }
1554 }
1555}
1556
1557impl IndicatorRef for AroonDownRef {
1558 fn key(&self) -> &str {
1559 &self.key
1560 }
1561
1562 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1563 vec![(self.key.clone(), Indicator::Aroon(self.period))]
1564 }
1565
1566 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1567 ctx.indicator(self.key())
1568 }
1569
1570 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1571 ctx.indicator_prev(self.key())
1572 }
1573}
1574
1575#[derive(Debug, Clone, Copy)]
1579pub struct IchimokuConfig {
1580 pub conversion: usize,
1581 pub base: usize,
1582 pub lagging: usize,
1583 pub displacement: usize,
1584}
1585
1586impl IchimokuConfig {
1587 pub fn conversion_line(&self) -> IchimokuConversionRef {
1589 IchimokuConversionRef::new(self.conversion, self.base, self.lagging, self.displacement)
1590 }
1591
1592 pub fn base_line(&self) -> IchimokuBaseRef {
1594 IchimokuBaseRef::new(self.conversion, self.base, self.lagging, self.displacement)
1595 }
1596
1597 pub fn leading_span_a(&self) -> IchimokuLeadingARef {
1599 IchimokuLeadingARef::new(self.conversion, self.base, self.lagging, self.displacement)
1600 }
1601
1602 pub fn leading_span_b(&self) -> IchimokuLeadingBRef {
1604 IchimokuLeadingBRef::new(self.conversion, self.base, self.lagging, self.displacement)
1605 }
1606
1607 pub fn lagging_span(&self) -> IchimokuLaggingRef {
1609 IchimokuLaggingRef::new(self.conversion, self.base, self.lagging, self.displacement)
1610 }
1611}
1612
1613#[inline]
1615pub fn ichimoku() -> IchimokuConfig {
1616 IchimokuConfig {
1617 conversion: 9,
1618 base: 26,
1619 lagging: 52,
1620 displacement: 26,
1621 }
1622}
1623
1624#[inline]
1626pub fn ichimoku_custom(
1627 conversion: usize,
1628 base: usize,
1629 lagging: usize,
1630 displacement: usize,
1631) -> IchimokuConfig {
1632 IchimokuConfig {
1633 conversion,
1634 base,
1635 lagging,
1636 displacement,
1637 }
1638}
1639
1640#[derive(Debug, Clone)]
1642pub struct IchimokuConversionRef {
1643 pub conversion: usize,
1644 pub base: usize,
1645 pub lagging: usize,
1646 pub displacement: usize,
1647 key: String,
1648}
1649
1650impl IchimokuConversionRef {
1651 fn new(conversion: usize, base: usize, lagging: usize, displacement: usize) -> Self {
1652 Self {
1653 conversion,
1654 base,
1655 lagging,
1656 displacement,
1657 key: format!("ichimoku_conversion_{conversion}_{base}_{lagging}_{displacement}"),
1658 }
1659 }
1660}
1661
1662impl IndicatorRef for IchimokuConversionRef {
1663 fn key(&self) -> &str {
1664 &self.key
1665 }
1666
1667 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1668 vec![(
1669 self.key.clone(),
1670 Indicator::Ichimoku {
1671 conversion: self.conversion,
1672 base: self.base,
1673 lagging: self.lagging,
1674 displacement: self.displacement,
1675 },
1676 )]
1677 }
1678
1679 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1680 ctx.indicator(self.key())
1681 }
1682
1683 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1684 ctx.indicator_prev(self.key())
1685 }
1686}
1687
1688#[derive(Debug, Clone)]
1690pub struct IchimokuBaseRef {
1691 pub conversion: usize,
1692 pub base: usize,
1693 pub lagging: usize,
1694 pub displacement: usize,
1695 key: String,
1696}
1697
1698impl IchimokuBaseRef {
1699 fn new(conversion: usize, base: usize, lagging: usize, displacement: usize) -> Self {
1700 Self {
1701 conversion,
1702 base,
1703 lagging,
1704 displacement,
1705 key: format!("ichimoku_base_{conversion}_{base}_{lagging}_{displacement}"),
1706 }
1707 }
1708}
1709
1710impl IndicatorRef for IchimokuBaseRef {
1711 fn key(&self) -> &str {
1712 &self.key
1713 }
1714
1715 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1716 vec![(
1717 self.key.clone(),
1718 Indicator::Ichimoku {
1719 conversion: self.conversion,
1720 base: self.base,
1721 lagging: self.lagging,
1722 displacement: self.displacement,
1723 },
1724 )]
1725 }
1726
1727 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1728 ctx.indicator(self.key())
1729 }
1730
1731 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1732 ctx.indicator_prev(self.key())
1733 }
1734}
1735
1736#[derive(Debug, Clone)]
1738pub struct IchimokuLeadingARef {
1739 pub conversion: usize,
1740 pub base: usize,
1741 pub lagging: usize,
1742 pub displacement: usize,
1743 key: String,
1744}
1745
1746impl IchimokuLeadingARef {
1747 fn new(conversion: usize, base: usize, lagging: usize, displacement: usize) -> Self {
1748 Self {
1749 conversion,
1750 base,
1751 lagging,
1752 displacement,
1753 key: format!("ichimoku_leading_a_{conversion}_{base}_{lagging}_{displacement}"),
1754 }
1755 }
1756}
1757
1758impl IndicatorRef for IchimokuLeadingARef {
1759 fn key(&self) -> &str {
1760 &self.key
1761 }
1762
1763 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1764 vec![(
1765 self.key.clone(),
1766 Indicator::Ichimoku {
1767 conversion: self.conversion,
1768 base: self.base,
1769 lagging: self.lagging,
1770 displacement: self.displacement,
1771 },
1772 )]
1773 }
1774
1775 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1776 ctx.indicator(self.key())
1777 }
1778
1779 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1780 ctx.indicator_prev(self.key())
1781 }
1782}
1783
1784#[derive(Debug, Clone)]
1786pub struct IchimokuLeadingBRef {
1787 pub conversion: usize,
1788 pub base: usize,
1789 pub lagging: usize,
1790 pub displacement: usize,
1791 key: String,
1792}
1793
1794impl IchimokuLeadingBRef {
1795 fn new(conversion: usize, base: usize, lagging: usize, displacement: usize) -> Self {
1796 Self {
1797 conversion,
1798 base,
1799 lagging,
1800 displacement,
1801 key: format!("ichimoku_leading_b_{conversion}_{base}_{lagging}_{displacement}"),
1802 }
1803 }
1804}
1805
1806impl IndicatorRef for IchimokuLeadingBRef {
1807 fn key(&self) -> &str {
1808 &self.key
1809 }
1810
1811 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1812 vec![(
1813 self.key.clone(),
1814 Indicator::Ichimoku {
1815 conversion: self.conversion,
1816 base: self.base,
1817 lagging: self.lagging,
1818 displacement: self.displacement,
1819 },
1820 )]
1821 }
1822
1823 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1824 ctx.indicator(self.key())
1825 }
1826
1827 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1828 ctx.indicator_prev(self.key())
1829 }
1830}
1831
1832#[derive(Debug, Clone)]
1834pub struct IchimokuLaggingRef {
1835 pub conversion: usize,
1836 pub base: usize,
1837 pub lagging: usize,
1838 pub displacement: usize,
1839 key: String,
1840}
1841
1842impl IchimokuLaggingRef {
1843 fn new(conversion: usize, base: usize, lagging: usize, displacement: usize) -> Self {
1844 Self {
1845 conversion,
1846 base,
1847 lagging,
1848 displacement,
1849 key: format!("ichimoku_lagging_{conversion}_{base}_{lagging}_{displacement}"),
1850 }
1851 }
1852}
1853
1854impl IndicatorRef for IchimokuLaggingRef {
1855 fn key(&self) -> &str {
1856 &self.key
1857 }
1858
1859 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1860 vec![(
1861 self.key.clone(),
1862 Indicator::Ichimoku {
1863 conversion: self.conversion,
1864 base: self.base,
1865 lagging: self.lagging,
1866 displacement: self.displacement,
1867 },
1868 )]
1869 }
1870
1871 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1872 ctx.indicator(self.key())
1873 }
1874
1875 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1876 ctx.indicator_prev(self.key())
1877 }
1878}
1879
1880#[derive(Debug, Clone, Copy)]
1884pub struct KeltnerConfig {
1885 pub period: usize,
1886 pub multiplier: f64,
1887 pub atr_period: usize,
1888}
1889
1890impl KeltnerConfig {
1891 pub fn upper(&self) -> KeltnerUpperRef {
1893 KeltnerUpperRef::new(self.period, self.multiplier, self.atr_period)
1894 }
1895
1896 pub fn middle(&self) -> KeltnerMiddleRef {
1898 KeltnerMiddleRef::new(self.period, self.multiplier, self.atr_period)
1899 }
1900
1901 pub fn lower(&self) -> KeltnerLowerRef {
1903 KeltnerLowerRef::new(self.period, self.multiplier, self.atr_period)
1904 }
1905}
1906
1907#[inline]
1909pub fn keltner(period: usize, multiplier: f64, atr_period: usize) -> KeltnerConfig {
1910 KeltnerConfig {
1911 period,
1912 multiplier,
1913 atr_period,
1914 }
1915}
1916
1917#[derive(Debug, Clone)]
1919pub struct KeltnerUpperRef {
1920 pub period: usize,
1921 pub multiplier: f64,
1922 pub atr_period: usize,
1923 key: String,
1924}
1925
1926impl KeltnerUpperRef {
1927 fn new(period: usize, multiplier: f64, atr_period: usize) -> Self {
1928 Self {
1929 period,
1930 multiplier,
1931 atr_period,
1932 key: format!("keltner_upper_{period}_{multiplier}_{atr_period}"),
1933 }
1934 }
1935}
1936
1937impl IndicatorRef for KeltnerUpperRef {
1938 fn key(&self) -> &str {
1939 &self.key
1940 }
1941
1942 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1943 vec![(
1944 self.key.clone(),
1945 Indicator::KeltnerChannels {
1946 period: self.period,
1947 multiplier: self.multiplier,
1948 atr_period: self.atr_period,
1949 },
1950 )]
1951 }
1952
1953 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1954 ctx.indicator(self.key())
1955 }
1956
1957 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1958 ctx.indicator_prev(self.key())
1959 }
1960}
1961
1962#[derive(Debug, Clone)]
1964pub struct KeltnerMiddleRef {
1965 pub period: usize,
1966 pub multiplier: f64,
1967 pub atr_period: usize,
1968 key: String,
1969}
1970
1971impl KeltnerMiddleRef {
1972 fn new(period: usize, multiplier: f64, atr_period: usize) -> Self {
1973 Self {
1974 period,
1975 multiplier,
1976 atr_period,
1977 key: format!("keltner_middle_{period}_{multiplier}_{atr_period}"),
1978 }
1979 }
1980}
1981
1982impl IndicatorRef for KeltnerMiddleRef {
1983 fn key(&self) -> &str {
1984 &self.key
1985 }
1986
1987 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1988 vec![(
1989 self.key.clone(),
1990 Indicator::KeltnerChannels {
1991 period: self.period,
1992 multiplier: self.multiplier,
1993 atr_period: self.atr_period,
1994 },
1995 )]
1996 }
1997
1998 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1999 ctx.indicator(self.key())
2000 }
2001
2002 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2003 ctx.indicator_prev(self.key())
2004 }
2005}
2006
2007#[derive(Debug, Clone)]
2009pub struct KeltnerLowerRef {
2010 pub period: usize,
2011 pub multiplier: f64,
2012 pub atr_period: usize,
2013 key: String,
2014}
2015
2016impl KeltnerLowerRef {
2017 fn new(period: usize, multiplier: f64, atr_period: usize) -> Self {
2018 Self {
2019 period,
2020 multiplier,
2021 atr_period,
2022 key: format!("keltner_lower_{period}_{multiplier}_{atr_period}"),
2023 }
2024 }
2025}
2026
2027impl IndicatorRef for KeltnerLowerRef {
2028 fn key(&self) -> &str {
2029 &self.key
2030 }
2031
2032 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2033 vec![(
2034 self.key.clone(),
2035 Indicator::KeltnerChannels {
2036 period: self.period,
2037 multiplier: self.multiplier,
2038 atr_period: self.atr_period,
2039 },
2040 )]
2041 }
2042
2043 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2044 ctx.indicator(self.key())
2045 }
2046
2047 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2048 ctx.indicator_prev(self.key())
2049 }
2050}
2051
2052#[derive(Debug, Clone, Copy)]
2056pub struct ParabolicSarConfig {
2057 pub step: f64,
2058 pub max: f64,
2059}
2060
2061#[inline]
2063pub fn parabolic_sar(step: f64, max: f64) -> ParabolicSarRef {
2064 ParabolicSarRef::new(step, max)
2065}
2066
2067#[derive(Debug, Clone)]
2069pub struct ParabolicSarRef {
2070 pub step: f64,
2071 pub max: f64,
2072 key: String,
2073}
2074
2075impl ParabolicSarRef {
2076 fn new(step: f64, max: f64) -> Self {
2077 Self {
2078 step,
2079 max,
2080 key: format!("psar_{step}_{max}"),
2081 }
2082 }
2083}
2084
2085impl IndicatorRef for ParabolicSarRef {
2086 fn key(&self) -> &str {
2087 &self.key
2088 }
2089
2090 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2091 vec![(
2092 self.key.clone(),
2093 Indicator::ParabolicSar {
2094 step: self.step,
2095 max: self.max,
2096 },
2097 )]
2098 }
2099
2100 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2101 ctx.indicator(self.key())
2102 }
2103
2104 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2105 ctx.indicator_prev(self.key())
2106 }
2107}
2108
2109#[derive(Debug, Clone, Copy)]
2113pub struct AlmaConfig {
2114 pub period: usize,
2115 pub offset: f64,
2116 pub sigma: f64,
2117}
2118
2119#[inline]
2121pub fn alma(period: usize, offset: f64, sigma: f64) -> AlmaRef {
2122 AlmaRef::new(period, offset, sigma)
2123}
2124
2125#[derive(Debug, Clone)]
2127pub struct AlmaRef {
2128 pub period: usize,
2129 pub offset: f64,
2130 pub sigma: f64,
2131 key: String,
2132}
2133
2134impl AlmaRef {
2135 fn new(period: usize, offset: f64, sigma: f64) -> Self {
2136 Self {
2137 period,
2138 offset,
2139 sigma,
2140 key: format!("alma_{period}_{offset}_{sigma}"),
2141 }
2142 }
2143}
2144
2145impl IndicatorRef for AlmaRef {
2146 fn key(&self) -> &str {
2147 &self.key
2148 }
2149
2150 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2151 vec![(
2152 self.key.clone(),
2153 Indicator::Alma {
2154 period: self.period,
2155 offset: self.offset,
2156 sigma: self.sigma,
2157 },
2158 )]
2159 }
2160
2161 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2162 ctx.indicator(self.key())
2163 }
2164
2165 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2166 ctx.indicator_prev(self.key())
2167 }
2168}
2169
2170#[derive(Debug, Clone, Copy)]
2190pub struct StochasticRsiConfig {
2191 pub rsi_period: usize,
2192 pub stoch_period: usize,
2193 pub k_period: usize,
2194 pub d_period: usize,
2195}
2196
2197impl StochasticRsiConfig {
2198 pub fn k(&self) -> StochasticRsiRef {
2200 StochasticRsiRef::new(
2201 self.rsi_period,
2202 self.stoch_period,
2203 self.k_period,
2204 self.d_period,
2205 )
2206 }
2207
2208 pub fn d(&self) -> StochasticRsiDRef {
2210 StochasticRsiDRef::new(
2211 self.rsi_period,
2212 self.stoch_period,
2213 self.k_period,
2214 self.d_period,
2215 )
2216 }
2217}
2218
2219#[inline]
2226pub fn stochastic_rsi(
2227 rsi_period: usize,
2228 stoch_period: usize,
2229 k_period: usize,
2230 d_period: usize,
2231) -> StochasticRsiConfig {
2232 StochasticRsiConfig {
2233 rsi_period,
2234 stoch_period,
2235 k_period,
2236 d_period,
2237 }
2238}
2239
2240#[derive(Debug, Clone)]
2242pub struct StochasticRsiRef {
2243 pub rsi_period: usize,
2244 pub stoch_period: usize,
2245 pub k_period: usize,
2246 pub d_period: usize,
2247 key: String,
2248}
2249
2250impl StochasticRsiRef {
2251 fn new(rsi_period: usize, stoch_period: usize, k_period: usize, d_period: usize) -> Self {
2252 Self {
2253 rsi_period,
2254 stoch_period,
2255 k_period,
2256 d_period,
2257 key: format!("stoch_rsi_k_{rsi_period}_{stoch_period}_{k_period}_{d_period}"),
2258 }
2259 }
2260}
2261
2262impl IndicatorRef for StochasticRsiRef {
2263 fn key(&self) -> &str {
2264 &self.key
2265 }
2266
2267 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2268 vec![(
2269 self.key.clone(),
2270 Indicator::StochasticRsi {
2271 rsi_period: self.rsi_period,
2272 stoch_period: self.stoch_period,
2273 k_period: self.k_period,
2274 d_period: self.d_period,
2275 },
2276 )]
2277 }
2278
2279 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2280 ctx.indicator(self.key())
2281 }
2282
2283 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2284 ctx.indicator_prev(self.key())
2285 }
2286}
2287
2288#[derive(Debug, Clone)]
2290pub struct StochasticRsiDRef {
2291 pub rsi_period: usize,
2292 pub stoch_period: usize,
2293 pub k_period: usize,
2294 pub d_period: usize,
2295 key: String,
2296}
2297
2298impl StochasticRsiDRef {
2299 fn new(rsi_period: usize, stoch_period: usize, k_period: usize, d_period: usize) -> Self {
2300 Self {
2301 rsi_period,
2302 stoch_period,
2303 k_period,
2304 d_period,
2305 key: format!("stoch_rsi_d_{rsi_period}_{stoch_period}_{k_period}_{d_period}"),
2306 }
2307 }
2308}
2309
2310impl IndicatorRef for StochasticRsiDRef {
2311 fn key(&self) -> &str {
2312 &self.key
2313 }
2314
2315 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2316 let k_key = format!(
2319 "stoch_rsi_k_{}_{}_{}_{}",
2320 self.rsi_period, self.stoch_period, self.k_period, self.d_period
2321 );
2322 vec![(
2323 k_key,
2324 Indicator::StochasticRsi {
2325 rsi_period: self.rsi_period,
2326 stoch_period: self.stoch_period,
2327 k_period: self.k_period,
2328 d_period: self.d_period,
2329 },
2330 )]
2331 }
2332
2333 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2334 ctx.indicator(self.key())
2335 }
2336
2337 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2338 ctx.indicator_prev(self.key())
2339 }
2340}
2341
2342#[derive(Debug, Clone)]
2346pub struct AwesomeOscillatorRef {
2347 pub fast: usize,
2348 pub slow: usize,
2349 key: String,
2350}
2351
2352#[inline]
2354pub fn awesome_oscillator(fast: usize, slow: usize) -> AwesomeOscillatorRef {
2355 AwesomeOscillatorRef {
2356 fast,
2357 slow,
2358 key: format!("ao_{fast}_{slow}"),
2359 }
2360}
2361
2362impl IndicatorRef for AwesomeOscillatorRef {
2363 fn key(&self) -> &str {
2364 &self.key
2365 }
2366
2367 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2368 vec![(
2369 self.key.clone(),
2370 Indicator::AwesomeOscillator {
2371 fast: self.fast,
2372 slow: self.slow,
2373 },
2374 )]
2375 }
2376
2377 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2378 ctx.indicator(self.key())
2379 }
2380
2381 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2382 ctx.indicator_prev(self.key())
2383 }
2384}
2385
2386#[derive(Debug, Clone)]
2390pub struct CoppockCurveRef {
2391 pub wma_period: usize,
2392 pub long_roc: usize,
2393 pub short_roc: usize,
2394 key: String,
2395}
2396
2397#[inline]
2399pub fn coppock_curve(wma_period: usize, long_roc: usize, short_roc: usize) -> CoppockCurveRef {
2400 CoppockCurveRef {
2401 wma_period,
2402 long_roc,
2403 short_roc,
2404 key: format!("coppock_{wma_period}_{long_roc}_{short_roc}"),
2405 }
2406}
2407
2408impl IndicatorRef for CoppockCurveRef {
2409 fn key(&self) -> &str {
2410 &self.key
2411 }
2412
2413 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2414 vec![(
2415 self.key.clone(),
2416 Indicator::CoppockCurve {
2417 wma_period: self.wma_period,
2418 long_roc: self.long_roc,
2419 short_roc: self.short_roc,
2420 },
2421 )]
2422 }
2423
2424 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2425 ctx.indicator(self.key())
2426 }
2427
2428 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2429 ctx.indicator_prev(self.key())
2430 }
2431}
2432
2433#[derive(Debug, Clone)]
2437pub struct ChoppinessIndexRef {
2438 pub period: usize,
2439 key: String,
2440}
2441
2442#[inline]
2444pub fn choppiness_index(period: usize) -> ChoppinessIndexRef {
2445 ChoppinessIndexRef {
2446 period,
2447 key: format!("chop_{period}"),
2448 }
2449}
2450
2451impl IndicatorRef for ChoppinessIndexRef {
2452 fn key(&self) -> &str {
2453 &self.key
2454 }
2455
2456 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2457 vec![(self.key.clone(), Indicator::ChoppinessIndex(self.period))]
2458 }
2459
2460 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2461 ctx.indicator(self.key())
2462 }
2463
2464 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2465 ctx.indicator_prev(self.key())
2466 }
2467}
2468
2469#[derive(Debug, Clone, Copy)]
2473pub struct TrueRangeRef;
2474
2475#[inline]
2477pub fn true_range() -> TrueRangeRef {
2478 TrueRangeRef
2479}
2480
2481impl IndicatorRef for TrueRangeRef {
2482 fn key(&self) -> &str {
2483 "true_range"
2484 }
2485
2486 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2487 vec![("true_range".to_string(), Indicator::TrueRange)]
2488 }
2489
2490 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2491 ctx.indicator(self.key())
2492 }
2493
2494 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2495 ctx.indicator_prev(self.key())
2496 }
2497}
2498
2499#[derive(Debug, Clone, Copy)]
2503pub struct ChaikinOscillatorRef;
2504
2505#[inline]
2507pub fn chaikin_oscillator() -> ChaikinOscillatorRef {
2508 ChaikinOscillatorRef
2509}
2510
2511impl IndicatorRef for ChaikinOscillatorRef {
2512 fn key(&self) -> &str {
2513 "chaikin_osc"
2514 }
2515
2516 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2517 vec![("chaikin_osc".to_string(), Indicator::ChaikinOscillator)]
2518 }
2519
2520 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2521 ctx.indicator(self.key())
2522 }
2523
2524 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2525 ctx.indicator_prev(self.key())
2526 }
2527}
2528
2529#[derive(Debug, Clone, Copy)]
2533pub struct AccumulationDistributionRef;
2534
2535#[inline]
2537pub fn accumulation_distribution() -> AccumulationDistributionRef {
2538 AccumulationDistributionRef
2539}
2540
2541impl IndicatorRef for AccumulationDistributionRef {
2542 fn key(&self) -> &str {
2543 "ad"
2544 }
2545
2546 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2547 vec![("ad".to_string(), Indicator::AccumulationDistribution)]
2548 }
2549
2550 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2551 ctx.indicator(self.key())
2552 }
2553
2554 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2555 ctx.indicator_prev(self.key())
2556 }
2557}
2558
2559#[derive(Debug, Clone)]
2563pub struct BalanceOfPowerRef {
2564 pub period: Option<usize>,
2565 key: String,
2566}
2567
2568#[inline]
2570pub fn balance_of_power(period: Option<usize>) -> BalanceOfPowerRef {
2571 let key = match period {
2572 Some(p) => format!("bop_{p}"),
2573 None => "bop".to_string(),
2574 };
2575 BalanceOfPowerRef { period, key }
2576}
2577
2578impl IndicatorRef for BalanceOfPowerRef {
2579 fn key(&self) -> &str {
2580 &self.key
2581 }
2582
2583 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2584 vec![(self.key.clone(), Indicator::BalanceOfPower(self.period))]
2585 }
2586
2587 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2588 ctx.indicator(self.key())
2589 }
2590
2591 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2592 ctx.indicator_prev(self.key())
2593 }
2594}
2595
2596#[derive(Debug, Clone)]
2600pub struct BullPowerRef {
2601 pub period: usize,
2602 key: String,
2603}
2604
2605#[inline]
2607pub fn bull_power(period: usize) -> BullPowerRef {
2608 BullPowerRef {
2609 period,
2610 key: format!("bull_power_{period}"),
2611 }
2612}
2613
2614impl IndicatorRef for BullPowerRef {
2615 fn key(&self) -> &str {
2616 &self.key
2617 }
2618
2619 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2620 vec![(self.key.clone(), Indicator::BullBearPower(self.period))]
2621 }
2622
2623 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2624 ctx.indicator(self.key())
2625 }
2626
2627 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2628 ctx.indicator_prev(self.key())
2629 }
2630}
2631
2632#[derive(Debug, Clone)]
2634pub struct BearPowerRef {
2635 pub period: usize,
2636 key: String,
2637}
2638
2639#[inline]
2641pub fn bear_power(period: usize) -> BearPowerRef {
2642 BearPowerRef {
2643 period,
2644 key: format!("bear_power_{period}"),
2645 }
2646}
2647
2648impl IndicatorRef for BearPowerRef {
2649 fn key(&self) -> &str {
2650 &self.key
2651 }
2652
2653 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2654 vec![(self.key.clone(), Indicator::BullBearPower(self.period))]
2655 }
2656
2657 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2658 ctx.indicator(self.key())
2659 }
2660
2661 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2662 ctx.indicator_prev(self.key())
2663 }
2664}
2665
2666#[derive(Debug, Clone)]
2670pub struct ElderBullPowerRef {
2671 pub period: usize,
2672 key: String,
2673}
2674
2675#[inline]
2677pub fn elder_bull_power(period: usize) -> ElderBullPowerRef {
2678 ElderBullPowerRef {
2679 period,
2680 key: format!("elder_bull_{period}"),
2681 }
2682}
2683
2684impl IndicatorRef for ElderBullPowerRef {
2685 fn key(&self) -> &str {
2686 &self.key
2687 }
2688
2689 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2690 vec![(self.key.clone(), Indicator::ElderRay(self.period))]
2691 }
2692
2693 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2694 ctx.indicator(self.key())
2695 }
2696
2697 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2698 ctx.indicator_prev(self.key())
2699 }
2700}
2701
2702#[derive(Debug, Clone)]
2704pub struct ElderBearPowerRef {
2705 pub period: usize,
2706 key: String,
2707}
2708
2709#[inline]
2711pub fn elder_bear_power(period: usize) -> ElderBearPowerRef {
2712 ElderBearPowerRef {
2713 period,
2714 key: format!("elder_bear_{period}"),
2715 }
2716}
2717
2718impl IndicatorRef for ElderBearPowerRef {
2719 fn key(&self) -> &str {
2720 &self.key
2721 }
2722
2723 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2724 vec![(self.key.clone(), Indicator::ElderRay(self.period))]
2725 }
2726
2727 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2728 ctx.indicator(self.key())
2729 }
2730
2731 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2732 ctx.indicator_prev(self.key())
2733 }
2734}
2735
2736#[cfg(test)]
2737mod tests {
2738 use super::*;
2739
2740 #[test]
2741 fn test_moving_average_keys() {
2742 assert_eq!(sma(20).key(), "sma_20");
2743 assert_eq!(ema(12).key(), "ema_12");
2744 assert_eq!(wma(14).key(), "wma_14");
2745 assert_eq!(dema(21).key(), "dema_21");
2746 assert_eq!(tema(21).key(), "tema_21");
2747 assert_eq!(hma(9).key(), "hma_9");
2748 assert_eq!(vwma(20).key(), "vwma_20");
2749 assert_eq!(mcginley(14).key(), "mcginley_14");
2750 assert_eq!(alma(9, 0.85, 6.0).key(), "alma_9_0.85_6");
2751 }
2752
2753 #[test]
2754 fn test_oscillator_keys() {
2755 assert_eq!(rsi(14).key(), "rsi_14");
2756 assert_eq!(cci(20).key(), "cci_20");
2757 assert_eq!(williams_r(14).key(), "williams_r_14");
2758 assert_eq!(cmo(14).key(), "cmo_14");
2759 assert_eq!(
2761 stochastic_rsi(14, 14, 3, 3).k().key(),
2762 "stoch_rsi_k_14_14_3_3"
2763 );
2764 assert_eq!(
2765 stochastic_rsi(14, 14, 3, 3).d().key(),
2766 "stoch_rsi_d_14_14_3_3"
2767 );
2768 assert_eq!(awesome_oscillator(5, 34).key(), "ao_5_34");
2769 assert_eq!(choppiness_index(14).key(), "chop_14");
2770 }
2771
2772 #[test]
2773 fn test_macd_keys() {
2774 let m = macd(12, 26, 9);
2775 assert_eq!(m.line().key(), "macd_line_12_26_9");
2776 assert_eq!(m.signal_line().key(), "macd_signal_12_26_9");
2777 assert_eq!(m.histogram().key(), "macd_histogram_12_26_9");
2778 }
2779
2780 #[test]
2781 fn test_bollinger_keys() {
2782 let bb = bollinger(20, 2.0);
2783 assert_eq!(bb.upper().key(), "bollinger_upper_20_2");
2784 assert_eq!(bb.middle().key(), "bollinger_middle_20_2");
2785 assert_eq!(bb.lower().key(), "bollinger_lower_20_2");
2786 }
2787
2788 #[test]
2789 fn test_donchian_keys() {
2790 let dc = donchian(20);
2791 assert_eq!(dc.upper().key(), "donchian_upper_20");
2792 assert_eq!(dc.middle().key(), "donchian_middle_20");
2793 assert_eq!(dc.lower().key(), "donchian_lower_20");
2794 }
2795
2796 #[test]
2797 fn test_supertrend_keys() {
2798 let st = supertrend(10, 3.0);
2799 assert_eq!(st.value().key(), "supertrend_value_10_3");
2800 assert_eq!(st.uptrend().key(), "supertrend_uptrend_10_3");
2801 }
2802
2803 #[test]
2804 fn test_stochastic_keys() {
2805 let stoch = stochastic(14, 3, 3);
2806 assert_eq!(stoch.k().key(), "stochastic_k_14_3_3");
2807 assert_eq!(stoch.d().key(), "stochastic_d_14_3_3");
2808 }
2809
2810 #[test]
2811 fn test_aroon_keys() {
2812 let ar = aroon(25);
2813 assert_eq!(ar.up().key(), "aroon_up_25");
2814 assert_eq!(ar.down().key(), "aroon_down_25");
2815 }
2816
2817 #[test]
2818 fn test_ichimoku_keys() {
2819 let ich = ichimoku();
2820 assert_eq!(
2821 ich.conversion_line().key(),
2822 "ichimoku_conversion_9_26_52_26"
2823 );
2824 assert_eq!(ich.base_line().key(), "ichimoku_base_9_26_52_26");
2825 assert_eq!(ich.leading_span_a().key(), "ichimoku_leading_a_9_26_52_26");
2826 assert_eq!(ich.leading_span_b().key(), "ichimoku_leading_b_9_26_52_26");
2827 assert_eq!(ich.lagging_span().key(), "ichimoku_lagging_9_26_52_26");
2828 }
2829
2830 #[test]
2831 fn test_keltner_keys() {
2832 let kc = keltner(20, 2.0, 10);
2833 assert_eq!(kc.upper().key(), "keltner_upper_20_2_10");
2834 assert_eq!(kc.middle().key(), "keltner_middle_20_2_10");
2835 assert_eq!(kc.lower().key(), "keltner_lower_20_2_10");
2836 }
2837
2838 #[test]
2839 fn test_volume_keys() {
2840 assert_eq!(obv().key(), "obv");
2841 assert_eq!(vwap().key(), "vwap");
2842 assert_eq!(mfi(14).key(), "mfi_14");
2843 assert_eq!(cmf(20).key(), "cmf_20");
2844 assert_eq!(chaikin_oscillator().key(), "chaikin_osc");
2845 assert_eq!(accumulation_distribution().key(), "ad");
2846 assert_eq!(balance_of_power(Some(14)).key(), "bop_14");
2847 assert_eq!(balance_of_power(None).key(), "bop");
2848 }
2849
2850 #[test]
2851 fn test_power_keys() {
2852 assert_eq!(bull_power(13).key(), "bull_power_13");
2853 assert_eq!(bear_power(13).key(), "bear_power_13");
2854 assert_eq!(elder_bull_power(13).key(), "elder_bull_13");
2855 assert_eq!(elder_bear_power(13).key(), "elder_bear_13");
2856 }
2857
2858 #[test]
2859 fn test_other_keys() {
2860 assert_eq!(parabolic_sar(0.02, 0.2).key(), "psar_0.02_0.2");
2861 assert_eq!(true_range().key(), "true_range");
2862 assert_eq!(coppock_curve(10, 14, 11).key(), "coppock_10_14_11");
2863 }
2864
2865 #[test]
2866 fn test_required_indicators() {
2867 let sma_ref = sma(20);
2868 let indicators = sma_ref.required_indicators();
2869 assert_eq!(indicators.len(), 1);
2870 assert_eq!(indicators[0].0, "sma_20");
2871 assert!(matches!(indicators[0].1, Indicator::Sma(20)));
2872 }
2873}