ta_benchmarks/
catalogue_execution.rs1use crate::catalogue_cases::{CaseKind, CaseSpec};
8
9#[derive(Clone, Copy, Debug, PartialEq, Eq)]
11pub struct CaseAdapter {
12 kind: CaseKind,
13}
14
15#[derive(Clone, Copy, Debug, PartialEq, Eq)]
17pub struct AdapterContract {
18 pub parameters: &'static str,
19 pub output_kind: &'static str,
20 pub output_arity: usize,
21}
22
23impl CaseAdapter {
24 #[must_use]
25 pub const fn new(kind: CaseKind) -> Self {
26 Self { kind }
27 }
28
29 #[must_use]
30 pub const fn kind(self) -> CaseKind {
31 self.kind
32 }
33
34 #[must_use]
36 pub const fn contract(self) -> AdapterContract {
37 match self.kind {
38 CaseKind::Sma => AdapterContract {
39 parameters: "timeperiod=14",
40 output_kind: "float",
41 output_arity: 1,
42 },
43 CaseKind::Bbands => AdapterContract {
44 parameters: "timeperiod=20;nbdevup=2;nbdevdn=2;matype=SMA",
45 output_kind: "float",
46 output_arity: 3,
47 },
48 CaseKind::Rsi => AdapterContract {
49 parameters: "timeperiod=14",
50 output_kind: "float",
51 output_arity: 1,
52 },
53 CaseKind::Macd => AdapterContract {
54 parameters: "fastperiod=12;slowperiod=26;signalperiod=9",
55 output_kind: "float",
56 output_arity: 3,
57 },
58 CaseKind::Atr | CaseKind::Adx | CaseKind::LinearReg => AdapterContract {
59 parameters: "timeperiod=14",
60 output_kind: "float",
61 output_arity: 1,
62 },
63 CaseKind::HtDcPhase
64 | CaseKind::TypPrice
65 | CaseKind::Obv
66 | CaseKind::Sin
67 | CaseKind::Add => AdapterContract {
68 parameters: "none",
69 output_kind: "float",
70 output_arity: 1,
71 },
72 CaseKind::CdlDoji | CaseKind::CdlEngulfing | CaseKind::Cdl3WhiteSoldiers => {
73 AdapterContract {
74 parameters: "candle_settings=TA-Lib defaults",
75 output_kind: "integer",
76 output_arity: 1,
77 }
78 }
79 }
80 }
81
82 pub fn validate_spec(self, spec: &CaseSpec) -> Result<(), String> {
84 let contract = self.contract();
85 if (spec.parameters, spec.output_kind, spec.output_arity)
86 != (
87 contract.parameters,
88 contract.output_kind,
89 contract.output_arity,
90 )
91 {
92 return Err(format!(
93 "case {} manifest metadata differs from executable adapter contract",
94 spec.id
95 ));
96 }
97 Ok(())
98 }
99
100 pub fn execute<C, O>(self, operations: &mut O, context: C) -> O::Output
105 where
106 O: CaseOperations<C>,
107 {
108 match self.kind {
109 CaseKind::Sma => operations.sma(context),
110 CaseKind::Bbands => operations.bbands(context),
111 CaseKind::Rsi => operations.rsi(context),
112 CaseKind::Macd => operations.macd(context),
113 CaseKind::Atr => operations.atr(context),
114 CaseKind::Adx => operations.adx(context),
115 CaseKind::HtDcPhase => operations.ht_dc_phase(context),
116 CaseKind::CdlDoji => operations.cdl_doji(context),
117 CaseKind::CdlEngulfing => operations.cdl_engulfing(context),
118 CaseKind::Cdl3WhiteSoldiers => operations.cdl_3_white_soldiers(context),
119 CaseKind::LinearReg => operations.linear_reg(context),
120 CaseKind::TypPrice => operations.typ_price(context),
121 CaseKind::Obv => operations.obv(context),
122 CaseKind::Sin => operations.sin(context),
123 CaseKind::Add => operations.add(context),
124 }
125 }
126}
127
128pub trait CaseOperations<Context> {
134 type Output;
135
136 fn sma(&mut self, context: Context) -> Self::Output;
137 fn bbands(&mut self, context: Context) -> Self::Output;
138 fn rsi(&mut self, context: Context) -> Self::Output;
139 fn macd(&mut self, context: Context) -> Self::Output;
140 fn atr(&mut self, context: Context) -> Self::Output;
141 fn adx(&mut self, context: Context) -> Self::Output;
142 fn ht_dc_phase(&mut self, context: Context) -> Self::Output;
143 fn cdl_doji(&mut self, context: Context) -> Self::Output;
144 fn cdl_engulfing(&mut self, context: Context) -> Self::Output;
145 fn cdl_3_white_soldiers(&mut self, context: Context) -> Self::Output;
146 fn linear_reg(&mut self, context: Context) -> Self::Output;
147 fn typ_price(&mut self, context: Context) -> Self::Output;
148 fn obv(&mut self, context: Context) -> Self::Output;
149 fn sin(&mut self, context: Context) -> Self::Output;
150 fn add(&mut self, context: Context) -> Self::Output;
151}