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