Skip to main content

nautilus_model/defi/data/
mod.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2026 Nautech Systems Pty Ltd. All rights reserved.
3//  https://nautechsystems.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16//! DeFi (Decentralized Finance) data models and types.
17//!
18//! This module provides core data structures for working with decentralized finance protocols,
19//! including blockchain networks, tokens, liquidity pools, swaps, and other DeFi primitives.
20
21use std::fmt::Display;
22
23use crate::{
24    defi::{Pool, pool_analysis::snapshot::PoolSnapshot},
25    identifiers::InstrumentId,
26};
27
28pub mod block;
29pub mod collect;
30pub mod flash;
31pub mod liquidity;
32pub mod swap;
33pub mod swap_trade_info;
34pub mod transaction;
35
36// Re-exports
37pub use block::Block;
38pub use collect::PoolFeeCollect;
39pub use flash::PoolFlash;
40pub use liquidity::{PoolLiquidityUpdate, PoolLiquidityUpdateType};
41pub use swap::PoolSwap;
42pub use transaction::Transaction;
43
44#[derive(Debug, Clone, PartialEq)]
45pub enum DexPoolData {
46    Swap(PoolSwap),
47    LiquidityUpdate(PoolLiquidityUpdate),
48    FeeCollect(PoolFeeCollect),
49    Flash(PoolFlash),
50}
51
52impl DexPoolData {
53    /// Returns the block number associated with this pool event.
54    #[must_use]
55    pub fn block_number(&self) -> u64 {
56        match self {
57            Self::Swap(s) => s.block,
58            Self::LiquidityUpdate(u) => u.block,
59            Self::FeeCollect(c) => c.block,
60            Self::Flash(f) => f.block,
61        }
62    }
63
64    /// Returns the transaction index associated with this pool event.
65    #[must_use]
66    pub fn transaction_index(&self) -> u32 {
67        match self {
68            Self::Swap(s) => s.transaction_index,
69            Self::LiquidityUpdate(u) => u.transaction_index,
70            Self::FeeCollect(c) => c.transaction_index,
71            Self::Flash(f) => f.transaction_index,
72        }
73    }
74
75    /// Returns the log index associated with this pool event.
76    #[must_use]
77    pub fn log_index(&self) -> u32 {
78        match self {
79            Self::Swap(s) => s.log_index,
80            Self::LiquidityUpdate(u) => u.log_index,
81            Self::FeeCollect(c) => c.log_index,
82            Self::Flash(f) => f.log_index,
83        }
84    }
85}
86
87/// Represents DeFi-specific data events in a decentralized exchange ecosystem.
88#[cfg_attr(
89    feature = "python",
90    pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.model", from_py_object)
91)]
92#[cfg_attr(
93    feature = "python",
94    pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
95)]
96#[derive(Debug, Clone, PartialEq)]
97pub enum DefiData {
98    /// A block completion in a blockchain network.
99    Block(Block),
100    /// A DEX liquidity pool definition or update.
101    Pool(Pool),
102    /// A complete snapshot of a pool's state at a specific point in time.
103    PoolSnapshot(PoolSnapshot),
104    /// A token swap transaction on a decentralized exchange.
105    PoolSwap(PoolSwap),
106    /// A liquidity update event (mint/burn) in a DEX pool.
107    PoolLiquidityUpdate(PoolLiquidityUpdate),
108    /// A fee collection event from a DEX pool position.
109    PoolFeeCollect(PoolFeeCollect),
110    /// A flash event
111    PoolFlash(PoolFlash),
112}
113
114impl DefiData {
115    /// Returns the instrument ID associated with this DeFi data.
116    ///
117    /// # Panics
118    ///
119    /// Panics if the variant is a `Block` or `PoolSnapshot` where instrument IDs are not applicable.
120    #[must_use]
121    pub fn instrument_id(&self) -> InstrumentId {
122        match self {
123            Self::Block(_) => panic!("`InstrumentId` not applicable to `Block`"), // TBD?
124            Self::PoolSnapshot(snapshot) => snapshot.instrument_id,
125            Self::PoolSwap(swap) => swap.instrument_id,
126            Self::PoolLiquidityUpdate(update) => update.instrument_id,
127            Self::PoolFeeCollect(collect) => collect.instrument_id,
128            Self::Pool(pool) => pool.instrument_id,
129            Self::PoolFlash(flash) => flash.instrument_id,
130        }
131    }
132}
133
134impl Display for DefiData {
135    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
136        match self {
137            Self::Block(b) => write!(f, "{b}"),
138            Self::Pool(p) => write!(f, "{p}"),
139            Self::PoolSnapshot(s) => write!(f, "PoolSnapshot(block={})", s.block_position.number),
140            Self::PoolSwap(s) => write!(f, "{s}"),
141            Self::PoolLiquidityUpdate(u) => write!(f, "{u}"),
142            Self::PoolFeeCollect(c) => write!(f, "{c}"),
143            Self::PoolFlash(p) => write!(f, "{p}"),
144        }
145    }
146}
147
148impl From<Pool> for DefiData {
149    fn from(value: Pool) -> Self {
150        Self::Pool(value)
151    }
152}
153
154impl From<PoolSwap> for DefiData {
155    fn from(value: PoolSwap) -> Self {
156        Self::PoolSwap(value)
157    }
158}
159
160impl From<PoolLiquidityUpdate> for DefiData {
161    fn from(value: PoolLiquidityUpdate) -> Self {
162        Self::PoolLiquidityUpdate(value)
163    }
164}
165
166impl From<PoolFeeCollect> for DefiData {
167    fn from(value: PoolFeeCollect) -> Self {
168        Self::PoolFeeCollect(value)
169    }
170}
171
172impl From<PoolSnapshot> for DefiData {
173    fn from(value: PoolSnapshot) -> Self {
174        Self::PoolSnapshot(value)
175    }
176}