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}