indicator/
lib.rs

1//! Abstractions for stream aggregation that we call "Indicator" s.
2//!
3//! This crate provides abstractions of different levels to build indicators:
4//!
5//! - Indicators are the combinations of [`Operator`]s. We can chain them by [`OperatorExt::then`]
6//! and apply them to the same input "simultaneously" by [`OperatorExt::facet`].
7//!
8//! - To handle [Time series] better, we introduced utils for ticked operators, which are defined in [`TickedOperatorExt`],
9//! of which the input and output are both [`Tickable`] and sharing the same [`Tick`].
10//! We provide many ticked version utils. For example, we can apply different [`TickedOperatorExt`]s
11//! (using [`TickedOperatorExt::facet_t`] or [`ticked::FacetMap`]) to the same [`Tickable`] stream to
12//! get a "synced" result stream of the combined outputs of those operators sharing the same [`Tick`]
13//! of theirs input. Each item of a "synced" stream will have the form of `TickValue<(O1, O2)>`.
14//!
15//! - [`TumblingOperator`]s are defined by some operations on events of non-overlapping time windows ([`TumblingWindow`]).
16//! [Moving average] is one of the famous examples, which is defined by the average of the numbers
17//! from those events occur in the same tumbling window. We call those operations [`TumblingOperation`]s.
18//! We can use [`tumbling`] function to create a [`TumblingOperator`] from a [`TumblingOperation`].
19//!
20//! - Finally, we can apply the indicators to [`Iterator`]s or [`Stream`](futures::stream::Stream)s
21//! by using [`IndicatorIteratorExt::indicator`] or [`IndicatorStreamExt::indicator`] accordingly.
22//!
23//!
24//! [Time series]: https://en.wikipedia.org/wiki/Time_series
25//! [Moving average]: https://en.wikipedia.org/wiki/Moving_average
26//!
27//! # Example
28//! ```
29//! use indicator::*;
30//! use rust_decimal::Decimal;
31//! use rust_decimal_macros::dec;
32//! use time::macros::offset;
33//! use arrayvec::ArrayVec;
34//!
35//! /// Return an indicator that calculates `hl2` and `ohlc4` simultaneously.
36//! fn hl2_ohlc4(period: Period) -> impl Operator<TickValue<Decimal>, Output = (Decimal, Decimal)> {
37//!     tumbling(
38//!         period,
39//!         |_w: &ArrayVec<[Decimal; 4], 0>, y: &mut Option<[Decimal; 4]>, x| match y {
40//!             Some(ohlc) => {
41//!                 ohlc[1] = ohlc[1].max(x);
42//!                 ohlc[2] = ohlc[2].min(x);
43//!                 ohlc[3] = x;
44//!                 *ohlc
45//!             }
46//!             None => {
47//!                 let ohlc = [x; 4];
48//!                 *y = Some(ohlc);
49//!                 ohlc
50//!             }
51//!         },
52//!     )
53//!     .then(facet_t(
54//!         map_t(|ohlc: [Decimal; 4]| (ohlc[1] + ohlc[2]) / dec!(2)),
55//!         map_t(|ohlc: [Decimal; 4]| (ohlc[0] + ohlc[1] + ohlc[2] + ohlc[3]) / dec!(4)),
56//!     ))
57//!     .map(|v| v.value)
58//! }
59//!```
60
61#![deny(missing_docs)]
62#![cfg_attr(not(feature = "std"), no_std)]
63
64#[cfg(feature = "alloc")]
65extern crate alloc;
66
67/// Operator.
68pub mod operator;
69
70/// Time window.
71pub mod window;
72
73/// Ticked operators.
74pub mod ticked;
75
76/// Iterator extension trait.
77pub mod iter;
78
79/// Operator using GAT.
80#[cfg(feature = "gat")]
81pub mod gat;
82
83#[cfg(feature = "stream")]
84/// Stream extension trait.
85pub mod stream;
86
87/// Rayon supported combinator.
88#[cfg(feature = "parallel")]
89pub mod rayon;
90
91/// Async operator support.
92#[cfg(feature = "async")]
93pub mod async_operator;
94
95/// Reactive streams pattern.
96#[cfg(feature = "reactive")]
97pub mod reactive;
98
99/// Context Pattern.
100#[cfg(feature = "context")]
101pub mod context;
102
103/// Prelude.
104pub mod prelude {
105    #[cfg(feature = "context")]
106    pub use crate::context::{
107        extractor::{Data, Env, In, Prev},
108        input, insert_and_output, insert_env_and_output,
109        layer::{layer_fn, stack::id_layer, BoxLayer, Layer, LayerExt},
110        output, BoxContextOperator, ContextOperator, ContextOperatorExt, Value, ValueRef,
111    };
112    #[cfg(feature = "gat")]
113    pub use crate::gat::*;
114    pub use crate::operator::{BoxOperator, LocalBoxOperator, Operator, OperatorExt};
115    pub use crate::window::{Period, Tick, TickValue, TumblingWindow};
116    #[cfg(feature = "indicator_macros")]
117    pub use indicator_macros::*;
118}
119
120#[cfg(feature = "indicator_macros")]
121pub use indicator_macros as macros;
122
123pub use iter::IndicatorIteratorExt;
124pub use operator::{facet, map, Operator, OperatorExt};
125pub use ticked::{
126    facet_t, map_t,
127    tumbling::{
128        cached, iterated, tumbling, Cached, CachedOperation, Iterated, IteratedOperation,
129        QueueCapAtLeast, TumblingOperation, TumblingOperator, TumblingQueue,
130    },
131    tuple_t, TickedOperatorExt,
132};
133pub use window::{Period, PeriodKind, Tick, TickValue, Tickable, TumblingWindow};
134
135#[cfg(feature = "std")]
136pub use ticked::facet_map_t;
137
138#[cfg(feature = "std")]
139pub use facet::facet_map;
140
141#[cfg(feature = "std")]
142pub use ticked::{shared, SharedMap};
143
144#[cfg(feature = "stream")]
145pub use stream::IndicatorStreamExt;
146
147#[cfg(feature = "array-vec")]
148pub use ticked::array_t;
149
150#[cfg(feature = "async")]
151pub use async_operator::AsyncOperator;
152
153#[cfg(feature = "tower")]
154pub use async_operator::ServiceOperator;