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