From 1ae419d88ea97b514b3fc73d0e5858ee3e0083f0 Mon Sep 17 00:00:00 2001 From: jgrusewski Date: Sun, 22 Feb 2026 03:08:30 +0100 Subject: [PATCH] feat(trading_engine): re-enable features module, clean stale comments - Remove 6 stale "TEMPORARILY COMMENTED OUT" comments (modules already active) - Fix features/mod.rs: repair corrupted use block, fix test_utils type mismatches - Fix features/unified_extractor.rs: correct MarketTick import, safe indexing - Add Debug derives, suppress dead_code on partially-implemented fields Co-Authored-By: Claude Opus 4.6 --- trading_engine/src/features/mod.rs | 115 ++++++------------ .../src/features/unified_extractor.rs | 31 ++--- trading_engine/src/lib.rs | 9 +- 3 files changed, 56 insertions(+), 99 deletions(-) diff --git a/trading_engine/src/features/mod.rs b/trading_engine/src/features/mod.rs index 0b4039404..1c335f287 100644 --- a/trading_engine/src/features/mod.rs +++ b/trading_engine/src/features/mod.rs @@ -67,50 +67,11 @@ pub mod unified_extractor; use async_trait::async_trait; -// Re-export the main types for convenient access -// DO NOT RE-EXPORT - Use explicit imports at usage sites - // AnalystRating variant - AnalystRating, - // Base feature components - // BaseMarketFeatures variant - BaseMarketFeatures, - // BenzingaNewsData variant - BenzingaNewsData, - // BenzingaNewsFeatures variant - BenzingaNewsFeatures, - - // DQNFeatures variant - DQNFeatures, - // Data provider structures - // DatabentoBuData variant - DatabentoBuData, - // DatabentoBuFeatures variant - DatabentoBuFeatures, - // FeatureError variant - FeatureError, - - // LiquidFeatures variant - LiquidFeatures, - // MAMBAFeatures variant - MAMBAFeatures, - // NewsArticle variant - NewsArticle, - // PPOFeatures variant - PPOFeatures, - // SentimentScore variant - SentimentScore, - // TFTFeatures variant - TFTFeatures, - - // Model-specific feature sets - // TLOBFeatures variant - TLOBFeatures, - // UnifiedConfig variant - UnifiedConfig, - // UnifiedFeatureExtractor variant - UnifiedFeatureExtractor, - // UnusualOptionsActivity variant - UnusualOptionsActivity, +// Types are NOT re-exported - use explicit imports at usage sites: +// use crate::features::unified_extractor::{...}; +use unified_extractor::{ + BaseMarketFeatures, BenzingaNewsData, BenzingaNewsFeatures, DatabentoBuData, + DatabentoBuFeatures, FeatureError, UnifiedFeatureExtractor, }; /// Feature extraction result type for ergonomic error handling @@ -267,6 +228,7 @@ pub mod monitoring { } /// Performance monitor for feature extraction + #[derive(Debug)] pub struct FeatureMonitor { metrics: HashMap>, start_times: HashMap, @@ -355,33 +317,32 @@ pub mod monitoring { /// Testing utilities for feature validation #[cfg(test)] pub mod test_utils { - use super::*; - use common::*; use chrono::Utc; + use common::types::{Exchange, HftTimestamp, MarketTick, TickType}; + use common::{Price, Quantity, Symbol, TradeEvent}; + use rust_decimal_macros::dec; + use super::unified_extractor::{ + BenzingaNewsData, DatabentoBuData, NewsArticle, SentimentScore, + }; /// Create mock Databento data for testing pub fn create_mock_databento_data() -> DatabentoBuData { + let bid_price = Price::from_f64(100.50).unwrap_or(Price::ZERO); + let ask_price = Price::from_f64(100.51).unwrap_or(Price::ZERO); + let bid_qty = Quantity::from_f64(1000.0).unwrap_or(Quantity::ZERO); + let ask_qty = Quantity::from_f64(800.0).unwrap_or(Quantity::ZERO); + DatabentoBuData { order_book: vec![ - OrderBookLevel { - price: Price::from_dollars(100.50), - size: Decimal::from(1000), - side: OrderSide::Bid, - }, - OrderBookLevel { - price: Price::from_dollars(100.51), - size: Decimal::from(800), - side: OrderSide::Ask, - }, + (bid_price, bid_qty), + (ask_price, ask_qty), ], - trades: vec![Trade { - symbol: Symbol::new("AAPL"), - price: Price::from_dollars(100.505), - volume: Decimal::from(100), - timestamp: Utc::now(), - side: OrderSide::Buy, - trade_id: "T123".to_string(), - }], + trades: vec![TradeEvent::new( + "AAPL".to_string(), + dec!(100.505), + dec!(100), + Utc::now(), + ).with_trade_id("T123")], quotes: vec![], timestamp: Utc::now(), } @@ -395,12 +356,12 @@ pub mod test_utils { content: "Apple exceeded expectations...".to_string(), source: "Reuters".to_string(), timestamp: Utc::now(), - symbols: vec![Symbol::new("AAPL")], + symbols: vec![Symbol::new("AAPL".to_string())], category: "earnings".to_string(), importance: 0.8, }], sentiment_scores: vec![SentimentScore { - symbol: Symbol::new("AAPL"), + symbol: Symbol::new("AAPL".to_string()), score: 0.6, confidence: 0.9, timestamp: Utc::now(), @@ -412,24 +373,24 @@ pub mod test_utils { } /// Create mock historical market data + #[allow(clippy::unwrap_used)] pub fn create_mock_historical_data() -> Vec { - let base_price = 100.0; + let base_price = 100.0_f64; let mut data = Vec::new(); - for i in 0..1000 { + for i in 0..1000_u64 { let price_change = (i as f64 / 100.0).sin() * 0.01; - let price = Price::from_dollars(base_price + price_change); - let volume = Decimal::from(1000 + (i % 500) as i64); + let price = Price::from_f64(base_price + price_change).unwrap_or(Price::ZERO); + let size = Quantity::from_f64(1000.0 + (i % 500) as f64).unwrap_or(Quantity::ZERO); data.push(MarketTick { - symbol: Symbol::new("AAPL"), + symbol: Symbol::new("AAPL".to_string()), price, - volume, - timestamp: Utc::now() - chrono::Duration::seconds(1000 - i as i64), - bid: Some(price - Price::from_cents(1)), - ask: Some(price + Price::from_cents(1)), - bid_size: Some(volume), - ask_size: Some(volume), + size, + timestamp: HftTimestamp::now().unwrap(), + tick_type: TickType::Trade, + exchange: Exchange::NASDAQ, + sequence_number: i, }); } diff --git a/trading_engine/src/features/unified_extractor.rs b/trading_engine/src/features/unified_extractor.rs index 06dc03ac1..016d0079e 100644 --- a/trading_engine/src/features/unified_extractor.rs +++ b/trading_engine/src/features/unified_extractor.rs @@ -22,7 +22,8 @@ use thiserror::Error; use tracing::{debug, error}; use crate::simd::SimdMarketDataOps; -use common::{Price, Volume, Symbol, MarketTick, Quantity, TradeEvent, QuoteEvent}; +use common::types::MarketTick; +use common::{Price, Quantity, QuoteEvent, Symbol, TradeEvent, Volume}; /// Feature extraction errors #[derive(Error, Debug)] @@ -455,6 +456,8 @@ impl Default for UnifiedConfig { } /// The unified feature extractor - SINGLE SOURCE OF TRUTH +#[derive(Debug)] +#[allow(dead_code)] pub struct UnifiedFeatureExtractor { config: UnifiedConfig, simd_processor: Option, @@ -762,7 +765,11 @@ impl UnifiedFeatureExtractor { }); } - let latest = historical_data.last().unwrap(); + let latest = historical_data.last().ok_or_else(|| FeatureError::InsufficientData { + feature: "base_features".to_owned(), + required: 1, + available: 0, + })?; // Calculate returns using SIMD optimization let returns_1m = self.calculate_returns(historical_data, Duration::from_secs(60))?; @@ -804,7 +811,7 @@ impl UnifiedFeatureExtractor { returns_1h, volatility_1h, volatility_4h, - volume: Volume::new(latest.size.value() as f64).unwrap_or(Volume::ZERO), + volume: Volume::from_f64(latest.size.to_f64()).unwrap_or(Volume::ZERO), volume_ratio_1h, vwap_deviation, volume_imbalance, @@ -971,9 +978,9 @@ impl UnifiedFeatureExtractor { // Calculate log returns let mut returns = Vec::with_capacity(data.len() - 1); - for i in 1..data.len() { - let curr_price = data[i].price; - let prev_price = data[i - 1].price; + for window in data.windows(2) { + let prev_price = window.first().map(|t| t.price).unwrap_or(Price::ZERO); + let curr_price = window.last().map(|t| t.price).unwrap_or(Price::ZERO); if prev_price.to_f64() > 0.0 && curr_price.to_f64() > 0.0 { returns.push((curr_price.to_f64() / prev_price.to_f64()).ln()); @@ -1036,15 +1043,13 @@ impl UnifiedFeatureExtractor { length: usize, ) -> Result, FeatureError> { let mut sequence = Vec::with_capacity(length); - let data_len = data.len(); for i in 0..length { - if i < data_len { - sequence.push(data[i].price.to_f64()); + if let Some(tick) = data.get(i) { + sequence.push(tick.price.to_f64()); } else { sequence.push(0.0); } } - // Ok variant Ok(sequence) } @@ -1054,15 +1059,13 @@ impl UnifiedFeatureExtractor { length: usize, ) -> Result, FeatureError> { let mut sequence = Vec::with_capacity(length); - let data_len = data.len(); for i in 0..length { - if i < data_len { - sequence.push(data[i].size.to_f64()); + if let Some(tick) = data.get(i) { + sequence.push(tick.size.to_f64()); } else { sequence.push(0.0); } } - // Ok variant Ok(sequence) } diff --git a/trading_engine/src/lib.rs b/trading_engine/src/lib.rs index e402e22b5..085ed65af 100644 --- a/trading_engine/src/lib.rs +++ b/trading_engine/src/lib.rs @@ -96,7 +96,6 @@ extern crate log as _; extern crate zeroize as _; /// Core trading types with optimized memory layout and financial safety -// TEMPORARILY COMMENTED OUT: Testing for compilation hang - causes circular dependencies pub mod types; /// RDTSC-based ultra-low latency timing (14ns precision) @@ -127,20 +126,17 @@ pub mod lockfree; pub mod small_batch_optimizer; /// High-performance event processing pipeline -// TEMPORARILY COMMENTED OUT: Testing for compilation hang pub mod events; /// Configuration management system // Configuration is provided by the config crate /// Persistence layer with PostgreSQL, `InfluxDB`, Redis, and `ClickHouse` -// TEMPORARILY COMMENTED OUT: Testing for compilation hang pub mod persistence; /// Prelude module for convenient imports pub mod prelude; /// Repository pattern abstractions for data access -// TEMPORARILY COMMENTED OUT: Testing for compilation hang pub mod repositories; /// Core trading operations with comprehensive metrics @@ -151,16 +147,13 @@ pub mod trading_operations; // Keep only working core trading_operations module /// Core trading engine and business logic -// TEMPORARILY COMMENTED OUT: Testing for compilation hang pub mod trading; /// Broker connectivity and routing -// TEMPORARILY COMMENTED OUT: Testing for compilation hang pub mod brokers; /// Unified feature extraction system - prevents training/serving skew -// TEMPORARILY COMMENTED OUT: features module may have dependency issues -// pub mod features; +pub mod features; /// Comprehensive performance benchmarks for `HFT` system validation #[cfg(feature = "benchmarks")] pub mod comprehensive_performance_benchmarks;