/home/jgrusewski/Work/foxhunt/common/src/thresholds.rs
Line | Count | Source |
1 | | //! Centralized threshold constants for the Foxhunt HFT system |
2 | | //! |
3 | | //! This module consolidates all hardcoded threshold values that were |
4 | | //! previously scattered throughout the codebase. Constants here are |
5 | | //! compile-time values for performance-critical operations. |
6 | | //! |
7 | | //! For runtime-configurable values, see the `config` crate's runtime module. |
8 | | |
9 | | use std::time::Duration; |
10 | | |
11 | | /// Risk management thresholds |
12 | | pub mod risk { |
13 | | |
14 | | |
15 | | /// Breach severity warning threshold (percentage of limit) |
16 | | /// Used when position is at 80-90% of limit |
17 | | pub const BREACH_WARNING_PCT: u8 = 80; |
18 | | |
19 | | /// Breach severity soft threshold (percentage of limit) |
20 | | /// Used when position is at 90-100% of limit |
21 | | pub const BREACH_SOFT_PCT: u8 = 90; |
22 | | |
23 | | /// Breach severity hard threshold (percentage of limit) |
24 | | /// Used when position is at 100-120% of limit |
25 | | pub const BREACH_HARD_PCT: u8 = 100; |
26 | | |
27 | | /// Breach severity critical threshold (percentage of limit) |
28 | | /// Used when position exceeds 120% of limit |
29 | | pub const BREACH_CRITICAL_PCT: u8 = 120; |
30 | | |
31 | | /// Minimum capital adequacy ratio (Basel III standard) |
32 | | pub const MIN_CAPITAL_ADEQUACY_RATIO: f64 = 0.08; |
33 | | |
34 | | /// Minimum leverage ratio (Basel III standard) |
35 | | pub const MIN_LEVERAGE_RATIO: f64 = 0.03; |
36 | | |
37 | | /// Default VaR confidence level (95%) |
38 | | pub const DEFAULT_VAR_CONFIDENCE: f64 = 0.95; |
39 | | |
40 | | /// High VaR confidence level (99%) |
41 | | pub const HIGH_VAR_CONFIDENCE: f64 = 0.99; |
42 | | |
43 | | /// Maximum drawdown warning threshold (percentage) |
44 | | pub const MAX_DRAWDOWN_WARNING_PCT: u8 = 15; |
45 | | |
46 | | /// Maximum drawdown critical threshold (percentage) |
47 | | pub const MAX_DRAWDOWN_CRITICAL_PCT: u8 = 25; |
48 | | } |
49 | | |
50 | | /// VaR calculation constants |
51 | | pub mod var { |
52 | | /// Z-score for 90% confidence level |
53 | | pub const Z_SCORE_P90: f64 = 1.282; |
54 | | |
55 | | /// Z-score for 95% confidence level |
56 | | pub const Z_SCORE_P95: f64 = 1.645; |
57 | | |
58 | | /// Z-score for 97.5% confidence level |
59 | | pub const Z_SCORE_P97_5: f64 = 1.96; |
60 | | |
61 | | /// Z-score for 99% confidence level |
62 | | pub const Z_SCORE_P99: f64 = 2.326; |
63 | | |
64 | | /// Z-score for 99.9% confidence level |
65 | | pub const Z_SCORE_P99_9: f64 = 3.09; |
66 | | |
67 | | /// Default lookback period for historical VaR (trading days) |
68 | | pub const DEFAULT_LOOKBACK_DAYS: usize = 252; |
69 | | |
70 | | /// Minimum data quality score for VaR calculation |
71 | | pub const MIN_DATA_QUALITY_SCORE: f64 = 0.6; |
72 | | } |
73 | | |
74 | | /// Performance and timing constants |
75 | | pub mod performance { |
76 | | |
77 | | |
78 | | /// Maximum latency for HFT critical path operations (nanoseconds) |
79 | | pub const MAX_CRITICAL_PATH_LATENCY_NS: u64 = 14; |
80 | | |
81 | | /// Maximum acceptable latency for risk checks (microseconds) |
82 | | pub const MAX_RISK_CHECK_LATENCY_US: u64 = 50; |
83 | | |
84 | | /// Maximum latency for ML inference (microseconds) |
85 | | pub const MAX_ML_INFERENCE_LATENCY_US: u64 = 100; |
86 | | |
87 | | /// Default batch processing size |
88 | | pub const DEFAULT_BATCH_SIZE: usize = 100; |
89 | | |
90 | | /// Ring buffer size for lock-free operations |
91 | | pub const RING_BUFFER_SIZE: usize = 4096; |
92 | | |
93 | | /// Small batch size for SIMD operations |
94 | | pub const SIMD_BATCH_SIZE: usize = 8; |
95 | | |
96 | | /// Maximum small batch size |
97 | | pub const MAX_SMALL_BATCH_SIZE: usize = 10; |
98 | | |
99 | | /// Default worker thread count (adjusted based on CPU cores at runtime) |
100 | | pub const DEFAULT_WORKER_THREADS: usize = 4; |
101 | | |
102 | | /// Default queue capacity for async operations |
103 | | pub const DEFAULT_QUEUE_CAPACITY: usize = 10000; |
104 | | } |
105 | | |
106 | | /// Cache TTL defaults (can be overridden by runtime config) |
107 | | pub mod cache { |
108 | | use super::Duration; |
109 | | |
110 | | /// Default TTL for position cache entries (1 minute) |
111 | | pub const POSITION_CACHE_TTL: Duration = Duration::from_secs(60); |
112 | | |
113 | | /// Default TTL for VaR calculation cache (1 hour) |
114 | | pub const VAR_CACHE_TTL: Duration = Duration::from_secs(3600); |
115 | | |
116 | | /// Default TTL for compliance check cache (24 hours) |
117 | | pub const COMPLIANCE_CACHE_TTL: Duration = Duration::from_secs(86400); |
118 | | |
119 | | /// Default TTL for market data cache (5 minutes) |
120 | | pub const MARKET_DATA_CACHE_TTL: Duration = Duration::from_secs(300); |
121 | | |
122 | | /// Default TTL for model predictions cache (1 minute) |
123 | | pub const MODEL_PREDICTION_CACHE_TTL: Duration = Duration::from_secs(60); |
124 | | |
125 | | /// Redis key TTL for position limits (5 minutes) |
126 | | pub const REDIS_POSITION_LIMIT_TTL_SECS: i32 = 300; |
127 | | |
128 | | /// Redis key TTL for compliance checks (24 hours) |
129 | | pub const REDIS_COMPLIANCE_TTL_SECS: i32 = 86400; |
130 | | |
131 | | /// Redis key TTL for VaR calculations (1 hour) |
132 | | pub const REDIS_VAR_TTL_SECS: i32 = 3600; |
133 | | } |
134 | | |
135 | | /// Database operation defaults |
136 | | pub mod database { |
137 | | use super::Duration; |
138 | | |
139 | | /// Default query timeout for standard operations |
140 | | pub const QUERY_TIMEOUT: Duration = Duration::from_millis(1000); |
141 | | |
142 | | /// Default connection timeout |
143 | | pub const CONNECTION_TIMEOUT: Duration = Duration::from_millis(100); |
144 | | |
145 | | /// Default pool acquire timeout |
146 | | pub const ACQUIRE_TIMEOUT: Duration = Duration::from_millis(50); |
147 | | |
148 | | /// Default connection lifetime (1 hour) |
149 | | pub const CONNECTION_LIFETIME: Duration = Duration::from_secs(3600); |
150 | | |
151 | | /// Default idle timeout (5 minutes) |
152 | | pub const IDLE_TIMEOUT: Duration = Duration::from_secs(300); |
153 | | |
154 | | /// Default pool size |
155 | | pub const DEFAULT_POOL_SIZE: u32 = 20; |
156 | | |
157 | | /// Maximum pool size |
158 | | pub const MAX_POOL_SIZE: u32 = 100; |
159 | | |
160 | | /// Maximum query result limit |
161 | | pub const MAX_QUERY_LIMIT: i64 = 1000; |
162 | | } |
163 | | |
164 | | /// Network and gRPC defaults |
165 | | pub mod network { |
166 | | use super::Duration; |
167 | | |
168 | | /// Default connect timeout for gRPC clients |
169 | | pub const GRPC_CONNECT_TIMEOUT: Duration = Duration::from_secs(5); |
170 | | |
171 | | /// Default request timeout for gRPC |
172 | | pub const GRPC_REQUEST_TIMEOUT: Duration = Duration::from_secs(10); |
173 | | |
174 | | /// Default keep-alive interval |
175 | | pub const KEEP_ALIVE_INTERVAL: Duration = Duration::from_secs(30); |
176 | | |
177 | | /// Keep-alive timeout |
178 | | pub const KEEP_ALIVE_TIMEOUT: Duration = Duration::from_secs(5); |
179 | | |
180 | | /// Maximum concurrent connections |
181 | | pub const MAX_CONCURRENT_CONNECTIONS: u32 = 100; |
182 | | |
183 | | /// HTTP/2 initial stream window size |
184 | | pub const INITIAL_STREAM_WINDOW_SIZE: u32 = 65535; |
185 | | |
186 | | /// HTTP/2 initial connection window size |
187 | | pub const INITIAL_CONNECTION_WINDOW_SIZE: u32 = 1048576; |
188 | | } |
189 | | |
190 | | /// Retry and recovery defaults |
191 | | pub mod retry { |
192 | | use super::Duration; |
193 | | |
194 | | /// Initial delay for exponential backoff |
195 | | pub const INITIAL_RETRY_DELAY: Duration = Duration::from_millis(100); |
196 | | |
197 | | /// Maximum delay for exponential backoff |
198 | | pub const MAX_RETRY_DELAY: Duration = Duration::from_secs(30); |
199 | | |
200 | | /// Maximum retry attempts for critical operations |
201 | | pub const MAX_RETRY_ATTEMPTS: u32 = 3; |
202 | | |
203 | | /// Backoff multiplier for exponential backoff |
204 | | pub const BACKOFF_MULTIPLIER: f32 = 1.5; |
205 | | |
206 | | /// Maximum total duration for retry attempts |
207 | | pub const MAX_TOTAL_RETRY_DURATION: Duration = Duration::from_secs(60); |
208 | | } |
209 | | |
210 | | /// Health check and monitoring intervals |
211 | | pub mod monitoring { |
212 | | use super::Duration; |
213 | | |
214 | | /// Default health check interval |
215 | | pub const HEALTH_CHECK_INTERVAL: Duration = Duration::from_secs(30); |
216 | | |
217 | | /// Default metrics collection interval |
218 | | pub const METRICS_COLLECTION_INTERVAL: Duration = Duration::from_secs(10); |
219 | | |
220 | | /// Default log flush interval |
221 | | pub const LOG_FLUSH_INTERVAL: Duration = Duration::from_secs(5); |
222 | | |
223 | | /// Circuit breaker check interval |
224 | | pub const CIRCUIT_BREAKER_CHECK_INTERVAL: Duration = Duration::from_millis(100); |
225 | | |
226 | | /// Kill switch session timeout (5 minutes) |
227 | | pub const KILL_SWITCH_SESSION_TIMEOUT: Duration = Duration::from_secs(300); |
228 | | } |
229 | | |
230 | | /// Event processing defaults |
231 | | pub mod events { |
232 | | use super::Duration; |
233 | | |
234 | | /// Event batch timeout |
235 | | pub const BATCH_TIMEOUT: Duration = Duration::from_millis(100); |
236 | | |
237 | | /// Event batch size |
238 | | pub const BATCH_SIZE: usize = 100; |
239 | | |
240 | | /// Event retry delay |
241 | | pub const RETRY_DELAY: Duration = Duration::from_millis(50); |
242 | | |
243 | | /// Maximum event backlog before applying backpressure |
244 | | pub const MAX_EVENT_BACKLOG: usize = 10000; |
245 | | |
246 | | /// Maximum span buffer size for tracing |
247 | | pub const MAX_SPAN_BUFFER_SIZE: usize = 100_000; |
248 | | |
249 | | /// Span export batch size |
250 | | pub const SPAN_EXPORT_BATCH_SIZE: usize = 1000; |
251 | | } |
252 | | |
253 | | /// ML model constants |
254 | | pub mod ml { |
255 | | use super::Duration; |
256 | | |
257 | | /// Maximum GPU batch size |
258 | | pub const MAX_GPU_BATCH_SIZE: usize = 8192; |
259 | | |
260 | | /// Maximum CPU batch size |
261 | | pub const MAX_CPU_BATCH_SIZE: usize = 1024; |
262 | | |
263 | | /// Default model cache cleanup interval (1 hour) |
264 | | pub const MODEL_CACHE_CLEANUP_INTERVAL: Duration = Duration::from_secs(3600); |
265 | | |
266 | | /// Default model health check interval (30 seconds) |
267 | | pub const MODEL_HEALTH_CHECK_INTERVAL: Duration = Duration::from_secs(30); |
268 | | |
269 | | /// Model deployment stage timeout (5 minutes) |
270 | | pub const DEPLOYMENT_STAGE_TIMEOUT: Duration = Duration::from_secs(300); |
271 | | |
272 | | /// Model deployment total timeout (30 minutes) |
273 | | pub const DEPLOYMENT_TOTAL_TIMEOUT: Duration = Duration::from_secs(1800); |
274 | | |
275 | | /// Model validation scan timeout (10 minutes) |
276 | | pub const VALIDATION_SCAN_TIMEOUT: Duration = Duration::from_secs(600); |
277 | | |
278 | | /// Canary deployment duration (5 minutes) |
279 | | pub const CANARY_DURATION: Duration = Duration::from_secs(300); |
280 | | |
281 | | /// Model rollback timeout (1 minute) |
282 | | pub const ROLLBACK_TIMEOUT: Duration = Duration::from_secs(60); |
283 | | |
284 | | /// Drift detection check interval (5 minutes) |
285 | | pub const DRIFT_CHECK_INTERVAL: Duration = Duration::from_secs(300); |
286 | | |
287 | | /// Drift detection warning threshold |
288 | | pub const DRIFT_WARNING_THRESHOLD: f64 = 0.05; |
289 | | |
290 | | /// Maximum recommendation age for Kelly sizing (1 minute) |
291 | | pub const MAX_KELLY_RECOMMENDATION_AGE: Duration = Duration::from_secs(60); |
292 | | |
293 | | /// Kelly sizing cache TTL (5 minutes) |
294 | | pub const KELLY_CACHE_TTL: Duration = Duration::from_secs(300); |
295 | | } |
296 | | |
297 | | /// Safety system defaults |
298 | | pub mod safety { |
299 | | use super::Duration; |
300 | | |
301 | | /// Safety check timeout for production (5ms) |
302 | | pub const PRODUCTION_SAFETY_CHECK_TIMEOUT: Duration = Duration::from_millis(5); |
303 | | |
304 | | /// Safety check timeout for development (50ms) |
305 | | pub const DEVELOPMENT_SAFETY_CHECK_TIMEOUT: Duration = Duration::from_millis(50); |
306 | | |
307 | | /// Auto-recovery delay for production (30 minutes) |
308 | | pub const PRODUCTION_AUTO_RECOVERY_DELAY: Duration = Duration::from_secs(1800); |
309 | | |
310 | | /// Auto-recovery delay for development (1 minute) |
311 | | pub const DEVELOPMENT_AUTO_RECOVERY_DELAY: Duration = Duration::from_secs(60); |
312 | | |
313 | | /// Loss check interval for production (5 seconds) |
314 | | pub const PRODUCTION_LOSS_CHECK_INTERVAL: Duration = Duration::from_secs(5); |
315 | | |
316 | | /// Loss check interval for development (30 seconds) |
317 | | pub const DEVELOPMENT_LOSS_CHECK_INTERVAL: Duration = Duration::from_secs(30); |
318 | | |
319 | | /// Position check interval for production (2 seconds) |
320 | | pub const PRODUCTION_POSITION_CHECK_INTERVAL: Duration = Duration::from_secs(2); |
321 | | |
322 | | /// Position check interval for development (15 seconds) |
323 | | pub const DEVELOPMENT_POSITION_CHECK_INTERVAL: Duration = Duration::from_secs(15); |
324 | | |
325 | | /// Memory check interval |
326 | | pub const MEMORY_CHECK_INTERVAL: Duration = Duration::from_secs(1); |
327 | | |
328 | | /// Circuit breaker trip cooldown (30 seconds) |
329 | | pub const CIRCUIT_BREAKER_COOLDOWN: Duration = Duration::from_secs(30); |
330 | | } |
331 | | |
332 | | /// Time conversion constants |
333 | | pub mod time { |
334 | | /// Nanoseconds per microsecond |
335 | | pub const NANOS_PER_MICRO: u64 = 1_000; |
336 | | |
337 | | /// Nanoseconds per millisecond |
338 | | pub const NANOS_PER_MILLI: u64 = 1_000_000; |
339 | | |
340 | | /// Nanoseconds per second |
341 | | pub const NANOS_PER_SECOND: u64 = 1_000_000_000; |
342 | | |
343 | | /// Microseconds per second |
344 | | pub const MICROS_PER_SECOND: u64 = 1_000_000; |
345 | | |
346 | | /// Milliseconds per second |
347 | | pub const MILLIS_PER_SECOND: u64 = 1_000; |
348 | | |
349 | | /// Seconds per minute |
350 | | pub const SECONDS_PER_MINUTE: u64 = 60; |
351 | | |
352 | | /// Seconds per hour |
353 | | pub const SECONDS_PER_HOUR: u64 = 3600; |
354 | | |
355 | | /// Seconds per day |
356 | | pub const SECONDS_PER_DAY: u64 = 86400; |
357 | | |
358 | | /// Trading days per year |
359 | | pub const TRADING_DAYS_PER_YEAR: usize = 252; |
360 | | } |
361 | | |
362 | | /// Financial constants |
363 | | pub mod financial { |
364 | | /// Basis points per unit |
365 | | pub const BASIS_POINTS_PER_UNIT: u32 = 10_000; |
366 | | |
367 | | /// Cents per dollar |
368 | | pub const CENTS_PER_DOLLAR: u32 = 100; |
369 | | |
370 | | /// Default profit target in basis points (1%) |
371 | | pub const DEFAULT_PROFIT_TARGET_BPS: u32 = 100; |
372 | | |
373 | | /// Default stop loss in basis points (0.5%) |
374 | | pub const DEFAULT_STOP_LOSS_BPS: u32 = 50; |
375 | | |
376 | | /// Minimum return threshold in basis points |
377 | | pub const MIN_RETURN_THRESHOLD_BPS: i32 = 5; |
378 | | |
379 | | /// Price scaling factor (6 decimal places) |
380 | | pub const PRICE_SCALE: i64 = 1_000_000; |
381 | | |
382 | | /// Quantity scaling factor (6 decimal places) |
383 | | pub const QUANTITY_SCALE: i64 = 1_000_000; |
384 | | |
385 | | /// Money scaling factor (6 decimal places) |
386 | | pub const MONEY_SCALE: i64 = 1_000_000; |
387 | | |
388 | | /// Unified scaling factor for all financial operations |
389 | | pub const UNIFIED_SCALE_FACTOR: i64 = 1_000_000; |
390 | | |
391 | | /// ML precision factor (8 decimal places) |
392 | | pub const PRECISION_FACTOR: i64 = 100_000_000; |
393 | | |
394 | | /// VPIN precision factor (4 decimal places) |
395 | | pub const VPIN_PRECISION_FACTOR: i64 = 10_000; |
396 | | } |
397 | | |
398 | | /// Validation limits |
399 | | pub mod limits { |
400 | | /// Maximum symbol length |
401 | | pub const MAX_SYMBOL_LENGTH: usize = 12; |
402 | | |
403 | | /// Maximum account ID length |
404 | | pub const MAX_ACCOUNT_ID_LENGTH: usize = 32; |
405 | | |
406 | | /// Maximum description length |
407 | | pub const MAX_DESCRIPTION_LENGTH: usize = 256; |
408 | | |
409 | | /// Maximum metadata key length |
410 | | pub const MAX_METADATA_KEY_LENGTH: usize = 64; |
411 | | |
412 | | /// Maximum metadata value length |
413 | | pub const MAX_METADATA_VALUE_LENGTH: usize = 512; |
414 | | |
415 | | /// Maximum metadata entries |
416 | | pub const MAX_METADATA_ENTRIES: usize = 100; |
417 | | |
418 | | /// Maximum price value |
419 | | pub const MAX_PRICE: f64 = 1_000_000.0; |
420 | | |
421 | | /// Minimum price value |
422 | | pub const MIN_PRICE: f64 = 0.000_001; |
423 | | |
424 | | /// Maximum quantity value |
425 | | pub const MAX_QUANTITY: f64 = 1_000_000_000.0; |
426 | | |
427 | | /// Minimum quantity value |
428 | | pub const MIN_QUANTITY: f64 = 0.000_001; |
429 | | |
430 | | /// Maximum leverage |
431 | | pub const MAX_LEVERAGE: f64 = 1000.0; |
432 | | |
433 | | /// Minimum leverage |
434 | | pub const MIN_LEVERAGE: f64 = 0.1; |
435 | | |
436 | | /// Maximum allocation size (1GB) |
437 | | pub const MAX_ALLOCATION_SIZE: usize = 1024 * 1024 * 1024; |
438 | | |
439 | | /// Maximum duration in milliseconds (24 hours) |
440 | | pub const MAX_DURATION_MILLIS: u64 = 24 * 60 * 60 * 1000; |
441 | | } |
442 | | |
443 | | /// Hardware alignment constants |
444 | | pub mod hardware { |
445 | | /// CPU cache line size |
446 | | pub const CACHE_LINE_SIZE: usize = 64; |
447 | | |
448 | | /// SIMD alignment for AVX2 |
449 | | pub const SIMD_ALIGNMENT: usize = 32; |
450 | | |
451 | | /// Page size (4KB) |
452 | | pub const PAGE_SIZE: usize = 4096; |
453 | | } |
454 | | |
455 | | #[cfg(test)] |
456 | | mod tests { |
457 | | use super::*; |
458 | | |
459 | | #[test] |
460 | 1 | fn test_breach_thresholds_ordered() { |
461 | 1 | assert!(risk::BREACH_WARNING_PCT < risk::BREACH_SOFT_PCT); |
462 | 1 | assert!(risk::BREACH_SOFT_PCT < risk::BREACH_HARD_PCT); |
463 | 1 | assert!(risk::BREACH_HARD_PCT < risk::BREACH_CRITICAL_PCT); |
464 | 1 | } |
465 | | |
466 | | #[test] |
467 | 1 | fn test_var_z_scores_ordered() { |
468 | 1 | assert!(var::Z_SCORE_P90 < var::Z_SCORE_P95); |
469 | 1 | assert!(var::Z_SCORE_P95 < var::Z_SCORE_P97_5); |
470 | 1 | assert!(var::Z_SCORE_P97_5 < var::Z_SCORE_P99); |
471 | 1 | assert!(var::Z_SCORE_P99 < var::Z_SCORE_P99_9); |
472 | 1 | } |
473 | | |
474 | | #[test] |
475 | 1 | fn test_time_conversions() { |
476 | 1 | assert_eq!(time::NANOS_PER_MICRO * 1000, time::NANOS_PER_MILLI); |
477 | 1 | assert_eq!(time::NANOS_PER_MILLI * 1000, time::NANOS_PER_SECOND); |
478 | 1 | assert_eq!(time::MICROS_PER_SECOND * 1000, time::NANOS_PER_SECOND); |
479 | 1 | } |
480 | | |
481 | | #[test] |
482 | 1 | fn test_financial_scales_consistent() { |
483 | 1 | assert_eq!(financial::PRICE_SCALE, financial::UNIFIED_SCALE_FACTOR); |
484 | 1 | assert_eq!(financial::QUANTITY_SCALE, financial::UNIFIED_SCALE_FACTOR); |
485 | 1 | assert_eq!(financial::MONEY_SCALE, financial::UNIFIED_SCALE_FACTOR); |
486 | 1 | } |
487 | | } |