Skip to content

Commit f0c9a1f

Browse files
feat: Add tests
1 parent 26ea9f8 commit f0c9a1f

File tree

1 file changed

+264
-0
lines changed

1 file changed

+264
-0
lines changed
Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
//! Tests for ArbitrageDetector constructor and configuration
2+
3+
mod common;
4+
5+
use analysis_tools::ArbitrageDetector;
6+
use common::{assert_no_arbitrage_opportunities, TestDataFactory};
7+
8+
#[tokio::test]
9+
async fn test_arbitrage_detector_new_with_custom_thresholds() {
10+
// Test creating ArbitrageDetector with custom thresholds
11+
let profit_threshold = 0.5; // 0.5%
12+
let volume_threshold = 0.1; // 0.1 units
13+
14+
let detector = ArbitrageDetector::new(profit_threshold, volume_threshold);
15+
16+
// Create a scenario with profit below the custom threshold
17+
let scenarios = TestDataFactory::create_arbitrage_scenario(
18+
"BTCUSDT",
19+
aggregator_core::Exchange::Bybit, // Buy here
20+
aggregator_core::Exchange::Binance, // Sell here
21+
50000.0, // Buy price
22+
50020.0, // Sell price (0.04% profit - below 0.5% threshold)
23+
1.0, // Volume above threshold
24+
);
25+
26+
let opportunities = detector.detect_opportunities(&scenarios).await;
27+
28+
// Should find no opportunities because profit is below custom threshold
29+
assert_no_arbitrage_opportunities(&opportunities);
30+
}
31+
32+
#[tokio::test]
33+
async fn test_arbitrage_detector_new_with_custom_thresholds_above_threshold() {
34+
// Test that custom thresholds work when profit is above threshold
35+
let profit_threshold = 0.1; // 0.1%
36+
let volume_threshold = 0.01; // 0.01 units
37+
38+
let detector = ArbitrageDetector::new(profit_threshold, volume_threshold);
39+
40+
// Create a scenario with profit above the custom threshold
41+
let scenarios = TestDataFactory::create_arbitrage_scenario(
42+
"BTCUSDT",
43+
aggregator_core::Exchange::Bybit, // Buy here
44+
aggregator_core::Exchange::Binance, // Sell here
45+
50000.0, // Buy price
46+
50100.0, // Sell price (0.2% profit - above 0.1% threshold)
47+
1.0, // Volume above threshold
48+
);
49+
50+
let opportunities = detector.detect_opportunities(&scenarios).await;
51+
52+
// Should find opportunities because profit is above custom threshold
53+
assert_eq!(opportunities.len(), 1);
54+
let opportunity = &opportunities[0];
55+
assert!(opportunity.profit_percentage >= profit_threshold);
56+
assert!(opportunity.volume >= volume_threshold);
57+
}
58+
59+
#[tokio::test]
60+
async fn test_arbitrage_detector_new_with_volume_threshold() {
61+
// Test that volume threshold is properly applied
62+
let profit_threshold = 0.1; // 0.1%
63+
let volume_threshold = 2.0; // 2.0 units (high threshold)
64+
65+
let detector = ArbitrageDetector::new(profit_threshold, volume_threshold);
66+
67+
// Create a scenario with high profit but low volume
68+
let scenarios = TestDataFactory::create_arbitrage_scenario(
69+
"BTCUSDT",
70+
aggregator_core::Exchange::Bybit, // Buy here
71+
aggregator_core::Exchange::Binance, // Sell here
72+
50000.0, // Buy price
73+
50500.0, // Sell price (1% profit - above threshold)
74+
1.0, // Volume below threshold (1.0 < 2.0)
75+
);
76+
77+
let opportunities = detector.detect_opportunities(&scenarios).await;
78+
79+
// Should find no opportunities because volume is below threshold
80+
assert_no_arbitrage_opportunities(&opportunities);
81+
}
82+
83+
#[tokio::test]
84+
async fn test_arbitrage_detector_default_implementation() {
85+
// Test that default implementation uses expected thresholds
86+
let detector = ArbitrageDetector::default();
87+
88+
// Create a scenario with profit just above default threshold (0.1%)
89+
let scenarios = TestDataFactory::create_arbitrage_scenario(
90+
"BTCUSDT",
91+
aggregator_core::Exchange::Bybit, // Buy here
92+
aggregator_core::Exchange::Binance, // Sell here
93+
50000.0, // Buy price
94+
50060.0, // Sell price (0.12% profit - above default 0.1% threshold)
95+
0.02, // Volume above default threshold (0.02 > 0.01)
96+
);
97+
98+
let opportunities = detector.detect_opportunities(&scenarios).await;
99+
100+
// Should find opportunities with default thresholds
101+
assert_eq!(opportunities.len(), 1);
102+
let opportunity = &opportunities[0];
103+
assert!(opportunity.profit_percentage >= 0.1); // Default profit threshold
104+
assert!(opportunity.volume >= 0.01); // Default volume threshold
105+
}
106+
107+
#[tokio::test]
108+
async fn test_arbitrage_detector_default_profit_threshold() {
109+
// Test that default profit threshold (0.1%) is enforced
110+
let detector = ArbitrageDetector::default();
111+
112+
// Create a scenario with profit just below default threshold
113+
let scenarios = TestDataFactory::create_arbitrage_scenario(
114+
"BTCUSDT",
115+
aggregator_core::Exchange::Bybit, // Buy here
116+
aggregator_core::Exchange::Binance, // Sell here
117+
50000.0, // Buy price
118+
50040.0, // Sell price (0.08% profit - below default 0.1% threshold)
119+
1.0, // Volume above threshold
120+
);
121+
122+
let opportunities = detector.detect_opportunities(&scenarios).await;
123+
124+
// Should find no opportunities because profit is below default threshold
125+
assert_no_arbitrage_opportunities(&opportunities);
126+
}
127+
128+
#[tokio::test]
129+
async fn test_arbitrage_detector_default_volume_threshold() {
130+
// Test that default volume threshold (0.01) is enforced
131+
let detector = ArbitrageDetector::default();
132+
133+
// Create a scenario with high profit but volume below default threshold
134+
let scenarios = TestDataFactory::create_arbitrage_scenario(
135+
"BTCUSDT",
136+
aggregator_core::Exchange::Bybit, // Buy here
137+
aggregator_core::Exchange::Binance, // Sell here
138+
50000.0, // Buy price
139+
50500.0, // Sell price (1% profit - well above threshold)
140+
0.005, // Volume below default threshold (0.005 < 0.01)
141+
);
142+
143+
let opportunities = detector.detect_opportunities(&scenarios).await;
144+
145+
// Should find no opportunities because volume is below default threshold
146+
assert_no_arbitrage_opportunities(&opportunities);
147+
}
148+
149+
#[tokio::test]
150+
async fn test_threshold_storage_and_usage_consistency() {
151+
// Test that thresholds are stored and used consistently
152+
let custom_profit = 0.25; // 0.25%
153+
let custom_volume = 0.5; // 0.5 units
154+
155+
let detector = ArbitrageDetector::new(custom_profit, custom_volume);
156+
157+
// Test multiple scenarios to ensure thresholds are consistently applied
158+
159+
// Scenario 1: Both thresholds met
160+
let scenarios1 = TestDataFactory::create_arbitrage_scenario(
161+
"BTCUSDT",
162+
aggregator_core::Exchange::Bybit,
163+
aggregator_core::Exchange::Binance,
164+
50000.0, // Buy price
165+
50150.0, // Sell price (0.3% profit - above 0.25% threshold)
166+
0.6, // Volume above 0.5 threshold
167+
);
168+
169+
let opportunities1 = detector.detect_opportunities(&scenarios1).await;
170+
assert_eq!(
171+
opportunities1.len(),
172+
1,
173+
"Should find opportunity when both thresholds are met"
174+
);
175+
176+
// Scenario 2: Profit threshold not met
177+
let scenarios2 = TestDataFactory::create_arbitrage_scenario(
178+
"BTCUSDT",
179+
aggregator_core::Exchange::Bybit,
180+
aggregator_core::Exchange::Binance,
181+
50000.0, // Buy price
182+
50100.0, // Sell price (0.2% profit - below 0.25% threshold)
183+
0.6, // Volume above threshold
184+
);
185+
186+
let opportunities2 = detector.detect_opportunities(&scenarios2).await;
187+
assert_no_arbitrage_opportunities(&opportunities2);
188+
189+
// Scenario 3: Volume threshold not met
190+
let scenarios3 = TestDataFactory::create_arbitrage_scenario(
191+
"BTCUSDT",
192+
aggregator_core::Exchange::Bybit,
193+
aggregator_core::Exchange::Binance,
194+
50000.0, // Buy price
195+
50200.0, // Sell price (0.4% profit - above threshold)
196+
0.3, // Volume below 0.5 threshold
197+
);
198+
199+
let opportunities3 = detector.detect_opportunities(&scenarios3).await;
200+
assert_no_arbitrage_opportunities(&opportunities3);
201+
}
202+
203+
#[tokio::test]
204+
async fn test_extreme_threshold_values() {
205+
// Test with very high thresholds
206+
let detector_high = ArbitrageDetector::new(10.0, 100.0); // 10% profit, 100 volume
207+
208+
let scenarios = TestDataFactory::create_arbitrage_scenario(
209+
"BTCUSDT",
210+
aggregator_core::Exchange::Bybit,
211+
aggregator_core::Exchange::Binance,
212+
50000.0, // Buy price
213+
52000.0, // Sell price (4% profit - below 10% threshold)
214+
50.0, // Volume below 100 threshold
215+
);
216+
217+
let opportunities = detector_high.detect_opportunities(&scenarios).await;
218+
assert_no_arbitrage_opportunities(&opportunities);
219+
220+
// Test with very low thresholds
221+
let detector_low = ArbitrageDetector::new(0.001, 0.0001); // 0.001% profit, 0.0001 volume
222+
223+
let scenarios_low = TestDataFactory::create_arbitrage_scenario(
224+
"BTCUSDT",
225+
aggregator_core::Exchange::Bybit,
226+
aggregator_core::Exchange::Binance,
227+
50000.0, // Buy price
228+
50001.0, // Sell price (0.002% profit - above 0.001% threshold)
229+
0.001, // Volume above 0.0001 threshold
230+
);
231+
232+
let opportunities_low = detector_low.detect_opportunities(&scenarios_low).await;
233+
assert_eq!(
234+
opportunities_low.len(),
235+
1,
236+
"Should find opportunity with very low thresholds"
237+
);
238+
}
239+
240+
#[tokio::test]
241+
async fn test_zero_thresholds() {
242+
// Test with zero thresholds (should accept any positive profit and volume)
243+
let detector = ArbitrageDetector::new(0.0, 0.0);
244+
245+
let scenarios = TestDataFactory::create_arbitrage_scenario(
246+
"BTCUSDT",
247+
aggregator_core::Exchange::Bybit,
248+
aggregator_core::Exchange::Binance,
249+
50000.0, // Buy price
250+
50000.1, // Sell price (tiny profit)
251+
0.0001, // Tiny volume
252+
);
253+
254+
let opportunities = detector.detect_opportunities(&scenarios).await;
255+
assert_eq!(
256+
opportunities.len(),
257+
1,
258+
"Should find opportunity with zero thresholds"
259+
);
260+
261+
let opportunity = &opportunities[0];
262+
assert!(opportunity.profit_percentage > 0.0);
263+
assert!(opportunity.volume > 0.0);
264+
}

0 commit comments

Comments
 (0)