Skip to main content

vector_ta/indicators/
registry.rs

1use crate::indicators::moving_averages::param_schema::{ma_param_schema, MaParamKind};
2use crate::indicators::moving_averages::registry::list_moving_averages;
3use once_cell::sync::Lazy;
4use serde::Serialize;
5use std::collections::HashMap;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
8#[serde(rename_all = "snake_case")]
9pub enum IndicatorParamKind {
10    Int,
11    Float,
12    Bool,
13    EnumString,
14}
15
16#[derive(Debug, Clone, Copy, PartialEq, Serialize)]
17#[serde(rename_all = "snake_case")]
18pub enum ParamValueStatic {
19    Int(i64),
20    Float(f64),
21    Bool(bool),
22    EnumString(&'static str),
23}
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
26#[serde(rename_all = "snake_case")]
27pub enum IndicatorValueType {
28    F64,
29    F32,
30    I32,
31    Bool,
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
35#[serde(rename_all = "snake_case")]
36pub enum IndicatorInputKind {
37    Slice,
38    Candles,
39    Ohlc,
40    Ohlcv,
41    HighLow,
42    CloseVolume,
43}
44
45#[derive(Debug, Clone, Serialize)]
46pub struct IndicatorParamInfo {
47    pub key: &'static str,
48    pub label: &'static str,
49    pub kind: IndicatorParamKind,
50    pub required: bool,
51    pub default: Option<ParamValueStatic>,
52    pub min: Option<f64>,
53    pub max: Option<f64>,
54    pub step: Option<f64>,
55    pub enum_values: &'static [&'static str],
56    pub notes: Option<&'static str>,
57}
58
59#[derive(Debug, Clone, Copy, Serialize)]
60pub struct IndicatorOutputInfo {
61    pub id: &'static str,
62    pub label: &'static str,
63    pub value_type: IndicatorValueType,
64}
65
66#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
67pub struct IndicatorCapabilities {
68    pub supports_cpu_single: bool,
69    pub supports_cpu_batch: bool,
70    pub supports_cuda_single: bool,
71    pub supports_cuda_batch: bool,
72    pub supports_cuda_vram: bool,
73}
74
75#[derive(Debug, Clone, Serialize)]
76pub struct IndicatorInfo {
77    pub id: &'static str,
78    pub label: &'static str,
79    pub category: &'static str,
80    pub dynamic_strategy_eligible: bool,
81    pub input_kind: IndicatorInputKind,
82    pub outputs: Vec<IndicatorOutputInfo>,
83    pub params: Vec<IndicatorParamInfo>,
84    pub capabilities: IndicatorCapabilities,
85    pub notes: Option<&'static str>,
86}
87
88const BUCKET_B_INDICATORS: &[&str] = &[
89    "acosc",
90    "alligator",
91    "alphatrend",
92    "aroon",
93    "aso",
94    "bandpass",
95    "chandelier_exit",
96    "cksp",
97    "correlation_cycle",
98    "damiani_volatmeter",
99    "di",
100    "dm",
101    "donchian",
102    "dvdiqqe",
103    "emd",
104    "eri",
105    "fisher",
106    "fvg_trailing_stop",
107    "gatorosc",
108    "halftrend",
109    "kdj",
110    "keltner",
111    "kst",
112    "lpc",
113    "mab",
114    "macz",
115    "mama",
116    "minmax",
117    "msw",
118    "nadaraya_watson_envelope",
119    "otto",
120    "pma",
121    "prb",
122    "qqe",
123    "range_filter",
124    "rsmk",
125    "squeeze_momentum",
126    "srsi",
127    "supertrend",
128    "vi",
129    "voss",
130    "wavetrend",
131    "wto",
132    "ehlers_pma",
133    "buff_averages",
134    "vwap",
135    "pivot",
136];
137
138const EMPTY_ENUM_VALUES: &[&str] = &[];
139const ENUM_VALUES_TRUE_FALSE: &[&str] = &["true", "false"];
140const ENUM_VALUES_MA_OUTPUT: &[&str] = &["mama", "fama"];
141const ENUM_VALUES_PMA_OUTPUT: &[&str] = &["predict", "trigger"];
142const ENUM_VALUES_BUFF_OUTPUT: &[&str] = &["fast", "slow"];
143
144const OUTPUT_VALUE_F64: IndicatorOutputInfo = IndicatorOutputInfo {
145    id: "value",
146    label: "Value",
147    value_type: IndicatorValueType::F64,
148};
149
150const OUTPUT_VALUE_BOOL: IndicatorOutputInfo = IndicatorOutputInfo {
151    id: "value",
152    label: "Value",
153    value_type: IndicatorValueType::Bool,
154};
155
156const OUTPUT_MATRIX: IndicatorOutputInfo = IndicatorOutputInfo {
157    id: "matrix",
158    label: "Matrix",
159    value_type: IndicatorValueType::Bool,
160};
161
162const OUTPUT_MACD: IndicatorOutputInfo = IndicatorOutputInfo {
163    id: "macd",
164    label: "MACD",
165    value_type: IndicatorValueType::F64,
166};
167const OUTPUT_SIGNAL: IndicatorOutputInfo = IndicatorOutputInfo {
168    id: "signal",
169    label: "Signal",
170    value_type: IndicatorValueType::F64,
171};
172const OUTPUT_HIST: IndicatorOutputInfo = IndicatorOutputInfo {
173    id: "hist",
174    label: "Histogram",
175    value_type: IndicatorValueType::F64,
176};
177const OUTPUT_UPPER: IndicatorOutputInfo = IndicatorOutputInfo {
178    id: "upper",
179    label: "Upper",
180    value_type: IndicatorValueType::F64,
181};
182const OUTPUT_MIDDLE: IndicatorOutputInfo = IndicatorOutputInfo {
183    id: "middle",
184    label: "Middle",
185    value_type: IndicatorValueType::F64,
186};
187const OUTPUT_LOWER: IndicatorOutputInfo = IndicatorOutputInfo {
188    id: "lower",
189    label: "Lower",
190    value_type: IndicatorValueType::F64,
191};
192const OUTPUT_K: IndicatorOutputInfo = IndicatorOutputInfo {
193    id: "k",
194    label: "K",
195    value_type: IndicatorValueType::F64,
196};
197const OUTPUT_D: IndicatorOutputInfo = IndicatorOutputInfo {
198    id: "d",
199    label: "D",
200    value_type: IndicatorValueType::F64,
201};
202const OUTPUT_VPCI: IndicatorOutputInfo = IndicatorOutputInfo {
203    id: "vpci",
204    label: "VPCI",
205    value_type: IndicatorValueType::F64,
206};
207const OUTPUT_VPCIS: IndicatorOutputInfo = IndicatorOutputInfo {
208    id: "vpcis",
209    label: "VPCIS",
210    value_type: IndicatorValueType::F64,
211};
212const OUTPUT_MOMENTUM: IndicatorOutputInfo = IndicatorOutputInfo {
213    id: "momentum",
214    label: "Momentum",
215    value_type: IndicatorValueType::F64,
216};
217const OUTPUT_SQUEEZE: IndicatorOutputInfo = IndicatorOutputInfo {
218    id: "squeeze",
219    label: "Squeeze",
220    value_type: IndicatorValueType::F64,
221};
222const OUTPUT_MAMA: IndicatorOutputInfo = IndicatorOutputInfo {
223    id: "mama",
224    label: "MAMA",
225    value_type: IndicatorValueType::F64,
226};
227const OUTPUT_FAMA: IndicatorOutputInfo = IndicatorOutputInfo {
228    id: "fama",
229    label: "FAMA",
230    value_type: IndicatorValueType::F64,
231};
232const OUTPUT_PREDICT: IndicatorOutputInfo = IndicatorOutputInfo {
233    id: "predict",
234    label: "Predict",
235    value_type: IndicatorValueType::F64,
236};
237const OUTPUT_TRIGGER: IndicatorOutputInfo = IndicatorOutputInfo {
238    id: "trigger",
239    label: "Trigger",
240    value_type: IndicatorValueType::F64,
241};
242const OUTPUT_FAST: IndicatorOutputInfo = IndicatorOutputInfo {
243    id: "fast",
244    label: "Fast",
245    value_type: IndicatorValueType::F64,
246};
247const OUTPUT_SLOW: IndicatorOutputInfo = IndicatorOutputInfo {
248    id: "slow",
249    label: "Slow",
250    value_type: IndicatorValueType::F64,
251};
252const OUTPUT_PLUS: IndicatorOutputInfo = IndicatorOutputInfo {
253    id: "plus",
254    label: "Plus",
255    value_type: IndicatorValueType::F64,
256};
257const OUTPUT_MINUS: IndicatorOutputInfo = IndicatorOutputInfo {
258    id: "minus",
259    label: "Minus",
260    value_type: IndicatorValueType::F64,
261};
262const OUTPUT_UP: IndicatorOutputInfo = IndicatorOutputInfo {
263    id: "up",
264    label: "Up",
265    value_type: IndicatorValueType::F64,
266};
267const OUTPUT_DOWN: IndicatorOutputInfo = IndicatorOutputInfo {
268    id: "down",
269    label: "Down",
270    value_type: IndicatorValueType::F64,
271};
272const OUTPUT_TREND: IndicatorOutputInfo = IndicatorOutputInfo {
273    id: "trend",
274    label: "Trend",
275    value_type: IndicatorValueType::F64,
276};
277const OUTPUT_CHANGED: IndicatorOutputInfo = IndicatorOutputInfo {
278    id: "changed",
279    label: "Changed",
280    value_type: IndicatorValueType::F64,
281};
282const OUTPUT_J: IndicatorOutputInfo = IndicatorOutputInfo {
283    id: "j",
284    label: "J",
285    value_type: IndicatorValueType::F64,
286};
287const OUTPUT_MOMENTUM_SIGNAL: IndicatorOutputInfo = IndicatorOutputInfo {
288    id: "signal",
289    label: "Signal",
290    value_type: IndicatorValueType::F64,
291};
292const OUTPUT_WT1: IndicatorOutputInfo = IndicatorOutputInfo {
293    id: "wt1",
294    label: "WT1",
295    value_type: IndicatorValueType::F64,
296};
297const OUTPUT_WT2: IndicatorOutputInfo = IndicatorOutputInfo {
298    id: "wt2",
299    label: "WT2",
300    value_type: IndicatorValueType::F64,
301};
302const OUTPUT_WT_DIFF: IndicatorOutputInfo = IndicatorOutputInfo {
303    id: "wt_diff",
304    label: "WT Diff",
305    value_type: IndicatorValueType::F64,
306};
307const OUTPUT_WAVETREND1: IndicatorOutputInfo = IndicatorOutputInfo {
308    id: "wavetrend1",
309    label: "WaveTrend 1",
310    value_type: IndicatorValueType::F64,
311};
312const OUTPUT_WAVETREND2: IndicatorOutputInfo = IndicatorOutputInfo {
313    id: "wavetrend2",
314    label: "WaveTrend 2",
315    value_type: IndicatorValueType::F64,
316};
317const OUTPUT_HISTOGRAM: IndicatorOutputInfo = IndicatorOutputInfo {
318    id: "histogram",
319    label: "Histogram",
320    value_type: IndicatorValueType::F64,
321};
322
323const OUTPUTS_VALUE_F64: &[IndicatorOutputInfo] = &[OUTPUT_VALUE_F64];
324const OUTPUTS_VALUE_BOOL: &[IndicatorOutputInfo] = &[OUTPUT_VALUE_BOOL];
325const OUTPUTS_MATRIX_BOOL: &[IndicatorOutputInfo] = &[OUTPUT_MATRIX];
326const OUTPUTS_MACD: &[IndicatorOutputInfo] = &[OUTPUT_MACD, OUTPUT_SIGNAL, OUTPUT_HIST];
327const OUTPUTS_BOLLINGER: &[IndicatorOutputInfo] = &[OUTPUT_UPPER, OUTPUT_MIDDLE, OUTPUT_LOWER];
328const OUTPUTS_STOCH: &[IndicatorOutputInfo] = &[OUTPUT_K, OUTPUT_D];
329const OUTPUTS_VPCI: &[IndicatorOutputInfo] = &[OUTPUT_VPCI, OUTPUT_VPCIS];
330const OUTPUTS_TTM_SQUEEZE: &[IndicatorOutputInfo] = &[OUTPUT_MOMENTUM, OUTPUT_SQUEEZE];
331const OUTPUTS_MAMA: &[IndicatorOutputInfo] = &[OUTPUT_MAMA, OUTPUT_FAMA];
332const OUTPUTS_EHLERS_PMA: &[IndicatorOutputInfo] = &[OUTPUT_PREDICT, OUTPUT_TRIGGER];
333const OUTPUTS_BUFF_AVERAGES: &[IndicatorOutputInfo] = &[OUTPUT_FAST, OUTPUT_SLOW];
334const OUTPUTS_PLUS_MINUS: &[IndicatorOutputInfo] = &[OUTPUT_PLUS, OUTPUT_MINUS];
335const OUTPUTS_UP_DOWN: &[IndicatorOutputInfo] = &[OUTPUT_UP, OUTPUT_DOWN];
336const OUTPUTS_TREND_CHANGED: &[IndicatorOutputInfo] = &[OUTPUT_TREND, OUTPUT_CHANGED];
337const OUTPUTS_KDJ: &[IndicatorOutputInfo] = &[OUTPUT_K, OUTPUT_D, OUTPUT_J];
338const OUTPUTS_SQUEEZE_MOMENTUM: &[IndicatorOutputInfo] =
339    &[OUTPUT_MOMENTUM, OUTPUT_SQUEEZE, OUTPUT_MOMENTUM_SIGNAL];
340const OUTPUTS_WTO: &[IndicatorOutputInfo] =
341    &[OUTPUT_WAVETREND1, OUTPUT_WAVETREND2, OUTPUT_HISTOGRAM];
342const OUTPUTS_WAVETREND: &[IndicatorOutputInfo] = &[OUTPUT_WT1, OUTPUT_WT2, OUTPUT_WT_DIFF];
343const OUTPUTS_ACOSC: &[IndicatorOutputInfo] = &[
344    IndicatorOutputInfo {
345        id: "osc",
346        label: "Oscillator",
347        value_type: IndicatorValueType::F64,
348    },
349    IndicatorOutputInfo {
350        id: "change",
351        label: "Change",
352        value_type: IndicatorValueType::F64,
353    },
354];
355const OUTPUTS_ALLIGATOR: &[IndicatorOutputInfo] = &[
356    IndicatorOutputInfo {
357        id: "jaw",
358        label: "Jaw",
359        value_type: IndicatorValueType::F64,
360    },
361    IndicatorOutputInfo {
362        id: "teeth",
363        label: "Teeth",
364        value_type: IndicatorValueType::F64,
365    },
366    IndicatorOutputInfo {
367        id: "lips",
368        label: "Lips",
369        value_type: IndicatorValueType::F64,
370    },
371];
372const OUTPUTS_K1_K2: &[IndicatorOutputInfo] = &[
373    IndicatorOutputInfo {
374        id: "k1",
375        label: "K1",
376        value_type: IndicatorValueType::F64,
377    },
378    IndicatorOutputInfo {
379        id: "k2",
380        label: "K2",
381        value_type: IndicatorValueType::F64,
382    },
383];
384const OUTPUTS_BULLS_BEARS: &[IndicatorOutputInfo] = &[
385    IndicatorOutputInfo {
386        id: "bulls",
387        label: "Bulls",
388        value_type: IndicatorValueType::F64,
389    },
390    IndicatorOutputInfo {
391        id: "bears",
392        label: "Bears",
393        value_type: IndicatorValueType::F64,
394    },
395];
396const OUTPUTS_BANDPASS: &[IndicatorOutputInfo] = &[
397    IndicatorOutputInfo {
398        id: "bp",
399        label: "BandPass",
400        value_type: IndicatorValueType::F64,
401    },
402    IndicatorOutputInfo {
403        id: "bp_normalized",
404        label: "Normalized",
405        value_type: IndicatorValueType::F64,
406    },
407    OUTPUT_SIGNAL,
408    OUTPUT_TRIGGER,
409];
410const OUTPUTS_LONG_SHORT_STOP: &[IndicatorOutputInfo] = &[
411    IndicatorOutputInfo {
412        id: "long_stop",
413        label: "Long Stop",
414        value_type: IndicatorValueType::F64,
415    },
416    IndicatorOutputInfo {
417        id: "short_stop",
418        label: "Short Stop",
419        value_type: IndicatorValueType::F64,
420    },
421];
422const OUTPUTS_LONG_SHORT_VALUES: &[IndicatorOutputInfo] = &[
423    IndicatorOutputInfo {
424        id: "long_values",
425        label: "Long",
426        value_type: IndicatorValueType::F64,
427    },
428    IndicatorOutputInfo {
429        id: "short_values",
430        label: "Short",
431        value_type: IndicatorValueType::F64,
432    },
433];
434const OUTPUTS_CORRELATION_CYCLE: &[IndicatorOutputInfo] = &[
435    IndicatorOutputInfo {
436        id: "real",
437        label: "Real",
438        value_type: IndicatorValueType::F64,
439    },
440    IndicatorOutputInfo {
441        id: "imag",
442        label: "Imag",
443        value_type: IndicatorValueType::F64,
444    },
445    IndicatorOutputInfo {
446        id: "angle",
447        label: "Angle",
448        value_type: IndicatorValueType::F64,
449    },
450    IndicatorOutputInfo {
451        id: "state",
452        label: "State",
453        value_type: IndicatorValueType::F64,
454    },
455];
456const OUTPUTS_VOL_ANTI: &[IndicatorOutputInfo] = &[
457    IndicatorOutputInfo {
458        id: "vol",
459        label: "Vol",
460        value_type: IndicatorValueType::F64,
461    },
462    IndicatorOutputInfo {
463        id: "anti",
464        label: "Anti",
465        value_type: IndicatorValueType::F64,
466    },
467];
468const OUTPUTS_DVDIQQE: &[IndicatorOutputInfo] = &[
469    IndicatorOutputInfo {
470        id: "dvdi",
471        label: "DVDI",
472        value_type: IndicatorValueType::F64,
473    },
474    IndicatorOutputInfo {
475        id: "fast_tl",
476        label: "Fast TL",
477        value_type: IndicatorValueType::F64,
478    },
479    IndicatorOutputInfo {
480        id: "slow_tl",
481        label: "Slow TL",
482        value_type: IndicatorValueType::F64,
483    },
484    IndicatorOutputInfo {
485        id: "center_line",
486        label: "Center Line",
487        value_type: IndicatorValueType::F64,
488    },
489];
490const OUTPUTS_UPPER_MIDDLE_LOWER_BAND: &[IndicatorOutputInfo] = &[
491    IndicatorOutputInfo {
492        id: "upperband",
493        label: "Upper",
494        value_type: IndicatorValueType::F64,
495    },
496    IndicatorOutputInfo {
497        id: "middleband",
498        label: "Middle",
499        value_type: IndicatorValueType::F64,
500    },
501    IndicatorOutputInfo {
502        id: "lowerband",
503        label: "Lower",
504        value_type: IndicatorValueType::F64,
505    },
506];
507const OUTPUTS_BULL_BEAR: &[IndicatorOutputInfo] = &[
508    IndicatorOutputInfo {
509        id: "bull",
510        label: "Bull",
511        value_type: IndicatorValueType::F64,
512    },
513    IndicatorOutputInfo {
514        id: "bear",
515        label: "Bear",
516        value_type: IndicatorValueType::F64,
517    },
518];
519const OUTPUTS_FVG_TS: &[IndicatorOutputInfo] = &[
520    OUTPUT_UPPER,
521    OUTPUT_LOWER,
522    IndicatorOutputInfo {
523        id: "upper_ts",
524        label: "Upper TS",
525        value_type: IndicatorValueType::F64,
526    },
527    IndicatorOutputInfo {
528        id: "lower_ts",
529        label: "Lower TS",
530        value_type: IndicatorValueType::F64,
531    },
532];
533const OUTPUTS_GATOROSC: &[IndicatorOutputInfo] = &[
534    OUTPUT_UPPER,
535    OUTPUT_LOWER,
536    IndicatorOutputInfo {
537        id: "upper_change",
538        label: "Upper Change",
539        value_type: IndicatorValueType::F64,
540    },
541    IndicatorOutputInfo {
542        id: "lower_change",
543        label: "Lower Change",
544        value_type: IndicatorValueType::F64,
545    },
546];
547const OUTPUTS_HALFTREND: &[IndicatorOutputInfo] = &[
548    IndicatorOutputInfo {
549        id: "halftrend",
550        label: "HalfTrend",
551        value_type: IndicatorValueType::F64,
552    },
553    OUTPUT_TREND,
554    IndicatorOutputInfo {
555        id: "atr_high",
556        label: "ATR High",
557        value_type: IndicatorValueType::F64,
558    },
559    IndicatorOutputInfo {
560        id: "atr_low",
561        label: "ATR Low",
562        value_type: IndicatorValueType::F64,
563    },
564    IndicatorOutputInfo {
565        id: "buy_signal",
566        label: "Buy",
567        value_type: IndicatorValueType::F64,
568    },
569    IndicatorOutputInfo {
570        id: "sell_signal",
571        label: "Sell",
572        value_type: IndicatorValueType::F64,
573    },
574];
575const OUTPUTS_LINE_SIGNAL: &[IndicatorOutputInfo] = &[
576    IndicatorOutputInfo {
577        id: "line",
578        label: "Line",
579        value_type: IndicatorValueType::F64,
580    },
581    OUTPUT_SIGNAL,
582];
583const OUTPUTS_FISHER: &[IndicatorOutputInfo] = &[
584    IndicatorOutputInfo {
585        id: "fisher",
586        label: "Fisher",
587        value_type: IndicatorValueType::F64,
588    },
589    OUTPUT_SIGNAL,
590];
591const OUTPUTS_UPPER_LOWER: &[IndicatorOutputInfo] = &[OUTPUT_UPPER, OUTPUT_LOWER];
592const OUTPUTS_FILTER_BANDS: &[IndicatorOutputInfo] = &[
593    IndicatorOutputInfo {
594        id: "filter",
595        label: "Filter",
596        value_type: IndicatorValueType::F64,
597    },
598    IndicatorOutputInfo {
599        id: "high_band",
600        label: "High Band",
601        value_type: IndicatorValueType::F64,
602    },
603    IndicatorOutputInfo {
604        id: "low_band",
605        label: "Low Band",
606        value_type: IndicatorValueType::F64,
607    },
608];
609const OUTPUTS_MINMAX: &[IndicatorOutputInfo] = &[
610    IndicatorOutputInfo {
611        id: "is_min",
612        label: "Is Min",
613        value_type: IndicatorValueType::F64,
614    },
615    IndicatorOutputInfo {
616        id: "is_max",
617        label: "Is Max",
618        value_type: IndicatorValueType::F64,
619    },
620    IndicatorOutputInfo {
621        id: "last_min",
622        label: "Last Min",
623        value_type: IndicatorValueType::F64,
624    },
625    IndicatorOutputInfo {
626        id: "last_max",
627        label: "Last Max",
628        value_type: IndicatorValueType::F64,
629    },
630];
631const OUTPUTS_SINE_LEAD: &[IndicatorOutputInfo] = &[
632    IndicatorOutputInfo {
633        id: "sine",
634        label: "Sine",
635        value_type: IndicatorValueType::F64,
636    },
637    IndicatorOutputInfo {
638        id: "lead",
639        label: "Lead",
640        value_type: IndicatorValueType::F64,
641    },
642];
643const OUTPUTS_HOTT_LOTT: &[IndicatorOutputInfo] = &[
644    IndicatorOutputInfo {
645        id: "hott",
646        label: "HOTT",
647        value_type: IndicatorValueType::F64,
648    },
649    IndicatorOutputInfo {
650        id: "lott",
651        label: "LOTT",
652        value_type: IndicatorValueType::F64,
653    },
654];
655const OUTPUTS_PRB: &[IndicatorOutputInfo] = &[
656    IndicatorOutputInfo {
657        id: "values",
658        label: "Value",
659        value_type: IndicatorValueType::F64,
660    },
661    IndicatorOutputInfo {
662        id: "upper_band",
663        label: "Upper",
664        value_type: IndicatorValueType::F64,
665    },
666    IndicatorOutputInfo {
667        id: "lower_band",
668        label: "Lower",
669        value_type: IndicatorValueType::F64,
670    },
671];
672const OUTPUTS_INDICATOR_SIGNAL: &[IndicatorOutputInfo] = &[
673    IndicatorOutputInfo {
674        id: "indicator",
675        label: "Indicator",
676        value_type: IndicatorValueType::F64,
677    },
678    OUTPUT_SIGNAL,
679];
680const OUTPUTS_VOSS: &[IndicatorOutputInfo] = &[
681    IndicatorOutputInfo {
682        id: "voss",
683        label: "Voss",
684        value_type: IndicatorValueType::F64,
685    },
686    IndicatorOutputInfo {
687        id: "filt",
688        label: "Filter",
689        value_type: IndicatorValueType::F64,
690    },
691];
692const OUTPUTS_PIVOT: &[IndicatorOutputInfo] = &[
693    IndicatorOutputInfo {
694        id: "pp",
695        label: "PP",
696        value_type: IndicatorValueType::F64,
697    },
698    IndicatorOutputInfo {
699        id: "r1",
700        label: "R1",
701        value_type: IndicatorValueType::F64,
702    },
703    IndicatorOutputInfo {
704        id: "r2",
705        label: "R2",
706        value_type: IndicatorValueType::F64,
707    },
708    IndicatorOutputInfo {
709        id: "r3",
710        label: "R3",
711        value_type: IndicatorValueType::F64,
712    },
713    IndicatorOutputInfo {
714        id: "r4",
715        label: "R4",
716        value_type: IndicatorValueType::F64,
717    },
718    IndicatorOutputInfo {
719        id: "s1",
720        label: "S1",
721        value_type: IndicatorValueType::F64,
722    },
723    IndicatorOutputInfo {
724        id: "s2",
725        label: "S2",
726        value_type: IndicatorValueType::F64,
727    },
728    IndicatorOutputInfo {
729        id: "s3",
730        label: "S3",
731        value_type: IndicatorValueType::F64,
732    },
733    IndicatorOutputInfo {
734        id: "s4",
735        label: "S4",
736        value_type: IndicatorValueType::F64,
737    },
738];
739
740const PARAM_PERIOD: IndicatorParamInfo = IndicatorParamInfo {
741    key: "period",
742    label: "Period",
743    kind: IndicatorParamKind::Int,
744    required: true,
745    default: Some(ParamValueStatic::Int(14)),
746    min: Some(1.0),
747    max: None,
748    step: Some(1.0),
749    enum_values: EMPTY_ENUM_VALUES,
750    notes: None,
751};
752
753const PARAM_OUTPUT_MAMA: IndicatorParamInfo = IndicatorParamInfo {
754    key: "output",
755    label: "Output",
756    kind: IndicatorParamKind::EnumString,
757    required: false,
758    default: Some(ParamValueStatic::EnumString("mama")),
759    min: None,
760    max: None,
761    step: None,
762    enum_values: ENUM_VALUES_MA_OUTPUT,
763    notes: None,
764};
765
766const PARAM_OUTPUT_EHLERS_PMA: IndicatorParamInfo = IndicatorParamInfo {
767    key: "output",
768    label: "Output",
769    kind: IndicatorParamKind::EnumString,
770    required: false,
771    default: Some(ParamValueStatic::EnumString("predict")),
772    min: None,
773    max: None,
774    step: None,
775    enum_values: ENUM_VALUES_PMA_OUTPUT,
776    notes: None,
777};
778
779const PARAM_OUTPUT_BUFF_AVERAGES: IndicatorParamInfo = IndicatorParamInfo {
780    key: "output",
781    label: "Output",
782    kind: IndicatorParamKind::EnumString,
783    required: false,
784    default: Some(ParamValueStatic::EnumString("fast")),
785    min: None,
786    max: None,
787    step: None,
788    enum_values: ENUM_VALUES_BUFF_OUTPUT,
789    notes: None,
790};
791
792const PARAM_ANCHOR: IndicatorParamInfo = IndicatorParamInfo {
793    key: "anchor",
794    label: "Anchor",
795    kind: IndicatorParamKind::EnumString,
796    required: false,
797    default: Some(ParamValueStatic::EnumString("1d")),
798    min: None,
799    max: None,
800    step: None,
801    enum_values: EMPTY_ENUM_VALUES,
802    notes: Some("Anchor string for session boundary"),
803};
804
805const PARAM_STRICT: IndicatorParamInfo = IndicatorParamInfo {
806    key: "strict",
807    label: "Strict",
808    kind: IndicatorParamKind::Bool,
809    required: false,
810    default: Some(ParamValueStatic::Bool(false)),
811    min: None,
812    max: None,
813    step: None,
814    enum_values: ENUM_VALUES_TRUE_FALSE,
815    notes: None,
816};
817
818const PARAM_NONE: &[IndicatorParamInfo] = &[];
819
820const PARAM_RSI_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
821    key: "period",
822    label: "Period",
823    kind: IndicatorParamKind::Int,
824    required: false,
825    default: Some(ParamValueStatic::Int(14)),
826    min: Some(1.0),
827    max: None,
828    step: Some(1.0),
829    enum_values: EMPTY_ENUM_VALUES,
830    notes: None,
831}];
832
833const PARAM_ROC_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
834    key: "period",
835    label: "Period",
836    kind: IndicatorParamKind::Int,
837    required: false,
838    default: Some(ParamValueStatic::Int(9)),
839    min: Some(1.0),
840    max: None,
841    step: Some(1.0),
842    enum_values: EMPTY_ENUM_VALUES,
843    notes: None,
844}];
845
846const PARAM_ADOSC: &[IndicatorParamInfo] = &[
847    IndicatorParamInfo {
848        key: "short_period",
849        label: "Short Period",
850        kind: IndicatorParamKind::Int,
851        required: false,
852        default: Some(ParamValueStatic::Int(3)),
853        min: Some(1.0),
854        max: None,
855        step: Some(1.0),
856        enum_values: EMPTY_ENUM_VALUES,
857        notes: None,
858    },
859    IndicatorParamInfo {
860        key: "long_period",
861        label: "Long Period",
862        kind: IndicatorParamKind::Int,
863        required: false,
864        default: Some(ParamValueStatic::Int(10)),
865        min: Some(1.0),
866        max: None,
867        step: Some(1.0),
868        enum_values: EMPTY_ENUM_VALUES,
869        notes: None,
870    },
871];
872
873const PARAM_AO: &[IndicatorParamInfo] = &[
874    IndicatorParamInfo {
875        key: "short_period",
876        label: "Short Period",
877        kind: IndicatorParamKind::Int,
878        required: false,
879        default: Some(ParamValueStatic::Int(5)),
880        min: Some(1.0),
881        max: None,
882        step: Some(1.0),
883        enum_values: EMPTY_ENUM_VALUES,
884        notes: None,
885    },
886    IndicatorParamInfo {
887        key: "long_period",
888        label: "Long Period",
889        kind: IndicatorParamKind::Int,
890        required: false,
891        default: Some(ParamValueStatic::Int(34)),
892        min: Some(1.0),
893        max: None,
894        step: Some(1.0),
895        enum_values: EMPTY_ENUM_VALUES,
896        notes: None,
897    },
898];
899
900const PARAM_EFI_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
901    key: "period",
902    label: "Period",
903    kind: IndicatorParamKind::Int,
904    required: false,
905    default: Some(ParamValueStatic::Int(13)),
906    min: Some(1.0),
907    max: None,
908    step: Some(1.0),
909    enum_values: EMPTY_ENUM_VALUES,
910    notes: None,
911}];
912
913const PARAM_MFI_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
914    key: "period",
915    label: "Period",
916    kind: IndicatorParamKind::Int,
917    required: false,
918    default: Some(ParamValueStatic::Int(14)),
919    min: Some(1.0),
920    max: None,
921    step: Some(1.0),
922    enum_values: EMPTY_ENUM_VALUES,
923    notes: None,
924}];
925
926const PARAM_MASS_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
927    key: "period",
928    label: "Period",
929    kind: IndicatorParamKind::Int,
930    required: false,
931    default: Some(ParamValueStatic::Int(5)),
932    min: Some(1.0),
933    max: None,
934    step: Some(1.0),
935    enum_values: EMPTY_ENUM_VALUES,
936    notes: None,
937}];
938
939const PARAM_KVO: &[IndicatorParamInfo] = &[
940    IndicatorParamInfo {
941        key: "short_period",
942        label: "Short Period",
943        kind: IndicatorParamKind::Int,
944        required: false,
945        default: Some(ParamValueStatic::Int(2)),
946        min: Some(1.0),
947        max: None,
948        step: Some(1.0),
949        enum_values: EMPTY_ENUM_VALUES,
950        notes: None,
951    },
952    IndicatorParamInfo {
953        key: "long_period",
954        label: "Long Period",
955        kind: IndicatorParamKind::Int,
956        required: false,
957        default: Some(ParamValueStatic::Int(5)),
958        min: Some(1.0),
959        max: None,
960        step: Some(1.0),
961        enum_values: EMPTY_ENUM_VALUES,
962        notes: None,
963    },
964];
965
966const PARAM_VOSC: &[IndicatorParamInfo] = &[
967    IndicatorParamInfo {
968        key: "short_period",
969        label: "Short Period",
970        kind: IndicatorParamKind::Int,
971        required: false,
972        default: Some(ParamValueStatic::Int(2)),
973        min: Some(1.0),
974        max: None,
975        step: Some(1.0),
976        enum_values: EMPTY_ENUM_VALUES,
977        notes: None,
978    },
979    IndicatorParamInfo {
980        key: "long_period",
981        label: "Long Period",
982        kind: IndicatorParamKind::Int,
983        required: false,
984        default: Some(ParamValueStatic::Int(5)),
985        min: Some(1.0),
986        max: None,
987        step: Some(1.0),
988        enum_values: EMPTY_ENUM_VALUES,
989        notes: None,
990    },
991];
992
993const PARAM_MOM_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
994    key: "period",
995    label: "Period",
996    kind: IndicatorParamKind::Int,
997    required: false,
998    default: Some(ParamValueStatic::Int(10)),
999    min: Some(1.0),
1000    max: None,
1001    step: Some(1.0),
1002    enum_values: EMPTY_ENUM_VALUES,
1003    notes: None,
1004}];
1005
1006const PARAM_CMO_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1007    key: "period",
1008    label: "Period",
1009    kind: IndicatorParamKind::Int,
1010    required: false,
1011    default: Some(ParamValueStatic::Int(14)),
1012    min: Some(1.0),
1013    max: None,
1014    step: Some(1.0),
1015    enum_values: EMPTY_ENUM_VALUES,
1016    notes: None,
1017}];
1018
1019const PARAM_ROCP_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1020    key: "period",
1021    label: "Period",
1022    kind: IndicatorParamKind::Int,
1023    required: false,
1024    default: Some(ParamValueStatic::Int(10)),
1025    min: Some(1.0),
1026    max: None,
1027    step: Some(1.0),
1028    enum_values: EMPTY_ENUM_VALUES,
1029    notes: None,
1030}];
1031
1032const PARAM_ROCR_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1033    key: "period",
1034    label: "Period",
1035    kind: IndicatorParamKind::Int,
1036    required: false,
1037    default: Some(ParamValueStatic::Int(10)),
1038    min: Some(1.0),
1039    max: None,
1040    step: Some(1.0),
1041    enum_values: EMPTY_ENUM_VALUES,
1042    notes: None,
1043}];
1044
1045const PARAM_PPO: &[IndicatorParamInfo] = &[
1046    IndicatorParamInfo {
1047        key: "fast_period",
1048        label: "Fast Period",
1049        kind: IndicatorParamKind::Int,
1050        required: false,
1051        default: Some(ParamValueStatic::Int(12)),
1052        min: Some(1.0),
1053        max: None,
1054        step: Some(1.0),
1055        enum_values: EMPTY_ENUM_VALUES,
1056        notes: None,
1057    },
1058    IndicatorParamInfo {
1059        key: "slow_period",
1060        label: "Slow Period",
1061        kind: IndicatorParamKind::Int,
1062        required: false,
1063        default: Some(ParamValueStatic::Int(26)),
1064        min: Some(1.0),
1065        max: None,
1066        step: Some(1.0),
1067        enum_values: EMPTY_ENUM_VALUES,
1068        notes: None,
1069    },
1070    IndicatorParamInfo {
1071        key: "ma_type",
1072        label: "MA Type",
1073        kind: IndicatorParamKind::EnumString,
1074        required: false,
1075        default: Some(ParamValueStatic::EnumString("sma")),
1076        min: None,
1077        max: None,
1078        step: None,
1079        enum_values: EMPTY_ENUM_VALUES,
1080        notes: None,
1081    },
1082];
1083
1084const PARAM_TRIX_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1085    key: "period",
1086    label: "Period",
1087    kind: IndicatorParamKind::Int,
1088    required: false,
1089    default: Some(ParamValueStatic::Int(18)),
1090    min: Some(1.0),
1091    max: None,
1092    step: Some(1.0),
1093    enum_values: EMPTY_ENUM_VALUES,
1094    notes: None,
1095}];
1096
1097const PARAM_TSI: &[IndicatorParamInfo] = &[
1098    IndicatorParamInfo {
1099        key: "long_period",
1100        label: "Long Period",
1101        kind: IndicatorParamKind::Int,
1102        required: false,
1103        default: Some(ParamValueStatic::Int(25)),
1104        min: Some(1.0),
1105        max: None,
1106        step: Some(1.0),
1107        enum_values: EMPTY_ENUM_VALUES,
1108        notes: None,
1109    },
1110    IndicatorParamInfo {
1111        key: "short_period",
1112        label: "Short Period",
1113        kind: IndicatorParamKind::Int,
1114        required: false,
1115        default: Some(ParamValueStatic::Int(13)),
1116        min: Some(1.0),
1117        max: None,
1118        step: Some(1.0),
1119        enum_values: EMPTY_ENUM_VALUES,
1120        notes: None,
1121    },
1122];
1123
1124const PARAM_STDDEV: &[IndicatorParamInfo] = &[
1125    IndicatorParamInfo {
1126        key: "period",
1127        label: "Period",
1128        kind: IndicatorParamKind::Int,
1129        required: false,
1130        default: Some(ParamValueStatic::Int(5)),
1131        min: Some(1.0),
1132        max: None,
1133        step: Some(1.0),
1134        enum_values: EMPTY_ENUM_VALUES,
1135        notes: None,
1136    },
1137    IndicatorParamInfo {
1138        key: "nbdev",
1139        label: "NB Dev",
1140        kind: IndicatorParamKind::Float,
1141        required: false,
1142        default: Some(ParamValueStatic::Float(1.0)),
1143        min: None,
1144        max: None,
1145        step: None,
1146        enum_values: EMPTY_ENUM_VALUES,
1147        notes: None,
1148    },
1149];
1150
1151const PARAM_WILLR_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1152    key: "period",
1153    label: "Period",
1154    kind: IndicatorParamKind::Int,
1155    required: false,
1156    default: Some(ParamValueStatic::Int(14)),
1157    min: Some(1.0),
1158    max: None,
1159    step: Some(1.0),
1160    enum_values: EMPTY_ENUM_VALUES,
1161    notes: None,
1162}];
1163
1164const PARAM_ULTOSC: &[IndicatorParamInfo] = &[
1165    IndicatorParamInfo {
1166        key: "timeperiod1",
1167        label: "Time Period 1",
1168        kind: IndicatorParamKind::Int,
1169        required: false,
1170        default: Some(ParamValueStatic::Int(7)),
1171        min: Some(1.0),
1172        max: None,
1173        step: Some(1.0),
1174        enum_values: EMPTY_ENUM_VALUES,
1175        notes: None,
1176    },
1177    IndicatorParamInfo {
1178        key: "timeperiod2",
1179        label: "Time Period 2",
1180        kind: IndicatorParamKind::Int,
1181        required: false,
1182        default: Some(ParamValueStatic::Int(14)),
1183        min: Some(1.0),
1184        max: None,
1185        step: Some(1.0),
1186        enum_values: EMPTY_ENUM_VALUES,
1187        notes: None,
1188    },
1189    IndicatorParamInfo {
1190        key: "timeperiod3",
1191        label: "Time Period 3",
1192        kind: IndicatorParamKind::Int,
1193        required: false,
1194        default: Some(ParamValueStatic::Int(28)),
1195        min: Some(1.0),
1196        max: None,
1197        step: Some(1.0),
1198        enum_values: EMPTY_ENUM_VALUES,
1199        notes: None,
1200    },
1201];
1202
1203const PARAM_APO: &[IndicatorParamInfo] = &[
1204    IndicatorParamInfo {
1205        key: "short_period",
1206        label: "Short Period",
1207        kind: IndicatorParamKind::Int,
1208        required: false,
1209        default: Some(ParamValueStatic::Int(10)),
1210        min: Some(1.0),
1211        max: None,
1212        step: Some(1.0),
1213        enum_values: EMPTY_ENUM_VALUES,
1214        notes: None,
1215    },
1216    IndicatorParamInfo {
1217        key: "long_period",
1218        label: "Long Period",
1219        kind: IndicatorParamKind::Int,
1220        required: false,
1221        default: Some(ParamValueStatic::Int(20)),
1222        min: Some(1.0),
1223        max: None,
1224        step: Some(1.0),
1225        enum_values: EMPTY_ENUM_VALUES,
1226        notes: None,
1227    },
1228];
1229
1230const PARAM_CCI_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1231    key: "period",
1232    label: "Period",
1233    kind: IndicatorParamKind::Int,
1234    required: false,
1235    default: Some(ParamValueStatic::Int(14)),
1236    min: Some(1.0),
1237    max: None,
1238    step: Some(1.0),
1239    enum_values: EMPTY_ENUM_VALUES,
1240    notes: None,
1241}];
1242
1243const PARAM_CFO: &[IndicatorParamInfo] = &[
1244    IndicatorParamInfo {
1245        key: "period",
1246        label: "Period",
1247        kind: IndicatorParamKind::Int,
1248        required: false,
1249        default: Some(ParamValueStatic::Int(14)),
1250        min: Some(1.0),
1251        max: None,
1252        step: Some(1.0),
1253        enum_values: EMPTY_ENUM_VALUES,
1254        notes: None,
1255    },
1256    IndicatorParamInfo {
1257        key: "scalar",
1258        label: "Scalar",
1259        kind: IndicatorParamKind::Float,
1260        required: false,
1261        default: Some(ParamValueStatic::Float(100.0)),
1262        min: None,
1263        max: None,
1264        step: None,
1265        enum_values: EMPTY_ENUM_VALUES,
1266        notes: None,
1267    },
1268];
1269
1270const PARAM_ER_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1271    key: "period",
1272    label: "Period",
1273    kind: IndicatorParamKind::Int,
1274    required: false,
1275    default: Some(ParamValueStatic::Int(5)),
1276    min: Some(1.0),
1277    max: None,
1278    step: Some(1.0),
1279    enum_values: EMPTY_ENUM_VALUES,
1280    notes: None,
1281}];
1282
1283const PARAM_KURTOSIS_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1284    key: "period",
1285    label: "Period",
1286    kind: IndicatorParamKind::Int,
1287    required: false,
1288    default: Some(ParamValueStatic::Int(5)),
1289    min: Some(1.0),
1290    max: None,
1291    step: Some(1.0),
1292    enum_values: EMPTY_ENUM_VALUES,
1293    notes: None,
1294}];
1295
1296const PARAM_NATR_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1297    key: "period",
1298    label: "Period",
1299    kind: IndicatorParamKind::Int,
1300    required: false,
1301    default: Some(ParamValueStatic::Int(14)),
1302    min: Some(1.0),
1303    max: None,
1304    step: Some(1.0),
1305    enum_values: EMPTY_ENUM_VALUES,
1306    notes: None,
1307}];
1308
1309const PARAM_MEAN_AD_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1310    key: "period",
1311    label: "Period",
1312    kind: IndicatorParamKind::Int,
1313    required: false,
1314    default: Some(ParamValueStatic::Int(5)),
1315    min: Some(1.0),
1316    max: None,
1317    step: Some(1.0),
1318    enum_values: EMPTY_ENUM_VALUES,
1319    notes: None,
1320}];
1321
1322const PARAM_MEDIUM_AD_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1323    key: "period",
1324    label: "Period",
1325    kind: IndicatorParamKind::Int,
1326    required: false,
1327    default: Some(ParamValueStatic::Int(5)),
1328    min: Some(1.0),
1329    max: None,
1330    step: Some(1.0),
1331    enum_values: EMPTY_ENUM_VALUES,
1332    notes: None,
1333}];
1334
1335const PARAM_DEVIATION: &[IndicatorParamInfo] = &[
1336    IndicatorParamInfo {
1337        key: "period",
1338        label: "Period",
1339        kind: IndicatorParamKind::Int,
1340        required: false,
1341        default: Some(ParamValueStatic::Int(9)),
1342        min: Some(1.0),
1343        max: None,
1344        step: Some(1.0),
1345        enum_values: EMPTY_ENUM_VALUES,
1346        notes: None,
1347    },
1348    IndicatorParamInfo {
1349        key: "devtype",
1350        label: "Dev Type",
1351        kind: IndicatorParamKind::Int,
1352        required: false,
1353        default: Some(ParamValueStatic::Int(0)),
1354        min: Some(0.0),
1355        max: Some(2.0),
1356        step: Some(1.0),
1357        enum_values: EMPTY_ENUM_VALUES,
1358        notes: None,
1359    },
1360];
1361
1362const PARAM_DPO_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1363    key: "period",
1364    label: "Period",
1365    kind: IndicatorParamKind::Int,
1366    required: false,
1367    default: Some(ParamValueStatic::Int(5)),
1368    min: Some(1.0),
1369    max: None,
1370    step: Some(1.0),
1371    enum_values: EMPTY_ENUM_VALUES,
1372    notes: None,
1373}];
1374
1375const PARAM_PVI: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1376    key: "initial_value",
1377    label: "Initial Value",
1378    kind: IndicatorParamKind::Float,
1379    required: false,
1380    default: Some(ParamValueStatic::Float(1000.0)),
1381    min: None,
1382    max: None,
1383    step: None,
1384    enum_values: EMPTY_ENUM_VALUES,
1385    notes: None,
1386}];
1387
1388const PARAM_PFE: &[IndicatorParamInfo] = &[
1389    IndicatorParamInfo {
1390        key: "period",
1391        label: "Period",
1392        kind: IndicatorParamKind::Int,
1393        required: false,
1394        default: Some(ParamValueStatic::Int(10)),
1395        min: Some(1.0),
1396        max: None,
1397        step: Some(1.0),
1398        enum_values: EMPTY_ENUM_VALUES,
1399        notes: None,
1400    },
1401    IndicatorParamInfo {
1402        key: "smoothing",
1403        label: "Smoothing",
1404        kind: IndicatorParamKind::Int,
1405        required: false,
1406        default: Some(ParamValueStatic::Int(5)),
1407        min: Some(1.0),
1408        max: None,
1409        step: Some(1.0),
1410        enum_values: EMPTY_ENUM_VALUES,
1411        notes: None,
1412    },
1413];
1414
1415const PARAM_PERCENTILE_NEAREST_RANK: &[IndicatorParamInfo] = &[
1416    IndicatorParamInfo {
1417        key: "length",
1418        label: "Length",
1419        kind: IndicatorParamKind::Int,
1420        required: false,
1421        default: Some(ParamValueStatic::Int(15)),
1422        min: Some(1.0),
1423        max: None,
1424        step: Some(1.0),
1425        enum_values: EMPTY_ENUM_VALUES,
1426        notes: None,
1427    },
1428    IndicatorParamInfo {
1429        key: "percentage",
1430        label: "Percentage",
1431        kind: IndicatorParamKind::Float,
1432        required: false,
1433        default: Some(ParamValueStatic::Float(50.0)),
1434        min: Some(0.0),
1435        max: Some(100.0),
1436        step: None,
1437        enum_values: EMPTY_ENUM_VALUES,
1438        notes: None,
1439    },
1440];
1441
1442const PARAM_UI: &[IndicatorParamInfo] = &[
1443    IndicatorParamInfo {
1444        key: "period",
1445        label: "Period",
1446        kind: IndicatorParamKind::Int,
1447        required: false,
1448        default: Some(ParamValueStatic::Int(14)),
1449        min: Some(1.0),
1450        max: None,
1451        step: Some(1.0),
1452        enum_values: EMPTY_ENUM_VALUES,
1453        notes: None,
1454    },
1455    IndicatorParamInfo {
1456        key: "scalar",
1457        label: "Scalar",
1458        kind: IndicatorParamKind::Float,
1459        required: false,
1460        default: Some(ParamValueStatic::Float(100.0)),
1461        min: None,
1462        max: None,
1463        step: None,
1464        enum_values: EMPTY_ENUM_VALUES,
1465        notes: None,
1466    },
1467];
1468
1469const PARAM_ZSCORE: &[IndicatorParamInfo] = &[
1470    IndicatorParamInfo {
1471        key: "period",
1472        label: "Period",
1473        kind: IndicatorParamKind::Int,
1474        required: false,
1475        default: Some(ParamValueStatic::Int(14)),
1476        min: Some(1.0),
1477        max: None,
1478        step: Some(1.0),
1479        enum_values: EMPTY_ENUM_VALUES,
1480        notes: None,
1481    },
1482    IndicatorParamInfo {
1483        key: "ma_type",
1484        label: "MA Type",
1485        kind: IndicatorParamKind::EnumString,
1486        required: false,
1487        default: Some(ParamValueStatic::EnumString("sma")),
1488        min: None,
1489        max: None,
1490        step: None,
1491        enum_values: EMPTY_ENUM_VALUES,
1492        notes: None,
1493    },
1494    IndicatorParamInfo {
1495        key: "nbdev",
1496        label: "NB Dev",
1497        kind: IndicatorParamKind::Float,
1498        required: false,
1499        default: Some(ParamValueStatic::Float(1.0)),
1500        min: None,
1501        max: None,
1502        step: None,
1503        enum_values: EMPTY_ENUM_VALUES,
1504        notes: None,
1505    },
1506    IndicatorParamInfo {
1507        key: "devtype",
1508        label: "Dev Type",
1509        kind: IndicatorParamKind::Int,
1510        required: false,
1511        default: Some(ParamValueStatic::Int(0)),
1512        min: Some(0.0),
1513        max: Some(2.0),
1514        step: Some(1.0),
1515        enum_values: EMPTY_ENUM_VALUES,
1516        notes: None,
1517    },
1518];
1519
1520const PARAM_MIDPOINT_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1521    key: "period",
1522    label: "Period",
1523    kind: IndicatorParamKind::Int,
1524    required: false,
1525    default: Some(ParamValueStatic::Int(14)),
1526    min: Some(1.0),
1527    max: None,
1528    step: Some(1.0),
1529    enum_values: EMPTY_ENUM_VALUES,
1530    notes: None,
1531}];
1532
1533const PARAM_MIDPRICE_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1534    key: "period",
1535    label: "Period",
1536    kind: IndicatorParamKind::Int,
1537    required: false,
1538    default: Some(ParamValueStatic::Int(14)),
1539    min: Some(1.0),
1540    max: None,
1541    step: Some(1.0),
1542    enum_values: EMPTY_ENUM_VALUES,
1543    notes: None,
1544}];
1545
1546const PARAM_TSF_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1547    key: "period",
1548    label: "Period",
1549    kind: IndicatorParamKind::Int,
1550    required: false,
1551    default: Some(ParamValueStatic::Int(14)),
1552    min: Some(2.0),
1553    max: None,
1554    step: Some(1.0),
1555    enum_values: EMPTY_ENUM_VALUES,
1556    notes: None,
1557}];
1558
1559const PARAM_VAR: &[IndicatorParamInfo] = &[
1560    IndicatorParamInfo {
1561        key: "period",
1562        label: "Period",
1563        kind: IndicatorParamKind::Int,
1564        required: false,
1565        default: Some(ParamValueStatic::Int(14)),
1566        min: Some(1.0),
1567        max: None,
1568        step: Some(1.0),
1569        enum_values: EMPTY_ENUM_VALUES,
1570        notes: None,
1571    },
1572    IndicatorParamInfo {
1573        key: "nbdev",
1574        label: "NB Dev",
1575        kind: IndicatorParamKind::Float,
1576        required: false,
1577        default: Some(ParamValueStatic::Float(1.0)),
1578        min: None,
1579        max: None,
1580        step: None,
1581        enum_values: EMPTY_ENUM_VALUES,
1582        notes: None,
1583    },
1584];
1585
1586const PARAM_ADX_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1587    key: "period",
1588    label: "Period",
1589    kind: IndicatorParamKind::Int,
1590    required: false,
1591    default: Some(ParamValueStatic::Int(14)),
1592    min: Some(1.0),
1593    max: None,
1594    step: Some(1.0),
1595    enum_values: EMPTY_ENUM_VALUES,
1596    notes: None,
1597}];
1598
1599const PARAM_DX_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1600    key: "period",
1601    label: "Period",
1602    kind: IndicatorParamKind::Int,
1603    required: false,
1604    default: Some(ParamValueStatic::Int(14)),
1605    min: Some(1.0),
1606    max: None,
1607    step: Some(1.0),
1608    enum_values: EMPTY_ENUM_VALUES,
1609    notes: None,
1610}];
1611
1612const PARAM_ATR_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1613    key: "length",
1614    label: "Length",
1615    kind: IndicatorParamKind::Int,
1616    required: false,
1617    default: Some(ParamValueStatic::Int(14)),
1618    min: Some(1.0),
1619    max: None,
1620    step: Some(1.0),
1621    enum_values: EMPTY_ENUM_VALUES,
1622    notes: None,
1623}];
1624
1625const PARAM_FOSC_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1626    key: "period",
1627    label: "Period",
1628    kind: IndicatorParamKind::Int,
1629    required: false,
1630    default: Some(ParamValueStatic::Int(5)),
1631    min: Some(1.0),
1632    max: None,
1633    step: Some(1.0),
1634    enum_values: EMPTY_ENUM_VALUES,
1635    notes: None,
1636}];
1637
1638const PARAM_IFT_RSI: &[IndicatorParamInfo] = &[
1639    IndicatorParamInfo {
1640        key: "rsi_period",
1641        label: "RSI Period",
1642        kind: IndicatorParamKind::Int,
1643        required: false,
1644        default: Some(ParamValueStatic::Int(5)),
1645        min: Some(1.0),
1646        max: None,
1647        step: Some(1.0),
1648        enum_values: EMPTY_ENUM_VALUES,
1649        notes: None,
1650    },
1651    IndicatorParamInfo {
1652        key: "wma_period",
1653        label: "WMA Period",
1654        kind: IndicatorParamKind::Int,
1655        required: false,
1656        default: Some(ParamValueStatic::Int(9)),
1657        min: Some(1.0),
1658        max: None,
1659        step: Some(1.0),
1660        enum_values: EMPTY_ENUM_VALUES,
1661        notes: None,
1662    },
1663];
1664
1665const PARAM_LINEARREG_ANGLE_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1666    key: "period",
1667    label: "Period",
1668    kind: IndicatorParamKind::Int,
1669    required: false,
1670    default: Some(ParamValueStatic::Int(14)),
1671    min: Some(2.0),
1672    max: None,
1673    step: Some(1.0),
1674    enum_values: EMPTY_ENUM_VALUES,
1675    notes: None,
1676}];
1677
1678const PARAM_LINEARREG_INTERCEPT_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1679    key: "period",
1680    label: "Period",
1681    kind: IndicatorParamKind::Int,
1682    required: false,
1683    default: Some(ParamValueStatic::Int(14)),
1684    min: Some(1.0),
1685    max: None,
1686    step: Some(1.0),
1687    enum_values: EMPTY_ENUM_VALUES,
1688    notes: None,
1689}];
1690
1691const PARAM_LINEARREG_SLOPE_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1692    key: "period",
1693    label: "Period",
1694    kind: IndicatorParamKind::Int,
1695    required: false,
1696    default: Some(ParamValueStatic::Int(14)),
1697    min: Some(2.0),
1698    max: None,
1699    step: Some(1.0),
1700    enum_values: EMPTY_ENUM_VALUES,
1701    notes: None,
1702}];
1703
1704const PARAM_CG_PERIOD: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1705    key: "period",
1706    label: "Period",
1707    kind: IndicatorParamKind::Int,
1708    required: false,
1709    default: Some(ParamValueStatic::Int(10)),
1710    min: Some(1.0),
1711    max: None,
1712    step: Some(1.0),
1713    enum_values: EMPTY_ENUM_VALUES,
1714    notes: None,
1715}];
1716
1717const PARAM_MACD: &[IndicatorParamInfo] = &[
1718    IndicatorParamInfo {
1719        key: "fast_period",
1720        label: "Fast Period",
1721        kind: IndicatorParamKind::Int,
1722        required: false,
1723        default: Some(ParamValueStatic::Int(12)),
1724        min: Some(1.0),
1725        max: None,
1726        step: Some(1.0),
1727        enum_values: EMPTY_ENUM_VALUES,
1728        notes: None,
1729    },
1730    IndicatorParamInfo {
1731        key: "slow_period",
1732        label: "Slow Period",
1733        kind: IndicatorParamKind::Int,
1734        required: false,
1735        default: Some(ParamValueStatic::Int(26)),
1736        min: Some(1.0),
1737        max: None,
1738        step: Some(1.0),
1739        enum_values: EMPTY_ENUM_VALUES,
1740        notes: None,
1741    },
1742    IndicatorParamInfo {
1743        key: "signal_period",
1744        label: "Signal Period",
1745        kind: IndicatorParamKind::Int,
1746        required: false,
1747        default: Some(ParamValueStatic::Int(9)),
1748        min: Some(1.0),
1749        max: None,
1750        step: Some(1.0),
1751        enum_values: EMPTY_ENUM_VALUES,
1752        notes: None,
1753    },
1754];
1755
1756const PARAM_BOLLINGER: &[IndicatorParamInfo] = &[
1757    IndicatorParamInfo {
1758        key: "period",
1759        label: "Period",
1760        kind: IndicatorParamKind::Int,
1761        required: false,
1762        default: Some(ParamValueStatic::Int(20)),
1763        min: Some(1.0),
1764        max: None,
1765        step: Some(1.0),
1766        enum_values: EMPTY_ENUM_VALUES,
1767        notes: None,
1768    },
1769    IndicatorParamInfo {
1770        key: "devup",
1771        label: "Dev Up",
1772        kind: IndicatorParamKind::Float,
1773        required: false,
1774        default: Some(ParamValueStatic::Float(2.0)),
1775        min: None,
1776        max: None,
1777        step: None,
1778        enum_values: EMPTY_ENUM_VALUES,
1779        notes: None,
1780    },
1781    IndicatorParamInfo {
1782        key: "devdn",
1783        label: "Dev Down",
1784        kind: IndicatorParamKind::Float,
1785        required: false,
1786        default: Some(ParamValueStatic::Float(2.0)),
1787        min: None,
1788        max: None,
1789        step: None,
1790        enum_values: EMPTY_ENUM_VALUES,
1791        notes: None,
1792    },
1793];
1794
1795const PARAM_STOCH: &[IndicatorParamInfo] = &[
1796    IndicatorParamInfo {
1797        key: "fastk_period",
1798        label: "Fast K Period",
1799        kind: IndicatorParamKind::Int,
1800        required: false,
1801        default: Some(ParamValueStatic::Int(14)),
1802        min: Some(1.0),
1803        max: None,
1804        step: Some(1.0),
1805        enum_values: EMPTY_ENUM_VALUES,
1806        notes: None,
1807    },
1808    IndicatorParamInfo {
1809        key: "slowk_period",
1810        label: "Slow K Period",
1811        kind: IndicatorParamKind::Int,
1812        required: false,
1813        default: Some(ParamValueStatic::Int(3)),
1814        min: Some(1.0),
1815        max: None,
1816        step: Some(1.0),
1817        enum_values: EMPTY_ENUM_VALUES,
1818        notes: None,
1819    },
1820    IndicatorParamInfo {
1821        key: "slowd_period",
1822        label: "Slow D Period",
1823        kind: IndicatorParamKind::Int,
1824        required: false,
1825        default: Some(ParamValueStatic::Int(3)),
1826        min: Some(1.0),
1827        max: None,
1828        step: Some(1.0),
1829        enum_values: EMPTY_ENUM_VALUES,
1830        notes: None,
1831    },
1832];
1833
1834const PARAM_STOCHF: &[IndicatorParamInfo] = &[
1835    IndicatorParamInfo {
1836        key: "fastk_period",
1837        label: "Fast K Period",
1838        kind: IndicatorParamKind::Int,
1839        required: false,
1840        default: Some(ParamValueStatic::Int(5)),
1841        min: Some(1.0),
1842        max: None,
1843        step: Some(1.0),
1844        enum_values: EMPTY_ENUM_VALUES,
1845        notes: None,
1846    },
1847    IndicatorParamInfo {
1848        key: "fastd_period",
1849        label: "Fast D Period",
1850        kind: IndicatorParamKind::Int,
1851        required: false,
1852        default: Some(ParamValueStatic::Int(3)),
1853        min: Some(1.0),
1854        max: None,
1855        step: Some(1.0),
1856        enum_values: EMPTY_ENUM_VALUES,
1857        notes: None,
1858    },
1859];
1860
1861const PARAM_VW_MACD: &[IndicatorParamInfo] = &[
1862    IndicatorParamInfo {
1863        key: "fast",
1864        label: "Fast",
1865        kind: IndicatorParamKind::Int,
1866        required: false,
1867        default: Some(ParamValueStatic::Int(12)),
1868        min: Some(1.0),
1869        max: None,
1870        step: Some(1.0),
1871        enum_values: EMPTY_ENUM_VALUES,
1872        notes: None,
1873    },
1874    IndicatorParamInfo {
1875        key: "slow",
1876        label: "Slow",
1877        kind: IndicatorParamKind::Int,
1878        required: false,
1879        default: Some(ParamValueStatic::Int(26)),
1880        min: Some(1.0),
1881        max: None,
1882        step: Some(1.0),
1883        enum_values: EMPTY_ENUM_VALUES,
1884        notes: None,
1885    },
1886    IndicatorParamInfo {
1887        key: "signal",
1888        label: "Signal",
1889        kind: IndicatorParamKind::Int,
1890        required: false,
1891        default: Some(ParamValueStatic::Int(9)),
1892        min: Some(1.0),
1893        max: None,
1894        step: Some(1.0),
1895        enum_values: EMPTY_ENUM_VALUES,
1896        notes: None,
1897    },
1898];
1899
1900const PARAM_VPCI: &[IndicatorParamInfo] = &[
1901    IndicatorParamInfo {
1902        key: "short_range",
1903        label: "Short Range",
1904        kind: IndicatorParamKind::Int,
1905        required: false,
1906        default: Some(ParamValueStatic::Int(5)),
1907        min: Some(1.0),
1908        max: None,
1909        step: Some(1.0),
1910        enum_values: EMPTY_ENUM_VALUES,
1911        notes: None,
1912    },
1913    IndicatorParamInfo {
1914        key: "long_range",
1915        label: "Long Range",
1916        kind: IndicatorParamKind::Int,
1917        required: false,
1918        default: Some(ParamValueStatic::Int(20)),
1919        min: Some(1.0),
1920        max: None,
1921        step: Some(1.0),
1922        enum_values: EMPTY_ENUM_VALUES,
1923        notes: None,
1924    },
1925];
1926
1927const PARAM_TTM_TREND: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1928    key: "period",
1929    label: "Period",
1930    kind: IndicatorParamKind::Int,
1931    required: false,
1932    default: Some(ParamValueStatic::Int(6)),
1933    min: Some(1.0),
1934    max: None,
1935    step: Some(1.0),
1936    enum_values: EMPTY_ENUM_VALUES,
1937    notes: None,
1938}];
1939
1940const PARAM_TTM_SQUEEZE: &[IndicatorParamInfo] = &[
1941    IndicatorParamInfo {
1942        key: "length",
1943        label: "Length",
1944        kind: IndicatorParamKind::Int,
1945        required: false,
1946        default: Some(ParamValueStatic::Int(20)),
1947        min: Some(1.0),
1948        max: None,
1949        step: Some(1.0),
1950        enum_values: EMPTY_ENUM_VALUES,
1951        notes: None,
1952    },
1953    IndicatorParamInfo {
1954        key: "bb_mult",
1955        label: "BB Mult",
1956        kind: IndicatorParamKind::Float,
1957        required: false,
1958        default: Some(ParamValueStatic::Float(2.0)),
1959        min: None,
1960        max: None,
1961        step: None,
1962        enum_values: EMPTY_ENUM_VALUES,
1963        notes: None,
1964    },
1965];
1966
1967const PARAM_DI: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1968    key: "period",
1969    label: "Period",
1970    kind: IndicatorParamKind::Int,
1971    required: false,
1972    default: Some(ParamValueStatic::Int(14)),
1973    min: Some(1.0),
1974    max: None,
1975    step: Some(1.0),
1976    enum_values: EMPTY_ENUM_VALUES,
1977    notes: None,
1978}];
1979
1980const PARAM_DM: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1981    key: "period",
1982    label: "Period",
1983    kind: IndicatorParamKind::Int,
1984    required: false,
1985    default: Some(ParamValueStatic::Int(14)),
1986    min: Some(1.0),
1987    max: None,
1988    step: Some(1.0),
1989    enum_values: EMPTY_ENUM_VALUES,
1990    notes: None,
1991}];
1992
1993const PARAM_DONCHIAN: &[IndicatorParamInfo] = &[IndicatorParamInfo {
1994    key: "period",
1995    label: "Period",
1996    kind: IndicatorParamKind::Int,
1997    required: false,
1998    default: Some(ParamValueStatic::Int(20)),
1999    min: Some(1.0),
2000    max: None,
2001    step: Some(1.0),
2002    enum_values: EMPTY_ENUM_VALUES,
2003    notes: None,
2004}];
2005
2006const PARAM_SUPERTREND: &[IndicatorParamInfo] = &[
2007    IndicatorParamInfo {
2008        key: "period",
2009        label: "Period",
2010        kind: IndicatorParamKind::Int,
2011        required: false,
2012        default: Some(ParamValueStatic::Int(10)),
2013        min: Some(1.0),
2014        max: None,
2015        step: Some(1.0),
2016        enum_values: EMPTY_ENUM_VALUES,
2017        notes: None,
2018    },
2019    IndicatorParamInfo {
2020        key: "factor",
2021        label: "Factor",
2022        kind: IndicatorParamKind::Float,
2023        required: false,
2024        default: Some(ParamValueStatic::Float(3.0)),
2025        min: Some(0.0),
2026        max: None,
2027        step: None,
2028        enum_values: EMPTY_ENUM_VALUES,
2029        notes: None,
2030    },
2031];
2032
2033const PARAM_KELTNER: &[IndicatorParamInfo] = &[
2034    IndicatorParamInfo {
2035        key: "period",
2036        label: "Period",
2037        kind: IndicatorParamKind::Int,
2038        required: false,
2039        default: Some(ParamValueStatic::Int(20)),
2040        min: Some(1.0),
2041        max: None,
2042        step: Some(1.0),
2043        enum_values: EMPTY_ENUM_VALUES,
2044        notes: None,
2045    },
2046    IndicatorParamInfo {
2047        key: "multiplier",
2048        label: "Multiplier",
2049        kind: IndicatorParamKind::Float,
2050        required: false,
2051        default: Some(ParamValueStatic::Float(2.0)),
2052        min: Some(0.0),
2053        max: None,
2054        step: None,
2055        enum_values: EMPTY_ENUM_VALUES,
2056        notes: None,
2057    },
2058    IndicatorParamInfo {
2059        key: "ma_type",
2060        label: "MA Type",
2061        kind: IndicatorParamKind::EnumString,
2062        required: false,
2063        default: Some(ParamValueStatic::EnumString("ema")),
2064        min: None,
2065        max: None,
2066        step: None,
2067        enum_values: EMPTY_ENUM_VALUES,
2068        notes: None,
2069    },
2070];
2071
2072const PARAM_AROON: &[IndicatorParamInfo] = &[IndicatorParamInfo {
2073    key: "length",
2074    label: "Length",
2075    kind: IndicatorParamKind::Int,
2076    required: false,
2077    default: Some(ParamValueStatic::Int(14)),
2078    min: Some(1.0),
2079    max: None,
2080    step: Some(1.0),
2081    enum_values: EMPTY_ENUM_VALUES,
2082    notes: None,
2083}];
2084
2085const PARAM_SRSI: &[IndicatorParamInfo] = &[
2086    IndicatorParamInfo {
2087        key: "rsi_period",
2088        label: "RSI Period",
2089        kind: IndicatorParamKind::Int,
2090        required: false,
2091        default: Some(ParamValueStatic::Int(14)),
2092        min: Some(1.0),
2093        max: None,
2094        step: Some(1.0),
2095        enum_values: EMPTY_ENUM_VALUES,
2096        notes: None,
2097    },
2098    IndicatorParamInfo {
2099        key: "stoch_period",
2100        label: "Stoch Period",
2101        kind: IndicatorParamKind::Int,
2102        required: false,
2103        default: Some(ParamValueStatic::Int(14)),
2104        min: Some(1.0),
2105        max: None,
2106        step: Some(1.0),
2107        enum_values: EMPTY_ENUM_VALUES,
2108        notes: None,
2109    },
2110    IndicatorParamInfo {
2111        key: "k",
2112        label: "K",
2113        kind: IndicatorParamKind::Int,
2114        required: false,
2115        default: Some(ParamValueStatic::Int(3)),
2116        min: Some(1.0),
2117        max: None,
2118        step: Some(1.0),
2119        enum_values: EMPTY_ENUM_VALUES,
2120        notes: None,
2121    },
2122    IndicatorParamInfo {
2123        key: "d",
2124        label: "D",
2125        kind: IndicatorParamKind::Int,
2126        required: false,
2127        default: Some(ParamValueStatic::Int(3)),
2128        min: Some(1.0),
2129        max: None,
2130        step: Some(1.0),
2131        enum_values: EMPTY_ENUM_VALUES,
2132        notes: None,
2133    },
2134    IndicatorParamInfo {
2135        key: "source",
2136        label: "Source",
2137        kind: IndicatorParamKind::EnumString,
2138        required: false,
2139        default: Some(ParamValueStatic::EnumString("close")),
2140        min: None,
2141        max: None,
2142        step: None,
2143        enum_values: EMPTY_ENUM_VALUES,
2144        notes: None,
2145    },
2146];
2147
2148const PARAM_SQUEEZE_MOMENTUM: &[IndicatorParamInfo] = &[
2149    IndicatorParamInfo {
2150        key: "length_bb",
2151        label: "BB Length",
2152        kind: IndicatorParamKind::Int,
2153        required: false,
2154        default: Some(ParamValueStatic::Int(20)),
2155        min: Some(1.0),
2156        max: None,
2157        step: Some(1.0),
2158        enum_values: EMPTY_ENUM_VALUES,
2159        notes: None,
2160    },
2161    IndicatorParamInfo {
2162        key: "mult_bb",
2163        label: "BB Mult",
2164        kind: IndicatorParamKind::Float,
2165        required: false,
2166        default: Some(ParamValueStatic::Float(2.0)),
2167        min: Some(0.0),
2168        max: None,
2169        step: None,
2170        enum_values: EMPTY_ENUM_VALUES,
2171        notes: None,
2172    },
2173    IndicatorParamInfo {
2174        key: "length_kc",
2175        label: "KC Length",
2176        kind: IndicatorParamKind::Int,
2177        required: false,
2178        default: Some(ParamValueStatic::Int(20)),
2179        min: Some(1.0),
2180        max: None,
2181        step: Some(1.0),
2182        enum_values: EMPTY_ENUM_VALUES,
2183        notes: None,
2184    },
2185    IndicatorParamInfo {
2186        key: "mult_kc",
2187        label: "KC Mult",
2188        kind: IndicatorParamKind::Float,
2189        required: false,
2190        default: Some(ParamValueStatic::Float(1.5)),
2191        min: Some(0.0),
2192        max: None,
2193        step: None,
2194        enum_values: EMPTY_ENUM_VALUES,
2195        notes: None,
2196    },
2197];
2198
2199const PARAM_WTO: &[IndicatorParamInfo] = &[
2200    IndicatorParamInfo {
2201        key: "channel_length",
2202        label: "Channel Length",
2203        kind: IndicatorParamKind::Int,
2204        required: false,
2205        default: Some(ParamValueStatic::Int(10)),
2206        min: Some(1.0),
2207        max: None,
2208        step: Some(1.0),
2209        enum_values: EMPTY_ENUM_VALUES,
2210        notes: None,
2211    },
2212    IndicatorParamInfo {
2213        key: "average_length",
2214        label: "Average Length",
2215        kind: IndicatorParamKind::Int,
2216        required: false,
2217        default: Some(ParamValueStatic::Int(21)),
2218        min: Some(1.0),
2219        max: None,
2220        step: Some(1.0),
2221        enum_values: EMPTY_ENUM_VALUES,
2222        notes: None,
2223    },
2224];
2225
2226const PARAM_WAVETREND: &[IndicatorParamInfo] = &[
2227    IndicatorParamInfo {
2228        key: "channel_length",
2229        label: "Channel Length",
2230        kind: IndicatorParamKind::Int,
2231        required: false,
2232        default: Some(ParamValueStatic::Int(9)),
2233        min: Some(1.0),
2234        max: None,
2235        step: Some(1.0),
2236        enum_values: EMPTY_ENUM_VALUES,
2237        notes: None,
2238    },
2239    IndicatorParamInfo {
2240        key: "average_length",
2241        label: "Average Length",
2242        kind: IndicatorParamKind::Int,
2243        required: false,
2244        default: Some(ParamValueStatic::Int(12)),
2245        min: Some(1.0),
2246        max: None,
2247        step: Some(1.0),
2248        enum_values: EMPTY_ENUM_VALUES,
2249        notes: None,
2250    },
2251    IndicatorParamInfo {
2252        key: "ma_length",
2253        label: "MA Length",
2254        kind: IndicatorParamKind::Int,
2255        required: false,
2256        default: Some(ParamValueStatic::Int(3)),
2257        min: Some(1.0),
2258        max: None,
2259        step: Some(1.0),
2260        enum_values: EMPTY_ENUM_VALUES,
2261        notes: None,
2262    },
2263    IndicatorParamInfo {
2264        key: "factor",
2265        label: "Factor",
2266        kind: IndicatorParamKind::Float,
2267        required: false,
2268        default: Some(ParamValueStatic::Float(0.015)),
2269        min: Some(0.0),
2270        max: None,
2271        step: None,
2272        enum_values: EMPTY_ENUM_VALUES,
2273        notes: None,
2274    },
2275];
2276
2277const PARAM_VI: &[IndicatorParamInfo] = &[IndicatorParamInfo {
2278    key: "period",
2279    label: "Period",
2280    kind: IndicatorParamKind::Int,
2281    required: false,
2282    default: Some(ParamValueStatic::Int(14)),
2283    min: Some(1.0),
2284    max: None,
2285    step: Some(1.0),
2286    enum_values: EMPTY_ENUM_VALUES,
2287    notes: None,
2288}];
2289
2290const PARAM_KDJ: &[IndicatorParamInfo] = &[
2291    IndicatorParamInfo {
2292        key: "fast_k_period",
2293        label: "Fast K Period",
2294        kind: IndicatorParamKind::Int,
2295        required: false,
2296        default: Some(ParamValueStatic::Int(9)),
2297        min: Some(1.0),
2298        max: None,
2299        step: Some(1.0),
2300        enum_values: EMPTY_ENUM_VALUES,
2301        notes: None,
2302    },
2303    IndicatorParamInfo {
2304        key: "slow_k_period",
2305        label: "Slow K Period",
2306        kind: IndicatorParamKind::Int,
2307        required: false,
2308        default: Some(ParamValueStatic::Int(3)),
2309        min: Some(1.0),
2310        max: None,
2311        step: Some(1.0),
2312        enum_values: EMPTY_ENUM_VALUES,
2313        notes: None,
2314    },
2315    IndicatorParamInfo {
2316        key: "slow_k_ma_type",
2317        label: "Slow K MA Type",
2318        kind: IndicatorParamKind::EnumString,
2319        required: false,
2320        default: Some(ParamValueStatic::EnumString("sma")),
2321        min: None,
2322        max: None,
2323        step: None,
2324        enum_values: EMPTY_ENUM_VALUES,
2325        notes: None,
2326    },
2327    IndicatorParamInfo {
2328        key: "slow_d_period",
2329        label: "Slow D Period",
2330        kind: IndicatorParamKind::Int,
2331        required: false,
2332        default: Some(ParamValueStatic::Int(3)),
2333        min: Some(1.0),
2334        max: None,
2335        step: Some(1.0),
2336        enum_values: EMPTY_ENUM_VALUES,
2337        notes: None,
2338    },
2339    IndicatorParamInfo {
2340        key: "slow_d_ma_type",
2341        label: "Slow D MA Type",
2342        kind: IndicatorParamKind::EnumString,
2343        required: false,
2344        default: Some(ParamValueStatic::EnumString("sma")),
2345        min: None,
2346        max: None,
2347        step: None,
2348        enum_values: EMPTY_ENUM_VALUES,
2349        notes: None,
2350    },
2351];
2352
2353const PARAM_ACOSC: &[IndicatorParamInfo] = PARAM_NONE;
2354
2355const PARAM_ALLIGATOR: &[IndicatorParamInfo] = &[
2356    IndicatorParamInfo {
2357        key: "jaw_period",
2358        label: "Jaw Period",
2359        kind: IndicatorParamKind::Int,
2360        required: false,
2361        default: Some(ParamValueStatic::Int(13)),
2362        min: Some(1.0),
2363        max: None,
2364        step: Some(1.0),
2365        enum_values: EMPTY_ENUM_VALUES,
2366        notes: None,
2367    },
2368    IndicatorParamInfo {
2369        key: "jaw_offset",
2370        label: "Jaw Offset",
2371        kind: IndicatorParamKind::Int,
2372        required: false,
2373        default: Some(ParamValueStatic::Int(8)),
2374        min: Some(0.0),
2375        max: None,
2376        step: Some(1.0),
2377        enum_values: EMPTY_ENUM_VALUES,
2378        notes: None,
2379    },
2380    IndicatorParamInfo {
2381        key: "teeth_period",
2382        label: "Teeth Period",
2383        kind: IndicatorParamKind::Int,
2384        required: false,
2385        default: Some(ParamValueStatic::Int(8)),
2386        min: Some(1.0),
2387        max: None,
2388        step: Some(1.0),
2389        enum_values: EMPTY_ENUM_VALUES,
2390        notes: None,
2391    },
2392    IndicatorParamInfo {
2393        key: "teeth_offset",
2394        label: "Teeth Offset",
2395        kind: IndicatorParamKind::Int,
2396        required: false,
2397        default: Some(ParamValueStatic::Int(5)),
2398        min: Some(0.0),
2399        max: None,
2400        step: Some(1.0),
2401        enum_values: EMPTY_ENUM_VALUES,
2402        notes: None,
2403    },
2404    IndicatorParamInfo {
2405        key: "lips_period",
2406        label: "Lips Period",
2407        kind: IndicatorParamKind::Int,
2408        required: false,
2409        default: Some(ParamValueStatic::Int(5)),
2410        min: Some(1.0),
2411        max: None,
2412        step: Some(1.0),
2413        enum_values: EMPTY_ENUM_VALUES,
2414        notes: None,
2415    },
2416    IndicatorParamInfo {
2417        key: "lips_offset",
2418        label: "Lips Offset",
2419        kind: IndicatorParamKind::Int,
2420        required: false,
2421        default: Some(ParamValueStatic::Int(3)),
2422        min: Some(0.0),
2423        max: None,
2424        step: Some(1.0),
2425        enum_values: EMPTY_ENUM_VALUES,
2426        notes: None,
2427    },
2428];
2429
2430const PARAM_ALPHATREND: &[IndicatorParamInfo] = &[
2431    IndicatorParamInfo {
2432        key: "coeff",
2433        label: "Coeff",
2434        kind: IndicatorParamKind::Float,
2435        required: false,
2436        default: Some(ParamValueStatic::Float(1.0)),
2437        min: Some(0.0),
2438        max: None,
2439        step: None,
2440        enum_values: EMPTY_ENUM_VALUES,
2441        notes: None,
2442    },
2443    IndicatorParamInfo {
2444        key: "period",
2445        label: "Period",
2446        kind: IndicatorParamKind::Int,
2447        required: false,
2448        default: Some(ParamValueStatic::Int(14)),
2449        min: Some(1.0),
2450        max: None,
2451        step: Some(1.0),
2452        enum_values: EMPTY_ENUM_VALUES,
2453        notes: None,
2454    },
2455    IndicatorParamInfo {
2456        key: "no_volume",
2457        label: "No Volume",
2458        kind: IndicatorParamKind::Bool,
2459        required: false,
2460        default: Some(ParamValueStatic::Bool(false)),
2461        min: None,
2462        max: None,
2463        step: None,
2464        enum_values: ENUM_VALUES_TRUE_FALSE,
2465        notes: None,
2466    },
2467];
2468
2469const PARAM_ASO: &[IndicatorParamInfo] = &[
2470    IndicatorParamInfo {
2471        key: "period",
2472        label: "Period",
2473        kind: IndicatorParamKind::Int,
2474        required: false,
2475        default: Some(ParamValueStatic::Int(10)),
2476        min: Some(1.0),
2477        max: None,
2478        step: Some(1.0),
2479        enum_values: EMPTY_ENUM_VALUES,
2480        notes: None,
2481    },
2482    IndicatorParamInfo {
2483        key: "mode",
2484        label: "Mode",
2485        kind: IndicatorParamKind::Int,
2486        required: false,
2487        default: Some(ParamValueStatic::Int(0)),
2488        min: Some(0.0),
2489        max: None,
2490        step: Some(1.0),
2491        enum_values: EMPTY_ENUM_VALUES,
2492        notes: None,
2493    },
2494];
2495
2496const PARAM_BANDPASS: &[IndicatorParamInfo] = &[
2497    IndicatorParamInfo {
2498        key: "period",
2499        label: "Period",
2500        kind: IndicatorParamKind::Int,
2501        required: false,
2502        default: Some(ParamValueStatic::Int(20)),
2503        min: Some(1.0),
2504        max: None,
2505        step: Some(1.0),
2506        enum_values: EMPTY_ENUM_VALUES,
2507        notes: None,
2508    },
2509    IndicatorParamInfo {
2510        key: "bandwidth",
2511        label: "Bandwidth",
2512        kind: IndicatorParamKind::Float,
2513        required: false,
2514        default: Some(ParamValueStatic::Float(0.3)),
2515        min: Some(0.0),
2516        max: None,
2517        step: None,
2518        enum_values: EMPTY_ENUM_VALUES,
2519        notes: None,
2520    },
2521];
2522
2523const PARAM_CHANDELIER_EXIT: &[IndicatorParamInfo] = &[
2524    IndicatorParamInfo {
2525        key: "period",
2526        label: "Period",
2527        kind: IndicatorParamKind::Int,
2528        required: false,
2529        default: Some(ParamValueStatic::Int(22)),
2530        min: Some(1.0),
2531        max: None,
2532        step: Some(1.0),
2533        enum_values: EMPTY_ENUM_VALUES,
2534        notes: None,
2535    },
2536    IndicatorParamInfo {
2537        key: "mult",
2538        label: "Multiplier",
2539        kind: IndicatorParamKind::Float,
2540        required: false,
2541        default: Some(ParamValueStatic::Float(3.0)),
2542        min: Some(0.0),
2543        max: None,
2544        step: None,
2545        enum_values: EMPTY_ENUM_VALUES,
2546        notes: None,
2547    },
2548    IndicatorParamInfo {
2549        key: "use_close",
2550        label: "Use Close",
2551        kind: IndicatorParamKind::Bool,
2552        required: false,
2553        default: Some(ParamValueStatic::Bool(true)),
2554        min: None,
2555        max: None,
2556        step: None,
2557        enum_values: ENUM_VALUES_TRUE_FALSE,
2558        notes: None,
2559    },
2560];
2561
2562const PARAM_CKSP: &[IndicatorParamInfo] = &[
2563    IndicatorParamInfo {
2564        key: "p",
2565        label: "P",
2566        kind: IndicatorParamKind::Int,
2567        required: false,
2568        default: Some(ParamValueStatic::Int(10)),
2569        min: Some(1.0),
2570        max: None,
2571        step: Some(1.0),
2572        enum_values: EMPTY_ENUM_VALUES,
2573        notes: None,
2574    },
2575    IndicatorParamInfo {
2576        key: "x",
2577        label: "X",
2578        kind: IndicatorParamKind::Float,
2579        required: false,
2580        default: Some(ParamValueStatic::Float(1.0)),
2581        min: Some(0.0),
2582        max: None,
2583        step: None,
2584        enum_values: EMPTY_ENUM_VALUES,
2585        notes: None,
2586    },
2587    IndicatorParamInfo {
2588        key: "q",
2589        label: "Q",
2590        kind: IndicatorParamKind::Int,
2591        required: false,
2592        default: Some(ParamValueStatic::Int(9)),
2593        min: Some(1.0),
2594        max: None,
2595        step: Some(1.0),
2596        enum_values: EMPTY_ENUM_VALUES,
2597        notes: None,
2598    },
2599];
2600
2601const PARAM_CORRELATION_CYCLE: &[IndicatorParamInfo] = &[
2602    IndicatorParamInfo {
2603        key: "period",
2604        label: "Period",
2605        kind: IndicatorParamKind::Int,
2606        required: false,
2607        default: Some(ParamValueStatic::Int(20)),
2608        min: Some(1.0),
2609        max: None,
2610        step: Some(1.0),
2611        enum_values: EMPTY_ENUM_VALUES,
2612        notes: None,
2613    },
2614    IndicatorParamInfo {
2615        key: "threshold",
2616        label: "Threshold",
2617        kind: IndicatorParamKind::Float,
2618        required: false,
2619        default: Some(ParamValueStatic::Float(9.0)),
2620        min: None,
2621        max: None,
2622        step: None,
2623        enum_values: EMPTY_ENUM_VALUES,
2624        notes: None,
2625    },
2626];
2627
2628const PARAM_DAMIANI_VOLATMETER: &[IndicatorParamInfo] = &[
2629    IndicatorParamInfo {
2630        key: "vis_atr",
2631        label: "Vis ATR",
2632        kind: IndicatorParamKind::Int,
2633        required: false,
2634        default: Some(ParamValueStatic::Int(13)),
2635        min: Some(1.0),
2636        max: None,
2637        step: Some(1.0),
2638        enum_values: EMPTY_ENUM_VALUES,
2639        notes: None,
2640    },
2641    IndicatorParamInfo {
2642        key: "vis_std",
2643        label: "Vis STD",
2644        kind: IndicatorParamKind::Int,
2645        required: false,
2646        default: Some(ParamValueStatic::Int(20)),
2647        min: Some(1.0),
2648        max: None,
2649        step: Some(1.0),
2650        enum_values: EMPTY_ENUM_VALUES,
2651        notes: None,
2652    },
2653    IndicatorParamInfo {
2654        key: "sed_atr",
2655        label: "Sed ATR",
2656        kind: IndicatorParamKind::Int,
2657        required: false,
2658        default: Some(ParamValueStatic::Int(40)),
2659        min: Some(1.0),
2660        max: None,
2661        step: Some(1.0),
2662        enum_values: EMPTY_ENUM_VALUES,
2663        notes: None,
2664    },
2665    IndicatorParamInfo {
2666        key: "sed_std",
2667        label: "Sed STD",
2668        kind: IndicatorParamKind::Int,
2669        required: false,
2670        default: Some(ParamValueStatic::Int(100)),
2671        min: Some(1.0),
2672        max: None,
2673        step: Some(1.0),
2674        enum_values: EMPTY_ENUM_VALUES,
2675        notes: None,
2676    },
2677    IndicatorParamInfo {
2678        key: "threshold",
2679        label: "Threshold",
2680        kind: IndicatorParamKind::Float,
2681        required: false,
2682        default: Some(ParamValueStatic::Float(1.4)),
2683        min: None,
2684        max: None,
2685        step: None,
2686        enum_values: EMPTY_ENUM_VALUES,
2687        notes: None,
2688    },
2689];
2690
2691const PARAM_DVDIQQE: &[IndicatorParamInfo] = &[
2692    IndicatorParamInfo {
2693        key: "period",
2694        label: "Period",
2695        kind: IndicatorParamKind::Int,
2696        required: false,
2697        default: Some(ParamValueStatic::Int(13)),
2698        min: Some(1.0),
2699        max: None,
2700        step: Some(1.0),
2701        enum_values: EMPTY_ENUM_VALUES,
2702        notes: None,
2703    },
2704    IndicatorParamInfo {
2705        key: "smoothing_period",
2706        label: "Smoothing Period",
2707        kind: IndicatorParamKind::Int,
2708        required: false,
2709        default: Some(ParamValueStatic::Int(6)),
2710        min: Some(1.0),
2711        max: None,
2712        step: Some(1.0),
2713        enum_values: EMPTY_ENUM_VALUES,
2714        notes: None,
2715    },
2716    IndicatorParamInfo {
2717        key: "fast_multiplier",
2718        label: "Fast Multiplier",
2719        kind: IndicatorParamKind::Float,
2720        required: false,
2721        default: Some(ParamValueStatic::Float(2.618)),
2722        min: Some(0.0),
2723        max: None,
2724        step: None,
2725        enum_values: EMPTY_ENUM_VALUES,
2726        notes: None,
2727    },
2728    IndicatorParamInfo {
2729        key: "slow_multiplier",
2730        label: "Slow Multiplier",
2731        kind: IndicatorParamKind::Float,
2732        required: false,
2733        default: Some(ParamValueStatic::Float(4.236)),
2734        min: Some(0.0),
2735        max: None,
2736        step: None,
2737        enum_values: EMPTY_ENUM_VALUES,
2738        notes: None,
2739    },
2740    IndicatorParamInfo {
2741        key: "volume_type",
2742        label: "Volume Type",
2743        kind: IndicatorParamKind::EnumString,
2744        required: false,
2745        default: Some(ParamValueStatic::EnumString("default")),
2746        min: None,
2747        max: None,
2748        step: None,
2749        enum_values: EMPTY_ENUM_VALUES,
2750        notes: None,
2751    },
2752    IndicatorParamInfo {
2753        key: "center_type",
2754        label: "Center Type",
2755        kind: IndicatorParamKind::EnumString,
2756        required: false,
2757        default: Some(ParamValueStatic::EnumString("dynamic")),
2758        min: None,
2759        max: None,
2760        step: None,
2761        enum_values: EMPTY_ENUM_VALUES,
2762        notes: None,
2763    },
2764    IndicatorParamInfo {
2765        key: "tick_size",
2766        label: "Tick Size",
2767        kind: IndicatorParamKind::Float,
2768        required: false,
2769        default: Some(ParamValueStatic::Float(0.01)),
2770        min: Some(0.0),
2771        max: None,
2772        step: None,
2773        enum_values: EMPTY_ENUM_VALUES,
2774        notes: None,
2775    },
2776];
2777
2778const PARAM_EMD: &[IndicatorParamInfo] = &[
2779    IndicatorParamInfo {
2780        key: "period",
2781        label: "Period",
2782        kind: IndicatorParamKind::Int,
2783        required: false,
2784        default: Some(ParamValueStatic::Int(20)),
2785        min: Some(1.0),
2786        max: None,
2787        step: Some(1.0),
2788        enum_values: EMPTY_ENUM_VALUES,
2789        notes: None,
2790    },
2791    IndicatorParamInfo {
2792        key: "delta",
2793        label: "Delta",
2794        kind: IndicatorParamKind::Float,
2795        required: false,
2796        default: Some(ParamValueStatic::Float(0.5)),
2797        min: Some(0.0),
2798        max: None,
2799        step: None,
2800        enum_values: EMPTY_ENUM_VALUES,
2801        notes: None,
2802    },
2803    IndicatorParamInfo {
2804        key: "fraction",
2805        label: "Fraction",
2806        kind: IndicatorParamKind::Float,
2807        required: false,
2808        default: Some(ParamValueStatic::Float(0.1)),
2809        min: Some(0.0),
2810        max: None,
2811        step: None,
2812        enum_values: EMPTY_ENUM_VALUES,
2813        notes: None,
2814    },
2815];
2816
2817const PARAM_ERI: &[IndicatorParamInfo] = &[
2818    IndicatorParamInfo {
2819        key: "period",
2820        label: "Period",
2821        kind: IndicatorParamKind::Int,
2822        required: false,
2823        default: Some(ParamValueStatic::Int(13)),
2824        min: Some(1.0),
2825        max: None,
2826        step: Some(1.0),
2827        enum_values: EMPTY_ENUM_VALUES,
2828        notes: None,
2829    },
2830    IndicatorParamInfo {
2831        key: "ma_type",
2832        label: "MA Type",
2833        kind: IndicatorParamKind::EnumString,
2834        required: false,
2835        default: Some(ParamValueStatic::EnumString("ema")),
2836        min: None,
2837        max: None,
2838        step: None,
2839        enum_values: EMPTY_ENUM_VALUES,
2840        notes: None,
2841    },
2842];
2843
2844const PARAM_FISHER: &[IndicatorParamInfo] = &[IndicatorParamInfo {
2845    key: "period",
2846    label: "Period",
2847    kind: IndicatorParamKind::Int,
2848    required: false,
2849    default: Some(ParamValueStatic::Int(9)),
2850    min: Some(1.0),
2851    max: None,
2852    step: Some(1.0),
2853    enum_values: EMPTY_ENUM_VALUES,
2854    notes: None,
2855}];
2856
2857const PARAM_FVG_TRAILING_STOP: &[IndicatorParamInfo] = &[
2858    IndicatorParamInfo {
2859        key: "unmitigated_fvg_lookback",
2860        label: "FVG Lookback",
2861        kind: IndicatorParamKind::Int,
2862        required: false,
2863        default: Some(ParamValueStatic::Int(5)),
2864        min: Some(1.0),
2865        max: None,
2866        step: Some(1.0),
2867        enum_values: EMPTY_ENUM_VALUES,
2868        notes: None,
2869    },
2870    IndicatorParamInfo {
2871        key: "smoothing_length",
2872        label: "Smoothing Length",
2873        kind: IndicatorParamKind::Int,
2874        required: false,
2875        default: Some(ParamValueStatic::Int(9)),
2876        min: Some(1.0),
2877        max: None,
2878        step: Some(1.0),
2879        enum_values: EMPTY_ENUM_VALUES,
2880        notes: None,
2881    },
2882    IndicatorParamInfo {
2883        key: "reset_on_cross",
2884        label: "Reset On Cross",
2885        kind: IndicatorParamKind::Bool,
2886        required: false,
2887        default: Some(ParamValueStatic::Bool(false)),
2888        min: None,
2889        max: None,
2890        step: None,
2891        enum_values: ENUM_VALUES_TRUE_FALSE,
2892        notes: None,
2893    },
2894];
2895
2896const PARAM_GATOROSC: &[IndicatorParamInfo] = &[
2897    IndicatorParamInfo {
2898        key: "jaws_length",
2899        label: "Jaws Length",
2900        kind: IndicatorParamKind::Int,
2901        required: false,
2902        default: Some(ParamValueStatic::Int(13)),
2903        min: Some(1.0),
2904        max: None,
2905        step: Some(1.0),
2906        enum_values: EMPTY_ENUM_VALUES,
2907        notes: None,
2908    },
2909    IndicatorParamInfo {
2910        key: "jaws_shift",
2911        label: "Jaws Shift",
2912        kind: IndicatorParamKind::Int,
2913        required: false,
2914        default: Some(ParamValueStatic::Int(8)),
2915        min: Some(0.0),
2916        max: None,
2917        step: Some(1.0),
2918        enum_values: EMPTY_ENUM_VALUES,
2919        notes: None,
2920    },
2921    IndicatorParamInfo {
2922        key: "teeth_length",
2923        label: "Teeth Length",
2924        kind: IndicatorParamKind::Int,
2925        required: false,
2926        default: Some(ParamValueStatic::Int(8)),
2927        min: Some(1.0),
2928        max: None,
2929        step: Some(1.0),
2930        enum_values: EMPTY_ENUM_VALUES,
2931        notes: None,
2932    },
2933    IndicatorParamInfo {
2934        key: "teeth_shift",
2935        label: "Teeth Shift",
2936        kind: IndicatorParamKind::Int,
2937        required: false,
2938        default: Some(ParamValueStatic::Int(5)),
2939        min: Some(0.0),
2940        max: None,
2941        step: Some(1.0),
2942        enum_values: EMPTY_ENUM_VALUES,
2943        notes: None,
2944    },
2945    IndicatorParamInfo {
2946        key: "lips_length",
2947        label: "Lips Length",
2948        kind: IndicatorParamKind::Int,
2949        required: false,
2950        default: Some(ParamValueStatic::Int(5)),
2951        min: Some(1.0),
2952        max: None,
2953        step: Some(1.0),
2954        enum_values: EMPTY_ENUM_VALUES,
2955        notes: None,
2956    },
2957    IndicatorParamInfo {
2958        key: "lips_shift",
2959        label: "Lips Shift",
2960        kind: IndicatorParamKind::Int,
2961        required: false,
2962        default: Some(ParamValueStatic::Int(3)),
2963        min: Some(0.0),
2964        max: None,
2965        step: Some(1.0),
2966        enum_values: EMPTY_ENUM_VALUES,
2967        notes: None,
2968    },
2969];
2970
2971const PARAM_HALFTREND: &[IndicatorParamInfo] = &[
2972    IndicatorParamInfo {
2973        key: "amplitude",
2974        label: "Amplitude",
2975        kind: IndicatorParamKind::Int,
2976        required: false,
2977        default: Some(ParamValueStatic::Int(2)),
2978        min: Some(1.0),
2979        max: None,
2980        step: Some(1.0),
2981        enum_values: EMPTY_ENUM_VALUES,
2982        notes: None,
2983    },
2984    IndicatorParamInfo {
2985        key: "channel_deviation",
2986        label: "Channel Deviation",
2987        kind: IndicatorParamKind::Float,
2988        required: false,
2989        default: Some(ParamValueStatic::Float(2.0)),
2990        min: Some(0.0),
2991        max: None,
2992        step: None,
2993        enum_values: EMPTY_ENUM_VALUES,
2994        notes: None,
2995    },
2996    IndicatorParamInfo {
2997        key: "atr_period",
2998        label: "ATR Period",
2999        kind: IndicatorParamKind::Int,
3000        required: false,
3001        default: Some(ParamValueStatic::Int(100)),
3002        min: Some(1.0),
3003        max: None,
3004        step: Some(1.0),
3005        enum_values: EMPTY_ENUM_VALUES,
3006        notes: None,
3007    },
3008];
3009
3010const PARAM_KST: &[IndicatorParamInfo] = &[
3011    IndicatorParamInfo {
3012        key: "sma_period1",
3013        label: "SMA 1",
3014        kind: IndicatorParamKind::Int,
3015        required: false,
3016        default: Some(ParamValueStatic::Int(10)),
3017        min: Some(1.0),
3018        max: None,
3019        step: Some(1.0),
3020        enum_values: EMPTY_ENUM_VALUES,
3021        notes: None,
3022    },
3023    IndicatorParamInfo {
3024        key: "sma_period2",
3025        label: "SMA 2",
3026        kind: IndicatorParamKind::Int,
3027        required: false,
3028        default: Some(ParamValueStatic::Int(10)),
3029        min: Some(1.0),
3030        max: None,
3031        step: Some(1.0),
3032        enum_values: EMPTY_ENUM_VALUES,
3033        notes: None,
3034    },
3035    IndicatorParamInfo {
3036        key: "sma_period3",
3037        label: "SMA 3",
3038        kind: IndicatorParamKind::Int,
3039        required: false,
3040        default: Some(ParamValueStatic::Int(10)),
3041        min: Some(1.0),
3042        max: None,
3043        step: Some(1.0),
3044        enum_values: EMPTY_ENUM_VALUES,
3045        notes: None,
3046    },
3047    IndicatorParamInfo {
3048        key: "sma_period4",
3049        label: "SMA 4",
3050        kind: IndicatorParamKind::Int,
3051        required: false,
3052        default: Some(ParamValueStatic::Int(15)),
3053        min: Some(1.0),
3054        max: None,
3055        step: Some(1.0),
3056        enum_values: EMPTY_ENUM_VALUES,
3057        notes: None,
3058    },
3059    IndicatorParamInfo {
3060        key: "roc_period1",
3061        label: "ROC 1",
3062        kind: IndicatorParamKind::Int,
3063        required: false,
3064        default: Some(ParamValueStatic::Int(10)),
3065        min: Some(1.0),
3066        max: None,
3067        step: Some(1.0),
3068        enum_values: EMPTY_ENUM_VALUES,
3069        notes: None,
3070    },
3071    IndicatorParamInfo {
3072        key: "roc_period2",
3073        label: "ROC 2",
3074        kind: IndicatorParamKind::Int,
3075        required: false,
3076        default: Some(ParamValueStatic::Int(15)),
3077        min: Some(1.0),
3078        max: None,
3079        step: Some(1.0),
3080        enum_values: EMPTY_ENUM_VALUES,
3081        notes: None,
3082    },
3083    IndicatorParamInfo {
3084        key: "roc_period3",
3085        label: "ROC 3",
3086        kind: IndicatorParamKind::Int,
3087        required: false,
3088        default: Some(ParamValueStatic::Int(20)),
3089        min: Some(1.0),
3090        max: None,
3091        step: Some(1.0),
3092        enum_values: EMPTY_ENUM_VALUES,
3093        notes: None,
3094    },
3095    IndicatorParamInfo {
3096        key: "roc_period4",
3097        label: "ROC 4",
3098        kind: IndicatorParamKind::Int,
3099        required: false,
3100        default: Some(ParamValueStatic::Int(30)),
3101        min: Some(1.0),
3102        max: None,
3103        step: Some(1.0),
3104        enum_values: EMPTY_ENUM_VALUES,
3105        notes: None,
3106    },
3107    IndicatorParamInfo {
3108        key: "signal_period",
3109        label: "Signal Period",
3110        kind: IndicatorParamKind::Int,
3111        required: false,
3112        default: Some(ParamValueStatic::Int(9)),
3113        min: Some(1.0),
3114        max: None,
3115        step: Some(1.0),
3116        enum_values: EMPTY_ENUM_VALUES,
3117        notes: None,
3118    },
3119];
3120
3121const PARAM_LPC: &[IndicatorParamInfo] = &[
3122    IndicatorParamInfo {
3123        key: "cutoff_type",
3124        label: "Cutoff Type",
3125        kind: IndicatorParamKind::EnumString,
3126        required: false,
3127        default: Some(ParamValueStatic::EnumString("adaptive")),
3128        min: None,
3129        max: None,
3130        step: None,
3131        enum_values: EMPTY_ENUM_VALUES,
3132        notes: None,
3133    },
3134    IndicatorParamInfo {
3135        key: "fixed_period",
3136        label: "Fixed Period",
3137        kind: IndicatorParamKind::Int,
3138        required: false,
3139        default: Some(ParamValueStatic::Int(20)),
3140        min: Some(1.0),
3141        max: None,
3142        step: Some(1.0),
3143        enum_values: EMPTY_ENUM_VALUES,
3144        notes: None,
3145    },
3146    IndicatorParamInfo {
3147        key: "max_cycle_limit",
3148        label: "Max Cycle Limit",
3149        kind: IndicatorParamKind::Int,
3150        required: false,
3151        default: Some(ParamValueStatic::Int(60)),
3152        min: Some(1.0),
3153        max: None,
3154        step: Some(1.0),
3155        enum_values: EMPTY_ENUM_VALUES,
3156        notes: None,
3157    },
3158    IndicatorParamInfo {
3159        key: "cycle_mult",
3160        label: "Cycle Mult",
3161        kind: IndicatorParamKind::Float,
3162        required: false,
3163        default: Some(ParamValueStatic::Float(1.0)),
3164        min: Some(0.0),
3165        max: None,
3166        step: None,
3167        enum_values: EMPTY_ENUM_VALUES,
3168        notes: None,
3169    },
3170    IndicatorParamInfo {
3171        key: "tr_mult",
3172        label: "TR Mult",
3173        kind: IndicatorParamKind::Float,
3174        required: false,
3175        default: Some(ParamValueStatic::Float(1.0)),
3176        min: Some(0.0),
3177        max: None,
3178        step: None,
3179        enum_values: EMPTY_ENUM_VALUES,
3180        notes: None,
3181    },
3182];
3183
3184const PARAM_MAB: &[IndicatorParamInfo] = &[
3185    IndicatorParamInfo {
3186        key: "fast_period",
3187        label: "Fast Period",
3188        kind: IndicatorParamKind::Int,
3189        required: false,
3190        default: Some(ParamValueStatic::Int(10)),
3191        min: Some(1.0),
3192        max: None,
3193        step: Some(1.0),
3194        enum_values: EMPTY_ENUM_VALUES,
3195        notes: None,
3196    },
3197    IndicatorParamInfo {
3198        key: "slow_period",
3199        label: "Slow Period",
3200        kind: IndicatorParamKind::Int,
3201        required: false,
3202        default: Some(ParamValueStatic::Int(50)),
3203        min: Some(1.0),
3204        max: None,
3205        step: Some(1.0),
3206        enum_values: EMPTY_ENUM_VALUES,
3207        notes: None,
3208    },
3209    IndicatorParamInfo {
3210        key: "devup",
3211        label: "Dev Up",
3212        kind: IndicatorParamKind::Float,
3213        required: false,
3214        default: Some(ParamValueStatic::Float(1.0)),
3215        min: Some(0.0),
3216        max: None,
3217        step: None,
3218        enum_values: EMPTY_ENUM_VALUES,
3219        notes: None,
3220    },
3221    IndicatorParamInfo {
3222        key: "devdn",
3223        label: "Dev Down",
3224        kind: IndicatorParamKind::Float,
3225        required: false,
3226        default: Some(ParamValueStatic::Float(1.0)),
3227        min: Some(0.0),
3228        max: None,
3229        step: None,
3230        enum_values: EMPTY_ENUM_VALUES,
3231        notes: None,
3232    },
3233    IndicatorParamInfo {
3234        key: "fast_ma_type",
3235        label: "Fast MA Type",
3236        kind: IndicatorParamKind::EnumString,
3237        required: false,
3238        default: Some(ParamValueStatic::EnumString("sma")),
3239        min: None,
3240        max: None,
3241        step: None,
3242        enum_values: EMPTY_ENUM_VALUES,
3243        notes: None,
3244    },
3245    IndicatorParamInfo {
3246        key: "slow_ma_type",
3247        label: "Slow MA Type",
3248        kind: IndicatorParamKind::EnumString,
3249        required: false,
3250        default: Some(ParamValueStatic::EnumString("sma")),
3251        min: None,
3252        max: None,
3253        step: None,
3254        enum_values: EMPTY_ENUM_VALUES,
3255        notes: None,
3256    },
3257];
3258
3259const PARAM_MACZ: &[IndicatorParamInfo] = &[
3260    IndicatorParamInfo {
3261        key: "fast_length",
3262        label: "Fast Length",
3263        kind: IndicatorParamKind::Int,
3264        required: false,
3265        default: Some(ParamValueStatic::Int(12)),
3266        min: Some(1.0),
3267        max: None,
3268        step: Some(1.0),
3269        enum_values: EMPTY_ENUM_VALUES,
3270        notes: None,
3271    },
3272    IndicatorParamInfo {
3273        key: "slow_length",
3274        label: "Slow Length",
3275        kind: IndicatorParamKind::Int,
3276        required: false,
3277        default: Some(ParamValueStatic::Int(25)),
3278        min: Some(1.0),
3279        max: None,
3280        step: Some(1.0),
3281        enum_values: EMPTY_ENUM_VALUES,
3282        notes: None,
3283    },
3284    IndicatorParamInfo {
3285        key: "signal_length",
3286        label: "Signal Length",
3287        kind: IndicatorParamKind::Int,
3288        required: false,
3289        default: Some(ParamValueStatic::Int(9)),
3290        min: Some(1.0),
3291        max: None,
3292        step: Some(1.0),
3293        enum_values: EMPTY_ENUM_VALUES,
3294        notes: None,
3295    },
3296    IndicatorParamInfo {
3297        key: "lengthz",
3298        label: "Length Z",
3299        kind: IndicatorParamKind::Int,
3300        required: false,
3301        default: Some(ParamValueStatic::Int(20)),
3302        min: Some(1.0),
3303        max: None,
3304        step: Some(1.0),
3305        enum_values: EMPTY_ENUM_VALUES,
3306        notes: None,
3307    },
3308    IndicatorParamInfo {
3309        key: "length_stdev",
3310        label: "Length StdDev",
3311        kind: IndicatorParamKind::Int,
3312        required: false,
3313        default: Some(ParamValueStatic::Int(25)),
3314        min: Some(1.0),
3315        max: None,
3316        step: Some(1.0),
3317        enum_values: EMPTY_ENUM_VALUES,
3318        notes: None,
3319    },
3320    IndicatorParamInfo {
3321        key: "a",
3322        label: "A",
3323        kind: IndicatorParamKind::Float,
3324        required: false,
3325        default: Some(ParamValueStatic::Float(1.0)),
3326        min: None,
3327        max: None,
3328        step: None,
3329        enum_values: EMPTY_ENUM_VALUES,
3330        notes: None,
3331    },
3332    IndicatorParamInfo {
3333        key: "b",
3334        label: "B",
3335        kind: IndicatorParamKind::Float,
3336        required: false,
3337        default: Some(ParamValueStatic::Float(1.0)),
3338        min: None,
3339        max: None,
3340        step: None,
3341        enum_values: EMPTY_ENUM_VALUES,
3342        notes: None,
3343    },
3344    IndicatorParamInfo {
3345        key: "use_lag",
3346        label: "Use Lag",
3347        kind: IndicatorParamKind::Bool,
3348        required: false,
3349        default: Some(ParamValueStatic::Bool(false)),
3350        min: None,
3351        max: None,
3352        step: None,
3353        enum_values: ENUM_VALUES_TRUE_FALSE,
3354        notes: None,
3355    },
3356    IndicatorParamInfo {
3357        key: "gamma",
3358        label: "Gamma",
3359        kind: IndicatorParamKind::Float,
3360        required: false,
3361        default: Some(ParamValueStatic::Float(0.02)),
3362        min: None,
3363        max: None,
3364        step: None,
3365        enum_values: EMPTY_ENUM_VALUES,
3366        notes: None,
3367    },
3368];
3369
3370const PARAM_MINMAX: &[IndicatorParamInfo] = &[IndicatorParamInfo {
3371    key: "order",
3372    label: "Order",
3373    kind: IndicatorParamKind::Int,
3374    required: false,
3375    default: Some(ParamValueStatic::Int(3)),
3376    min: Some(1.0),
3377    max: None,
3378    step: Some(1.0),
3379    enum_values: EMPTY_ENUM_VALUES,
3380    notes: None,
3381}];
3382
3383const PARAM_MSW: &[IndicatorParamInfo] = &[IndicatorParamInfo {
3384    key: "period",
3385    label: "Period",
3386    kind: IndicatorParamKind::Int,
3387    required: false,
3388    default: Some(ParamValueStatic::Int(5)),
3389    min: Some(1.0),
3390    max: None,
3391    step: Some(1.0),
3392    enum_values: EMPTY_ENUM_VALUES,
3393    notes: None,
3394}];
3395
3396const PARAM_NWE: &[IndicatorParamInfo] = &[
3397    IndicatorParamInfo {
3398        key: "bandwidth",
3399        label: "Bandwidth",
3400        kind: IndicatorParamKind::Float,
3401        required: false,
3402        default: Some(ParamValueStatic::Float(8.0)),
3403        min: Some(0.0),
3404        max: None,
3405        step: None,
3406        enum_values: EMPTY_ENUM_VALUES,
3407        notes: None,
3408    },
3409    IndicatorParamInfo {
3410        key: "multiplier",
3411        label: "Multiplier",
3412        kind: IndicatorParamKind::Float,
3413        required: false,
3414        default: Some(ParamValueStatic::Float(3.0)),
3415        min: Some(0.0),
3416        max: None,
3417        step: None,
3418        enum_values: EMPTY_ENUM_VALUES,
3419        notes: None,
3420    },
3421    IndicatorParamInfo {
3422        key: "lookback",
3423        label: "Lookback",
3424        kind: IndicatorParamKind::Int,
3425        required: false,
3426        default: Some(ParamValueStatic::Int(500)),
3427        min: Some(1.0),
3428        max: None,
3429        step: Some(1.0),
3430        enum_values: EMPTY_ENUM_VALUES,
3431        notes: None,
3432    },
3433];
3434
3435const PARAM_OTTO: &[IndicatorParamInfo] = &[
3436    IndicatorParamInfo {
3437        key: "ott_period",
3438        label: "OTT Period",
3439        kind: IndicatorParamKind::Int,
3440        required: false,
3441        default: Some(ParamValueStatic::Int(2)),
3442        min: Some(1.0),
3443        max: None,
3444        step: Some(1.0),
3445        enum_values: EMPTY_ENUM_VALUES,
3446        notes: None,
3447    },
3448    IndicatorParamInfo {
3449        key: "ott_percent",
3450        label: "OTT Percent",
3451        kind: IndicatorParamKind::Float,
3452        required: false,
3453        default: Some(ParamValueStatic::Float(0.6)),
3454        min: Some(0.0),
3455        max: None,
3456        step: None,
3457        enum_values: EMPTY_ENUM_VALUES,
3458        notes: None,
3459    },
3460    IndicatorParamInfo {
3461        key: "fast_vidya_length",
3462        label: "Fast VIDYA Length",
3463        kind: IndicatorParamKind::Int,
3464        required: false,
3465        default: Some(ParamValueStatic::Int(10)),
3466        min: Some(1.0),
3467        max: None,
3468        step: Some(1.0),
3469        enum_values: EMPTY_ENUM_VALUES,
3470        notes: None,
3471    },
3472    IndicatorParamInfo {
3473        key: "slow_vidya_length",
3474        label: "Slow VIDYA Length",
3475        kind: IndicatorParamKind::Int,
3476        required: false,
3477        default: Some(ParamValueStatic::Int(25)),
3478        min: Some(1.0),
3479        max: None,
3480        step: Some(1.0),
3481        enum_values: EMPTY_ENUM_VALUES,
3482        notes: None,
3483    },
3484    IndicatorParamInfo {
3485        key: "correcting_constant",
3486        label: "Correcting Constant",
3487        kind: IndicatorParamKind::Float,
3488        required: false,
3489        default: Some(ParamValueStatic::Float(100000.0)),
3490        min: Some(0.0),
3491        max: None,
3492        step: None,
3493        enum_values: EMPTY_ENUM_VALUES,
3494        notes: None,
3495    },
3496    IndicatorParamInfo {
3497        key: "ma_type",
3498        label: "MA Type",
3499        kind: IndicatorParamKind::EnumString,
3500        required: false,
3501        default: Some(ParamValueStatic::EnumString("VAR")),
3502        min: None,
3503        max: None,
3504        step: None,
3505        enum_values: EMPTY_ENUM_VALUES,
3506        notes: None,
3507    },
3508];
3509
3510const PARAM_PMA: &[IndicatorParamInfo] = PARAM_NONE;
3511
3512const PARAM_PRB: &[IndicatorParamInfo] = &[
3513    IndicatorParamInfo {
3514        key: "smooth_data",
3515        label: "Smooth Data",
3516        kind: IndicatorParamKind::Bool,
3517        required: false,
3518        default: Some(ParamValueStatic::Bool(true)),
3519        min: None,
3520        max: None,
3521        step: None,
3522        enum_values: ENUM_VALUES_TRUE_FALSE,
3523        notes: None,
3524    },
3525    IndicatorParamInfo {
3526        key: "smooth_period",
3527        label: "Smooth Period",
3528        kind: IndicatorParamKind::Int,
3529        required: false,
3530        default: Some(ParamValueStatic::Int(10)),
3531        min: Some(1.0),
3532        max: None,
3533        step: Some(1.0),
3534        enum_values: EMPTY_ENUM_VALUES,
3535        notes: None,
3536    },
3537    IndicatorParamInfo {
3538        key: "regression_period",
3539        label: "Regression Period",
3540        kind: IndicatorParamKind::Int,
3541        required: false,
3542        default: Some(ParamValueStatic::Int(100)),
3543        min: Some(1.0),
3544        max: None,
3545        step: Some(1.0),
3546        enum_values: EMPTY_ENUM_VALUES,
3547        notes: None,
3548    },
3549    IndicatorParamInfo {
3550        key: "polynomial_order",
3551        label: "Polynomial Order",
3552        kind: IndicatorParamKind::Int,
3553        required: false,
3554        default: Some(ParamValueStatic::Int(2)),
3555        min: Some(1.0),
3556        max: None,
3557        step: Some(1.0),
3558        enum_values: EMPTY_ENUM_VALUES,
3559        notes: None,
3560    },
3561    IndicatorParamInfo {
3562        key: "regression_offset",
3563        label: "Regression Offset",
3564        kind: IndicatorParamKind::Int,
3565        required: false,
3566        default: Some(ParamValueStatic::Int(0)),
3567        min: None,
3568        max: None,
3569        step: Some(1.0),
3570        enum_values: EMPTY_ENUM_VALUES,
3571        notes: None,
3572    },
3573    IndicatorParamInfo {
3574        key: "ndev",
3575        label: "NDev",
3576        kind: IndicatorParamKind::Float,
3577        required: false,
3578        default: Some(ParamValueStatic::Float(2.0)),
3579        min: Some(0.0),
3580        max: None,
3581        step: None,
3582        enum_values: EMPTY_ENUM_VALUES,
3583        notes: None,
3584    },
3585    IndicatorParamInfo {
3586        key: "equ_from",
3587        label: "Equ From",
3588        kind: IndicatorParamKind::Int,
3589        required: false,
3590        default: Some(ParamValueStatic::Int(0)),
3591        min: Some(0.0),
3592        max: None,
3593        step: Some(1.0),
3594        enum_values: EMPTY_ENUM_VALUES,
3595        notes: None,
3596    },
3597];
3598
3599const PARAM_QQE: &[IndicatorParamInfo] = &[
3600    IndicatorParamInfo {
3601        key: "rsi_period",
3602        label: "RSI Period",
3603        kind: IndicatorParamKind::Int,
3604        required: false,
3605        default: Some(ParamValueStatic::Int(14)),
3606        min: Some(1.0),
3607        max: None,
3608        step: Some(1.0),
3609        enum_values: EMPTY_ENUM_VALUES,
3610        notes: None,
3611    },
3612    IndicatorParamInfo {
3613        key: "smoothing_factor",
3614        label: "Smoothing Factor",
3615        kind: IndicatorParamKind::Int,
3616        required: false,
3617        default: Some(ParamValueStatic::Int(5)),
3618        min: Some(1.0),
3619        max: None,
3620        step: Some(1.0),
3621        enum_values: EMPTY_ENUM_VALUES,
3622        notes: None,
3623    },
3624    IndicatorParamInfo {
3625        key: "fast_factor",
3626        label: "Fast Factor",
3627        kind: IndicatorParamKind::Float,
3628        required: false,
3629        default: Some(ParamValueStatic::Float(4.236)),
3630        min: Some(0.0),
3631        max: None,
3632        step: None,
3633        enum_values: EMPTY_ENUM_VALUES,
3634        notes: None,
3635    },
3636];
3637
3638const PARAM_RANGE_FILTER: &[IndicatorParamInfo] = &[
3639    IndicatorParamInfo {
3640        key: "range_size",
3641        label: "Range Size",
3642        kind: IndicatorParamKind::Float,
3643        required: false,
3644        default: Some(ParamValueStatic::Float(2.618)),
3645        min: Some(0.0),
3646        max: None,
3647        step: None,
3648        enum_values: EMPTY_ENUM_VALUES,
3649        notes: None,
3650    },
3651    IndicatorParamInfo {
3652        key: "range_period",
3653        label: "Range Period",
3654        kind: IndicatorParamKind::Int,
3655        required: false,
3656        default: Some(ParamValueStatic::Int(14)),
3657        min: Some(1.0),
3658        max: None,
3659        step: Some(1.0),
3660        enum_values: EMPTY_ENUM_VALUES,
3661        notes: None,
3662    },
3663    IndicatorParamInfo {
3664        key: "smooth_range",
3665        label: "Smooth Range",
3666        kind: IndicatorParamKind::Bool,
3667        required: false,
3668        default: Some(ParamValueStatic::Bool(true)),
3669        min: None,
3670        max: None,
3671        step: None,
3672        enum_values: ENUM_VALUES_TRUE_FALSE,
3673        notes: None,
3674    },
3675    IndicatorParamInfo {
3676        key: "smooth_period",
3677        label: "Smooth Period",
3678        kind: IndicatorParamKind::Int,
3679        required: false,
3680        default: Some(ParamValueStatic::Int(27)),
3681        min: Some(1.0),
3682        max: None,
3683        step: Some(1.0),
3684        enum_values: EMPTY_ENUM_VALUES,
3685        notes: None,
3686    },
3687];
3688
3689const PARAM_RSMK: &[IndicatorParamInfo] = &[
3690    IndicatorParamInfo {
3691        key: "lookback",
3692        label: "Lookback",
3693        kind: IndicatorParamKind::Int,
3694        required: false,
3695        default: Some(ParamValueStatic::Int(90)),
3696        min: Some(1.0),
3697        max: None,
3698        step: Some(1.0),
3699        enum_values: EMPTY_ENUM_VALUES,
3700        notes: None,
3701    },
3702    IndicatorParamInfo {
3703        key: "period",
3704        label: "Period",
3705        kind: IndicatorParamKind::Int,
3706        required: false,
3707        default: Some(ParamValueStatic::Int(3)),
3708        min: Some(1.0),
3709        max: None,
3710        step: Some(1.0),
3711        enum_values: EMPTY_ENUM_VALUES,
3712        notes: None,
3713    },
3714    IndicatorParamInfo {
3715        key: "signal_period",
3716        label: "Signal Period",
3717        kind: IndicatorParamKind::Int,
3718        required: false,
3719        default: Some(ParamValueStatic::Int(20)),
3720        min: Some(1.0),
3721        max: None,
3722        step: Some(1.0),
3723        enum_values: EMPTY_ENUM_VALUES,
3724        notes: None,
3725    },
3726    IndicatorParamInfo {
3727        key: "matype",
3728        label: "MA Type",
3729        kind: IndicatorParamKind::EnumString,
3730        required: false,
3731        default: Some(ParamValueStatic::EnumString("ema")),
3732        min: None,
3733        max: None,
3734        step: None,
3735        enum_values: EMPTY_ENUM_VALUES,
3736        notes: None,
3737    },
3738    IndicatorParamInfo {
3739        key: "signal_matype",
3740        label: "Signal MA Type",
3741        kind: IndicatorParamKind::EnumString,
3742        required: false,
3743        default: Some(ParamValueStatic::EnumString("ema")),
3744        min: None,
3745        max: None,
3746        step: None,
3747        enum_values: EMPTY_ENUM_VALUES,
3748        notes: None,
3749    },
3750];
3751
3752const PARAM_VOSS: &[IndicatorParamInfo] = &[
3753    IndicatorParamInfo {
3754        key: "period",
3755        label: "Period",
3756        kind: IndicatorParamKind::Int,
3757        required: false,
3758        default: Some(ParamValueStatic::Int(20)),
3759        min: Some(1.0),
3760        max: None,
3761        step: Some(1.0),
3762        enum_values: EMPTY_ENUM_VALUES,
3763        notes: None,
3764    },
3765    IndicatorParamInfo {
3766        key: "predict",
3767        label: "Predict",
3768        kind: IndicatorParamKind::Int,
3769        required: false,
3770        default: Some(ParamValueStatic::Int(3)),
3771        min: Some(1.0),
3772        max: None,
3773        step: Some(1.0),
3774        enum_values: EMPTY_ENUM_VALUES,
3775        notes: None,
3776    },
3777    IndicatorParamInfo {
3778        key: "bandwidth",
3779        label: "Bandwidth",
3780        kind: IndicatorParamKind::Float,
3781        required: false,
3782        default: Some(ParamValueStatic::Float(0.25)),
3783        min: Some(0.0),
3784        max: None,
3785        step: None,
3786        enum_values: EMPTY_ENUM_VALUES,
3787        notes: None,
3788    },
3789];
3790
3791const PARAM_PIVOT: &[IndicatorParamInfo] = &[IndicatorParamInfo {
3792    key: "mode",
3793    label: "Mode",
3794    kind: IndicatorParamKind::Int,
3795    required: false,
3796    default: Some(ParamValueStatic::Int(3)),
3797    min: Some(0.0),
3798    max: None,
3799    step: Some(1.0),
3800    enum_values: EMPTY_ENUM_VALUES,
3801    notes: None,
3802}];
3803
3804const SUPPLEMENTAL_SEED_NOTE: &str =
3805    "Phase 1 seed metadata; parameter and capability metadata will expand.";
3806
3807struct SupplementalIndicatorSeed {
3808    id: &'static str,
3809    label: &'static str,
3810    category: &'static str,
3811    input_kind: IndicatorInputKind,
3812    outputs: &'static [IndicatorOutputInfo],
3813    params: &'static [IndicatorParamInfo],
3814}
3815
3816const SUPPLEMENTAL_INDICATORS: &[SupplementalIndicatorSeed] = &[
3817    SupplementalIndicatorSeed {
3818        id: "adx",
3819        label: "ADX",
3820        category: "trend",
3821        input_kind: IndicatorInputKind::Ohlc,
3822        outputs: OUTPUTS_VALUE_F64,
3823        params: PARAM_ADX_PERIOD,
3824    },
3825    SupplementalIndicatorSeed {
3826        id: "dx",
3827        label: "DX",
3828        category: "trend",
3829        input_kind: IndicatorInputKind::Ohlc,
3830        outputs: OUTPUTS_VALUE_F64,
3831        params: PARAM_DX_PERIOD,
3832    },
3833    SupplementalIndicatorSeed {
3834        id: "di",
3835        label: "DI",
3836        category: "trend",
3837        input_kind: IndicatorInputKind::Ohlc,
3838        outputs: OUTPUTS_PLUS_MINUS,
3839        params: PARAM_DI,
3840    },
3841    SupplementalIndicatorSeed {
3842        id: "dm",
3843        label: "DM",
3844        category: "trend",
3845        input_kind: IndicatorInputKind::HighLow,
3846        outputs: OUTPUTS_PLUS_MINUS,
3847        params: PARAM_DM,
3848    },
3849    SupplementalIndicatorSeed {
3850        id: "vi",
3851        label: "VI",
3852        category: "trend",
3853        input_kind: IndicatorInputKind::Ohlc,
3854        outputs: OUTPUTS_PLUS_MINUS,
3855        params: PARAM_VI,
3856    },
3857    SupplementalIndicatorSeed {
3858        id: "donchian",
3859        label: "Donchian",
3860        category: "volatility",
3861        input_kind: IndicatorInputKind::HighLow,
3862        outputs: OUTPUTS_BOLLINGER,
3863        params: PARAM_DONCHIAN,
3864    },
3865    SupplementalIndicatorSeed {
3866        id: "supertrend",
3867        label: "SuperTrend",
3868        category: "trend",
3869        input_kind: IndicatorInputKind::Ohlc,
3870        outputs: OUTPUTS_TREND_CHANGED,
3871        params: PARAM_SUPERTREND,
3872    },
3873    SupplementalIndicatorSeed {
3874        id: "keltner",
3875        label: "Keltner",
3876        category: "volatility",
3877        input_kind: IndicatorInputKind::Ohlc,
3878        outputs: OUTPUTS_BOLLINGER,
3879        params: PARAM_KELTNER,
3880    },
3881    SupplementalIndicatorSeed {
3882        id: "aroon",
3883        label: "Aroon",
3884        category: "trend",
3885        input_kind: IndicatorInputKind::HighLow,
3886        outputs: OUTPUTS_UP_DOWN,
3887        params: PARAM_AROON,
3888    },
3889    SupplementalIndicatorSeed {
3890        id: "srsi",
3891        label: "Stochastic RSI",
3892        category: "momentum",
3893        input_kind: IndicatorInputKind::Slice,
3894        outputs: OUTPUTS_STOCH,
3895        params: PARAM_SRSI,
3896    },
3897    SupplementalIndicatorSeed {
3898        id: "kdj",
3899        label: "KDJ",
3900        category: "momentum",
3901        input_kind: IndicatorInputKind::Ohlc,
3902        outputs: OUTPUTS_KDJ,
3903        params: PARAM_KDJ,
3904    },
3905    SupplementalIndicatorSeed {
3906        id: "squeeze_momentum",
3907        label: "Squeeze Momentum",
3908        category: "momentum",
3909        input_kind: IndicatorInputKind::Ohlc,
3910        outputs: OUTPUTS_SQUEEZE_MOMENTUM,
3911        params: PARAM_SQUEEZE_MOMENTUM,
3912    },
3913    SupplementalIndicatorSeed {
3914        id: "wavetrend",
3915        label: "WaveTrend",
3916        category: "momentum",
3917        input_kind: IndicatorInputKind::Slice,
3918        outputs: OUTPUTS_WAVETREND,
3919        params: PARAM_WAVETREND,
3920    },
3921    SupplementalIndicatorSeed {
3922        id: "wto",
3923        label: "WTO",
3924        category: "momentum",
3925        input_kind: IndicatorInputKind::Slice,
3926        outputs: OUTPUTS_WTO,
3927        params: PARAM_WTO,
3928    },
3929    SupplementalIndicatorSeed {
3930        id: "atr",
3931        label: "ATR",
3932        category: "volatility",
3933        input_kind: IndicatorInputKind::Ohlc,
3934        outputs: OUTPUTS_VALUE_F64,
3935        params: PARAM_ATR_PERIOD,
3936    },
3937    SupplementalIndicatorSeed {
3938        id: "ad",
3939        label: "AD",
3940        category: "volume",
3941        input_kind: IndicatorInputKind::Ohlcv,
3942        outputs: OUTPUTS_VALUE_F64,
3943        params: PARAM_NONE,
3944    },
3945    SupplementalIndicatorSeed {
3946        id: "adosc",
3947        label: "ADOSC",
3948        category: "volume",
3949        input_kind: IndicatorInputKind::Ohlcv,
3950        outputs: OUTPUTS_VALUE_F64,
3951        params: PARAM_ADOSC,
3952    },
3953    SupplementalIndicatorSeed {
3954        id: "ao",
3955        label: "AO",
3956        category: "momentum",
3957        input_kind: IndicatorInputKind::HighLow,
3958        outputs: OUTPUTS_VALUE_F64,
3959        params: PARAM_AO,
3960    },
3961    SupplementalIndicatorSeed {
3962        id: "bop",
3963        label: "BOP",
3964        category: "momentum",
3965        input_kind: IndicatorInputKind::Ohlc,
3966        outputs: OUTPUTS_VALUE_F64,
3967        params: PARAM_NONE,
3968    },
3969    SupplementalIndicatorSeed {
3970        id: "emv",
3971        label: "EMV",
3972        category: "volume",
3973        input_kind: IndicatorInputKind::Ohlcv,
3974        outputs: OUTPUTS_VALUE_F64,
3975        params: PARAM_NONE,
3976    },
3977    SupplementalIndicatorSeed {
3978        id: "efi",
3979        label: "EFI",
3980        category: "volume",
3981        input_kind: IndicatorInputKind::CloseVolume,
3982        outputs: OUTPUTS_VALUE_F64,
3983        params: PARAM_EFI_PERIOD,
3984    },
3985    SupplementalIndicatorSeed {
3986        id: "mfi",
3987        label: "MFI",
3988        category: "volume",
3989        input_kind: IndicatorInputKind::CloseVolume,
3990        outputs: OUTPUTS_VALUE_F64,
3991        params: PARAM_MFI_PERIOD,
3992    },
3993    SupplementalIndicatorSeed {
3994        id: "mass",
3995        label: "MASS",
3996        category: "volatility",
3997        input_kind: IndicatorInputKind::HighLow,
3998        outputs: OUTPUTS_VALUE_F64,
3999        params: PARAM_MASS_PERIOD,
4000    },
4001    SupplementalIndicatorSeed {
4002        id: "kvo",
4003        label: "KVO",
4004        category: "volume",
4005        input_kind: IndicatorInputKind::Ohlcv,
4006        outputs: OUTPUTS_VALUE_F64,
4007        params: PARAM_KVO,
4008    },
4009    SupplementalIndicatorSeed {
4010        id: "vosc",
4011        label: "VOSC",
4012        category: "volume",
4013        input_kind: IndicatorInputKind::Slice,
4014        outputs: OUTPUTS_VALUE_F64,
4015        params: PARAM_VOSC,
4016    },
4017    SupplementalIndicatorSeed {
4018        id: "rsi",
4019        label: "RSI",
4020        category: "momentum",
4021        input_kind: IndicatorInputKind::Slice,
4022        outputs: OUTPUTS_VALUE_F64,
4023        params: PARAM_RSI_PERIOD,
4024    },
4025    SupplementalIndicatorSeed {
4026        id: "roc",
4027        label: "ROC",
4028        category: "momentum",
4029        input_kind: IndicatorInputKind::Slice,
4030        outputs: OUTPUTS_VALUE_F64,
4031        params: PARAM_ROC_PERIOD,
4032    },
4033    SupplementalIndicatorSeed {
4034        id: "apo",
4035        label: "APO",
4036        category: "momentum",
4037        input_kind: IndicatorInputKind::Slice,
4038        outputs: OUTPUTS_VALUE_F64,
4039        params: PARAM_APO,
4040    },
4041    SupplementalIndicatorSeed {
4042        id: "cci",
4043        label: "CCI",
4044        category: "momentum",
4045        input_kind: IndicatorInputKind::Slice,
4046        outputs: OUTPUTS_VALUE_F64,
4047        params: PARAM_CCI_PERIOD,
4048    },
4049    SupplementalIndicatorSeed {
4050        id: "cfo",
4051        label: "CFO",
4052        category: "momentum",
4053        input_kind: IndicatorInputKind::Slice,
4054        outputs: OUTPUTS_VALUE_F64,
4055        params: PARAM_CFO,
4056    },
4057    SupplementalIndicatorSeed {
4058        id: "cg",
4059        label: "CG",
4060        category: "momentum",
4061        input_kind: IndicatorInputKind::Slice,
4062        outputs: OUTPUTS_VALUE_F64,
4063        params: PARAM_CG_PERIOD,
4064    },
4065    SupplementalIndicatorSeed {
4066        id: "er",
4067        label: "ER",
4068        category: "momentum",
4069        input_kind: IndicatorInputKind::Slice,
4070        outputs: OUTPUTS_VALUE_F64,
4071        params: PARAM_ER_PERIOD,
4072    },
4073    SupplementalIndicatorSeed {
4074        id: "kurtosis",
4075        label: "Kurtosis",
4076        category: "statistics",
4077        input_kind: IndicatorInputKind::Slice,
4078        outputs: OUTPUTS_VALUE_F64,
4079        params: PARAM_KURTOSIS_PERIOD,
4080    },
4081    SupplementalIndicatorSeed {
4082        id: "natr",
4083        label: "NATR",
4084        category: "volatility",
4085        input_kind: IndicatorInputKind::Ohlc,
4086        outputs: OUTPUTS_VALUE_F64,
4087        params: PARAM_NATR_PERIOD,
4088    },
4089    SupplementalIndicatorSeed {
4090        id: "mean_ad",
4091        label: "Mean AD",
4092        category: "statistics",
4093        input_kind: IndicatorInputKind::Slice,
4094        outputs: OUTPUTS_VALUE_F64,
4095        params: PARAM_MEAN_AD_PERIOD,
4096    },
4097    SupplementalIndicatorSeed {
4098        id: "medium_ad",
4099        label: "Medium AD",
4100        category: "statistics",
4101        input_kind: IndicatorInputKind::Slice,
4102        outputs: OUTPUTS_VALUE_F64,
4103        params: PARAM_MEDIUM_AD_PERIOD,
4104    },
4105    SupplementalIndicatorSeed {
4106        id: "deviation",
4107        label: "Deviation",
4108        category: "statistics",
4109        input_kind: IndicatorInputKind::Slice,
4110        outputs: OUTPUTS_VALUE_F64,
4111        params: PARAM_DEVIATION,
4112    },
4113    SupplementalIndicatorSeed {
4114        id: "dpo",
4115        label: "DPO",
4116        category: "trend",
4117        input_kind: IndicatorInputKind::Slice,
4118        outputs: OUTPUTS_VALUE_F64,
4119        params: PARAM_DPO_PERIOD,
4120    },
4121    SupplementalIndicatorSeed {
4122        id: "fosc",
4123        label: "FOSC",
4124        category: "momentum",
4125        input_kind: IndicatorInputKind::Slice,
4126        outputs: OUTPUTS_VALUE_F64,
4127        params: PARAM_FOSC_PERIOD,
4128    },
4129    SupplementalIndicatorSeed {
4130        id: "ift_rsi",
4131        label: "IFT RSI",
4132        category: "momentum",
4133        input_kind: IndicatorInputKind::Slice,
4134        outputs: OUTPUTS_VALUE_F64,
4135        params: PARAM_IFT_RSI,
4136    },
4137    SupplementalIndicatorSeed {
4138        id: "linearreg_angle",
4139        label: "Linear Regression Angle",
4140        category: "trend",
4141        input_kind: IndicatorInputKind::Slice,
4142        outputs: OUTPUTS_VALUE_F64,
4143        params: PARAM_LINEARREG_ANGLE_PERIOD,
4144    },
4145    SupplementalIndicatorSeed {
4146        id: "linearreg_intercept",
4147        label: "Linear Regression Intercept",
4148        category: "trend",
4149        input_kind: IndicatorInputKind::Slice,
4150        outputs: OUTPUTS_VALUE_F64,
4151        params: PARAM_LINEARREG_INTERCEPT_PERIOD,
4152    },
4153    SupplementalIndicatorSeed {
4154        id: "linearreg_slope",
4155        label: "Linear Regression Slope",
4156        category: "trend",
4157        input_kind: IndicatorInputKind::Slice,
4158        outputs: OUTPUTS_VALUE_F64,
4159        params: PARAM_LINEARREG_SLOPE_PERIOD,
4160    },
4161    SupplementalIndicatorSeed {
4162        id: "pfe",
4163        label: "PFE",
4164        category: "trend",
4165        input_kind: IndicatorInputKind::Slice,
4166        outputs: OUTPUTS_VALUE_F64,
4167        params: PARAM_PFE,
4168    },
4169    SupplementalIndicatorSeed {
4170        id: "percentile_nearest_rank",
4171        label: "Percentile Nearest Rank",
4172        category: "statistics",
4173        input_kind: IndicatorInputKind::Slice,
4174        outputs: OUTPUTS_VALUE_F64,
4175        params: PARAM_PERCENTILE_NEAREST_RANK,
4176    },
4177    SupplementalIndicatorSeed {
4178        id: "ui",
4179        label: "UI",
4180        category: "volatility",
4181        input_kind: IndicatorInputKind::Slice,
4182        outputs: OUTPUTS_VALUE_F64,
4183        params: PARAM_UI,
4184    },
4185    SupplementalIndicatorSeed {
4186        id: "zscore",
4187        label: "Zscore",
4188        category: "statistics",
4189        input_kind: IndicatorInputKind::Slice,
4190        outputs: OUTPUTS_VALUE_F64,
4191        params: PARAM_ZSCORE,
4192    },
4193    SupplementalIndicatorSeed {
4194        id: "medprice",
4195        label: "Medprice",
4196        category: "price",
4197        input_kind: IndicatorInputKind::HighLow,
4198        outputs: OUTPUTS_VALUE_F64,
4199        params: PARAM_NONE,
4200    },
4201    SupplementalIndicatorSeed {
4202        id: "midpoint",
4203        label: "Midpoint",
4204        category: "price",
4205        input_kind: IndicatorInputKind::Slice,
4206        outputs: OUTPUTS_VALUE_F64,
4207        params: PARAM_MIDPOINT_PERIOD,
4208    },
4209    SupplementalIndicatorSeed {
4210        id: "midprice",
4211        label: "Midprice",
4212        category: "price",
4213        input_kind: IndicatorInputKind::HighLow,
4214        outputs: OUTPUTS_VALUE_F64,
4215        params: PARAM_MIDPRICE_PERIOD,
4216    },
4217    SupplementalIndicatorSeed {
4218        id: "wclprice",
4219        label: "WCLPRICE",
4220        category: "price",
4221        input_kind: IndicatorInputKind::Ohlc,
4222        outputs: OUTPUTS_VALUE_F64,
4223        params: PARAM_NONE,
4224    },
4225    SupplementalIndicatorSeed {
4226        id: "obv",
4227        label: "OBV",
4228        category: "volume",
4229        input_kind: IndicatorInputKind::CloseVolume,
4230        outputs: OUTPUTS_VALUE_F64,
4231        params: PARAM_NONE,
4232    },
4233    SupplementalIndicatorSeed {
4234        id: "vpt",
4235        label: "VPT",
4236        category: "volume",
4237        input_kind: IndicatorInputKind::CloseVolume,
4238        outputs: OUTPUTS_VALUE_F64,
4239        params: PARAM_NONE,
4240    },
4241    SupplementalIndicatorSeed {
4242        id: "nvi",
4243        label: "NVI",
4244        category: "volume",
4245        input_kind: IndicatorInputKind::CloseVolume,
4246        outputs: OUTPUTS_VALUE_F64,
4247        params: PARAM_NONE,
4248    },
4249    SupplementalIndicatorSeed {
4250        id: "pvi",
4251        label: "PVI",
4252        category: "volume",
4253        input_kind: IndicatorInputKind::CloseVolume,
4254        outputs: OUTPUTS_VALUE_F64,
4255        params: PARAM_PVI,
4256    },
4257    SupplementalIndicatorSeed {
4258        id: "mom",
4259        label: "MOM",
4260        category: "momentum",
4261        input_kind: IndicatorInputKind::Slice,
4262        outputs: OUTPUTS_VALUE_F64,
4263        params: PARAM_MOM_PERIOD,
4264    },
4265    SupplementalIndicatorSeed {
4266        id: "cmo",
4267        label: "CMO",
4268        category: "momentum",
4269        input_kind: IndicatorInputKind::Slice,
4270        outputs: OUTPUTS_VALUE_F64,
4271        params: PARAM_CMO_PERIOD,
4272    },
4273    SupplementalIndicatorSeed {
4274        id: "rocp",
4275        label: "ROCP",
4276        category: "momentum",
4277        input_kind: IndicatorInputKind::Slice,
4278        outputs: OUTPUTS_VALUE_F64,
4279        params: PARAM_ROCP_PERIOD,
4280    },
4281    SupplementalIndicatorSeed {
4282        id: "rocr",
4283        label: "ROCR",
4284        category: "momentum",
4285        input_kind: IndicatorInputKind::Slice,
4286        outputs: OUTPUTS_VALUE_F64,
4287        params: PARAM_ROCR_PERIOD,
4288    },
4289    SupplementalIndicatorSeed {
4290        id: "tsf",
4291        label: "TSF",
4292        category: "trend",
4293        input_kind: IndicatorInputKind::Slice,
4294        outputs: OUTPUTS_VALUE_F64,
4295        params: PARAM_TSF_PERIOD,
4296    },
4297    SupplementalIndicatorSeed {
4298        id: "ppo",
4299        label: "PPO",
4300        category: "momentum",
4301        input_kind: IndicatorInputKind::Slice,
4302        outputs: OUTPUTS_VALUE_F64,
4303        params: PARAM_PPO,
4304    },
4305    SupplementalIndicatorSeed {
4306        id: "trix",
4307        label: "TRIX",
4308        category: "momentum",
4309        input_kind: IndicatorInputKind::Slice,
4310        outputs: OUTPUTS_VALUE_F64,
4311        params: PARAM_TRIX_PERIOD,
4312    },
4313    SupplementalIndicatorSeed {
4314        id: "tsi",
4315        label: "TSI",
4316        category: "momentum",
4317        input_kind: IndicatorInputKind::Slice,
4318        outputs: OUTPUTS_VALUE_F64,
4319        params: PARAM_TSI,
4320    },
4321    SupplementalIndicatorSeed {
4322        id: "stddev",
4323        label: "StdDev",
4324        category: "volatility",
4325        input_kind: IndicatorInputKind::Slice,
4326        outputs: OUTPUTS_VALUE_F64,
4327        params: PARAM_STDDEV,
4328    },
4329    SupplementalIndicatorSeed {
4330        id: "var",
4331        label: "VAR",
4332        category: "volatility",
4333        input_kind: IndicatorInputKind::Slice,
4334        outputs: OUTPUTS_VALUE_F64,
4335        params: PARAM_VAR,
4336    },
4337    SupplementalIndicatorSeed {
4338        id: "willr",
4339        label: "WILLR",
4340        category: "momentum",
4341        input_kind: IndicatorInputKind::Ohlc,
4342        outputs: OUTPUTS_VALUE_F64,
4343        params: PARAM_WILLR_PERIOD,
4344    },
4345    SupplementalIndicatorSeed {
4346        id: "ultosc",
4347        label: "ULTOSC",
4348        category: "momentum",
4349        input_kind: IndicatorInputKind::Ohlc,
4350        outputs: OUTPUTS_VALUE_F64,
4351        params: PARAM_ULTOSC,
4352    },
4353    SupplementalIndicatorSeed {
4354        id: "macd",
4355        label: "MACD",
4356        category: "momentum",
4357        input_kind: IndicatorInputKind::Slice,
4358        outputs: OUTPUTS_MACD,
4359        params: PARAM_MACD,
4360    },
4361    SupplementalIndicatorSeed {
4362        id: "bollinger_bands",
4363        label: "Bollinger Bands",
4364        category: "volatility",
4365        input_kind: IndicatorInputKind::Slice,
4366        outputs: OUTPUTS_BOLLINGER,
4367        params: PARAM_BOLLINGER,
4368    },
4369    SupplementalIndicatorSeed {
4370        id: "stoch",
4371        label: "Stochastic",
4372        category: "momentum",
4373        input_kind: IndicatorInputKind::Ohlc,
4374        outputs: OUTPUTS_STOCH,
4375        params: PARAM_STOCH,
4376    },
4377    SupplementalIndicatorSeed {
4378        id: "stochf",
4379        label: "Fast Stochastic",
4380        category: "momentum",
4381        input_kind: IndicatorInputKind::Ohlc,
4382        outputs: OUTPUTS_STOCH,
4383        params: PARAM_STOCHF,
4384    },
4385    SupplementalIndicatorSeed {
4386        id: "vwmacd",
4387        label: "VWMACD",
4388        category: "volume",
4389        input_kind: IndicatorInputKind::CloseVolume,
4390        outputs: OUTPUTS_MACD,
4391        params: PARAM_VW_MACD,
4392    },
4393    SupplementalIndicatorSeed {
4394        id: "vpci",
4395        label: "VPCI",
4396        category: "volume",
4397        input_kind: IndicatorInputKind::CloseVolume,
4398        outputs: OUTPUTS_VPCI,
4399        params: PARAM_VPCI,
4400    },
4401    SupplementalIndicatorSeed {
4402        id: "ttm_trend",
4403        label: "TTM Trend",
4404        category: "trend",
4405        input_kind: IndicatorInputKind::Ohlc,
4406        outputs: OUTPUTS_VALUE_BOOL,
4407        params: PARAM_TTM_TREND,
4408    },
4409    SupplementalIndicatorSeed {
4410        id: "ttm_squeeze",
4411        label: "TTM Squeeze",
4412        category: "momentum",
4413        input_kind: IndicatorInputKind::Ohlc,
4414        outputs: OUTPUTS_TTM_SQUEEZE,
4415        params: PARAM_TTM_SQUEEZE,
4416    },
4417    SupplementalIndicatorSeed {
4418        id: "acosc",
4419        label: "Acosc",
4420        category: "momentum",
4421        input_kind: IndicatorInputKind::HighLow,
4422        outputs: OUTPUTS_ACOSC,
4423        params: PARAM_ACOSC,
4424    },
4425    SupplementalIndicatorSeed {
4426        id: "alligator",
4427        label: "Alligator",
4428        category: "trend",
4429        input_kind: IndicatorInputKind::Slice,
4430        outputs: OUTPUTS_ALLIGATOR,
4431        params: PARAM_ALLIGATOR,
4432    },
4433    SupplementalIndicatorSeed {
4434        id: "alphatrend",
4435        label: "AlphaTrend",
4436        category: "trend",
4437        input_kind: IndicatorInputKind::Ohlcv,
4438        outputs: OUTPUTS_K1_K2,
4439        params: PARAM_ALPHATREND,
4440    },
4441    SupplementalIndicatorSeed {
4442        id: "aso",
4443        label: "ASO",
4444        category: "momentum",
4445        input_kind: IndicatorInputKind::Ohlc,
4446        outputs: OUTPUTS_BULLS_BEARS,
4447        params: PARAM_ASO,
4448    },
4449    SupplementalIndicatorSeed {
4450        id: "bandpass",
4451        label: "BandPass",
4452        category: "cycle",
4453        input_kind: IndicatorInputKind::Slice,
4454        outputs: OUTPUTS_BANDPASS,
4455        params: PARAM_BANDPASS,
4456    },
4457    SupplementalIndicatorSeed {
4458        id: "chandelier_exit",
4459        label: "Chandelier Exit",
4460        category: "trend",
4461        input_kind: IndicatorInputKind::Ohlc,
4462        outputs: OUTPUTS_LONG_SHORT_STOP,
4463        params: PARAM_CHANDELIER_EXIT,
4464    },
4465    SupplementalIndicatorSeed {
4466        id: "cksp",
4467        label: "CKSP",
4468        category: "trend",
4469        input_kind: IndicatorInputKind::Ohlc,
4470        outputs: OUTPUTS_LONG_SHORT_VALUES,
4471        params: PARAM_CKSP,
4472    },
4473    SupplementalIndicatorSeed {
4474        id: "correlation_cycle",
4475        label: "Correlation Cycle",
4476        category: "cycle",
4477        input_kind: IndicatorInputKind::Slice,
4478        outputs: OUTPUTS_CORRELATION_CYCLE,
4479        params: PARAM_CORRELATION_CYCLE,
4480    },
4481    SupplementalIndicatorSeed {
4482        id: "damiani_volatmeter",
4483        label: "Damiani Volatmeter",
4484        category: "volatility",
4485        input_kind: IndicatorInputKind::Slice,
4486        outputs: OUTPUTS_VOL_ANTI,
4487        params: PARAM_DAMIANI_VOLATMETER,
4488    },
4489    SupplementalIndicatorSeed {
4490        id: "dvdiqqe",
4491        label: "DVDIQQE",
4492        category: "volume",
4493        input_kind: IndicatorInputKind::Ohlc,
4494        outputs: OUTPUTS_DVDIQQE,
4495        params: PARAM_DVDIQQE,
4496    },
4497    SupplementalIndicatorSeed {
4498        id: "emd",
4499        label: "EMD",
4500        category: "volatility",
4501        input_kind: IndicatorInputKind::Ohlcv,
4502        outputs: OUTPUTS_UPPER_MIDDLE_LOWER_BAND,
4503        params: PARAM_EMD,
4504    },
4505    SupplementalIndicatorSeed {
4506        id: "eri",
4507        label: "ERI",
4508        category: "trend",
4509        input_kind: IndicatorInputKind::Ohlc,
4510        outputs: OUTPUTS_BULL_BEAR,
4511        params: PARAM_ERI,
4512    },
4513    SupplementalIndicatorSeed {
4514        id: "fisher",
4515        label: "Fisher",
4516        category: "momentum",
4517        input_kind: IndicatorInputKind::HighLow,
4518        outputs: OUTPUTS_FISHER,
4519        params: PARAM_FISHER,
4520    },
4521    SupplementalIndicatorSeed {
4522        id: "fvg_trailing_stop",
4523        label: "FVG Trailing Stop",
4524        category: "trend",
4525        input_kind: IndicatorInputKind::Ohlc,
4526        outputs: OUTPUTS_FVG_TS,
4527        params: PARAM_FVG_TRAILING_STOP,
4528    },
4529    SupplementalIndicatorSeed {
4530        id: "gatorosc",
4531        label: "Gator Oscillator",
4532        category: "trend",
4533        input_kind: IndicatorInputKind::Slice,
4534        outputs: OUTPUTS_GATOROSC,
4535        params: PARAM_GATOROSC,
4536    },
4537    SupplementalIndicatorSeed {
4538        id: "halftrend",
4539        label: "HalfTrend",
4540        category: "trend",
4541        input_kind: IndicatorInputKind::Ohlc,
4542        outputs: OUTPUTS_HALFTREND,
4543        params: PARAM_HALFTREND,
4544    },
4545    SupplementalIndicatorSeed {
4546        id: "kst",
4547        label: "KST",
4548        category: "momentum",
4549        input_kind: IndicatorInputKind::Slice,
4550        outputs: OUTPUTS_LINE_SIGNAL,
4551        params: PARAM_KST,
4552    },
4553    SupplementalIndicatorSeed {
4554        id: "lpc",
4555        label: "LPC",
4556        category: "cycle",
4557        input_kind: IndicatorInputKind::Ohlc,
4558        outputs: OUTPUTS_FILTER_BANDS,
4559        params: PARAM_LPC,
4560    },
4561    SupplementalIndicatorSeed {
4562        id: "mab",
4563        label: "MAB",
4564        category: "volatility",
4565        input_kind: IndicatorInputKind::Slice,
4566        outputs: OUTPUTS_UPPER_MIDDLE_LOWER_BAND,
4567        params: PARAM_MAB,
4568    },
4569    SupplementalIndicatorSeed {
4570        id: "macz",
4571        label: "MACZ",
4572        category: "momentum",
4573        input_kind: IndicatorInputKind::Slice,
4574        outputs: OUTPUTS_VALUE_F64,
4575        params: PARAM_MACZ,
4576    },
4577    SupplementalIndicatorSeed {
4578        id: "minmax",
4579        label: "MinMax",
4580        category: "pattern",
4581        input_kind: IndicatorInputKind::HighLow,
4582        outputs: OUTPUTS_MINMAX,
4583        params: PARAM_MINMAX,
4584    },
4585    SupplementalIndicatorSeed {
4586        id: "pattern_recognition",
4587        label: "Pattern Recognition",
4588        category: "pattern",
4589        input_kind: IndicatorInputKind::Ohlc,
4590        outputs: OUTPUTS_MATRIX_BOOL,
4591        params: PARAM_NONE,
4592    },
4593    SupplementalIndicatorSeed {
4594        id: "msw",
4595        label: "MSW",
4596        category: "cycle",
4597        input_kind: IndicatorInputKind::Slice,
4598        outputs: OUTPUTS_SINE_LEAD,
4599        params: PARAM_MSW,
4600    },
4601    SupplementalIndicatorSeed {
4602        id: "nadaraya_watson_envelope",
4603        label: "Nadaraya Watson Envelope",
4604        category: "volatility",
4605        input_kind: IndicatorInputKind::Slice,
4606        outputs: OUTPUTS_UPPER_LOWER,
4607        params: PARAM_NWE,
4608    },
4609    SupplementalIndicatorSeed {
4610        id: "otto",
4611        label: "OTTO",
4612        category: "trend",
4613        input_kind: IndicatorInputKind::Slice,
4614        outputs: OUTPUTS_HOTT_LOTT,
4615        params: PARAM_OTTO,
4616    },
4617    SupplementalIndicatorSeed {
4618        id: "pma",
4619        label: "PMA",
4620        category: "trend",
4621        input_kind: IndicatorInputKind::Slice,
4622        outputs: OUTPUTS_EHLERS_PMA,
4623        params: PARAM_PMA,
4624    },
4625    SupplementalIndicatorSeed {
4626        id: "prb",
4627        label: "PRB",
4628        category: "statistics",
4629        input_kind: IndicatorInputKind::Slice,
4630        outputs: OUTPUTS_PRB,
4631        params: PARAM_PRB,
4632    },
4633    SupplementalIndicatorSeed {
4634        id: "qqe",
4635        label: "QQE",
4636        category: "momentum",
4637        input_kind: IndicatorInputKind::Slice,
4638        outputs: &[OUTPUT_FAST, OUTPUT_SLOW],
4639        params: PARAM_QQE,
4640    },
4641    SupplementalIndicatorSeed {
4642        id: "range_filter",
4643        label: "Range Filter",
4644        category: "volatility",
4645        input_kind: IndicatorInputKind::Slice,
4646        outputs: OUTPUTS_FILTER_BANDS,
4647        params: PARAM_RANGE_FILTER,
4648    },
4649    SupplementalIndicatorSeed {
4650        id: "rsmk",
4651        label: "RSMK",
4652        category: "relative_strength",
4653        input_kind: IndicatorInputKind::CloseVolume,
4654        outputs: OUTPUTS_INDICATOR_SIGNAL,
4655        params: PARAM_RSMK,
4656    },
4657    SupplementalIndicatorSeed {
4658        id: "voss",
4659        label: "Voss",
4660        category: "cycle",
4661        input_kind: IndicatorInputKind::Slice,
4662        outputs: OUTPUTS_VOSS,
4663        params: PARAM_VOSS,
4664    },
4665    SupplementalIndicatorSeed {
4666        id: "pivot",
4667        label: "Pivot",
4668        category: "price",
4669        input_kind: IndicatorInputKind::Ohlc,
4670        outputs: OUTPUTS_PIVOT,
4671        params: PARAM_PIVOT,
4672    },
4673];
4674
4675fn supplemental_supports_cpu_batch(id: &str) -> bool {
4676    matches!(
4677        id,
4678        "adx"
4679            | "atr"
4680            | "ad"
4681            | "adosc"
4682            | "ao"
4683            | "dx"
4684            | "di"
4685            | "dm"
4686            | "vi"
4687            | "donchian"
4688            | "supertrend"
4689            | "keltner"
4690            | "aroon"
4691            | "srsi"
4692            | "kdj"
4693            | "squeeze_momentum"
4694            | "wavetrend"
4695            | "wto"
4696            | "bop"
4697            | "emv"
4698            | "efi"
4699            | "mfi"
4700            | "mass"
4701            | "kvo"
4702            | "vosc"
4703            | "rsi"
4704            | "roc"
4705            | "apo"
4706            | "cci"
4707            | "cfo"
4708            | "cg"
4709            | "er"
4710            | "kurtosis"
4711            | "natr"
4712            | "mean_ad"
4713            | "medium_ad"
4714            | "deviation"
4715            | "dpo"
4716            | "fosc"
4717            | "ift_rsi"
4718            | "linearreg_angle"
4719            | "linearreg_intercept"
4720            | "linearreg_slope"
4721            | "pfe"
4722            | "percentile_nearest_rank"
4723            | "ui"
4724            | "zscore"
4725            | "medprice"
4726            | "midpoint"
4727            | "midprice"
4728            | "wclprice"
4729            | "obv"
4730            | "vpt"
4731            | "nvi"
4732            | "pvi"
4733            | "mom"
4734            | "cmo"
4735            | "rocp"
4736            | "rocr"
4737            | "tsf"
4738            | "ppo"
4739            | "trix"
4740            | "tsi"
4741            | "stddev"
4742            | "var"
4743            | "willr"
4744            | "ultosc"
4745            | "macd"
4746            | "bollinger_bands"
4747            | "stoch"
4748            | "stochf"
4749            | "vwmacd"
4750            | "vpci"
4751            | "ttm_trend"
4752            | "ttm_squeeze"
4753            | "acosc"
4754            | "alligator"
4755            | "alphatrend"
4756            | "aso"
4757            | "bandpass"
4758            | "chandelier_exit"
4759            | "cksp"
4760            | "correlation_cycle"
4761            | "damiani_volatmeter"
4762            | "dvdiqqe"
4763            | "emd"
4764            | "eri"
4765            | "fisher"
4766            | "fvg_trailing_stop"
4767            | "gatorosc"
4768            | "halftrend"
4769            | "kst"
4770            | "lpc"
4771            | "mab"
4772            | "macz"
4773            | "minmax"
4774            | "msw"
4775            | "nadaraya_watson_envelope"
4776            | "otto"
4777            | "pma"
4778            | "prb"
4779            | "qqe"
4780            | "range_filter"
4781            | "rsmk"
4782            | "voss"
4783            | "pivot"
4784    )
4785}
4786
4787fn supplemental_supports_cuda_single(id: &str) -> bool {
4788    matches!(id, "pattern_recognition")
4789}
4790
4791fn supplemental_supports_cuda_batch(id: &str) -> bool {
4792    matches!(
4793        id,
4794            "acosc" | "adosc" | "adx" | "adxr" | "alligator" | "alphatrend" | "ao" | "apo" |
4795            "aroon" | "aroonosc" | "aso" | "atr" | "avsl" | "bandpass" | "bollinger_bands" |
4796            "bollinger_bands_width" | "bop" | "cci" | "cci_cycle" | "cfo" | "cg" | "chande" |
4797            "chandelier_exit" | "chop" | "cksp" | "cmo" | "coppock" | "correl_hl" |
4798            "correlation_cycle" | "cvi" | "damiani_volatmeter" | "dec_osc" | "decycler" |
4799            "deviation" | "devstop" | "di" | "dm" | "donchian" | "dpo" | "dti" | "dvdiqqe" | "dx" |
4800            "efi" | "emd" | "emv" | "er" | "eri" | "fisher" | "fosc" | "fvg_trailing_stop" |
4801            "gatorosc" | "halftrend" | "ift_rsi" | "kaufmanstop" | "kdj" | "keltner" | "kst" |
4802            "kurtosis" | "kvo" | "linearreg_angle" | "linearreg_intercept" | "linearreg_slope" |
4803            "lpc" | "lrsi" | "mab" | "macd" | "macz" | "marketefi" | "mass" | "mean_ad" |
4804            "medium_ad" | "medprice" | "mfi" | "minmax" | "mod_god_mode" | "mom" | "msw" |
4805            "nadaraya_watson_envelope" | "natr" | "net_myrsi" | "nvi" | "obv" | "ott" | "otto" |
4806            "percentile_nearest_rank" | "pfe" | "pivot" | "pma" | "ppo" | "prb" | "pvi" | "qqe" |
4807            "qstick" | "range_filter" | "reverse_rsi" | "roc" | "rocp" | "rocr" | "rsi" | "rsmk" |
4808            "rsx" | "rvi" | "safezonestop" | "sar" | "squeeze_momentum" | "srsi" | "stc" |
4809            "stddev" | "stoch" | "stochf" | "supertrend" | "trix" | "tsf" | "tsi" | "ttm_squeeze" |
4810            "ttm_trend" | "ui" | "ultosc" | "var" | "vi" | "vidya" | "vlma" | "vosc" | "voss" |
4811            "vpci" | "vpt" | "vwmacd" | "wad" | "wavetrend" | "wclprice" | "willr" | "wto" |
4812            "zscore"
4813    )
4814}
4815
4816fn supplemental_supports_cuda_vram(id: &str) -> bool {
4817    matches!(id, "pattern_recognition") || supplemental_supports_cuda_batch(id)
4818}
4819
4820pub fn is_bucket_b_indicator(id: &str) -> bool {
4821    BUCKET_B_INDICATORS
4822        .iter()
4823        .any(|item| item.eq_ignore_ascii_case(id))
4824}
4825
4826static INDICATOR_REGISTRY: Lazy<Vec<IndicatorInfo>> = Lazy::new(build_registry);
4827static INDICATOR_EXACT_INDEX: Lazy<HashMap<&'static str, usize>> = Lazy::new(|| {
4828    let mut map = HashMap::with_capacity(INDICATOR_REGISTRY.len());
4829    for (idx, info) in INDICATOR_REGISTRY.iter().enumerate() {
4830        map.insert(info.id, idx);
4831    }
4832    map
4833});
4834
4835fn ma_outputs_for(ma_id: &str) -> Vec<IndicatorOutputInfo> {
4836    match ma_id {
4837        "mama" => OUTPUTS_MAMA.to_vec(),
4838        "ehlers_pma" => OUTPUTS_EHLERS_PMA.to_vec(),
4839        "buff_averages" => OUTPUTS_BUFF_AVERAGES.to_vec(),
4840        _ => OUTPUTS_VALUE_F64.to_vec(),
4841    }
4842}
4843
4844fn ma_params_for(ma_id: &str, period_based: bool) -> Vec<IndicatorParamInfo> {
4845    let mut params = Vec::new();
4846    if period_based {
4847        params.push(PARAM_PERIOD);
4848    }
4849    for item in ma_param_schema(ma_id).iter() {
4850        let kind = match item.kind {
4851            MaParamKind::Float => IndicatorParamKind::Float,
4852            MaParamKind::Int => IndicatorParamKind::Int,
4853        };
4854        let default = match kind {
4855            IndicatorParamKind::Float => Some(ParamValueStatic::Float(item.default)),
4856            IndicatorParamKind::Int => Some(ParamValueStatic::Int(item.default as i64)),
4857            IndicatorParamKind::Bool | IndicatorParamKind::EnumString => None,
4858        };
4859        params.push(IndicatorParamInfo {
4860            key: item.key,
4861            label: item.label,
4862            kind,
4863            required: false,
4864            default,
4865            min: item.min,
4866            max: item.max,
4867            step: item.step,
4868            enum_values: EMPTY_ENUM_VALUES,
4869            notes: item.notes,
4870        });
4871    }
4872    match ma_id {
4873        "mama" => params.push(PARAM_OUTPUT_MAMA),
4874        "ehlers_pma" => params.push(PARAM_OUTPUT_EHLERS_PMA),
4875        "buff_averages" => params.push(PARAM_OUTPUT_BUFF_AVERAGES),
4876        "vwap" => params.push(PARAM_ANCHOR),
4877        "volume_adjusted_ma" => params.push(PARAM_STRICT),
4878        _ => {}
4879    }
4880    params
4881}
4882
4883fn build_registry() -> Vec<IndicatorInfo> {
4884    let mut out = Vec::new();
4885
4886    for ma in list_moving_averages().iter() {
4887        out.push(IndicatorInfo {
4888            id: ma.id,
4889            label: ma.label,
4890            category: "moving_averages",
4891            dynamic_strategy_eligible: true,
4892            input_kind: if ma.requires_candles {
4893                IndicatorInputKind::Candles
4894            } else {
4895                IndicatorInputKind::Slice
4896            },
4897            outputs: ma_outputs_for(ma.id),
4898            params: ma_params_for(ma.id, ma.period_based),
4899            capabilities: IndicatorCapabilities {
4900                supports_cpu_single: ma.supports_cpu_single,
4901                supports_cpu_batch: ma.supports_cpu_batch,
4902                supports_cuda_single: ma.supports_cuda_single,
4903                supports_cuda_batch: ma.supports_cuda_sweep,
4904                supports_cuda_vram: ma.supports_cuda_sweep,
4905            },
4906            notes: ma.notes,
4907        });
4908    }
4909
4910    for seed in SUPPLEMENTAL_INDICATORS.iter() {
4911        out.push(IndicatorInfo {
4912            id: seed.id,
4913            label: seed.label,
4914            category: seed.category,
4915            dynamic_strategy_eligible: true,
4916            input_kind: seed.input_kind,
4917            outputs: seed.outputs.to_vec(),
4918            params: seed.params.to_vec(),
4919            capabilities: IndicatorCapabilities {
4920                supports_cpu_single: true,
4921                supports_cpu_batch: supplemental_supports_cpu_batch(seed.id),
4922                supports_cuda_single: supplemental_supports_cuda_single(seed.id),
4923                supports_cuda_batch: supplemental_supports_cuda_batch(seed.id),
4924                supports_cuda_vram: supplemental_supports_cuda_vram(seed.id),
4925            },
4926            notes: Some(SUPPLEMENTAL_SEED_NOTE),
4927        });
4928    }
4929
4930    out.sort_by(|a, b| a.id.cmp(b.id));
4931    out
4932}
4933
4934pub fn list_indicators() -> &'static [IndicatorInfo] {
4935    INDICATOR_REGISTRY.as_slice()
4936}
4937
4938pub fn get_indicator(id: &str) -> Option<&'static IndicatorInfo> {
4939    let indicators = list_indicators();
4940    if let Some(idx) = INDICATOR_EXACT_INDEX.get(id).copied() {
4941        return Some(&indicators[idx]);
4942    }
4943    if let Ok(idx) = indicators.binary_search_by(|info| info.id.cmp(id)) {
4944        return Some(&indicators[idx]);
4945    }
4946    indicators
4947        .iter()
4948        .find(|info| info.id.eq_ignore_ascii_case(id))
4949}
4950
4951pub fn indicator_param_schema(id: &str) -> Option<&'static [IndicatorParamInfo]> {
4952    get_indicator(id).map(|info| info.params.as_slice())
4953}
4954
4955pub fn indicator_output_schema(id: &str) -> Option<&'static [IndicatorOutputInfo]> {
4956    get_indicator(id).map(|info| info.outputs.as_slice())
4957}
4958
4959pub fn indicator_capabilities(id: &str) -> Option<IndicatorCapabilities> {
4960    get_indicator(id).map(|info| info.capabilities)
4961}
4962
4963#[cfg(test)]
4964mod tests {
4965    use super::*;
4966
4967    #[test]
4968    fn registry_is_non_empty() {
4969        assert!(!list_indicators().is_empty());
4970    }
4971
4972    #[test]
4973    fn ids_are_unique_case_insensitive() {
4974        use std::collections::HashSet;
4975        let mut seen = HashSet::new();
4976        for info in list_indicators().iter() {
4977            let lower = info.id.to_ascii_lowercase();
4978            assert!(seen.insert(lower), "duplicate id {}", info.id);
4979        }
4980    }
4981
4982    #[test]
4983    fn all_registered_entries_have_output_schema() {
4984        for info in list_indicators().iter() {
4985            assert!(
4986                !info.outputs.is_empty(),
4987                "indicator {} has no output schema",
4988                info.id
4989            );
4990        }
4991    }
4992
4993    #[test]
4994    fn ma_registry_is_mirrored() {
4995        for ma in list_moving_averages().iter() {
4996            assert!(
4997                get_indicator(ma.id).is_some(),
4998                "missing moving average {} in global registry",
4999                ma.id
5000            );
5001        }
5002    }
5003
5004    #[test]
5005    fn lookup_is_case_insensitive() {
5006        assert!(get_indicator("SMA").is_some());
5007        assert!(get_indicator("sma").is_some());
5008    }
5009
5010    #[test]
5011    fn schema_accessors_work() {
5012        assert!(indicator_output_schema("macd").is_some());
5013        assert!(indicator_param_schema("sma").is_some());
5014        assert!(indicator_capabilities("sma").is_some());
5015        assert!(indicator_output_schema("not_real").is_none());
5016    }
5017
5018    #[test]
5019    fn pattern_recognition_capability_is_registered_as_non_batch() {
5020        let info = get_indicator("pattern_recognition").unwrap();
5021        assert_eq!(info.input_kind, IndicatorInputKind::Ohlc);
5022        assert_eq!(info.outputs.len(), 1);
5023        assert_eq!(info.outputs[0].id, "matrix");
5024        assert!(info.capabilities.supports_cpu_single);
5025        assert!(!info.capabilities.supports_cpu_batch);
5026        assert!(info.capabilities.supports_cuda_single);
5027        assert!(!info.capabilities.supports_cuda_batch);
5028        assert!(info.capabilities.supports_cuda_vram);
5029    }
5030
5031    #[test]
5032    fn bucket_b_ma_capabilities_follow_ma_registry() {
5033        let mama = indicator_capabilities("mama").unwrap();
5034        assert!(mama.supports_cpu_batch);
5035        assert!(mama.supports_cuda_batch);
5036        assert!(mama.supports_cuda_vram);
5037
5038        let vwap = indicator_capabilities("vwap").unwrap();
5039        assert!(vwap.supports_cpu_batch);
5040        assert!(vwap.supports_cuda_batch);
5041        assert!(vwap.supports_cuda_vram);
5042    }
5043
5044    #[test]
5045    fn bucket_membership_lookup_is_case_insensitive() {
5046        assert!(is_bucket_b_indicator("MAMA"));
5047        assert!(is_bucket_b_indicator("pivot"));
5048        assert!(!is_bucket_b_indicator("sma"));
5049        assert!(!is_bucket_b_indicator("adx"));
5050    }
5051}