nautilus_model/defi/pool_analysis/
compare.rs1use super::{position::PoolPosition, profiler::PoolProfiler};
19use crate::defi::pool_analysis::snapshot::PoolSnapshot;
20
21pub fn compare_pool_profiler(profiler: &PoolProfiler, snapshot: &PoolSnapshot) -> bool {
45 if !profiler.is_initialized {
46 panic!("Profiler is not initialized");
47 }
48
49 let mut all_match = true;
50 let total_ticks = snapshot.ticks.len();
51 let total_positions = snapshot.positions.len();
52
53 if snapshot.state.current_tick != profiler.state.current_tick {
54 tracing::error!(
55 "Tick mismatch: profiler={}, compared={}",
56 profiler.state.current_tick,
57 snapshot.state.current_tick
58 );
59 all_match = false;
60 } else {
61 tracing::info!("✓ current_tick matches: {}", snapshot.state.current_tick);
62 }
63
64 if snapshot.state.price_sqrt_ratio_x96 != profiler.state.price_sqrt_ratio_x96 {
65 tracing::error!(
66 "Sqrt ratio mismatch: profiler={}, compared={}",
67 profiler.state.price_sqrt_ratio_x96,
68 snapshot.state.price_sqrt_ratio_x96
69 );
70 all_match = false;
71 } else {
72 tracing::info!(
73 "✓ sqrt_price_x96 matches: {}",
74 profiler.state.price_sqrt_ratio_x96,
75 );
76 }
77
78 if snapshot.state.fee_protocol != profiler.state.fee_protocol {
79 tracing::error!(
80 "Fee protocol mismatch: profiler={}, compared={}",
81 profiler.state.fee_protocol,
82 snapshot.state.fee_protocol
83 );
84 all_match = false;
85 } else {
86 tracing::info!("✓ fee_protocol matches: {}", snapshot.state.fee_protocol);
87 }
88
89 if snapshot.state.liquidity != profiler.tick_map.liquidity {
90 tracing::error!(
91 "Liquidity mismatch: profiler={}, compared={}",
92 profiler.tick_map.liquidity,
93 snapshot.state.liquidity
94 );
95 all_match = false;
96 } else {
97 tracing::info!("✓ liquidity matches: {}", snapshot.state.liquidity);
98 }
99
100 let mut tick_mismatches = 0;
104 for tick in &snapshot.ticks {
105 if let Some(profiler_tick) = profiler.get_tick(tick.value) {
106 let mut all_tick_fields_matching = true;
107 if profiler_tick.liquidity_net != tick.liquidity_net {
108 tracing::error!(
109 "Tick {} mismatch on net liquidity: profiler={}, compared={}",
110 tick.value,
111 profiler_tick.liquidity_net,
112 tick.liquidity_net
113 );
114 all_tick_fields_matching = false;
115 }
116 if profiler_tick.liquidity_gross != tick.liquidity_gross {
117 tracing::error!(
118 "Tick {} mismatch on gross liquidity: profiler={}, compared={}",
119 tick.value,
120 profiler_tick.liquidity_gross,
121 tick.liquidity_gross
122 );
123 all_tick_fields_matching = false;
124 }
125 if !all_tick_fields_matching {
128 tick_mismatches += 1;
129 all_match = false;
130 }
131 } else {
132 tracing::error!(
133 "Tick {} not found in the profiler but provided in the compare mapping",
134 tick.value
135 );
136 all_match = false;
137 }
138 }
139
140 if tick_mismatches == 0 {
141 tracing::info!(
142 "✓ Provided {} ticks with liquidity net and gross are matching",
143 total_ticks
144 );
145 }
146
147 let mut position_mismatches = 0;
149 for position in &snapshot.positions {
150 if let Some(profiler_position) =
151 profiler.get_position(&position.owner, position.tick_lower, position.tick_upper)
152 {
153 let position_key = PoolPosition::get_position_key(
154 &position.owner,
155 position.tick_lower,
156 position.tick_upper,
157 );
158 if position.liquidity != profiler_position.liquidity {
159 tracing::error!(
160 "Position '{}' mismatch on liquidity: profiler={}, compared={}",
161 position_key,
162 profiler_position.liquidity,
163 position.liquidity
164 );
165 position_mismatches += 1;
166 }
167 } else {
169 tracing::error!(
170 "Position {} not found in the profiler but provided in the compare mapping",
171 position.owner
172 );
173 all_match = false;
174 }
175 }
176
177 if position_mismatches == 0 {
178 tracing::info!(
179 "✓ Provided {} active positions with liquidity are matching",
180 total_positions
181 );
182 } else {
183 all_match = false;
184 }
185
186 all_match
187}