nautilus_model/python/defi/
profiler.rs1use std::str::FromStr;
19
20use alloy_primitives::{U160, U256};
21use nautilus_core::python::to_pyvalue_err;
22use pyo3::prelude::*;
23
24use crate::{
25 defi::{
26 Pool,
27 pool_analysis::{PoolProfiler, quote::SwapQuote},
28 },
29 identifiers::InstrumentId,
30};
31
32#[pymethods]
33impl PoolProfiler {
34 #[getter]
35 #[pyo3(name = "pool")]
36 fn py_pool(&self) -> Pool {
37 self.pool.as_ref().clone()
38 }
39
40 #[getter]
41 #[pyo3(name = "instrument_id")]
42 fn py_instrument_id(&self) -> InstrumentId {
43 self.pool.instrument_id
44 }
45
46 #[getter]
47 #[pyo3(name = "is_initialized")]
48 fn py_is_initialized(&self) -> bool {
49 self.is_initialized
50 }
51
52 #[getter]
53 #[pyo3(name = "current_tick")]
54 fn py_current_tick(&self) -> i32 {
55 self.state.current_tick
56 }
57
58 #[getter]
59 #[pyo3(name = "price_sqrt_ratio_x96")]
60 fn py_price_sqrt_ratio_x96(&self) -> String {
61 self.state.price_sqrt_ratio_x96.to_string()
62 }
63
64 #[getter]
65 #[pyo3(name = "total_amount0_deposited")]
66 fn py_total_amount0_deposited(&self) -> String {
67 self.analytics.total_amount0_deposited.to_string()
68 }
69
70 #[getter]
71 #[pyo3(name = "total_amount1_deposited")]
72 fn py_total_amount1_deposited(&self) -> String {
73 self.analytics.total_amount1_deposited.to_string()
74 }
75
76 #[getter]
77 #[pyo3(name = "total_amount0_collected")]
78 fn py_total_amount0_collected(&self) -> String {
79 self.analytics.total_amount0_collected.to_string()
80 }
81
82 #[getter]
83 #[pyo3(name = "total_amount1_collected")]
84 fn py_total_amount1_collected(&self) -> String {
85 self.analytics.total_amount1_collected.to_string()
86 }
87
88 #[getter]
89 #[pyo3(name = "protocol_fees_token0")]
90 fn py_protocol_fees_token0(&self) -> String {
91 self.state.protocol_fees_token0.to_string()
92 }
93
94 #[getter]
95 #[pyo3(name = "protocol_fees_token1")]
96 fn py_protocol_fees_token1(&self) -> String {
97 self.state.protocol_fees_token1.to_string()
98 }
99
100 #[getter]
101 #[pyo3(name = "fee_protocol")]
102 fn py_fee_protocol(&self) -> u8 {
103 self.state.fee_protocol
104 }
105
106 #[pyo3(name = "get_active_liquidity")]
107 fn py_get_active_liquidity(&self) -> u128 {
108 self.get_active_liquidity()
109 }
110
111 #[pyo3(name = "get_active_tick_count")]
112 fn py_get_active_tick_count(&self) -> usize {
113 self.get_active_tick_count()
114 }
115
116 #[pyo3(name = "get_total_tick_count")]
117 fn py_get_total_tick_count(&self) -> usize {
118 self.get_total_tick_count()
119 }
120
121 #[pyo3(name = "get_total_active_positions")]
122 fn py_get_total_active_positions(&self) -> usize {
123 self.get_total_active_positions()
124 }
125
126 #[pyo3(name = "get_total_inactive_positions")]
127 fn py_get_total_inactive_positions(&self) -> usize {
128 self.get_total_inactive_positions()
129 }
130
131 #[pyo3(name = "estimate_balance_of_token0")]
132 fn py_estimate_balance_of_token0(&self) -> String {
133 self.estimate_balance_of_token0().to_string()
134 }
135
136 #[pyo3(name = "estimate_balance_of_token1")]
137 fn py_estimate_balance_of_token1(&self) -> String {
138 self.estimate_balance_of_token1().to_string()
139 }
140
141 #[pyo3(name = "get_total_liquidity")]
142 fn py_get_total_liquidity_all_positions(&self) -> String {
143 self.get_total_liquidity().to_string()
144 }
145
146 #[pyo3(name = "liquidity_utilization_rate")]
147 fn py_liquidity_utilization_rate(&self) -> f64 {
148 self.liquidity_utilization_rate()
149 }
150
151 #[pyo3(name = "swap_exact_in")]
152 fn py_swap_exact_in(
153 &self,
154 amount_in: &str,
155 zero_for_one: bool,
156 sqrt_price_limit_x96: Option<&str>,
157 ) -> PyResult<SwapQuote> {
158 let amount_in = U256::from_str(amount_in).map_err(to_pyvalue_err)?;
159 let sqrt_price_limit = match sqrt_price_limit_x96 {
160 Some(limit_str) => Some(U160::from_str(limit_str).map_err(to_pyvalue_err)?),
161 None => None,
162 };
163
164 self.swap_exact_in(amount_in, zero_for_one, sqrt_price_limit)
165 .map_err(to_pyvalue_err)
166 }
167
168 #[pyo3(name = "swap_exact_out")]
169 fn py_swap_exact_out(
170 &self,
171 amount_out: &str,
172 zero_for_one: bool,
173 sqrt_price_limit_x96: Option<&str>,
174 ) -> PyResult<SwapQuote> {
175 let amount_out = U256::from_str(amount_out).map_err(to_pyvalue_err)?;
176 let sqrt_price_limit = match sqrt_price_limit_x96 {
177 Some(limit_str) => Some(U160::from_str(limit_str).map_err(to_pyvalue_err)?),
178 None => None,
179 };
180
181 self.swap_exact_out(amount_out, zero_for_one, sqrt_price_limit)
182 .map_err(to_pyvalue_err)
183 }
184}