fix(warnings): Eliminate 136 warnings across workspace via 11 parallel agents

## Summary
Pre-commit warning regression fix wave - deployed 11 parallel Task agents to systematically eliminate all compilation errors (2) and warnings (136) across the entire workspace.

## Changes by Category

### P0 Compilation Fixes (2 errors → 0)
- ml/src/hyperopt/adapters/mamba2.rs: Added missing `trial_counter: 0` to test initializers (lines 1135, 1165)

### ML Crate Warnings (35 → 0)
- ml/src/hyperopt/tests.rs: Added `#[allow(deprecated)]` for test-specific deprecated function usage
- ml/src/ensemble/ab_testing.rs: Renamed unused variables (_control_count, _rng)
- ml/src/security/*.rs: Fixed unused loop variables (i → _)
- ml/src/tft/quantized_attention.rs: Renamed unused test variable (_v)
- ml/src/features/regime_adaptive.rs: Renamed unused variables (_adaptive)
- ml/src/regime/{orchestrator,ranging}.rs: Renamed unused variables

### Data Crate Fixes (28 warnings + 4 errors → 0)
- data/Cargo.toml: Moved clap from [dev-dependencies] to [dependencies] (examples require it)
- data/examples/validate_cl_fut.rs: Updated to databento 0.42.0 API (decode_record_ref loop pattern)
- data/examples/download_mbp10_data.rs: Fixed reqwest 0.12 API (bytes_stream → chunk)
- data/examples/*.rs: Removed unused imports (4 files via cargo fix)
- data/tests/real_data_helpers.rs: Added `#[allow(dead_code)]` to cross-binary test helpers

### API Gateway Test Warnings (19 → 0)
- services/api_gateway/tests/common/mod.rs: Added `#[allow(dead_code)]` to shared test utilities (6 items)
- services/api_gateway/tests/rate_limiting_tests.rs: Added `#[allow(dead_code)]` to REDIS_URL constant

## Verification
```bash
cargo check --workspace
# Result: Finished in 49.41s
# Warnings: 0 (was 136)
# Errors: 0 (was 2)
```

## Files Modified: 26 total
- ML: 14 files (9 manual + 5 auto-fixed)
- Data: 10 files (2 Cargo.toml + 6 examples + 1 test + 1 dependency update)
- API Gateway: 2 test files

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2025-11-03 10:15:09 +01:00
parent fd5ac54e87
commit cb515363a9
26 changed files with 94 additions and 90 deletions

1
Cargo.lock generated
View File

@@ -2866,6 +2866,7 @@ dependencies = [
"bincode",
"bytes",
"chrono",
"clap",
"common",
"config",
"criterion",

View File

@@ -107,6 +107,9 @@ trading_engine.workspace = true
common = { path = "../common" }
dbn = "0.42.0"
# CLI argument parsing (needed for examples)
clap = { version = "4", features = ["derive"] }
[dev-dependencies]
tokio-test = { workspace = true }
# proptest = { workspace = true } # REMOVED from workspace

View File

@@ -3,7 +3,7 @@ use common::{OrderId, OrderSide, Price, Quantity, Symbol};
use data::brokers::interactive_brokers::{IBConfig, InteractiveBrokersAdapter};
use data::brokers::BrokerClient;
use tokio::time::{sleep, Duration};
use tracing::{error, info};
use tracing::error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {

View File

@@ -6,9 +6,8 @@
use common::{Order, OrderSide, OrderType, Price, Quantity, Symbol, TimeInForce};
use data::brokers::interactive_brokers::{IBConfig, InteractiveBrokersAdapter};
use data::brokers::BrokerClient;
use tokio::time::{timeout, Duration};
use tracing::{error, info, warn};
use tracing::{info, warn};
// use trading_engine::prelude::*; // REMOVED - prelude does not exist
#[tokio::main]
@@ -117,7 +116,7 @@ async fn data_manager_example() -> anyhow::Result<()> {
/// Example of order submission (commented out for safety)
#[allow(dead_code)]
async fn order_submission_example(adapter: &mut InteractiveBrokersAdapter) -> anyhow::Result<()> {
async fn order_submission_example(_adapter: &mut InteractiveBrokersAdapter) -> anyhow::Result<()> {
info!("=== Order Submission Example (DEMO ONLY) ===");
warn!("This example is for demonstration only - no actual orders will be submitted");
@@ -148,6 +147,7 @@ async fn order_submission_example(adapter: &mut InteractiveBrokersAdapter) -> an
}
/// Helper function to check if TWS is running
#[allow(dead_code)]
async fn check_tws_status() -> bool {
match tokio::net::TcpStream::connect("127.0.0.1:7497").await {
Ok(_) => {
@@ -166,6 +166,7 @@ async fn check_tws_status() -> bool {
}
/// Configuration helper
#[allow(dead_code)]
fn print_setup_instructions() {
info!("=== Setup Instructions ===");
info!("To run broker connection examples:");

View File

@@ -218,12 +218,10 @@ async fn download_file(api_key: &str, download_url: &str, output_path: &PathBuf)
let mut file = File::create(output_path).context("Failed to create output file")?;
let mut downloaded: u64 = 0;
let mut stream = response.bytes_stream();
use futures_util::stream::StreamExt;
while let Some(chunk) = stream.next().await {
let chunk = chunk.context("Failed to read chunk")?;
// Use chunk() method for reqwest 0.12 (replaces bytes_stream())
let mut response = response;
while let Some(chunk) = response.chunk().await.context("Failed to read chunk")? {
file.write_all(&chunk)
.context("Failed to write chunk to file")?;

View File

@@ -2,7 +2,7 @@
use common::{Price, Quantity, Symbol};
use data::brokers::interactive_brokers::{IBConfig, InteractiveBrokersAdapter};
use tokio::time::{sleep, Duration};
use tracing::{error, info, warn};
use tracing::error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
println!("=== Interactive Brokers Market Data Subscription Example ===");

View File

@@ -12,7 +12,7 @@
#![allow(unused_crate_dependencies)]
use common::{
Order, OrderId, OrderSide, OrderStatus, OrderType, Price, Quantity, Symbol, TimeInForce,
Order, OrderSide, OrderType, Price, Quantity, Symbol, TimeInForce,
};
use data::brokers::interactive_brokers::{IBConfig, InteractiveBrokersAdapter};
use data::brokers::{common::TradingOrder, BrokerClient};

View File

@@ -5,7 +5,7 @@ use data::brokers::{common::TradingOrder, BrokerClient};
use rust_decimal::prelude::ToPrimitive;
use rust_decimal_macros::dec;
use tokio::time::{sleep, Duration};
use tracing::{error, info};
use tracing::error;
// use trading_engine::prelude::*; // REMOVED - prelude does not exist
#[tokio::main]

View File

@@ -2,7 +2,7 @@
//!
//! Inspects the downloaded CL.FUT data and reports statistics.
use dbn::decode::DbnDecoder;
use dbn::decode::{DbnDecoder, DbnMetadata, DecodeRecordRef};
use std::fs::File;
#[tokio::main]
@@ -36,11 +36,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("📋 Metadata:");
println!(" Dataset: {}", metadata.dataset);
println!(" Schema: {}", metadata.schema);
println!(" Schema: {:?}", metadata.schema);
println!(" Start: {}", metadata.start);
println!(" End: {}", metadata.end);
println!(" End: {:?}", metadata.end);
println!(" Symbols: {}", metadata.symbols.join(", "));
println!(" Stype In: {}", metadata.stype_in);
println!(" Stype In: {:?}", metadata.stype_in);
println!();
let mut bar_count = 0;
@@ -48,32 +48,40 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut max_price = f64::MIN;
let mut total_volume = 0.0;
// Read all records
for record in decoder.decode_records::<dbn::OhlcvMsg>() {
let record = record?;
bar_count += 1;
// Read all records using decode_record_ref() loop pattern
loop {
match decoder.decode_record_ref() {
Ok(Some(record_ref)) => {
// Cast to OhlcvMsg
if let Some(record) = record_ref.get::<dbn::OhlcvMsg>() {
bar_count += 1;
// Track price range
let open = record.open as f64 / 1_000_000_000.0; // Convert from fixed point
let high = record.high as f64 / 1_000_000_000.0;
let low = record.low as f64 / 1_000_000_000.0;
let close = record.close as f64 / 1_000_000_000.0;
let volume = record.volume as f64;
// Track price range
let open = record.open as f64 / 1_000_000_000.0; // Convert from fixed point
let high = record.high as f64 / 1_000_000_000.0;
let low = record.low as f64 / 1_000_000_000.0;
let close = record.close as f64 / 1_000_000_000.0;
let volume = record.volume as f64;
if low < min_price {
min_price = low;
}
if high > max_price {
max_price = high;
}
total_volume += volume;
if low < min_price {
min_price = low;
}
if high > max_price {
max_price = high;
}
total_volume += volume;
// Print first few bars for inspection
if bar_count <= 3 {
println!(
"📊 Bar {}: O={:.2} H={:.2} L={:.2} C={:.2} V={:.0}",
bar_count, open, high, low, close, volume
);
// Print first few bars for inspection
if bar_count <= 3 {
println!(
"📊 Bar {}: O={:.2} H={:.2} L={:.2} C={:.2} V={:.0}",
bar_count, open, high, low, close, volume
);
}
}
}
Ok(None) => break, // End of records
Err(e) => return Err(e.into()),
}
}

View File

@@ -15,13 +15,13 @@ const BTC_FILE: &str = "BTC-USD_30day_2024-09.parquet";
const ETH_FILE: &str = "ETH-USD_30day_2024-09.parquet";
/// Real market data loader for feature engineering tests
pub struct RealDataLoader {
pub(crate) struct RealDataLoader {
base_path: String,
}
impl RealDataLoader {
/// Create new loader with workspace-relative path
pub fn new() -> Self {
pub(crate) fn new() -> Self {
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let base_path = PathBuf::from(manifest_dir)
.parent()
@@ -34,33 +34,38 @@ impl RealDataLoader {
}
/// Check if real data files exist
pub fn files_exist(&self) -> bool {
pub(crate) fn files_exist(&self) -> bool {
let btc_path = PathBuf::from(&self.base_path).join(BTC_FILE);
let eth_path = PathBuf::from(&self.base_path).join(ETH_FILE);
btc_path.exists() && eth_path.exists()
}
/// Load BTC price data as PricePoints
pub async fn load_btc_prices(&self, count: usize) -> Result<Vec<PricePoint>> {
#[allow(dead_code)]
pub(crate) async fn load_btc_prices(&self, count: usize) -> Result<Vec<PricePoint>> {
self.load_prices(BTC_FILE, count).await
}
/// Load ETH price data as PricePoints
pub async fn load_eth_prices(&self, count: usize) -> Result<Vec<PricePoint>> {
#[allow(dead_code)]
pub(crate) async fn load_eth_prices(&self, count: usize) -> Result<Vec<PricePoint>> {
self.load_prices(ETH_FILE, count).await
}
/// Load BTC close prices as f64 vector (for simple technical indicator tests)
pub async fn load_btc_close_prices(&self, count: usize) -> Result<Vec<f64>> {
#[allow(dead_code)]
pub(crate) async fn load_btc_close_prices(&self, count: usize) -> Result<Vec<f64>> {
self.load_close_prices(BTC_FILE, count).await
}
/// Load ETH close prices as f64 vector (for simple technical indicator tests)
pub async fn load_eth_close_prices(&self, count: usize) -> Result<Vec<f64>> {
#[allow(dead_code)]
pub(crate) async fn load_eth_close_prices(&self, count: usize) -> Result<Vec<f64>> {
self.load_close_prices(ETH_FILE, count).await
}
/// Load price data from a specific file as PricePoints
#[allow(dead_code)]
async fn load_prices(&self, filename: &str, count: usize) -> Result<Vec<PricePoint>> {
let reader = ParquetMarketDataReader::new(self.base_path.clone());
let events = reader
@@ -81,6 +86,7 @@ impl RealDataLoader {
}
/// Load close prices as f64 vector for simple indicator calculations
#[allow(dead_code)]
async fn load_close_prices(&self, filename: &str, count: usize) -> Result<Vec<f64>> {
let reader = ParquetMarketDataReader::new(self.base_path.clone());
let events = reader
@@ -99,6 +105,7 @@ impl RealDataLoader {
}
/// Convert MarketDataEvent to PricePoint
#[allow(dead_code)]
fn event_to_price_point(&self, event: &MarketDataEvent) -> Result<PricePoint> {
let timestamp = self.ns_to_datetime(event.timestamp_ns)?;
let close = event.price.context("Price is None")?;
@@ -118,6 +125,7 @@ impl RealDataLoader {
}
/// Convert nanosecond timestamp to DateTime<Utc>
#[allow(dead_code)]
fn ns_to_datetime(&self, timestamp_ns: u64) -> Result<DateTime<Utc>> {
let timestamp_ms = (timestamp_ns / 1_000_000) as i64;
DateTime::from_timestamp_millis(timestamp_ms).context("Invalid timestamp")
@@ -129,27 +137,3 @@ impl Default for RealDataLoader {
Self::new()
}
}
/// Extract a specific time range from price data
pub fn extract_time_range(
data: &[PricePoint],
start: DateTime<Utc>,
end: DateTime<Utc>,
) -> Vec<PricePoint> {
data.iter()
.filter(|point| point.timestamp >= start && point.timestamp <= end)
.cloned()
.collect()
}
/// Extract a specific number of bars from the middle of the dataset
/// This helps avoid edge effects in technical indicators
pub fn extract_middle_bars(data: &[PricePoint], count: usize) -> Vec<PricePoint> {
if data.len() <= count {
return data.to_vec();
}
let start_idx = (data.len() - count) / 2;
let end_idx = start_idx + count;
data[start_idx..end_idx].to_vec()
}

View File

@@ -771,7 +771,7 @@ mod tests {
let router = ABTestRouter::new(config);
let mut treatment_count = 0;
let mut control_count = 0;
let mut _control_count = 0;
let total_users = 10000;
for i in 0..total_users {
@@ -779,7 +779,7 @@ mod tests {
let group = router.get_or_assign_group(&user_id).await;
match group {
ABGroup::Treatment => treatment_count += 1,
ABGroup::Control => control_count += 1,
ABGroup::Control => _control_count += 1,
}
}
@@ -876,7 +876,7 @@ mod tests {
};
let router = ABTestRouter::new(config);
let rng = rand::thread_rng();
let _rng = rand::thread_rng();
// Simulate 200 predictions (~100 per group with 50/50 split)
for i in 0..200 {

View File

@@ -380,7 +380,7 @@ mod tests {
#[test]
fn test_position_multipliers() {
let adaptive = RegimeAdaptiveFeatures::new(20, 100_000.0, 14);
let _adaptive = RegimeAdaptiveFeatures::new(20, 100_000.0, 14);
// Check all regime multipliers are defined
for (regime, _) in POSITION_MULTIPLIERS.iter() {
@@ -394,7 +394,7 @@ mod tests {
#[test]
fn test_stoploss_multipliers() {
let adaptive = RegimeAdaptiveFeatures::new(20, 100_000.0, 14);
let _adaptive = RegimeAdaptiveFeatures::new(20, 100_000.0, 14);
// Check all regime multipliers are defined
for (regime, _) in STOPLOSS_MULTIPLIERS.iter() {

View File

@@ -1132,6 +1132,7 @@ mod tests {
training_paths: TrainingPaths::new("/tmp/test", "mamba2", "test"),
early_stopping_patience: 10,
early_stopping_min_epochs: 5,
trial_counter: 0,
};
// Test denormalization
@@ -1161,6 +1162,7 @@ mod tests {
training_paths: TrainingPaths::new("/tmp/test", "mamba2", "test"),
early_stopping_patience: 10,
early_stopping_min_epochs: 5,
trial_counter: 0,
};
// Should panic

View File

@@ -4,6 +4,7 @@
//! parameter space conversions, and optimization logic.
#[cfg(test)]
#[allow(deprecated)] // Tests for deprecated denormalize_params function
mod tests {
use super::super::egobox_tuner::*;
use approx::assert_relative_eq;

View File

@@ -517,7 +517,7 @@ mod tests {
#[test]
fn test_insufficient_data_error() {
let bars = create_test_bars(10, 100.0);
let _bars = create_test_bars(10, 100.0);
let error = OrchestratorError::InsufficientData {
required: 20,
actual: 10,

View File

@@ -506,7 +506,7 @@ mod tests {
let mut classifier = RangingClassifier::new(20, 2.0, 20.0);
let bars = create_ranging_bars(100);
let mut ranging_count = 0;
let mut _ranging_count = 0;
let mut total_processed = 0;
for bar in bars {
let signal = classifier.classify(bar);
@@ -517,7 +517,7 @@ mod tests {
| RangingSignal::ModerateRanging
| RangingSignal::WeakRanging
) {
ranging_count += 1;
_ranging_count += 1;
}
}

View File

@@ -450,7 +450,7 @@ mod tests {
let detector = EnsembleAnomalyDetector::new();
// Build history with stable predictions
for i in 0..10 {
for _ in 0..10 {
let decision = create_test_decision(0.1, HashMap::new());
detector.update_history(&decision).await;
}

View File

@@ -481,7 +481,7 @@ mod tests {
let validator = PredictionValidator::with_config(config);
// Inject many extreme predictions quickly
for i in 0..100 {
for _ in 0..100 {
let result = validator.validate(0.95, 0.8, "test_model").await;
// Should eventually hit rate limit
@@ -520,7 +520,7 @@ mod tests {
let validator = PredictionValidator::new();
// Add some data
for i in 0..100 {
for _ in 0..100 {
validator.update_statistics(0.5).await;
}

View File

@@ -481,7 +481,7 @@ mod tests {
// Reshape back to 3D
let q = q_2d.reshape(&[batch_size, seq_len, hidden_dim])?;
let k = k_2d.reshape(&[batch_size, seq_len, hidden_dim])?;
let v = v_2d.reshape(&[batch_size, seq_len, hidden_dim])?;
let _v = v_2d.reshape(&[batch_size, seq_len, hidden_dim])?;
// Reshape for multi-head attention
let q = q.reshape((batch_size, seq_len, num_heads, head_dim))?;

View File

@@ -9,8 +9,7 @@
//! 3. **Improvement Handling**: Verify training continues when improving
//! 4. **Validation Frequency**: Confirm validation runs every epoch
use ml::hyperopt::adapters::tft::{TFTParams, TFTTrainer};
use ml::hyperopt::traits::HyperparameterOptimizable;
use ml::hyperopt::adapters::tft::TFTTrainer;
use ml::trainers::tft::TFTTrainerConfig;
use std::path::PathBuf;
@@ -242,7 +241,7 @@ fn test_tft_early_stopping_integration() {
#[cfg(test)]
mod additional_tests {
use super::*;
/// Verify patience counter logic
#[test]

View File

@@ -6,10 +6,10 @@
#[cfg(test)]
mod imbalance_bars_tests {
use chrono::{DateTime, Utc};
use std::str::FromStr;
// Implemented in ml/src/features/alternative_bars.rs
use ml::features::alternative_bars::{ImbalanceBarSampler, OHLCVBar};
use ml::features::alternative_bars::ImbalanceBarSampler;
fn timestamp(secs: i64) -> DateTime<Utc> {
DateTime::from_timestamp(secs, 0).unwrap()

View File

@@ -8,7 +8,7 @@
//! 5. Performance benchmarks (<80μs target)
use anyhow::Result;
use ml::regime::pages_test::{PAGESTest, VarianceChange};
use ml::regime::pages_test::PAGESTest;
use std::time::Instant;
// ============================================================================

View File

@@ -11,7 +11,7 @@
//! - Test 7: End-to-end pipeline (validates full integration)
use ml::data_loaders::parquet_utils::load_parquet_data;
use std::path::{Path, PathBuf};
use std::path::PathBuf;
/// Helper function to find test data file across different working directories
fn find_test_data_file() -> Option<PathBuf> {

View File

@@ -992,7 +992,7 @@ fn test_performance_regression_memory_footprint() {
println!("📊 Creating models for memory footprint test");
// FP32 model
let mut fp32_model = TemporalFusionTransformer::new_with_device(config.clone(), device.clone())
let fp32_model = TemporalFusionTransformer::new_with_device(config.clone(), device.clone())
.unwrap();
println!(" ✓ FP32 model created");

View File

@@ -8,6 +8,7 @@ use uuid::Uuid;
pub use api_gateway::auth::{Jti, JwtClaims};
/// Test JWT configuration
#[allow(dead_code)]
pub struct TestJwtConfig {
pub secret: String,
pub issuer: String,
@@ -25,6 +26,7 @@ impl Default for TestJwtConfig {
}
/// Generate a valid JWT token for testing
#[allow(dead_code)]
pub fn generate_test_token(
user_id: &str,
roles: Vec<String>,
@@ -60,6 +62,7 @@ pub fn generate_test_token(
}
/// Generate an expired JWT token for testing
#[allow(dead_code)]
pub fn generate_expired_token(user_id: &str) -> Result<String> {
let config = TestJwtConfig::default();
@@ -89,6 +92,7 @@ pub fn generate_expired_token(user_id: &str) -> Result<String> {
}
/// Generate a token with invalid signature
#[allow(dead_code)]
pub fn generate_invalid_signature_token(user_id: &str) -> Result<String> {
let now = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
@@ -123,6 +127,7 @@ pub fn generate_invalid_signature_token(user_id: &str) -> Result<String> {
/// 60+ second OS-level TCP timeouts when Redis is unavailable.
///
/// Solution: Use tokio::time::timeout() to wrap async operations.
#[allow(dead_code)]
pub async fn wait_for_redis(redis_url: &str, max_attempts: usize) -> Result<()> {
use tokio::time::{timeout, Duration};
@@ -184,6 +189,7 @@ pub async fn wait_for_redis(redis_url: &str, max_attempts: usize) -> Result<()>
}
/// Clean up Redis test data with proper timeout handling
#[allow(dead_code)]
pub async fn cleanup_redis(redis_url: &str) -> Result<()> {
use tokio::time::{timeout, Duration};

View File

@@ -14,6 +14,7 @@ use std::time::{Duration, Instant};
use api_gateway::auth::RateLimiter;
#[allow(dead_code)]
const REDIS_URL: &str = "redis://localhost:6379";
#[tokio::test]