Skip to main content

mantis_ta/types/
mod.rs

1use thiserror::Error;
2
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6/// A single OHLCV bar.
7#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8#[derive(Debug, Clone, Copy, PartialEq)]
9pub struct Candle {
10    pub timestamp: i64, // Unix timestamp ms
11    pub open: f64,
12    pub high: f64,
13    pub low: f64,
14    pub close: f64,
15    pub volume: f64,
16}
17
18/// Which price field to use as input source.
19#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
20#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub enum PriceSource {
22    Open,
23    High,
24    Low,
25    Close,
26    HLC3,
27    OHLC4,
28    HL2,
29}
30
31/// Trading direction.
32#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
34pub enum Side {
35    Long,
36    Short,
37}
38
39/// Signal emitted by strategy evaluation.
40#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
41#[derive(Debug, Clone, PartialEq)]
42pub enum Signal {
43    Entry(Side),
44    Exit(ExitReason),
45    Hold,
46}
47
48/// Why an exit was triggered.
49#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
50#[derive(Debug, Clone, PartialEq)]
51pub enum ExitReason {
52    RuleTriggered,
53    StopLoss,
54    TakeProfit,
55    TrailingStop,
56    DailyLossLimit,
57    DrawdownBreaker,
58}
59
60/// Candle timeframe.
61#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
62#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
63pub enum Timeframe {
64    M1,
65    M5,
66    M15,
67    M30,
68    H1,
69    H4,
70    D1,
71    W1,
72    MN1,
73}
74
75/// MACD output values.
76#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
77#[derive(Debug, Clone, Copy, PartialEq)]
78pub struct MacdOutput {
79    pub macd_line: f64,
80    pub signal_line: f64,
81    pub histogram: f64,
82}
83
84/// Bollinger Bands output values.
85#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
86#[derive(Debug, Clone, Copy, PartialEq)]
87pub struct BollingerOutput {
88    pub upper: f64,
89    pub middle: f64,
90    pub lower: f64,
91}
92
93/// Keltner Channels output values.
94#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
95#[derive(Debug, Clone, Copy, PartialEq)]
96pub struct KeltnerOutput {
97    pub upper: f64,
98    pub middle: f64,
99    pub lower: f64,
100}
101
102/// Donchian Channels output values.
103#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
104#[derive(Debug, Clone, Copy, PartialEq)]
105pub struct DonchianOutput {
106    pub upper: f64,
107    pub middle: f64,
108    pub lower: f64,
109}
110
111/// Stochastic oscillator output values.
112#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
113#[derive(Debug, Clone, Copy, PartialEq)]
114pub struct StochasticOutput {
115    pub k: f64,
116    pub d: f64,
117}
118
119/// ADX (Average Directional Index) output values.
120#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
121#[derive(Debug, Clone, Copy, PartialEq)]
122pub struct AdxOutput {
123    pub plus_di: f64,
124    pub minus_di: f64,
125    pub adx: f64,
126}
127
128/// Ichimoku Cloud output values.
129#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
130#[derive(Debug, Clone, Copy, PartialEq)]
131pub struct IchimokuOutput {
132    pub tenkan_sen: f64,
133    pub kijun_sen: f64,
134    pub senkou_span_a: f64,
135    pub senkou_span_b: f64,
136    pub chikou_span: f64,
137}
138
139/// Pivot points output values.
140#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
141#[derive(Debug, Clone, Copy, PartialEq)]
142pub struct PivotOutput {
143    pub pp: f64,
144    pub r1: f64,
145    pub r2: f64,
146    pub r3: f64,
147    pub s1: f64,
148    pub s2: f64,
149    pub s3: f64,
150}
151
152/// Common error type for the crate.
153#[derive(Error, Debug)]
154pub enum MantisError {
155    #[error("Invalid parameter: {param} = {value} ({reason})")]
156    InvalidParameter {
157        param: &'static str,
158        value: String,
159        reason: &'static str,
160    },
161
162    #[error("Insufficient data: need {required} candles, got {provided}")]
163    InsufficientData { required: usize, provided: usize },
164
165    #[error("Strategy validation failed: {0}")]
166    StrategyValidation(String),
167
168    #[error("Backtest error: {0}")]
169    BacktestError(String),
170}
171
172/// Convenience result alias.
173pub type Result<T> = std::result::Result<T, MantisError>;