nautilus_model/defi/data/
swap.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2025 Posei Systems Pty Ltd. All rights reserved.
3//  https://poseitrader.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
16use std::fmt::Display;
17
18use alloy_primitives::Address;
19use nautilus_core::UnixNanos;
20use serde::{Deserialize, Serialize};
21
22use crate::{
23    data::HasTsInit,
24    defi::{amm::SharedPool, chain::SharedChain, dex::SharedDex},
25    enums::OrderSide,
26    identifiers::InstrumentId,
27    types::{Price, Quantity},
28};
29
30/// Represents a token swap transaction on a decentralized exchange (DEX).
31#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
32pub struct PoolSwap {
33    /// The blockchain network where the swap occurred.
34    pub chain: SharedChain,
35    /// The decentralized exchange where the swap was executed.
36    pub dex: SharedDex,
37    /// The DEX liquidity pool.
38    pub pool: SharedPool,
39    /// The blockchain block number at which the swap was executed.
40    pub block: u64,
41    /// The unique hash identifier of the blockchain transaction containing the swap.
42    pub transaction_hash: String,
43    /// The index position of the transaction within the block.
44    pub transaction_index: u32,
45    /// The index position of the swap event log within the transaction.
46    pub log_index: u32,
47    /// The blockchain address of the user or contract that initiated the swap.
48    pub sender: Address,
49    /// The direction of the swap from the perspective of the base token.
50    pub side: OrderSide,
51    /// The amount of tokens swapped.
52    pub size: Quantity,
53    /// The exchange rate at which the swap occurred.
54    pub price: Price,
55    /// UNIX timestamp (nanoseconds) when the swap occurred.
56    pub timestamp: UnixNanos,
57    /// UNIX timestamp (nanoseconds) when the instance was initialized.
58    pub ts_init: UnixNanos,
59}
60
61impl PoolSwap {
62    /// Creates a new [`PoolSwap`] instance with the specified properties.
63    #[must_use]
64    #[allow(clippy::too_many_arguments)]
65    pub fn new(
66        chain: SharedChain,
67        dex: SharedDex,
68        pool: SharedPool,
69        block: u64,
70        transaction_hash: String,
71        transaction_index: u32,
72        log_index: u32,
73        timestamp: UnixNanos,
74        sender: Address,
75        side: OrderSide,
76        size: Quantity,
77        price: Price,
78    ) -> Self {
79        Self {
80            chain,
81            dex,
82            pool,
83            block,
84            transaction_hash,
85            transaction_index,
86            log_index,
87            timestamp,
88            sender,
89            side,
90            size,
91            price,
92            ts_init: timestamp, // TODO: Use swap timestamp as init timestamp for now
93        }
94    }
95
96    /// Returns the instrument ID for this swap.
97    #[must_use]
98    pub fn instrument_id(&self) -> InstrumentId {
99        self.pool.instrument_id()
100    }
101}
102
103impl HasTsInit for PoolSwap {
104    fn ts_init(&self) -> UnixNanos {
105        self.ts_init
106    }
107}
108
109impl Display for PoolSwap {
110    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111        write!(
112            f,
113            "{}(chain={}, dex={}, pool={}, side={}, quantity={}, price={})",
114            stringify!(PoolSwap),
115            self.chain.name,
116            self.dex.name,
117            self.pool.ticker(),
118            self.side,
119            self.size,
120            self.price,
121        )
122    }
123}