1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
//! Abstractions for stream aggregation that we call "Indicator" s.
//!
//! This crate provides abstractions of different levels to build indicators:
//!
//! - Indicators are the combinations of [`Operator`]s. We can chain them by [`OperatorExt::then`]
//! and apply them to the same input "simultaneously" by [`OperatorExt::facet`].
//!
//! - To handle [Time series] better, we introduced utils for ticked operators, which are defined in [`TickedOperatorExt`],
//! of which the input and output are both [`Tickable`] and sharing the same [`Tick`].
//! We provide many ticked version utils. For example, we can apply different [`TickedOperatorExt`]s
//! (using [`TickedOperatorExt::facet_t`] or [`ticked::FacetMap`]) to the same [`Tickable`] stream to
//! get a "synced" result stream of the combined outputs of those operators sharing the same [`Tick`]
//! of theirs input. Each item of a "synced" stream will have the form of `TickValue<(O1, O2)>`.
//!
//! - [`TumblingOperator`]s are defined by some operations on events of non-overlapping time windows ([`TumblingWindow`]).
//! [Moving average] is one of the famous examples, which is defined by the average of the numbers
//! from those events occur in the same tumbling window. We call those operations [`TumblingOperation`]s.
//! We can use [`tumbling`] function to create a [`TumblingOperator`] from a [`TumblingOperation`].
//!
//! - Finally, we can apply the indicators to [`Iterator`]s or [`Stream`](futures::stream::Stream)s
//! by using [`IndicatorIteratorExt::indicator`] or [`IndicatorStreamExt::indicator`] accordingly.
//!
//!
//! [Time series]: https://en.wikipedia.org/wiki/Time_series
//! [Moving average]: https://en.wikipedia.org/wiki/Moving_average
//!
//! # Example
//! ```
//! use indicator::*;
//! use rust_decimal::Decimal;
//! use rust_decimal_macros::dec;
//! use time::macros::offset;
//! use arrayvec::ArrayVec;
//!
//! /// Return an indicator that calculates `hl2` and `ohlc4` simultaneously.
//! fn hl2_ohlc4(period: Period) -> impl Operator<TickValue<Decimal>, Output = (Decimal, Decimal)> {
//!     tumbling(
//!         period,
//!         |_w: &ArrayVec<[Decimal; 4], 0>, y: &mut Option<[Decimal; 4]>, x| match y {
//!             Some(ohlc) => {
//!                 ohlc[1] = ohlc[1].max(x);
//!                 ohlc[2] = ohlc[2].min(x);
//!                 ohlc[3] = x;
//!                 *ohlc
//!             }
//!             None => {
//!                 let ohlc = [x; 4];
//!                 *y = Some(ohlc);
//!                 ohlc
//!             }
//!         },
//!     )
//!     .then(facet_t(
//!         map_t(|ohlc: [Decimal; 4]| (ohlc[1] + ohlc[2]) / dec!(2)),
//!         map_t(|ohlc: [Decimal; 4]| (ohlc[0] + ohlc[1] + ohlc[2] + ohlc[3]) / dec!(4)),
//!     ))
//!     .map(|v| v.value)
//! }
//!```

#![deny(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]

/// Operator.
pub mod operator;

/// Time window.
pub mod window;

/// Ticked operators.
pub mod ticked;

/// Iterator extension trait.
pub mod iter;

#[cfg(feature = "stream")]
/// Stream extension trait.
pub mod stream;

pub use iter::IndicatorIteratorExt;
pub use operator::{facet, map, Operator, OperatorExt};
pub use ticked::{
    facet_t, map_t,
    tumbling::{
        cached, tumbling, Cached, CachedOperation, QueueCapAtLeast, TumblingOperation,
        TumblingOperator, TumblingQueue,
    },
    TickedOperatorExt,
};
pub use window::{Period, Tick, TickValue, Tickable, TumblingWindow};

#[cfg(feature = "std")]
pub use ticked::facet_map_t;

#[cfg(feature = "std")]
pub use facet::facet_map;

#[cfg(feature = "std")]
pub use ticked::{shared, SharedMap};

#[cfg(feature = "stream")]
pub use stream::IndicatorStreamExt;