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 format!("macd_line_{}_{}_{}", self.fast, self.slow, self.signal)
712 }
713
714 fn required_indicators(&self) -> Vec<(String, Indicator)> {
715 vec![(
716 self.key(),
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(&self.key())
727 }
728
729 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
730 ctx.indicator_prev(&self.key())
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 format!("macd_signal_{}_{}_{}", self.fast, self.slow, self.signal)
748 }
749
750 fn required_indicators(&self) -> Vec<(String, Indicator)> {
751 vec![(
752 self.key(),
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(&self.key())
763 }
764
765 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
766 ctx.indicator_prev(&self.key())
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 format!("macd_histogram_{}_{}_{}", self.fast, self.slow, self.signal)
784 }
785
786 fn required_indicators(&self) -> Vec<(String, Indicator)> {
787 vec![(
788 self.key(),
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(&self.key())
799 }
800
801 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
802 ctx.indicator_prev(&self.key())
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 format!("bollinger_upper_{}_{}", self.period, self.std_dev)
871 }
872
873 fn required_indicators(&self) -> Vec<(String, Indicator)> {
874 vec![(
875 self.key(),
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(&self.key())
885 }
886
887 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
888 ctx.indicator_prev(&self.key())
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 format!("bollinger_middle_{}_{}", self.period, self.std_dev)
904 }
905
906 fn required_indicators(&self) -> Vec<(String, Indicator)> {
907 vec![(
908 self.key(),
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(&self.key())
918 }
919
920 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
921 ctx.indicator_prev(&self.key())
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 format!("bollinger_lower_{}_{}", self.period, self.std_dev)
937 }
938
939 fn required_indicators(&self) -> Vec<(String, Indicator)> {
940 vec![(
941 self.key(),
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(&self.key())
951 }
952
953 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
954 ctx.indicator_prev(&self.key())
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 format!("donchian_upper_{}", self.period)
1004 }
1005
1006 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1007 vec![(self.key(), Indicator::DonchianChannels(self.period))]
1008 }
1009
1010 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1011 ctx.indicator(&self.key())
1012 }
1013
1014 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1015 ctx.indicator_prev(&self.key())
1016 }
1017}
1018
1019#[derive(Debug, Clone, Copy)]
1021pub struct DonchianMiddleRef {
1022 pub period: usize,
1023}
1024
1025impl IndicatorRef for DonchianMiddleRef {
1026 fn key(&self) -> String {
1027 format!("donchian_middle_{}", self.period)
1028 }
1029
1030 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1031 vec![(self.key(), Indicator::DonchianChannels(self.period))]
1032 }
1033
1034 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1035 ctx.indicator(&self.key())
1036 }
1037
1038 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1039 ctx.indicator_prev(&self.key())
1040 }
1041}
1042
1043#[derive(Debug, Clone, Copy)]
1045pub struct DonchianLowerRef {
1046 pub period: usize,
1047}
1048
1049impl IndicatorRef for DonchianLowerRef {
1050 fn key(&self) -> String {
1051 format!("donchian_lower_{}", self.period)
1052 }
1053
1054 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1055 vec![(self.key(), Indicator::DonchianChannels(self.period))]
1056 }
1057
1058 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1059 ctx.indicator(&self.key())
1060 }
1061
1062 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1063 ctx.indicator_prev(&self.key())
1064 }
1065}
1066
1067#[derive(Debug, Clone, Copy)]
1071pub struct SupertrendConfig {
1072 pub period: usize,
1073 pub multiplier: f64,
1074}
1075
1076impl SupertrendConfig {
1077 pub fn value(&self) -> SupertrendValueRef {
1079 SupertrendValueRef {
1080 period: self.period,
1081 multiplier: self.multiplier,
1082 }
1083 }
1084
1085 pub fn uptrend(&self) -> SupertrendUptrendRef {
1087 SupertrendUptrendRef {
1088 period: self.period,
1089 multiplier: self.multiplier,
1090 }
1091 }
1092}
1093
1094#[inline]
1096pub fn supertrend(period: usize, multiplier: f64) -> SupertrendConfig {
1097 SupertrendConfig { period, multiplier }
1098}
1099
1100#[derive(Debug, Clone, Copy)]
1102pub struct SupertrendValueRef {
1103 pub period: usize,
1104 pub multiplier: f64,
1105}
1106
1107impl IndicatorRef for SupertrendValueRef {
1108 fn key(&self) -> String {
1109 format!("supertrend_value_{}_{}", self.period, self.multiplier)
1110 }
1111
1112 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1113 vec![(
1114 self.key(),
1115 Indicator::Supertrend {
1116 period: self.period,
1117 multiplier: self.multiplier,
1118 },
1119 )]
1120 }
1121
1122 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1123 ctx.indicator(&self.key())
1124 }
1125
1126 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1127 ctx.indicator_prev(&self.key())
1128 }
1129}
1130
1131#[derive(Debug, Clone, Copy)]
1134pub struct SupertrendUptrendRef {
1135 pub period: usize,
1136 pub multiplier: f64,
1137}
1138
1139impl IndicatorRef for SupertrendUptrendRef {
1140 fn key(&self) -> String {
1141 format!("supertrend_uptrend_{}_{}", self.period, self.multiplier)
1142 }
1143
1144 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1145 vec![(
1146 self.key(),
1147 Indicator::Supertrend {
1148 period: self.period,
1149 multiplier: self.multiplier,
1150 },
1151 )]
1152 }
1153
1154 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1155 ctx.indicator(&self.key())
1156 }
1157
1158 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1159 ctx.indicator_prev(&self.key())
1160 }
1161}
1162
1163#[derive(Debug, Clone, Copy)]
1167pub struct StochasticConfig {
1168 pub k_period: usize,
1169 pub k_slow: usize,
1170 pub d_period: usize,
1171}
1172
1173impl StochasticConfig {
1174 pub fn k(&self) -> StochasticKRef {
1176 StochasticKRef {
1177 k_period: self.k_period,
1178 k_slow: self.k_slow,
1179 d_period: self.d_period,
1180 }
1181 }
1182
1183 pub fn d(&self) -> StochasticDRef {
1185 StochasticDRef {
1186 k_period: self.k_period,
1187 k_slow: self.k_slow,
1188 d_period: self.d_period,
1189 }
1190 }
1191}
1192
1193#[inline]
1195pub fn stochastic(k_period: usize, k_slow: usize, d_period: usize) -> StochasticConfig {
1196 StochasticConfig {
1197 k_period,
1198 k_slow,
1199 d_period,
1200 }
1201}
1202
1203#[derive(Debug, Clone, Copy)]
1205pub struct StochasticKRef {
1206 pub k_period: usize,
1207 pub k_slow: usize,
1208 pub d_period: usize,
1209}
1210
1211impl IndicatorRef for StochasticKRef {
1212 fn key(&self) -> String {
1213 format!(
1214 "stochastic_k_{}_{}_{}",
1215 self.k_period, self.k_slow, self.d_period
1216 )
1217 }
1218
1219 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1220 vec![(
1221 self.key(),
1222 Indicator::Stochastic {
1223 k_period: self.k_period,
1224 k_slow: self.k_slow,
1225 d_period: self.d_period,
1226 },
1227 )]
1228 }
1229
1230 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1231 ctx.indicator(&self.key())
1232 }
1233
1234 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1235 ctx.indicator_prev(&self.key())
1236 }
1237}
1238
1239#[derive(Debug, Clone, Copy)]
1241pub struct StochasticDRef {
1242 pub k_period: usize,
1243 pub k_slow: usize,
1244 pub d_period: usize,
1245}
1246
1247impl IndicatorRef for StochasticDRef {
1248 fn key(&self) -> String {
1249 format!(
1250 "stochastic_d_{}_{}_{}",
1251 self.k_period, self.k_slow, self.d_period
1252 )
1253 }
1254
1255 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1256 vec![(
1257 self.key(),
1258 Indicator::Stochastic {
1259 k_period: self.k_period,
1260 k_slow: self.k_slow,
1261 d_period: self.d_period,
1262 },
1263 )]
1264 }
1265
1266 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1267 ctx.indicator(&self.key())
1268 }
1269
1270 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1271 ctx.indicator_prev(&self.key())
1272 }
1273}
1274
1275#[derive(Debug, Clone, Copy)]
1279pub struct AroonConfig {
1280 pub period: usize,
1281}
1282
1283impl AroonConfig {
1284 pub fn up(&self) -> AroonUpRef {
1286 AroonUpRef {
1287 period: self.period,
1288 }
1289 }
1290
1291 pub fn down(&self) -> AroonDownRef {
1293 AroonDownRef {
1294 period: self.period,
1295 }
1296 }
1297}
1298
1299#[inline]
1301pub fn aroon(period: usize) -> AroonConfig {
1302 AroonConfig { period }
1303}
1304
1305#[derive(Debug, Clone, Copy)]
1307pub struct AroonUpRef {
1308 pub period: usize,
1309}
1310
1311impl IndicatorRef for AroonUpRef {
1312 fn key(&self) -> String {
1313 format!("aroon_up_{}", self.period)
1314 }
1315
1316 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1317 vec![(self.key(), Indicator::Aroon(self.period))]
1318 }
1319
1320 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1321 ctx.indicator(&self.key())
1322 }
1323
1324 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1325 ctx.indicator_prev(&self.key())
1326 }
1327}
1328
1329#[derive(Debug, Clone, Copy)]
1331pub struct AroonDownRef {
1332 pub period: usize,
1333}
1334
1335impl IndicatorRef for AroonDownRef {
1336 fn key(&self) -> String {
1337 format!("aroon_down_{}", self.period)
1338 }
1339
1340 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1341 vec![(self.key(), Indicator::Aroon(self.period))]
1342 }
1343
1344 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1345 ctx.indicator(&self.key())
1346 }
1347
1348 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1349 ctx.indicator_prev(&self.key())
1350 }
1351}
1352
1353#[derive(Debug, Clone, Copy)]
1357pub struct IchimokuConfig {
1358 pub conversion: usize,
1359 pub base: usize,
1360 pub lagging: usize,
1361 pub displacement: usize,
1362}
1363
1364impl IchimokuConfig {
1365 pub fn conversion_line(&self) -> IchimokuConversionRef {
1367 IchimokuConversionRef {
1368 conversion: self.conversion,
1369 base: self.base,
1370 lagging: self.lagging,
1371 displacement: self.displacement,
1372 }
1373 }
1374
1375 pub fn base_line(&self) -> IchimokuBaseRef {
1377 IchimokuBaseRef {
1378 conversion: self.conversion,
1379 base: self.base,
1380 lagging: self.lagging,
1381 displacement: self.displacement,
1382 }
1383 }
1384
1385 pub fn leading_span_a(&self) -> IchimokuLeadingARef {
1387 IchimokuLeadingARef {
1388 conversion: self.conversion,
1389 base: self.base,
1390 lagging: self.lagging,
1391 displacement: self.displacement,
1392 }
1393 }
1394
1395 pub fn leading_span_b(&self) -> IchimokuLeadingBRef {
1397 IchimokuLeadingBRef {
1398 conversion: self.conversion,
1399 base: self.base,
1400 lagging: self.lagging,
1401 displacement: self.displacement,
1402 }
1403 }
1404
1405 pub fn lagging_span(&self) -> IchimokuLaggingRef {
1407 IchimokuLaggingRef {
1408 conversion: self.conversion,
1409 base: self.base,
1410 lagging: self.lagging,
1411 displacement: self.displacement,
1412 }
1413 }
1414}
1415
1416#[inline]
1418pub fn ichimoku() -> IchimokuConfig {
1419 IchimokuConfig {
1420 conversion: 9,
1421 base: 26,
1422 lagging: 52,
1423 displacement: 26,
1424 }
1425}
1426
1427#[inline]
1429pub fn ichimoku_custom(
1430 conversion: usize,
1431 base: usize,
1432 lagging: usize,
1433 displacement: usize,
1434) -> IchimokuConfig {
1435 IchimokuConfig {
1436 conversion,
1437 base,
1438 lagging,
1439 displacement,
1440 }
1441}
1442
1443#[derive(Debug, Clone, Copy)]
1445pub struct IchimokuConversionRef {
1446 pub conversion: usize,
1447 pub base: usize,
1448 pub lagging: usize,
1449 pub displacement: usize,
1450}
1451
1452impl IndicatorRef for IchimokuConversionRef {
1453 fn key(&self) -> String {
1454 format!(
1455 "ichimoku_conversion_{}_{}_{}_{}",
1456 self.conversion, self.base, self.lagging, self.displacement
1457 )
1458 }
1459
1460 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1461 vec![(
1462 self.key(),
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(&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)]
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 format!(
1493 "ichimoku_base_{}_{}_{}_{}",
1494 self.conversion, self.base, self.lagging, self.displacement
1495 )
1496 }
1497
1498 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1499 vec![(
1500 self.key(),
1501 Indicator::Ichimoku {
1502 conversion: self.conversion,
1503 base: self.base,
1504 lagging: self.lagging,
1505 displacement: self.displacement,
1506 },
1507 )]
1508 }
1509
1510 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1511 ctx.indicator(&self.key())
1512 }
1513
1514 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1515 ctx.indicator_prev(&self.key())
1516 }
1517}
1518
1519#[derive(Debug, Clone, Copy)]
1521pub struct IchimokuLeadingARef {
1522 pub conversion: usize,
1523 pub base: usize,
1524 pub lagging: usize,
1525 pub displacement: usize,
1526}
1527
1528impl IndicatorRef for IchimokuLeadingARef {
1529 fn key(&self) -> String {
1530 format!(
1531 "ichimoku_leading_a_{}_{}_{}_{}",
1532 self.conversion, self.base, self.lagging, self.displacement
1533 )
1534 }
1535
1536 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1537 vec![(
1538 self.key(),
1539 Indicator::Ichimoku {
1540 conversion: self.conversion,
1541 base: self.base,
1542 lagging: self.lagging,
1543 displacement: self.displacement,
1544 },
1545 )]
1546 }
1547
1548 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1549 ctx.indicator(&self.key())
1550 }
1551
1552 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1553 ctx.indicator_prev(&self.key())
1554 }
1555}
1556
1557#[derive(Debug, Clone, Copy)]
1559pub struct IchimokuLeadingBRef {
1560 pub conversion: usize,
1561 pub base: usize,
1562 pub lagging: usize,
1563 pub displacement: usize,
1564}
1565
1566impl IndicatorRef for IchimokuLeadingBRef {
1567 fn key(&self) -> String {
1568 format!(
1569 "ichimoku_leading_b_{}_{}_{}_{}",
1570 self.conversion, self.base, self.lagging, self.displacement
1571 )
1572 }
1573
1574 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1575 vec![(
1576 self.key(),
1577 Indicator::Ichimoku {
1578 conversion: self.conversion,
1579 base: self.base,
1580 lagging: self.lagging,
1581 displacement: self.displacement,
1582 },
1583 )]
1584 }
1585
1586 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1587 ctx.indicator(&self.key())
1588 }
1589
1590 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1591 ctx.indicator_prev(&self.key())
1592 }
1593}
1594
1595#[derive(Debug, Clone, Copy)]
1597pub struct IchimokuLaggingRef {
1598 pub conversion: usize,
1599 pub base: usize,
1600 pub lagging: usize,
1601 pub displacement: usize,
1602}
1603
1604impl IndicatorRef for IchimokuLaggingRef {
1605 fn key(&self) -> String {
1606 format!(
1607 "ichimoku_lagging_{}_{}_{}_{}",
1608 self.conversion, self.base, self.lagging, self.displacement
1609 )
1610 }
1611
1612 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1613 vec![(
1614 self.key(),
1615 Indicator::Ichimoku {
1616 conversion: self.conversion,
1617 base: self.base,
1618 lagging: self.lagging,
1619 displacement: self.displacement,
1620 },
1621 )]
1622 }
1623
1624 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1625 ctx.indicator(&self.key())
1626 }
1627
1628 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1629 ctx.indicator_prev(&self.key())
1630 }
1631}
1632
1633#[derive(Debug, Clone, Copy)]
1637pub struct KeltnerConfig {
1638 pub period: usize,
1639 pub multiplier: f64,
1640 pub atr_period: usize,
1641}
1642
1643impl KeltnerConfig {
1644 pub fn upper(&self) -> KeltnerUpperRef {
1646 KeltnerUpperRef {
1647 period: self.period,
1648 multiplier: self.multiplier,
1649 atr_period: self.atr_period,
1650 }
1651 }
1652
1653 pub fn middle(&self) -> KeltnerMiddleRef {
1655 KeltnerMiddleRef {
1656 period: self.period,
1657 multiplier: self.multiplier,
1658 atr_period: self.atr_period,
1659 }
1660 }
1661
1662 pub fn lower(&self) -> KeltnerLowerRef {
1664 KeltnerLowerRef {
1665 period: self.period,
1666 multiplier: self.multiplier,
1667 atr_period: self.atr_period,
1668 }
1669 }
1670}
1671
1672#[inline]
1674pub fn keltner(period: usize, multiplier: f64, atr_period: usize) -> KeltnerConfig {
1675 KeltnerConfig {
1676 period,
1677 multiplier,
1678 atr_period,
1679 }
1680}
1681
1682#[derive(Debug, Clone, Copy)]
1684pub struct KeltnerUpperRef {
1685 pub period: usize,
1686 pub multiplier: f64,
1687 pub atr_period: usize,
1688}
1689
1690impl IndicatorRef for KeltnerUpperRef {
1691 fn key(&self) -> String {
1692 format!(
1693 "keltner_upper_{}_{}_{}",
1694 self.period, self.multiplier, self.atr_period
1695 )
1696 }
1697
1698 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1699 vec![(
1700 self.key(),
1701 Indicator::KeltnerChannels {
1702 period: self.period,
1703 multiplier: self.multiplier,
1704 atr_period: self.atr_period,
1705 },
1706 )]
1707 }
1708
1709 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1710 ctx.indicator(&self.key())
1711 }
1712
1713 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1714 ctx.indicator_prev(&self.key())
1715 }
1716}
1717
1718#[derive(Debug, Clone, Copy)]
1720pub struct KeltnerMiddleRef {
1721 pub period: usize,
1722 pub multiplier: f64,
1723 pub atr_period: usize,
1724}
1725
1726impl IndicatorRef for KeltnerMiddleRef {
1727 fn key(&self) -> String {
1728 format!(
1729 "keltner_middle_{}_{}_{}",
1730 self.period, self.multiplier, self.atr_period
1731 )
1732 }
1733
1734 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1735 vec![(
1736 self.key(),
1737 Indicator::KeltnerChannels {
1738 period: self.period,
1739 multiplier: self.multiplier,
1740 atr_period: self.atr_period,
1741 },
1742 )]
1743 }
1744
1745 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1746 ctx.indicator(&self.key())
1747 }
1748
1749 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1750 ctx.indicator_prev(&self.key())
1751 }
1752}
1753
1754#[derive(Debug, Clone, Copy)]
1756pub struct KeltnerLowerRef {
1757 pub period: usize,
1758 pub multiplier: f64,
1759 pub atr_period: usize,
1760}
1761
1762impl IndicatorRef for KeltnerLowerRef {
1763 fn key(&self) -> String {
1764 format!(
1765 "keltner_lower_{}_{}_{}",
1766 self.period, self.multiplier, self.atr_period
1767 )
1768 }
1769
1770 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1771 vec![(
1772 self.key(),
1773 Indicator::KeltnerChannels {
1774 period: self.period,
1775 multiplier: self.multiplier,
1776 atr_period: self.atr_period,
1777 },
1778 )]
1779 }
1780
1781 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1782 ctx.indicator(&self.key())
1783 }
1784
1785 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1786 ctx.indicator_prev(&self.key())
1787 }
1788}
1789
1790#[derive(Debug, Clone, Copy)]
1794pub struct ParabolicSarConfig {
1795 pub step: f64,
1796 pub max: f64,
1797}
1798
1799#[inline]
1801pub fn parabolic_sar(step: f64, max: f64) -> ParabolicSarRef {
1802 ParabolicSarRef { step, max }
1803}
1804
1805#[derive(Debug, Clone, Copy)]
1807pub struct ParabolicSarRef {
1808 pub step: f64,
1809 pub max: f64,
1810}
1811
1812impl IndicatorRef for ParabolicSarRef {
1813 fn key(&self) -> String {
1814 format!("psar_{}_{}", self.step, self.max)
1815 }
1816
1817 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1818 vec![(
1819 self.key(),
1820 Indicator::ParabolicSar {
1821 step: self.step,
1822 max: self.max,
1823 },
1824 )]
1825 }
1826
1827 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1828 ctx.indicator(&self.key())
1829 }
1830
1831 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1832 ctx.indicator_prev(&self.key())
1833 }
1834}
1835
1836#[derive(Debug, Clone, Copy)]
1840pub struct AlmaConfig {
1841 pub period: usize,
1842 pub offset: f64,
1843 pub sigma: f64,
1844}
1845
1846#[inline]
1848pub fn alma(period: usize, offset: f64, sigma: f64) -> AlmaRef {
1849 AlmaRef {
1850 period,
1851 offset,
1852 sigma,
1853 }
1854}
1855
1856#[derive(Debug, Clone, Copy)]
1858pub struct AlmaRef {
1859 pub period: usize,
1860 pub offset: f64,
1861 pub sigma: f64,
1862}
1863
1864impl IndicatorRef for AlmaRef {
1865 fn key(&self) -> String {
1866 format!("alma_{}_{}_{}", self.period, self.offset, self.sigma)
1867 }
1868
1869 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1870 vec![(
1871 self.key(),
1872 Indicator::Alma {
1873 period: self.period,
1874 offset: self.offset,
1875 sigma: self.sigma,
1876 },
1877 )]
1878 }
1879
1880 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1881 ctx.indicator(&self.key())
1882 }
1883
1884 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1885 ctx.indicator_prev(&self.key())
1886 }
1887}
1888
1889#[derive(Debug, Clone, Copy)]
1909pub struct StochasticRsiConfig {
1910 pub rsi_period: usize,
1911 pub stoch_period: usize,
1912 pub k_period: usize,
1913 pub d_period: usize,
1914}
1915
1916impl StochasticRsiConfig {
1917 pub fn k(&self) -> StochasticRsiRef {
1919 StochasticRsiRef {
1920 rsi_period: self.rsi_period,
1921 stoch_period: self.stoch_period,
1922 k_period: self.k_period,
1923 d_period: self.d_period,
1924 }
1925 }
1926
1927 pub fn d(&self) -> StochasticRsiDRef {
1929 StochasticRsiDRef {
1930 rsi_period: self.rsi_period,
1931 stoch_period: self.stoch_period,
1932 k_period: self.k_period,
1933 d_period: self.d_period,
1934 }
1935 }
1936}
1937
1938#[inline]
1945pub fn stochastic_rsi(
1946 rsi_period: usize,
1947 stoch_period: usize,
1948 k_period: usize,
1949 d_period: usize,
1950) -> StochasticRsiConfig {
1951 StochasticRsiConfig {
1952 rsi_period,
1953 stoch_period,
1954 k_period,
1955 d_period,
1956 }
1957}
1958
1959#[derive(Debug, Clone, Copy)]
1961pub struct StochasticRsiRef {
1962 pub rsi_period: usize,
1963 pub stoch_period: usize,
1964 pub k_period: usize,
1965 pub d_period: usize,
1966}
1967
1968impl IndicatorRef for StochasticRsiRef {
1969 fn key(&self) -> String {
1970 format!(
1971 "stoch_rsi_k_{}_{}_{}_{}",
1972 self.rsi_period, self.stoch_period, self.k_period, self.d_period
1973 )
1974 }
1975
1976 fn required_indicators(&self) -> Vec<(String, Indicator)> {
1977 vec![(
1978 self.key(),
1979 Indicator::StochasticRsi {
1980 rsi_period: self.rsi_period,
1981 stoch_period: self.stoch_period,
1982 k_period: self.k_period,
1983 d_period: self.d_period,
1984 },
1985 )]
1986 }
1987
1988 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
1989 ctx.indicator(&self.key())
1990 }
1991
1992 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
1993 ctx.indicator_prev(&self.key())
1994 }
1995}
1996
1997#[derive(Debug, Clone, Copy)]
1999pub struct StochasticRsiDRef {
2000 pub rsi_period: usize,
2001 pub stoch_period: usize,
2002 pub k_period: usize,
2003 pub d_period: usize,
2004}
2005
2006impl IndicatorRef for StochasticRsiDRef {
2007 fn key(&self) -> String {
2008 format!(
2009 "stoch_rsi_d_{}_{}_{}_{}",
2010 self.rsi_period, self.stoch_period, self.k_period, self.d_period
2011 )
2012 }
2013
2014 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2015 let k_key = format!(
2018 "stoch_rsi_k_{}_{}_{}_{}",
2019 self.rsi_period, self.stoch_period, self.k_period, self.d_period
2020 );
2021 vec![(
2022 k_key,
2023 Indicator::StochasticRsi {
2024 rsi_period: self.rsi_period,
2025 stoch_period: self.stoch_period,
2026 k_period: self.k_period,
2027 d_period: self.d_period,
2028 },
2029 )]
2030 }
2031
2032 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2033 ctx.indicator(&self.key())
2034 }
2035
2036 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2037 ctx.indicator_prev(&self.key())
2038 }
2039}
2040
2041#[derive(Debug, Clone, Copy)]
2045pub struct AwesomeOscillatorRef {
2046 pub fast: usize,
2047 pub slow: usize,
2048}
2049
2050#[inline]
2052pub fn awesome_oscillator(fast: usize, slow: usize) -> AwesomeOscillatorRef {
2053 AwesomeOscillatorRef { fast, slow }
2054}
2055
2056impl IndicatorRef for AwesomeOscillatorRef {
2057 fn key(&self) -> String {
2058 format!("ao_{}_{}", self.fast, self.slow)
2059 }
2060
2061 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2062 vec![(
2063 self.key(),
2064 Indicator::AwesomeOscillator {
2065 fast: self.fast,
2066 slow: self.slow,
2067 },
2068 )]
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 CoppockCurveRef {
2085 pub wma_period: usize,
2086 pub long_roc: usize,
2087 pub short_roc: usize,
2088}
2089
2090#[inline]
2092pub fn coppock_curve(wma_period: usize, long_roc: usize, short_roc: usize) -> CoppockCurveRef {
2093 CoppockCurveRef {
2094 wma_period,
2095 long_roc,
2096 short_roc,
2097 }
2098}
2099
2100impl IndicatorRef for CoppockCurveRef {
2101 fn key(&self) -> String {
2102 format!(
2103 "coppock_{}_{}_{}",
2104 self.wma_period, self.long_roc, self.short_roc
2105 )
2106 }
2107
2108 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2109 vec![(
2110 self.key(),
2111 Indicator::CoppockCurve {
2112 wma_period: self.wma_period,
2113 long_roc: self.long_roc,
2114 short_roc: self.short_roc,
2115 },
2116 )]
2117 }
2118
2119 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2120 ctx.indicator(&self.key())
2121 }
2122
2123 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2124 ctx.indicator_prev(&self.key())
2125 }
2126}
2127
2128#[derive(Debug, Clone, Copy)]
2132pub struct ChoppinessIndexRef(pub usize);
2133
2134#[inline]
2136pub fn choppiness_index(period: usize) -> ChoppinessIndexRef {
2137 ChoppinessIndexRef(period)
2138}
2139
2140impl IndicatorRef for ChoppinessIndexRef {
2141 fn key(&self) -> String {
2142 format!("chop_{}", self.0)
2143 }
2144
2145 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2146 vec![(self.key(), Indicator::ChoppinessIndex(self.0))]
2147 }
2148
2149 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2150 ctx.indicator(&self.key())
2151 }
2152
2153 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2154 ctx.indicator_prev(&self.key())
2155 }
2156}
2157
2158#[derive(Debug, Clone, Copy)]
2162pub struct TrueRangeRef;
2163
2164#[inline]
2166pub fn true_range() -> TrueRangeRef {
2167 TrueRangeRef
2168}
2169
2170impl IndicatorRef for TrueRangeRef {
2171 fn key(&self) -> String {
2172 "true_range".to_string()
2173 }
2174
2175 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2176 vec![(self.key(), Indicator::TrueRange)]
2177 }
2178
2179 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2180 ctx.indicator(&self.key())
2181 }
2182
2183 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2184 ctx.indicator_prev(&self.key())
2185 }
2186}
2187
2188#[derive(Debug, Clone, Copy)]
2192pub struct ChaikinOscillatorRef;
2193
2194#[inline]
2196pub fn chaikin_oscillator() -> ChaikinOscillatorRef {
2197 ChaikinOscillatorRef
2198}
2199
2200impl IndicatorRef for ChaikinOscillatorRef {
2201 fn key(&self) -> String {
2202 "chaikin_osc".to_string()
2203 }
2204
2205 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2206 vec![(self.key(), Indicator::ChaikinOscillator)]
2207 }
2208
2209 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2210 ctx.indicator(&self.key())
2211 }
2212
2213 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2214 ctx.indicator_prev(&self.key())
2215 }
2216}
2217
2218#[derive(Debug, Clone, Copy)]
2222pub struct AccumulationDistributionRef;
2223
2224#[inline]
2226pub fn accumulation_distribution() -> AccumulationDistributionRef {
2227 AccumulationDistributionRef
2228}
2229
2230impl IndicatorRef for AccumulationDistributionRef {
2231 fn key(&self) -> String {
2232 "ad".to_string()
2233 }
2234
2235 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2236 vec![(self.key(), Indicator::AccumulationDistribution)]
2237 }
2238
2239 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2240 ctx.indicator(&self.key())
2241 }
2242
2243 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2244 ctx.indicator_prev(&self.key())
2245 }
2246}
2247
2248#[derive(Debug, Clone, Copy)]
2252pub struct BalanceOfPowerRef(pub Option<usize>);
2253
2254#[inline]
2256pub fn balance_of_power(period: Option<usize>) -> BalanceOfPowerRef {
2257 BalanceOfPowerRef(period)
2258}
2259
2260impl IndicatorRef for BalanceOfPowerRef {
2261 fn key(&self) -> String {
2262 match self.0 {
2263 Some(p) => format!("bop_{}", p),
2264 None => "bop".to_string(),
2265 }
2266 }
2267
2268 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2269 vec![(self.key(), Indicator::BalanceOfPower(self.0))]
2270 }
2271
2272 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2273 ctx.indicator(&self.key())
2274 }
2275
2276 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2277 ctx.indicator_prev(&self.key())
2278 }
2279}
2280
2281#[derive(Debug, Clone, Copy)]
2285pub struct BullPowerRef(pub usize);
2286
2287#[inline]
2289pub fn bull_power(period: usize) -> BullPowerRef {
2290 BullPowerRef(period)
2291}
2292
2293impl IndicatorRef for BullPowerRef {
2294 fn key(&self) -> String {
2295 format!("bull_power_{}", self.0)
2296 }
2297
2298 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2299 vec![(self.key(), Indicator::BullBearPower(self.0))]
2300 }
2301
2302 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2303 ctx.indicator(&self.key())
2304 }
2305
2306 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2307 ctx.indicator_prev(&self.key())
2308 }
2309}
2310
2311#[derive(Debug, Clone, Copy)]
2313pub struct BearPowerRef(pub usize);
2314
2315#[inline]
2317pub fn bear_power(period: usize) -> BearPowerRef {
2318 BearPowerRef(period)
2319}
2320
2321impl IndicatorRef for BearPowerRef {
2322 fn key(&self) -> String {
2323 format!("bear_power_{}", self.0)
2324 }
2325
2326 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2327 vec![(self.key(), Indicator::BullBearPower(self.0))]
2328 }
2329
2330 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2331 ctx.indicator(&self.key())
2332 }
2333
2334 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2335 ctx.indicator_prev(&self.key())
2336 }
2337}
2338
2339#[derive(Debug, Clone, Copy)]
2343pub struct ElderBullPowerRef(pub usize);
2344
2345#[inline]
2347pub fn elder_bull_power(period: usize) -> ElderBullPowerRef {
2348 ElderBullPowerRef(period)
2349}
2350
2351impl IndicatorRef for ElderBullPowerRef {
2352 fn key(&self) -> String {
2353 format!("elder_bull_{}", self.0)
2354 }
2355
2356 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2357 vec![(self.key(), Indicator::ElderRay(self.0))]
2358 }
2359
2360 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2361 ctx.indicator(&self.key())
2362 }
2363
2364 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2365 ctx.indicator_prev(&self.key())
2366 }
2367}
2368
2369#[derive(Debug, Clone, Copy)]
2371pub struct ElderBearPowerRef(pub usize);
2372
2373#[inline]
2375pub fn elder_bear_power(period: usize) -> ElderBearPowerRef {
2376 ElderBearPowerRef(period)
2377}
2378
2379impl IndicatorRef for ElderBearPowerRef {
2380 fn key(&self) -> String {
2381 format!("elder_bear_{}", self.0)
2382 }
2383
2384 fn required_indicators(&self) -> Vec<(String, Indicator)> {
2385 vec![(self.key(), Indicator::ElderRay(self.0))]
2386 }
2387
2388 fn value(&self, ctx: &StrategyContext) -> Option<f64> {
2389 ctx.indicator(&self.key())
2390 }
2391
2392 fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
2393 ctx.indicator_prev(&self.key())
2394 }
2395}
2396
2397#[cfg(test)]
2398mod tests {
2399 use super::*;
2400
2401 #[test]
2402 fn test_moving_average_keys() {
2403 assert_eq!(sma(20).key(), "sma_20");
2404 assert_eq!(ema(12).key(), "ema_12");
2405 assert_eq!(wma(14).key(), "wma_14");
2406 assert_eq!(dema(21).key(), "dema_21");
2407 assert_eq!(tema(21).key(), "tema_21");
2408 assert_eq!(hma(9).key(), "hma_9");
2409 assert_eq!(vwma(20).key(), "vwma_20");
2410 assert_eq!(mcginley(14).key(), "mcginley_14");
2411 assert_eq!(alma(9, 0.85, 6.0).key(), "alma_9_0.85_6");
2412 }
2413
2414 #[test]
2415 fn test_oscillator_keys() {
2416 assert_eq!(rsi(14).key(), "rsi_14");
2417 assert_eq!(cci(20).key(), "cci_20");
2418 assert_eq!(williams_r(14).key(), "williams_r_14");
2419 assert_eq!(cmo(14).key(), "cmo_14");
2420 assert_eq!(
2422 stochastic_rsi(14, 14, 3, 3).k().key(),
2423 "stoch_rsi_k_14_14_3_3"
2424 );
2425 assert_eq!(
2426 stochastic_rsi(14, 14, 3, 3).d().key(),
2427 "stoch_rsi_d_14_14_3_3"
2428 );
2429 assert_eq!(awesome_oscillator(5, 34).key(), "ao_5_34");
2430 assert_eq!(choppiness_index(14).key(), "chop_14");
2431 }
2432
2433 #[test]
2434 fn test_macd_keys() {
2435 let m = macd(12, 26, 9);
2436 assert_eq!(m.line().key(), "macd_line_12_26_9");
2437 assert_eq!(m.signal_line().key(), "macd_signal_12_26_9");
2438 assert_eq!(m.histogram().key(), "macd_histogram_12_26_9");
2439 }
2440
2441 #[test]
2442 fn test_bollinger_keys() {
2443 let bb = bollinger(20, 2.0);
2444 assert_eq!(bb.upper().key(), "bollinger_upper_20_2");
2445 assert_eq!(bb.middle().key(), "bollinger_middle_20_2");
2446 assert_eq!(bb.lower().key(), "bollinger_lower_20_2");
2447 }
2448
2449 #[test]
2450 fn test_donchian_keys() {
2451 let dc = donchian(20);
2452 assert_eq!(dc.upper().key(), "donchian_upper_20");
2453 assert_eq!(dc.middle().key(), "donchian_middle_20");
2454 assert_eq!(dc.lower().key(), "donchian_lower_20");
2455 }
2456
2457 #[test]
2458 fn test_supertrend_keys() {
2459 let st = supertrend(10, 3.0);
2460 assert_eq!(st.value().key(), "supertrend_value_10_3");
2461 assert_eq!(st.uptrend().key(), "supertrend_uptrend_10_3");
2462 }
2463
2464 #[test]
2465 fn test_stochastic_keys() {
2466 let stoch = stochastic(14, 3, 3);
2467 assert_eq!(stoch.k().key(), "stochastic_k_14_3_3");
2468 assert_eq!(stoch.d().key(), "stochastic_d_14_3_3");
2469 }
2470
2471 #[test]
2472 fn test_aroon_keys() {
2473 let ar = aroon(25);
2474 assert_eq!(ar.up().key(), "aroon_up_25");
2475 assert_eq!(ar.down().key(), "aroon_down_25");
2476 }
2477
2478 #[test]
2479 fn test_ichimoku_keys() {
2480 let ich = ichimoku();
2481 assert_eq!(
2482 ich.conversion_line().key(),
2483 "ichimoku_conversion_9_26_52_26"
2484 );
2485 assert_eq!(ich.base_line().key(), "ichimoku_base_9_26_52_26");
2486 assert_eq!(ich.leading_span_a().key(), "ichimoku_leading_a_9_26_52_26");
2487 assert_eq!(ich.leading_span_b().key(), "ichimoku_leading_b_9_26_52_26");
2488 assert_eq!(ich.lagging_span().key(), "ichimoku_lagging_9_26_52_26");
2489 }
2490
2491 #[test]
2492 fn test_keltner_keys() {
2493 let kc = keltner(20, 2.0, 10);
2494 assert_eq!(kc.upper().key(), "keltner_upper_20_2_10");
2495 assert_eq!(kc.middle().key(), "keltner_middle_20_2_10");
2496 assert_eq!(kc.lower().key(), "keltner_lower_20_2_10");
2497 }
2498
2499 #[test]
2500 fn test_volume_keys() {
2501 assert_eq!(obv().key(), "obv");
2502 assert_eq!(vwap().key(), "vwap");
2503 assert_eq!(mfi(14).key(), "mfi_14");
2504 assert_eq!(cmf(20).key(), "cmf_20");
2505 assert_eq!(chaikin_oscillator().key(), "chaikin_osc");
2506 assert_eq!(accumulation_distribution().key(), "ad");
2507 assert_eq!(balance_of_power(Some(14)).key(), "bop_14");
2508 assert_eq!(balance_of_power(None).key(), "bop");
2509 }
2510
2511 #[test]
2512 fn test_power_keys() {
2513 assert_eq!(bull_power(13).key(), "bull_power_13");
2514 assert_eq!(bear_power(13).key(), "bear_power_13");
2515 assert_eq!(elder_bull_power(13).key(), "elder_bull_13");
2516 assert_eq!(elder_bear_power(13).key(), "elder_bear_13");
2517 }
2518
2519 #[test]
2520 fn test_other_keys() {
2521 assert_eq!(parabolic_sar(0.02, 0.2).key(), "psar_0.02_0.2");
2522 assert_eq!(true_range().key(), "true_range");
2523 assert_eq!(coppock_curve(10, 14, 11).key(), "coppock_10_14_11");
2524 }
2525
2526 #[test]
2527 fn test_required_indicators() {
2528 let sma_ref = sma(20);
2529 let indicators = sma_ref.required_indicators();
2530 assert_eq!(indicators.len(), 1);
2531 assert_eq!(indicators[0].0, "sma_20");
2532 assert!(matches!(indicators[0].1, Indicator::Sma(20)));
2533 }
2534}