1#![allow(missing_docs)]
18
19use crate::backtesting::strategy::StrategyContext;
20use crate::indicators::Indicator;
21
22use super::IndicatorRef;
23
24#[derive(Debug, Clone, Copy)]
30pub struct SmaRef(pub usize);
31
32impl IndicatorRef for SmaRef {
33 fn key(&self) -> String {
34 format!("sma_{}", self.0)
35 }
36
37 fn required_indicators(&self) -> Vec<(String, Indicator)> {
38 vec![(self.key(), Indicator::Sma(self.0))]
39 }
40
41 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
42 ctx.indicator(&self.key())
43 }
44
45 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
46 ctx.indicator_prev(&self.key())
47 }
48}
49
50#[inline]
61pub fn sma(period: usize) -> SmaRef {
62 SmaRef(period)
63}
64
65#[derive(Debug, Clone, Copy)]
67pub struct EmaRef(pub usize);
68
69impl IndicatorRef for EmaRef {
70 fn key(&self) -> String {
71 format!("ema_{}", self.0)
72 }
73
74 fn required_indicators(&self) -> Vec<(String, Indicator)> {
75 vec![(self.key(), Indicator::Ema(self.0))]
76 }
77
78 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
79 ctx.indicator(&self.key())
80 }
81
82 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
83 ctx.indicator_prev(&self.key())
84 }
85}
86
87#[inline]
89pub fn ema(period: usize) -> EmaRef {
90 EmaRef(period)
91}
92
93#[derive(Debug, Clone, Copy)]
95pub struct WmaRef(pub usize);
96
97impl IndicatorRef for WmaRef {
98 fn key(&self) -> String {
99 format!("wma_{}", self.0)
100 }
101
102 fn required_indicators(&self) -> Vec<(String, Indicator)> {
103 vec![(self.key(), Indicator::Wma(self.0))]
104 }
105
106 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
107 ctx.indicator(&self.key())
108 }
109
110 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
111 ctx.indicator_prev(&self.key())
112 }
113}
114
115#[inline]
117pub fn wma(period: usize) -> WmaRef {
118 WmaRef(period)
119}
120
121#[derive(Debug, Clone, Copy)]
123pub struct DemaRef(pub usize);
124
125impl IndicatorRef for DemaRef {
126 fn key(&self) -> String {
127 format!("dema_{}", self.0)
128 }
129
130 fn required_indicators(&self) -> Vec<(String, Indicator)> {
131 vec![(self.key(), Indicator::Dema(self.0))]
132 }
133
134 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
135 ctx.indicator(&self.key())
136 }
137
138 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
139 ctx.indicator_prev(&self.key())
140 }
141}
142
143#[inline]
145pub fn dema(period: usize) -> DemaRef {
146 DemaRef(period)
147}
148
149#[derive(Debug, Clone, Copy)]
151pub struct TemaRef(pub usize);
152
153impl IndicatorRef for TemaRef {
154 fn key(&self) -> String {
155 format!("tema_{}", self.0)
156 }
157
158 fn required_indicators(&self) -> Vec<(String, Indicator)> {
159 vec![(self.key(), Indicator::Tema(self.0))]
160 }
161
162 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
163 ctx.indicator(&self.key())
164 }
165
166 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
167 ctx.indicator_prev(&self.key())
168 }
169}
170
171#[inline]
173pub fn tema(period: usize) -> TemaRef {
174 TemaRef(period)
175}
176
177#[derive(Debug, Clone, Copy)]
179pub struct HmaRef(pub usize);
180
181impl IndicatorRef for HmaRef {
182 fn key(&self) -> String {
183 format!("hma_{}", self.0)
184 }
185
186 fn required_indicators(&self) -> Vec<(String, Indicator)> {
187 vec![(self.key(), Indicator::Hma(self.0))]
188 }
189
190 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
191 ctx.indicator(&self.key())
192 }
193
194 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
195 ctx.indicator_prev(&self.key())
196 }
197}
198
199#[inline]
201pub fn hma(period: usize) -> HmaRef {
202 HmaRef(period)
203}
204
205#[derive(Debug, Clone, Copy)]
207pub struct VwmaRef(pub usize);
208
209impl IndicatorRef for VwmaRef {
210 fn key(&self) -> String {
211 format!("vwma_{}", self.0)
212 }
213
214 fn required_indicators(&self) -> Vec<(String, Indicator)> {
215 vec![(self.key(), Indicator::Vwma(self.0))]
216 }
217
218 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
219 ctx.indicator(&self.key())
220 }
221
222 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
223 ctx.indicator_prev(&self.key())
224 }
225}
226
227#[inline]
229pub fn vwma(period: usize) -> VwmaRef {
230 VwmaRef(period)
231}
232
233#[derive(Debug, Clone, Copy)]
235pub struct McginleyDynamicRef(pub usize);
236
237impl IndicatorRef for McginleyDynamicRef {
238 fn key(&self) -> String {
239 format!("mcginley_{}", self.0)
240 }
241
242 fn required_indicators(&self) -> Vec<(String, Indicator)> {
243 vec![(self.key(), Indicator::McginleyDynamic(self.0))]
244 }
245
246 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
247 ctx.indicator(&self.key())
248 }
249
250 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
251 ctx.indicator_prev(&self.key())
252 }
253}
254
255#[inline]
257pub fn mcginley(period: usize) -> McginleyDynamicRef {
258 McginleyDynamicRef(period)
259}
260
261#[derive(Debug, Clone, Copy)]
267pub struct RsiRef(pub usize);
268
269impl IndicatorRef for RsiRef {
270 fn key(&self) -> String {
271 format!("rsi_{}", self.0)
272 }
273
274 fn required_indicators(&self) -> Vec<(String, Indicator)> {
275 vec![(self.key(), Indicator::Rsi(self.0))]
276 }
277
278 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
279 ctx.indicator(&self.key())
280 }
281
282 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
283 ctx.indicator_prev(&self.key())
284 }
285}
286
287#[inline]
299pub fn rsi(period: usize) -> RsiRef {
300 RsiRef(period)
301}
302
303#[derive(Debug, Clone, Copy)]
305pub struct CciRef(pub usize);
306
307impl IndicatorRef for CciRef {
308 fn key(&self) -> String {
309 format!("cci_{}", self.0)
310 }
311
312 fn required_indicators(&self) -> Vec<(String, Indicator)> {
313 vec![(self.key(), Indicator::Cci(self.0))]
314 }
315
316 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
317 ctx.indicator(&self.key())
318 }
319
320 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
321 ctx.indicator_prev(&self.key())
322 }
323}
324
325#[inline]
327pub fn cci(period: usize) -> CciRef {
328 CciRef(period)
329}
330
331#[derive(Debug, Clone, Copy)]
333pub struct WilliamsRRef(pub usize);
334
335impl IndicatorRef for WilliamsRRef {
336 fn key(&self) -> String {
337 format!("williams_r_{}", self.0)
338 }
339
340 fn required_indicators(&self) -> Vec<(String, Indicator)> {
341 vec![(self.key(), Indicator::WilliamsR(self.0))]
342 }
343
344 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
345 ctx.indicator(&self.key())
346 }
347
348 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
349 ctx.indicator_prev(&self.key())
350 }
351}
352
353#[inline]
355pub fn williams_r(period: usize) -> WilliamsRRef {
356 WilliamsRRef(period)
357}
358
359#[derive(Debug, Clone, Copy)]
361pub struct CmoRef(pub usize);
362
363impl IndicatorRef for CmoRef {
364 fn key(&self) -> String {
365 format!("cmo_{}", self.0)
366 }
367
368 fn required_indicators(&self) -> Vec<(String, Indicator)> {
369 vec![(self.key(), Indicator::Cmo(self.0))]
370 }
371
372 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
373 ctx.indicator(&self.key())
374 }
375
376 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
377 ctx.indicator_prev(&self.key())
378 }
379}
380
381#[inline]
383pub fn cmo(period: usize) -> CmoRef {
384 CmoRef(period)
385}
386
387#[derive(Debug, Clone, Copy)]
393pub struct MomentumRef(pub usize);
394
395impl IndicatorRef for MomentumRef {
396 fn key(&self) -> String {
397 format!("momentum_{}", self.0)
398 }
399
400 fn required_indicators(&self) -> Vec<(String, Indicator)> {
401 vec![(self.key(), Indicator::Momentum(self.0))]
402 }
403
404 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
405 ctx.indicator(&self.key())
406 }
407
408 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
409 ctx.indicator_prev(&self.key())
410 }
411}
412
413#[inline]
415pub fn momentum(period: usize) -> MomentumRef {
416 MomentumRef(period)
417}
418
419#[derive(Debug, Clone, Copy)]
421pub struct RocRef(pub usize);
422
423impl IndicatorRef for RocRef {
424 fn key(&self) -> String {
425 format!("roc_{}", self.0)
426 }
427
428 fn required_indicators(&self) -> Vec<(String, Indicator)> {
429 vec![(self.key(), Indicator::Roc(self.0))]
430 }
431
432 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
433 ctx.indicator(&self.key())
434 }
435
436 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
437 ctx.indicator_prev(&self.key())
438 }
439}
440
441#[inline]
443pub fn roc(period: usize) -> RocRef {
444 RocRef(period)
445}
446
447#[derive(Debug, Clone, Copy)]
453pub struct AdxRef(pub usize);
454
455impl IndicatorRef for AdxRef {
456 fn key(&self) -> String {
457 format!("adx_{}", self.0)
458 }
459
460 fn required_indicators(&self) -> Vec<(String, Indicator)> {
461 vec![(self.key(), Indicator::Adx(self.0))]
462 }
463
464 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
465 ctx.indicator(&self.key())
466 }
467
468 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
469 ctx.indicator_prev(&self.key())
470 }
471}
472
473#[inline]
484pub fn adx(period: usize) -> AdxRef {
485 AdxRef(period)
486}
487
488#[derive(Debug, Clone, Copy)]
494pub struct AtrRef(pub usize);
495
496impl IndicatorRef for AtrRef {
497 fn key(&self) -> String {
498 format!("atr_{}", self.0)
499 }
500
501 fn required_indicators(&self) -> Vec<(String, Indicator)> {
502 vec![(self.key(), Indicator::Atr(self.0))]
503 }
504
505 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
506 ctx.indicator(&self.key())
507 }
508
509 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
510 ctx.indicator_prev(&self.key())
511 }
512}
513
514#[inline]
516pub fn atr(period: usize) -> AtrRef {
517 AtrRef(period)
518}
519
520#[derive(Debug, Clone, Copy)]
526pub struct ObvRef;
527
528impl IndicatorRef for ObvRef {
529 fn key(&self) -> String {
530 "obv".to_string()
531 }
532
533 fn required_indicators(&self) -> Vec<(String, Indicator)> {
534 vec![(self.key(), Indicator::Obv)]
535 }
536
537 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
538 ctx.indicator(&self.key())
539 }
540
541 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
542 ctx.indicator_prev(&self.key())
543 }
544}
545
546#[inline]
548pub fn obv() -> ObvRef {
549 ObvRef
550}
551
552#[derive(Debug, Clone, Copy)]
554pub struct VwapRef;
555
556impl IndicatorRef for VwapRef {
557 fn key(&self) -> String {
558 "vwap".to_string()
559 }
560
561 fn required_indicators(&self) -> Vec<(String, Indicator)> {
562 vec![(self.key(), Indicator::Vwap)]
563 }
564
565 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
566 ctx.indicator(&self.key())
567 }
568
569 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
570 ctx.indicator_prev(&self.key())
571 }
572}
573
574#[inline]
576pub fn vwap() -> VwapRef {
577 VwapRef
578}
579
580#[derive(Debug, Clone, Copy)]
582pub struct MfiRef(pub usize);
583
584impl IndicatorRef for MfiRef {
585 fn key(&self) -> String {
586 format!("mfi_{}", self.0)
587 }
588
589 fn required_indicators(&self) -> Vec<(String, Indicator)> {
590 vec![(self.key(), Indicator::Mfi(self.0))]
591 }
592
593 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
594 ctx.indicator(&self.key())
595 }
596
597 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
598 ctx.indicator_prev(&self.key())
599 }
600}
601
602#[inline]
604pub fn mfi(period: usize) -> MfiRef {
605 MfiRef(period)
606}
607
608#[derive(Debug, Clone, Copy)]
610pub struct CmfRef(pub usize);
611
612impl IndicatorRef for CmfRef {
613 fn key(&self) -> String {
614 format!("cmf_{}", self.0)
615 }
616
617 fn required_indicators(&self) -> Vec<(String, Indicator)> {
618 vec![(self.key(), Indicator::Cmf(self.0))]
619 }
620
621 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
622 ctx.indicator(&self.key())
623 }
624
625 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
626 ctx.indicator_prev(&self.key())
627 }
628}
629
630#[inline]
632pub fn cmf(period: usize) -> CmfRef {
633 CmfRef(period)
634}
635
636#[derive(Debug, Clone, Copy)]
644pub struct MacdConfig {
645 pub fast: usize,
647 pub slow: usize,
649 pub signal: usize,
651}
652
653impl MacdConfig {
654 pub fn line(&self) -> MacdLineRef {
656 MacdLineRef {
657 fast: self.fast,
658 slow: self.slow,
659 signal: self.signal,
660 }
661 }
662
663 pub fn signal_line(&self) -> MacdSignalRef {
665 MacdSignalRef {
666 fast: self.fast,
667 slow: self.slow,
668 signal: self.signal,
669 }
670 }
671
672 pub fn histogram(&self) -> MacdHistogramRef {
674 MacdHistogramRef {
675 fast: self.fast,
676 slow: self.slow,
677 signal: self.signal,
678 }
679 }
680}
681
682#[inline]
694pub fn macd(fast: usize, slow: usize, signal: usize) -> MacdConfig {
695 MacdConfig { fast, slow, signal }
696}
697
698#[derive(Debug, Clone, Copy)]
700pub struct MacdLineRef {
701 pub fast: usize,
703 pub slow: usize,
705 pub signal: usize,
707}
708
709impl IndicatorRef for MacdLineRef {
710 fn key(&self) -> String {
711 "macd_line".to_string()
712 }
713
714 fn required_indicators(&self) -> Vec<(String, Indicator)> {
715 vec![(
716 "macd".to_string(),
717 Indicator::Macd {
718 fast: self.fast,
719 slow: self.slow,
720 signal: self.signal,
721 },
722 )]
723 }
724
725 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
726 ctx.indicator("macd_line")
727 }
728
729 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
730 ctx.indicator_prev("macd_line")
731 }
732}
733
734#[derive(Debug, Clone, Copy)]
736pub struct MacdSignalRef {
737 pub fast: usize,
739 pub slow: usize,
741 pub signal: usize,
743}
744
745impl IndicatorRef for MacdSignalRef {
746 fn key(&self) -> String {
747 "macd_signal".to_string()
748 }
749
750 fn required_indicators(&self) -> Vec<(String, Indicator)> {
751 vec![(
752 "macd".to_string(),
753 Indicator::Macd {
754 fast: self.fast,
755 slow: self.slow,
756 signal: self.signal,
757 },
758 )]
759 }
760
761 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
762 ctx.indicator("macd_signal")
763 }
764
765 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
766 ctx.indicator_prev("macd_signal")
767 }
768}
769
770#[derive(Debug, Clone, Copy)]
772pub struct MacdHistogramRef {
773 pub fast: usize,
775 pub slow: usize,
777 pub signal: usize,
779}
780
781impl IndicatorRef for MacdHistogramRef {
782 fn key(&self) -> String {
783 "macd_histogram".to_string()
784 }
785
786 fn required_indicators(&self) -> Vec<(String, Indicator)> {
787 vec![(
788 "macd".to_string(),
789 Indicator::Macd {
790 fast: self.fast,
791 slow: self.slow,
792 signal: self.signal,
793 },
794 )]
795 }
796
797 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
798 ctx.indicator("macd_histogram")
799 }
800
801 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
802 ctx.indicator_prev("macd_histogram")
803 }
804}
805
806#[derive(Debug, Clone, Copy)]
810pub struct BollingerConfig {
811 pub period: usize,
813 pub std_dev: f64,
815}
816
817impl BollingerConfig {
818 pub fn upper(&self) -> BollingerUpperRef {
820 BollingerUpperRef {
821 period: self.period,
822 std_dev: self.std_dev,
823 }
824 }
825
826 pub fn middle(&self) -> BollingerMiddleRef {
828 BollingerMiddleRef {
829 period: self.period,
830 std_dev: self.std_dev,
831 }
832 }
833
834 pub fn lower(&self) -> BollingerLowerRef {
836 BollingerLowerRef {
837 period: self.period,
838 std_dev: self.std_dev,
839 }
840 }
841}
842
843#[inline]
855pub fn bollinger(period: usize, std_dev: f64) -> BollingerConfig {
856 BollingerConfig { period, std_dev }
857}
858
859#[derive(Debug, Clone, Copy)]
861pub struct BollingerUpperRef {
862 pub period: usize,
864 pub std_dev: f64,
866}
867
868impl IndicatorRef for BollingerUpperRef {
869 fn key(&self) -> String {
870 "bollinger_upper".to_string()
871 }
872
873 fn required_indicators(&self) -> Vec<(String, Indicator)> {
874 vec![(
875 "bollinger".to_string(),
876 Indicator::Bollinger {
877 period: self.period,
878 std_dev: self.std_dev,
879 },
880 )]
881 }
882
883 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
884 ctx.indicator("bollinger_upper")
885 }
886
887 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
888 ctx.indicator_prev("bollinger_upper")
889 }
890}
891
892#[derive(Debug, Clone, Copy)]
894pub struct BollingerMiddleRef {
895 pub period: usize,
897 pub std_dev: f64,
899}
900
901impl IndicatorRef for BollingerMiddleRef {
902 fn key(&self) -> String {
903 "bollinger_middle".to_string()
904 }
905
906 fn required_indicators(&self) -> Vec<(String, Indicator)> {
907 vec![(
908 "bollinger".to_string(),
909 Indicator::Bollinger {
910 period: self.period,
911 std_dev: self.std_dev,
912 },
913 )]
914 }
915
916 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
917 ctx.indicator("bollinger_middle")
918 }
919
920 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
921 ctx.indicator_prev("bollinger_middle")
922 }
923}
924
925#[derive(Debug, Clone, Copy)]
927pub struct BollingerLowerRef {
928 pub period: usize,
930 pub std_dev: f64,
932}
933
934impl IndicatorRef for BollingerLowerRef {
935 fn key(&self) -> String {
936 "bollinger_lower".to_string()
937 }
938
939 fn required_indicators(&self) -> Vec<(String, Indicator)> {
940 vec![(
941 "bollinger".to_string(),
942 Indicator::Bollinger {
943 period: self.period,
944 std_dev: self.std_dev,
945 },
946 )]
947 }
948
949 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
950 ctx.indicator("bollinger_lower")
951 }
952
953 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
954 ctx.indicator_prev("bollinger_lower")
955 }
956}
957
958#[derive(Debug, Clone, Copy)]
962pub struct DonchianConfig {
963 pub period: usize,
964}
965
966impl DonchianConfig {
967 pub fn upper(&self) -> DonchianUpperRef {
969 DonchianUpperRef {
970 period: self.period,
971 }
972 }
973
974 pub fn middle(&self) -> DonchianMiddleRef {
976 DonchianMiddleRef {
977 period: self.period,
978 }
979 }
980
981 pub fn lower(&self) -> DonchianLowerRef {
983 DonchianLowerRef {
984 period: self.period,
985 }
986 }
987}
988
989#[inline]
991pub fn donchian(period: usize) -> DonchianConfig {
992 DonchianConfig { period }
993}
994
995#[derive(Debug, Clone, Copy)]
997pub struct DonchianUpperRef {
998 pub period: usize,
999}
1000
1001impl IndicatorRef for DonchianUpperRef {
1002 fn key(&self) -> String {
1003 "donchian_upper".to_string()
1004 }
1005
1006 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1007 vec![(
1008 "donchian".to_string(),
1009 Indicator::DonchianChannels(self.period),
1010 )]
1011 }
1012
1013 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1014 ctx.indicator("donchian_upper")
1015 }
1016
1017 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1018 ctx.indicator_prev("donchian_upper")
1019 }
1020}
1021
1022#[derive(Debug, Clone, Copy)]
1024pub struct DonchianMiddleRef {
1025 pub period: usize,
1026}
1027
1028impl IndicatorRef for DonchianMiddleRef {
1029 fn key(&self) -> String {
1030 "donchian_middle".to_string()
1031 }
1032
1033 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1034 vec![(
1035 "donchian".to_string(),
1036 Indicator::DonchianChannels(self.period),
1037 )]
1038 }
1039
1040 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1041 ctx.indicator("donchian_middle")
1042 }
1043
1044 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1045 ctx.indicator_prev("donchian_middle")
1046 }
1047}
1048
1049#[derive(Debug, Clone, Copy)]
1051pub struct DonchianLowerRef {
1052 pub period: usize,
1053}
1054
1055impl IndicatorRef for DonchianLowerRef {
1056 fn key(&self) -> String {
1057 "donchian_lower".to_string()
1058 }
1059
1060 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1061 vec![(
1062 "donchian".to_string(),
1063 Indicator::DonchianChannels(self.period),
1064 )]
1065 }
1066
1067 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1068 ctx.indicator("donchian_lower")
1069 }
1070
1071 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1072 ctx.indicator_prev("donchian_lower")
1073 }
1074}
1075
1076#[derive(Debug, Clone, Copy)]
1080pub struct SupertrendConfig {
1081 pub period: usize,
1082 pub multiplier: f64,
1083}
1084
1085impl SupertrendConfig {
1086 pub fn value(&self) -> SupertrendValueRef {
1088 SupertrendValueRef {
1089 period: self.period,
1090 multiplier: self.multiplier,
1091 }
1092 }
1093
1094 pub fn uptrend(&self) -> SupertrendUptrendRef {
1096 SupertrendUptrendRef {
1097 period: self.period,
1098 multiplier: self.multiplier,
1099 }
1100 }
1101}
1102
1103#[inline]
1105pub fn supertrend(period: usize, multiplier: f64) -> SupertrendConfig {
1106 SupertrendConfig { period, multiplier }
1107}
1108
1109#[derive(Debug, Clone, Copy)]
1111pub struct SupertrendValueRef {
1112 pub period: usize,
1113 pub multiplier: f64,
1114}
1115
1116impl IndicatorRef for SupertrendValueRef {
1117 fn key(&self) -> String {
1118 "supertrend_value".to_string()
1119 }
1120
1121 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1122 vec![(
1123 "supertrend".to_string(),
1124 Indicator::Supertrend {
1125 period: self.period,
1126 multiplier: self.multiplier,
1127 },
1128 )]
1129 }
1130
1131 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1132 ctx.indicator("supertrend_value")
1133 }
1134
1135 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1136 ctx.indicator_prev("supertrend_value")
1137 }
1138}
1139
1140#[derive(Debug, Clone, Copy)]
1143pub struct SupertrendUptrendRef {
1144 pub period: usize,
1145 pub multiplier: f64,
1146}
1147
1148impl IndicatorRef for SupertrendUptrendRef {
1149 fn key(&self) -> String {
1150 "supertrend_uptrend".to_string()
1151 }
1152
1153 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1154 vec![(
1155 "supertrend".to_string(),
1156 Indicator::Supertrend {
1157 period: self.period,
1158 multiplier: self.multiplier,
1159 },
1160 )]
1161 }
1162
1163 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1164 ctx.indicator("supertrend_uptrend")
1165 }
1166
1167 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1168 ctx.indicator_prev("supertrend_uptrend")
1169 }
1170}
1171
1172#[derive(Debug, Clone, Copy)]
1176pub struct StochasticConfig {
1177 pub k_period: usize,
1178 pub k_slow: usize,
1179 pub d_period: usize,
1180}
1181
1182impl StochasticConfig {
1183 pub fn k(&self) -> StochasticKRef {
1185 StochasticKRef {
1186 k_period: self.k_period,
1187 k_slow: self.k_slow,
1188 d_period: self.d_period,
1189 }
1190 }
1191
1192 pub fn d(&self) -> StochasticDRef {
1194 StochasticDRef {
1195 k_period: self.k_period,
1196 k_slow: self.k_slow,
1197 d_period: self.d_period,
1198 }
1199 }
1200}
1201
1202#[inline]
1204pub fn stochastic(k_period: usize, k_slow: usize, d_period: usize) -> StochasticConfig {
1205 StochasticConfig {
1206 k_period,
1207 k_slow,
1208 d_period,
1209 }
1210}
1211
1212#[derive(Debug, Clone, Copy)]
1214pub struct StochasticKRef {
1215 pub k_period: usize,
1216 pub k_slow: usize,
1217 pub d_period: usize,
1218}
1219
1220impl IndicatorRef for StochasticKRef {
1221 fn key(&self) -> String {
1222 "stochastic_k".to_string()
1223 }
1224
1225 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1226 vec![(
1227 "stochastic".to_string(),
1228 Indicator::Stochastic {
1229 k_period: self.k_period,
1230 k_slow: self.k_slow,
1231 d_period: self.d_period,
1232 },
1233 )]
1234 }
1235
1236 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1237 ctx.indicator("stochastic_k")
1238 }
1239
1240 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1241 ctx.indicator_prev("stochastic_k")
1242 }
1243}
1244
1245#[derive(Debug, Clone, Copy)]
1247pub struct StochasticDRef {
1248 pub k_period: usize,
1249 pub k_slow: usize,
1250 pub d_period: usize,
1251}
1252
1253impl IndicatorRef for StochasticDRef {
1254 fn key(&self) -> String {
1255 "stochastic_d".to_string()
1256 }
1257
1258 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1259 vec![(
1260 "stochastic".to_string(),
1261 Indicator::Stochastic {
1262 k_period: self.k_period,
1263 k_slow: self.k_slow,
1264 d_period: self.d_period,
1265 },
1266 )]
1267 }
1268
1269 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1270 ctx.indicator("stochastic_d")
1271 }
1272
1273 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1274 ctx.indicator_prev("stochastic_d")
1275 }
1276}
1277
1278#[derive(Debug, Clone, Copy)]
1282pub struct AroonConfig {
1283 pub period: usize,
1284}
1285
1286impl AroonConfig {
1287 pub fn up(&self) -> AroonUpRef {
1289 AroonUpRef {
1290 period: self.period,
1291 }
1292 }
1293
1294 pub fn down(&self) -> AroonDownRef {
1296 AroonDownRef {
1297 period: self.period,
1298 }
1299 }
1300}
1301
1302#[inline]
1304pub fn aroon(period: usize) -> AroonConfig {
1305 AroonConfig { period }
1306}
1307
1308#[derive(Debug, Clone, Copy)]
1310pub struct AroonUpRef {
1311 pub period: usize,
1312}
1313
1314impl IndicatorRef for AroonUpRef {
1315 fn key(&self) -> String {
1316 "aroon_up".to_string()
1317 }
1318
1319 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1320 vec![("aroon".to_string(), Indicator::Aroon(self.period))]
1321 }
1322
1323 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1324 ctx.indicator("aroon_up")
1325 }
1326
1327 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1328 ctx.indicator_prev("aroon_up")
1329 }
1330}
1331
1332#[derive(Debug, Clone, Copy)]
1334pub struct AroonDownRef {
1335 pub period: usize,
1336}
1337
1338impl IndicatorRef for AroonDownRef {
1339 fn key(&self) -> String {
1340 "aroon_down".to_string()
1341 }
1342
1343 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1344 vec![("aroon".to_string(), Indicator::Aroon(self.period))]
1345 }
1346
1347 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1348 ctx.indicator("aroon_down")
1349 }
1350
1351 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1352 ctx.indicator_prev("aroon_down")
1353 }
1354}
1355
1356#[derive(Debug, Clone, Copy)]
1360pub struct IchimokuConfig {
1361 pub conversion: usize,
1362 pub base: usize,
1363 pub lagging: usize,
1364 pub displacement: usize,
1365}
1366
1367impl IchimokuConfig {
1368 pub fn conversion_line(&self) -> IchimokuConversionRef {
1370 IchimokuConversionRef {
1371 conversion: self.conversion,
1372 base: self.base,
1373 lagging: self.lagging,
1374 displacement: self.displacement,
1375 }
1376 }
1377
1378 pub fn base_line(&self) -> IchimokuBaseRef {
1380 IchimokuBaseRef {
1381 conversion: self.conversion,
1382 base: self.base,
1383 lagging: self.lagging,
1384 displacement: self.displacement,
1385 }
1386 }
1387
1388 pub fn leading_span_a(&self) -> IchimokuLeadingARef {
1390 IchimokuLeadingARef {
1391 conversion: self.conversion,
1392 base: self.base,
1393 lagging: self.lagging,
1394 displacement: self.displacement,
1395 }
1396 }
1397
1398 pub fn leading_span_b(&self) -> IchimokuLeadingBRef {
1400 IchimokuLeadingBRef {
1401 conversion: self.conversion,
1402 base: self.base,
1403 lagging: self.lagging,
1404 displacement: self.displacement,
1405 }
1406 }
1407
1408 pub fn lagging_span(&self) -> IchimokuLaggingRef {
1410 IchimokuLaggingRef {
1411 conversion: self.conversion,
1412 base: self.base,
1413 lagging: self.lagging,
1414 displacement: self.displacement,
1415 }
1416 }
1417}
1418
1419#[inline]
1421pub fn ichimoku() -> IchimokuConfig {
1422 IchimokuConfig {
1423 conversion: 9,
1424 base: 26,
1425 lagging: 52,
1426 displacement: 26,
1427 }
1428}
1429
1430#[inline]
1432pub fn ichimoku_custom(
1433 conversion: usize,
1434 base: usize,
1435 lagging: usize,
1436 displacement: usize,
1437) -> IchimokuConfig {
1438 IchimokuConfig {
1439 conversion,
1440 base,
1441 lagging,
1442 displacement,
1443 }
1444}
1445
1446#[derive(Debug, Clone, Copy)]
1448pub struct IchimokuConversionRef {
1449 pub conversion: usize,
1450 pub base: usize,
1451 pub lagging: usize,
1452 pub displacement: usize,
1453}
1454
1455impl IndicatorRef for IchimokuConversionRef {
1456 fn key(&self) -> String {
1457 "ichimoku_conversion".to_string()
1458 }
1459
1460 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1461 vec![(
1462 "ichimoku".to_string(),
1463 Indicator::Ichimoku {
1464 conversion: self.conversion,
1465 base: self.base,
1466 lagging: self.lagging,
1467 displacement: self.displacement,
1468 },
1469 )]
1470 }
1471
1472 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1473 ctx.indicator("ichimoku_conversion")
1474 }
1475
1476 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1477 ctx.indicator_prev("ichimoku_conversion")
1478 }
1479}
1480
1481#[derive(Debug, Clone, Copy)]
1483pub struct IchimokuBaseRef {
1484 pub conversion: usize,
1485 pub base: usize,
1486 pub lagging: usize,
1487 pub displacement: usize,
1488}
1489
1490impl IndicatorRef for IchimokuBaseRef {
1491 fn key(&self) -> String {
1492 "ichimoku_base".to_string()
1493 }
1494
1495 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1496 vec![(
1497 "ichimoku".to_string(),
1498 Indicator::Ichimoku {
1499 conversion: self.conversion,
1500 base: self.base,
1501 lagging: self.lagging,
1502 displacement: self.displacement,
1503 },
1504 )]
1505 }
1506
1507 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1508 ctx.indicator("ichimoku_base")
1509 }
1510
1511 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1512 ctx.indicator_prev("ichimoku_base")
1513 }
1514}
1515
1516#[derive(Debug, Clone, Copy)]
1518pub struct IchimokuLeadingARef {
1519 pub conversion: usize,
1520 pub base: usize,
1521 pub lagging: usize,
1522 pub displacement: usize,
1523}
1524
1525impl IndicatorRef for IchimokuLeadingARef {
1526 fn key(&self) -> String {
1527 "ichimoku_leading_a".to_string()
1528 }
1529
1530 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1531 vec![(
1532 "ichimoku".to_string(),
1533 Indicator::Ichimoku {
1534 conversion: self.conversion,
1535 base: self.base,
1536 lagging: self.lagging,
1537 displacement: self.displacement,
1538 },
1539 )]
1540 }
1541
1542 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1543 ctx.indicator("ichimoku_leading_a")
1544 }
1545
1546 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1547 ctx.indicator_prev("ichimoku_leading_a")
1548 }
1549}
1550
1551#[derive(Debug, Clone, Copy)]
1553pub struct IchimokuLeadingBRef {
1554 pub conversion: usize,
1555 pub base: usize,
1556 pub lagging: usize,
1557 pub displacement: usize,
1558}
1559
1560impl IndicatorRef for IchimokuLeadingBRef {
1561 fn key(&self) -> String {
1562 "ichimoku_leading_b".to_string()
1563 }
1564
1565 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1566 vec![(
1567 "ichimoku".to_string(),
1568 Indicator::Ichimoku {
1569 conversion: self.conversion,
1570 base: self.base,
1571 lagging: self.lagging,
1572 displacement: self.displacement,
1573 },
1574 )]
1575 }
1576
1577 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1578 ctx.indicator("ichimoku_leading_b")
1579 }
1580
1581 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1582 ctx.indicator_prev("ichimoku_leading_b")
1583 }
1584}
1585
1586#[derive(Debug, Clone, Copy)]
1588pub struct IchimokuLaggingRef {
1589 pub conversion: usize,
1590 pub base: usize,
1591 pub lagging: usize,
1592 pub displacement: usize,
1593}
1594
1595impl IndicatorRef for IchimokuLaggingRef {
1596 fn key(&self) -> String {
1597 "ichimoku_lagging".to_string()
1598 }
1599
1600 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1601 vec![(
1602 "ichimoku".to_string(),
1603 Indicator::Ichimoku {
1604 conversion: self.conversion,
1605 base: self.base,
1606 lagging: self.lagging,
1607 displacement: self.displacement,
1608 },
1609 )]
1610 }
1611
1612 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1613 ctx.indicator("ichimoku_lagging")
1614 }
1615
1616 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1617 ctx.indicator_prev("ichimoku_lagging")
1618 }
1619}
1620
1621#[derive(Debug, Clone, Copy)]
1625pub struct KeltnerConfig {
1626 pub period: usize,
1627 pub multiplier: f64,
1628 pub atr_period: usize,
1629}
1630
1631impl KeltnerConfig {
1632 pub fn upper(&self) -> KeltnerUpperRef {
1634 KeltnerUpperRef {
1635 period: self.period,
1636 multiplier: self.multiplier,
1637 atr_period: self.atr_period,
1638 }
1639 }
1640
1641 pub fn middle(&self) -> KeltnerMiddleRef {
1643 KeltnerMiddleRef {
1644 period: self.period,
1645 multiplier: self.multiplier,
1646 atr_period: self.atr_period,
1647 }
1648 }
1649
1650 pub fn lower(&self) -> KeltnerLowerRef {
1652 KeltnerLowerRef {
1653 period: self.period,
1654 multiplier: self.multiplier,
1655 atr_period: self.atr_period,
1656 }
1657 }
1658}
1659
1660#[inline]
1662pub fn keltner(period: usize, multiplier: f64, atr_period: usize) -> KeltnerConfig {
1663 KeltnerConfig {
1664 period,
1665 multiplier,
1666 atr_period,
1667 }
1668}
1669
1670#[derive(Debug, Clone, Copy)]
1672pub struct KeltnerUpperRef {
1673 pub period: usize,
1674 pub multiplier: f64,
1675 pub atr_period: usize,
1676}
1677
1678impl IndicatorRef for KeltnerUpperRef {
1679 fn key(&self) -> String {
1680 "keltner_upper".to_string()
1681 }
1682
1683 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1684 vec![(
1685 "keltner".to_string(),
1686 Indicator::KeltnerChannels {
1687 period: self.period,
1688 multiplier: self.multiplier,
1689 atr_period: self.atr_period,
1690 },
1691 )]
1692 }
1693
1694 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1695 ctx.indicator("keltner_upper")
1696 }
1697
1698 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1699 ctx.indicator_prev("keltner_upper")
1700 }
1701}
1702
1703#[derive(Debug, Clone, Copy)]
1705pub struct KeltnerMiddleRef {
1706 pub period: usize,
1707 pub multiplier: f64,
1708 pub atr_period: usize,
1709}
1710
1711impl IndicatorRef for KeltnerMiddleRef {
1712 fn key(&self) -> String {
1713 "keltner_middle".to_string()
1714 }
1715
1716 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1717 vec![(
1718 "keltner".to_string(),
1719 Indicator::KeltnerChannels {
1720 period: self.period,
1721 multiplier: self.multiplier,
1722 atr_period: self.atr_period,
1723 },
1724 )]
1725 }
1726
1727 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1728 ctx.indicator("keltner_middle")
1729 }
1730
1731 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1732 ctx.indicator_prev("keltner_middle")
1733 }
1734}
1735
1736#[derive(Debug, Clone, Copy)]
1738pub struct KeltnerLowerRef {
1739 pub period: usize,
1740 pub multiplier: f64,
1741 pub atr_period: usize,
1742}
1743
1744impl IndicatorRef for KeltnerLowerRef {
1745 fn key(&self) -> String {
1746 "keltner_lower".to_string()
1747 }
1748
1749 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1750 vec![(
1751 "keltner".to_string(),
1752 Indicator::KeltnerChannels {
1753 period: self.period,
1754 multiplier: self.multiplier,
1755 atr_period: self.atr_period,
1756 },
1757 )]
1758 }
1759
1760 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1761 ctx.indicator("keltner_lower")
1762 }
1763
1764 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1765 ctx.indicator_prev("keltner_lower")
1766 }
1767}
1768
1769#[derive(Debug, Clone, Copy)]
1773pub struct ParabolicSarConfig {
1774 pub step: f64,
1775 pub max: f64,
1776}
1777
1778#[inline]
1780pub fn parabolic_sar(step: f64, max: f64) -> ParabolicSarRef {
1781 ParabolicSarRef { step, max }
1782}
1783
1784#[derive(Debug, Clone, Copy)]
1786pub struct ParabolicSarRef {
1787 pub step: f64,
1788 pub max: f64,
1789}
1790
1791impl IndicatorRef for ParabolicSarRef {
1792 fn key(&self) -> String {
1793 format!("psar_{}_{}", self.step, self.max)
1794 }
1795
1796 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1797 vec![(
1798 self.key(),
1799 Indicator::ParabolicSar {
1800 step: self.step,
1801 max: self.max,
1802 },
1803 )]
1804 }
1805
1806 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1807 ctx.indicator(&self.key())
1808 }
1809
1810 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1811 ctx.indicator_prev(&self.key())
1812 }
1813}
1814
1815#[derive(Debug, Clone, Copy)]
1819pub struct AlmaConfig {
1820 pub period: usize,
1821 pub offset: f64,
1822 pub sigma: f64,
1823}
1824
1825#[inline]
1827pub fn alma(period: usize, offset: f64, sigma: f64) -> AlmaRef {
1828 AlmaRef {
1829 period,
1830 offset,
1831 sigma,
1832 }
1833}
1834
1835#[derive(Debug, Clone, Copy)]
1837pub struct AlmaRef {
1838 pub period: usize,
1839 pub offset: f64,
1840 pub sigma: f64,
1841}
1842
1843impl IndicatorRef for AlmaRef {
1844 fn key(&self) -> String {
1845 format!("alma_{}_{}_{}", self.period, self.offset, self.sigma)
1846 }
1847
1848 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1849 vec![(
1850 self.key(),
1851 Indicator::Alma {
1852 period: self.period,
1853 offset: self.offset,
1854 sigma: self.sigma,
1855 },
1856 )]
1857 }
1858
1859 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1860 ctx.indicator(&self.key())
1861 }
1862
1863 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1864 ctx.indicator_prev(&self.key())
1865 }
1866}
1867
1868#[derive(Debug, Clone, Copy)]
1872pub struct StochasticRsiConfig {
1873 pub rsi_period: usize,
1874 pub stoch_period: usize,
1875 pub k_period: usize,
1876 pub d_period: usize,
1877}
1878
1879#[inline]
1881pub fn stochastic_rsi(
1882 rsi_period: usize,
1883 stoch_period: usize,
1884 k_period: usize,
1885 d_period: usize,
1886) -> StochasticRsiRef {
1887 StochasticRsiRef {
1888 rsi_period,
1889 stoch_period,
1890 k_period,
1891 d_period,
1892 }
1893}
1894
1895#[derive(Debug, Clone, Copy)]
1897pub struct StochasticRsiRef {
1898 pub rsi_period: usize,
1899 pub stoch_period: usize,
1900 pub k_period: usize,
1901 pub d_period: usize,
1902}
1903
1904impl IndicatorRef for StochasticRsiRef {
1905 fn key(&self) -> String {
1906 format!(
1907 "stoch_rsi_{}_{}_{}_{}",
1908 self.rsi_period, self.stoch_period, self.k_period, self.d_period
1909 )
1910 }
1911
1912 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1913 vec![(
1914 self.key(),
1915 Indicator::StochasticRsi {
1916 rsi_period: self.rsi_period,
1917 stoch_period: self.stoch_period,
1918 k_period: self.k_period,
1919 d_period: self.d_period,
1920 },
1921 )]
1922 }
1923
1924 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1925 ctx.indicator(&self.key())
1926 }
1927
1928 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1929 ctx.indicator_prev(&self.key())
1930 }
1931}
1932
1933#[derive(Debug, Clone, Copy)]
1937pub struct AwesomeOscillatorRef {
1938 pub fast: usize,
1939 pub slow: usize,
1940}
1941
1942#[inline]
1944pub fn awesome_oscillator(fast: usize, slow: usize) -> AwesomeOscillatorRef {
1945 AwesomeOscillatorRef { fast, slow }
1946}
1947
1948impl IndicatorRef for AwesomeOscillatorRef {
1949 fn key(&self) -> String {
1950 format!("ao_{}_{}", self.fast, self.slow)
1951 }
1952
1953 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1954 vec![(
1955 self.key(),
1956 Indicator::AwesomeOscillator {
1957 fast: self.fast,
1958 slow: self.slow,
1959 },
1960 )]
1961 }
1962
1963 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1964 ctx.indicator(&self.key())
1965 }
1966
1967 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1968 ctx.indicator_prev(&self.key())
1969 }
1970}
1971
1972#[derive(Debug, Clone, Copy)]
1976pub struct CoppockCurveRef {
1977 pub wma_period: usize,
1978 pub long_roc: usize,
1979 pub short_roc: usize,
1980}
1981
1982#[inline]
1984pub fn coppock_curve(wma_period: usize, long_roc: usize, short_roc: usize) -> CoppockCurveRef {
1985 CoppockCurveRef {
1986 wma_period,
1987 long_roc,
1988 short_roc,
1989 }
1990}
1991
1992impl IndicatorRef for CoppockCurveRef {
1993 fn key(&self) -> String {
1994 format!(
1995 "coppock_{}_{}_{}",
1996 self.wma_period, self.long_roc, self.short_roc
1997 )
1998 }
1999
2000 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2001 vec![(
2002 self.key(),
2003 Indicator::CoppockCurve {
2004 wma_period: self.wma_period,
2005 long_roc: self.long_roc,
2006 short_roc: self.short_roc,
2007 },
2008 )]
2009 }
2010
2011 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2012 ctx.indicator(&self.key())
2013 }
2014
2015 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2016 ctx.indicator_prev(&self.key())
2017 }
2018}
2019
2020#[derive(Debug, Clone, Copy)]
2024pub struct ChoppinessIndexRef(pub usize);
2025
2026#[inline]
2028pub fn choppiness_index(period: usize) -> ChoppinessIndexRef {
2029 ChoppinessIndexRef(period)
2030}
2031
2032impl IndicatorRef for ChoppinessIndexRef {
2033 fn key(&self) -> String {
2034 format!("chop_{}", self.0)
2035 }
2036
2037 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2038 vec![(self.key(), Indicator::ChoppinessIndex(self.0))]
2039 }
2040
2041 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2042 ctx.indicator(&self.key())
2043 }
2044
2045 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2046 ctx.indicator_prev(&self.key())
2047 }
2048}
2049
2050#[derive(Debug, Clone, Copy)]
2054pub struct TrueRangeRef;
2055
2056#[inline]
2058pub fn true_range() -> TrueRangeRef {
2059 TrueRangeRef
2060}
2061
2062impl IndicatorRef for TrueRangeRef {
2063 fn key(&self) -> String {
2064 "true_range".to_string()
2065 }
2066
2067 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2068 vec![(self.key(), Indicator::TrueRange)]
2069 }
2070
2071 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2072 ctx.indicator(&self.key())
2073 }
2074
2075 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2076 ctx.indicator_prev(&self.key())
2077 }
2078}
2079
2080#[derive(Debug, Clone, Copy)]
2084pub struct ChaikinOscillatorRef;
2085
2086#[inline]
2088pub fn chaikin_oscillator() -> ChaikinOscillatorRef {
2089 ChaikinOscillatorRef
2090}
2091
2092impl IndicatorRef for ChaikinOscillatorRef {
2093 fn key(&self) -> String {
2094 "chaikin_osc".to_string()
2095 }
2096
2097 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2098 vec![(self.key(), Indicator::ChaikinOscillator)]
2099 }
2100
2101 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2102 ctx.indicator(&self.key())
2103 }
2104
2105 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2106 ctx.indicator_prev(&self.key())
2107 }
2108}
2109
2110#[derive(Debug, Clone, Copy)]
2114pub struct AccumulationDistributionRef;
2115
2116#[inline]
2118pub fn accumulation_distribution() -> AccumulationDistributionRef {
2119 AccumulationDistributionRef
2120}
2121
2122impl IndicatorRef for AccumulationDistributionRef {
2123 fn key(&self) -> String {
2124 "ad".to_string()
2125 }
2126
2127 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2128 vec![(self.key(), Indicator::AccumulationDistribution)]
2129 }
2130
2131 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2132 ctx.indicator(&self.key())
2133 }
2134
2135 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2136 ctx.indicator_prev(&self.key())
2137 }
2138}
2139
2140#[derive(Debug, Clone, Copy)]
2144pub struct BalanceOfPowerRef(pub Option<usize>);
2145
2146#[inline]
2148pub fn balance_of_power(period: Option<usize>) -> BalanceOfPowerRef {
2149 BalanceOfPowerRef(period)
2150}
2151
2152impl IndicatorRef for BalanceOfPowerRef {
2153 fn key(&self) -> String {
2154 match self.0 {
2155 Some(p) => format!("bop_{}", p),
2156 None => "bop".to_string(),
2157 }
2158 }
2159
2160 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2161 vec![(self.key(), Indicator::BalanceOfPower(self.0))]
2162 }
2163
2164 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2165 ctx.indicator(&self.key())
2166 }
2167
2168 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2169 ctx.indicator_prev(&self.key())
2170 }
2171}
2172
2173#[derive(Debug, Clone, Copy)]
2177pub struct BullPowerRef(pub usize);
2178
2179#[inline]
2181pub fn bull_power(period: usize) -> BullPowerRef {
2182 BullPowerRef(period)
2183}
2184
2185impl IndicatorRef for BullPowerRef {
2186 fn key(&self) -> String {
2187 "bull_power".to_string()
2188 }
2189
2190 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2191 vec![(self.key(), Indicator::BullBearPower(self.0))]
2192 }
2193
2194 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2195 ctx.indicator("bull_power")
2196 }
2197
2198 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2199 ctx.indicator_prev("bull_power")
2200 }
2201}
2202
2203#[derive(Debug, Clone, Copy)]
2205pub struct BearPowerRef(pub usize);
2206
2207#[inline]
2209pub fn bear_power(period: usize) -> BearPowerRef {
2210 BearPowerRef(period)
2211}
2212
2213impl IndicatorRef for BearPowerRef {
2214 fn key(&self) -> String {
2215 "bear_power".to_string()
2216 }
2217
2218 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2219 vec![(self.key(), Indicator::BullBearPower(self.0))]
2220 }
2221
2222 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2223 ctx.indicator("bear_power")
2224 }
2225
2226 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2227 ctx.indicator_prev("bear_power")
2228 }
2229}
2230
2231#[derive(Debug, Clone, Copy)]
2235pub struct ElderBullPowerRef(pub usize);
2236
2237#[inline]
2239pub fn elder_bull_power(period: usize) -> ElderBullPowerRef {
2240 ElderBullPowerRef(period)
2241}
2242
2243impl IndicatorRef for ElderBullPowerRef {
2244 fn key(&self) -> String {
2245 "elder_bull".to_string()
2246 }
2247
2248 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2249 vec![(self.key(), Indicator::ElderRay(self.0))]
2250 }
2251
2252 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2253 ctx.indicator("elder_bull")
2254 }
2255
2256 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2257 ctx.indicator_prev("elder_bull")
2258 }
2259}
2260
2261#[derive(Debug, Clone, Copy)]
2263pub struct ElderBearPowerRef(pub usize);
2264
2265#[inline]
2267pub fn elder_bear_power(period: usize) -> ElderBearPowerRef {
2268 ElderBearPowerRef(period)
2269}
2270
2271impl IndicatorRef for ElderBearPowerRef {
2272 fn key(&self) -> String {
2273 "elder_bear".to_string()
2274 }
2275
2276 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2277 vec![(self.key(), Indicator::ElderRay(self.0))]
2278 }
2279
2280 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2281 ctx.indicator("elder_bear")
2282 }
2283
2284 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2285 ctx.indicator_prev("elder_bear")
2286 }
2287}
2288
2289#[cfg(test)]
2290mod tests {
2291 use super::*;
2292
2293 #[test]
2294 fn test_moving_average_keys() {
2295 assert_eq!(sma(20).key(), "sma_20");
2296 assert_eq!(ema(12).key(), "ema_12");
2297 assert_eq!(wma(14).key(), "wma_14");
2298 assert_eq!(dema(21).key(), "dema_21");
2299 assert_eq!(tema(21).key(), "tema_21");
2300 assert_eq!(hma(9).key(), "hma_9");
2301 assert_eq!(vwma(20).key(), "vwma_20");
2302 assert_eq!(mcginley(14).key(), "mcginley_14");
2303 assert_eq!(alma(9, 0.85, 6.0).key(), "alma_9_0.85_6");
2304 }
2305
2306 #[test]
2307 fn test_oscillator_keys() {
2308 assert_eq!(rsi(14).key(), "rsi_14");
2309 assert_eq!(cci(20).key(), "cci_20");
2310 assert_eq!(williams_r(14).key(), "williams_r_14");
2311 assert_eq!(cmo(14).key(), "cmo_14");
2312 assert_eq!(stochastic_rsi(14, 14, 3, 3).key(), "stoch_rsi_14_14_3_3");
2313 assert_eq!(awesome_oscillator(5, 34).key(), "ao_5_34");
2314 assert_eq!(choppiness_index(14).key(), "chop_14");
2315 }
2316
2317 #[test]
2318 fn test_macd_keys() {
2319 let m = macd(12, 26, 9);
2320 assert_eq!(m.line().key(), "macd_line");
2321 assert_eq!(m.signal_line().key(), "macd_signal");
2322 assert_eq!(m.histogram().key(), "macd_histogram");
2323 }
2324
2325 #[test]
2326 fn test_bollinger_keys() {
2327 let bb = bollinger(20, 2.0);
2328 assert_eq!(bb.upper().key(), "bollinger_upper");
2329 assert_eq!(bb.middle().key(), "bollinger_middle");
2330 assert_eq!(bb.lower().key(), "bollinger_lower");
2331 }
2332
2333 #[test]
2334 fn test_donchian_keys() {
2335 let dc = donchian(20);
2336 assert_eq!(dc.upper().key(), "donchian_upper");
2337 assert_eq!(dc.middle().key(), "donchian_middle");
2338 assert_eq!(dc.lower().key(), "donchian_lower");
2339 }
2340
2341 #[test]
2342 fn test_supertrend_keys() {
2343 let st = supertrend(10, 3.0);
2344 assert_eq!(st.value().key(), "supertrend_value");
2345 assert_eq!(st.uptrend().key(), "supertrend_uptrend");
2346 }
2347
2348 #[test]
2349 fn test_stochastic_keys() {
2350 let stoch = stochastic(14, 3, 3);
2351 assert_eq!(stoch.k().key(), "stochastic_k");
2352 assert_eq!(stoch.d().key(), "stochastic_d");
2353 }
2354
2355 #[test]
2356 fn test_aroon_keys() {
2357 let ar = aroon(25);
2358 assert_eq!(ar.up().key(), "aroon_up");
2359 assert_eq!(ar.down().key(), "aroon_down");
2360 }
2361
2362 #[test]
2363 fn test_ichimoku_keys() {
2364 let ich = ichimoku();
2365 assert_eq!(ich.conversion_line().key(), "ichimoku_conversion");
2366 assert_eq!(ich.base_line().key(), "ichimoku_base");
2367 assert_eq!(ich.leading_span_a().key(), "ichimoku_leading_a");
2368 assert_eq!(ich.leading_span_b().key(), "ichimoku_leading_b");
2369 assert_eq!(ich.lagging_span().key(), "ichimoku_lagging");
2370 }
2371
2372 #[test]
2373 fn test_keltner_keys() {
2374 let kc = keltner(20, 2.0, 10);
2375 assert_eq!(kc.upper().key(), "keltner_upper");
2376 assert_eq!(kc.middle().key(), "keltner_middle");
2377 assert_eq!(kc.lower().key(), "keltner_lower");
2378 }
2379
2380 #[test]
2381 fn test_volume_keys() {
2382 assert_eq!(obv().key(), "obv");
2383 assert_eq!(vwap().key(), "vwap");
2384 assert_eq!(mfi(14).key(), "mfi_14");
2385 assert_eq!(cmf(20).key(), "cmf_20");
2386 assert_eq!(chaikin_oscillator().key(), "chaikin_osc");
2387 assert_eq!(accumulation_distribution().key(), "ad");
2388 assert_eq!(balance_of_power(Some(14)).key(), "bop_14");
2389 assert_eq!(balance_of_power(None).key(), "bop");
2390 }
2391
2392 #[test]
2393 fn test_power_keys() {
2394 assert_eq!(bull_power(13).key(), "bull_power");
2395 assert_eq!(bear_power(13).key(), "bear_power");
2396 assert_eq!(elder_bull_power(13).key(), "elder_bull");
2397 assert_eq!(elder_bear_power(13).key(), "elder_bear");
2398 }
2399
2400 #[test]
2401 fn test_other_keys() {
2402 assert_eq!(parabolic_sar(0.02, 0.2).key(), "psar_0.02_0.2");
2403 assert_eq!(true_range().key(), "true_range");
2404 assert_eq!(coppock_curve(10, 14, 11).key(), "coppock_10_14_11");
2405 }
2406
2407 #[test]
2408 fn test_required_indicators() {
2409 let sma_ref = sma(20);
2410 let indicators = sma_ref.required_indicators();
2411 assert_eq!(indicators.len(), 1);
2412 assert_eq!(indicators[0].0, "sma_20");
2413 assert!(matches!(indicators[0].1, Indicator::Sma(20)));
2414 }
2415}