🔧 Fix database crate duplicate name errors (E0252)
- Removed duplicate re-exports in database/src/lib.rs - Types are already imported at module level, no need to re-export - Fixes compilation error that was blocking workspace build
This commit is contained in:
@@ -248,9 +248,8 @@ pub struct RegimePerformanceTracker {
|
||||
regime_performance: HashMap<MarketRegime, RegimePerformance>,
|
||||
/// Detection accuracy tracking
|
||||
detection_accuracy: VecDeque<AccuracyMeasurement>,
|
||||
/// False positive tracking
|
||||
|
||||
}
|
||||
/// False positive tracking metrics
|
||||
false_positives: VecDeque<FalsePositiveRecord>, }
|
||||
|
||||
/// Performance metrics for a specific regime
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
|
||||
@@ -60,6 +60,8 @@ use crate::transaction::{DatabaseTransaction, TransactionManager, TransactionSta
|
||||
use crate::query::QueryBuilder;
|
||||
use config::database::DatabaseConfig;
|
||||
|
||||
// Re-export commonly used types - Already imported above, no need to re-export
|
||||
|
||||
// serde imports removed - not needed
|
||||
use sqlx::postgres::PgRow;
|
||||
use sqlx::FromRow;
|
||||
|
||||
@@ -302,7 +302,7 @@ impl FeatureRepository {
|
||||
let conn = self.pool.get().await?;
|
||||
|
||||
// Using sqlx query builder pattern
|
||||
let query =
|
||||
let (query, params) =
|
||||
if let Some(version) = feature_set_version {
|
||||
(r#"SELECT features, last_updated, expires_at
|
||||
FROM ml_feature_cache
|
||||
@@ -347,40 +347,37 @@ impl FeatureRepository {
|
||||
WHERE feature_set_id = $1
|
||||
"#.to_string();
|
||||
|
||||
// Using sqlx query builder pattern instead of raw parameters
|
||||
// Using sqlx query builder pattern
|
||||
let mut query_builder = sqlx::QueryBuilder::new(
|
||||
"SELECT feature_name, feature_value, computation_timestamp FROM ml_feature_vectors WHERE feature_set_id = "
|
||||
);
|
||||
query_builder.push_bind(feature_set_id);
|
||||
let mut param_count = 1;
|
||||
|
||||
// Add entity filter
|
||||
if !entity_ids.is_empty() {
|
||||
param_count += 1;
|
||||
query.push_str(&format!(" AND entity_id = ANY(${}) ", param_count));
|
||||
params.push(&entity_ids);
|
||||
query_builder.push(" AND entity_id = ANY(");
|
||||
query_builder.push_bind(&entity_ids);
|
||||
query_builder.push(")");
|
||||
}
|
||||
|
||||
// Add time range filter
|
||||
if let Some((start, end)) = time_range {
|
||||
param_count += 1;
|
||||
query.push_str(&format!(" AND timestamp >= ${} ", param_count));
|
||||
params.push(&start);
|
||||
param_count += 1;
|
||||
query.push_str(&format!(" AND timestamp <= ${} ", param_count));
|
||||
params.push(&end);
|
||||
query_builder.push(" AND timestamp >= ");
|
||||
query_builder.push_bind(start);
|
||||
query_builder.push(" AND timestamp <= ");
|
||||
query_builder.push_bind(end);
|
||||
}
|
||||
|
||||
query.push_str(" ORDER BY timestamp DESC");
|
||||
query_builder.push(" ORDER BY timestamp DESC");
|
||||
|
||||
// Add limit
|
||||
if let Some(limit_val) = limit {
|
||||
param_count += 1;
|
||||
query.push_str(&format!(" LIMIT ${}", param_count));
|
||||
params.push(&(limit_val as i64));
|
||||
}
|
||||
|
||||
let rows = conn.query(&query, ¶ms).await?;
|
||||
query_builder.push(" LIMIT ");
|
||||
query_builder.push_bind(limit_val as i64);
|
||||
}
|
||||
|
||||
let query = query_builder.build();
|
||||
let rows = query.fetch_all(&mut *conn).await?;
|
||||
|
||||
let mut results = Vec::new();
|
||||
for row in rows {
|
||||
|
||||
@@ -219,40 +219,37 @@ impl PerformanceRepository {
|
||||
WHERE model_id = $1
|
||||
"#.to_string();
|
||||
|
||||
// Using sqlx query builder pattern instead of raw parameters
|
||||
// Using sqlx query builder pattern
|
||||
let mut query_builder = sqlx::QueryBuilder::new(
|
||||
"SELECT timestamp, metric_name, metric_value, metric_metadata FROM ml_model_performance WHERE model_id = "
|
||||
);
|
||||
query_builder.push_bind(model_id);
|
||||
let mut param_count = 1;
|
||||
|
||||
// Add metric name filter
|
||||
if let Some(ref names) = metric_names {
|
||||
param_count += 1;
|
||||
query.push_str(&format!(" AND metric_name = ANY(${}) ", param_count));
|
||||
params.push(names);
|
||||
query_builder.push(" AND metric_name = ANY(");
|
||||
query_builder.push_bind(names);
|
||||
query_builder.push(")");
|
||||
}
|
||||
|
||||
// Add time range filter
|
||||
if let Some((start, end)) = time_range {
|
||||
param_count += 1;
|
||||
query.push_str(&format!(" AND timestamp >= ${} ", param_count));
|
||||
params.push(&start);
|
||||
param_count += 1;
|
||||
query.push_str(&format!(" AND timestamp <= ${} ", param_count));
|
||||
params.push(&end);
|
||||
query_builder.push(" AND timestamp >= ");
|
||||
query_builder.push_bind(start);
|
||||
query_builder.push(" AND timestamp <= ");
|
||||
query_builder.push_bind(end);
|
||||
}
|
||||
|
||||
query.push_str(" ORDER BY timestamp DESC");
|
||||
query_builder.push(" ORDER BY timestamp DESC");
|
||||
|
||||
// Add limit
|
||||
if let Some(limit_val) = limit {
|
||||
param_count += 1;
|
||||
query.push_str(&format!(" LIMIT ${}", param_count));
|
||||
params.push(&(limit_val as i64));
|
||||
query_builder.push(" LIMIT ");
|
||||
query_builder.push_bind(limit_val as i64);
|
||||
}
|
||||
|
||||
let rows = conn.query(&query, ¶ms).await?;
|
||||
let query = query_builder.build();
|
||||
let rows = query.fetch_all(&mut *conn).await?;
|
||||
|
||||
let mut metrics = Vec::new();
|
||||
for row in rows {
|
||||
@@ -418,22 +415,21 @@ impl PerformanceRepository {
|
||||
|
||||
// Using sqlx query builder pattern
|
||||
let query =
|
||||
if let Some(model_id) = model_id {
|
||||
(r#"SELECT id, model_id, model_name, alert_type, severity, metric_name,
|
||||
threshold_value, actual_value, triggered_at, message, metadata
|
||||
FROM ml_performance_alerts
|
||||
WHERE model_id = $1 AND status = 'active'
|
||||
ORDER BY triggered_at DESC"#.to_string(),
|
||||
vec![&model_id])
|
||||
} else {
|
||||
(r#"SELECT id, model_id, model_name, alert_type, severity, metric_name,
|
||||
threshold_value, actual_value, triggered_at, message, metadata
|
||||
FROM ml_performance_alerts
|
||||
WHERE status = 'active'
|
||||
ORDER BY triggered_at DESC"#.to_string(),
|
||||
vec![])
|
||||
};
|
||||
|
||||
let (query, params) = if let Some(model_id) = model_id {
|
||||
(r#"SELECT id, model_id, model_name, alert_type, severity, metric_name,
|
||||
threshold_value, actual_value, triggered_at, message, metadata
|
||||
FROM ml_performance_alerts
|
||||
WHERE model_id = $1 AND status = 'active'
|
||||
ORDER BY triggered_at DESC"#.to_string(),
|
||||
vec![&model_id])
|
||||
} else {
|
||||
(r#"SELECT id, model_id, model_name, alert_type, severity, metric_name,
|
||||
threshold_value, actual_value, triggered_at, message, metadata
|
||||
FROM ml_performance_alerts
|
||||
WHERE status = 'active'
|
||||
ORDER BY triggered_at DESC"#.to_string(),
|
||||
vec![])
|
||||
};
|
||||
let rows = conn.query(&query, ¶ms).await?;
|
||||
|
||||
let mut alerts = Vec::new();
|
||||
|
||||
@@ -1043,8 +1043,7 @@ impl ComplianceValidator {
|
||||
// CRITICAL: Market abuse thresholds must be configurable, not hardcoded
|
||||
// Different markets have different reporting thresholds - hardcoding could cause regulatory violations
|
||||
let threshold = self.config.market_abuse_threshold
|
||||
.ok_or_else(|| RiskError::ConfigurationError {
|
||||
parameter: "market_abuse_threshold".to_owned(),
|
||||
.ok_or_else(|| RiskError::Configuration {
|
||||
message: "Market abuse threshold not configured - required for regulatory compliance".to_owned(),
|
||||
})?;
|
||||
if order_value > threshold {
|
||||
@@ -1256,7 +1255,7 @@ impl ComplianceValidator {
|
||||
order: &OrderInfo,
|
||||
violations: &[RiskViolation],
|
||||
warnings: &[ComplianceWarning],
|
||||
) -> Result<Price, ComplianceError> {
|
||||
) -> Result<Price, RiskError> {
|
||||
let mut risk_score = Price::ZERO;
|
||||
|
||||
// Base risk from order size - use safe conversion helpers
|
||||
@@ -1280,7 +1279,7 @@ impl ComplianceValidator {
|
||||
let order_risk = f64_to_price_safe(order_value_f64 / 100_000.0, "order risk calculation")
|
||||
.map_err(|e| {
|
||||
error!("CRITICAL: Failed to calculate order risk - this could hide compliance violations: {}", e);
|
||||
ComplianceError::ConversionError(format!("Failed to calculate order risk: {}", e))
|
||||
RiskError::Calculation { operation: "order_risk_calculation".to_string(), reason: format!("Failed to calculate order risk: {}", e) }
|
||||
})?;
|
||||
let current_risk_f64 = decimal_to_f64_safe(
|
||||
risk_score.to_decimal().unwrap_or(Decimal::ZERO),
|
||||
@@ -1309,7 +1308,7 @@ impl ComplianceValidator {
|
||||
f64_to_price_safe((violations.len() * 10) as f64, "violation risk calculation")
|
||||
.map_err(|e| {
|
||||
error!("CRITICAL: Failed to calculate violation risk - this could hide compliance issues: {}", e);
|
||||
ComplianceError::ConversionError(format!("Failed to calculate violation risk: {}", e))
|
||||
RiskError::Calculation { operation: "violation_risk_calculation".to_string(), reason: format!("Failed to calculate violation risk: {}", e) }
|
||||
})?;
|
||||
let violation_risk_f64 = decimal_to_f64_safe(
|
||||
violation_risk.to_decimal().unwrap_or(Decimal::ZERO),
|
||||
|
||||
@@ -325,6 +325,15 @@ pub enum RiskError {
|
||||
/// Market data system error occurred
|
||||
#[error("Market data error: {0}")]
|
||||
MarketDataError(String),
|
||||
|
||||
/// Required data is unavailable for calculations
|
||||
#[error("Data unavailable: {resource} - {reason}")]
|
||||
DataUnavailable {
|
||||
/// The data resource that is unavailable
|
||||
resource: String,
|
||||
/// Reason why the data is unavailable
|
||||
reason: String,
|
||||
},
|
||||
}
|
||||
|
||||
/// Result type for risk management operations
|
||||
@@ -500,8 +509,9 @@ impl RiskError {
|
||||
RiskError::BrokerConnection { .. } => "BROKER_CONNECTION_ERROR",
|
||||
RiskError::Connection { .. } => "CONNECTION_ERROR",
|
||||
RiskError::MarketDataError(_) => "MARKET_DATA_ERROR",
|
||||
RiskError::DataUnavailable { .. } => "DATA_UNAVAILABLE",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert from tokio timeout error
|
||||
|
||||
@@ -1404,18 +1404,18 @@ impl PositionTracker {
|
||||
position.base_position.unrealized_pnl = Price::from_f64(
|
||||
ToPrimitive::to_f64(&unrealized_pnl)
|
||||
.ok_or_else(|| RiskError::TypeConversion {
|
||||
from: "Decimal".to_string(),
|
||||
to: "f64".to_string(),
|
||||
value: unrealized_pnl.to_string(),
|
||||
from_type: "Decimal".to_string(),
|
||||
to_type: "f64".to_string(),
|
||||
reason: format!("invalid Decimal value {}", unrealized_pnl),
|
||||
})?
|
||||
)?;
|
||||
position.volatility = market_data
|
||||
.volatility
|
||||
.map(|v| Price::from_f64(v)
|
||||
.map_err(|_| RiskError::TypeConversion {
|
||||
from: "f64".to_string(),
|
||||
to: "Price".to_string(),
|
||||
value: v.to_string(),
|
||||
from_type: "f64".to_string(),
|
||||
to_type: "Price".to_string(),
|
||||
reason: format!("invalid f64 value {}", v),
|
||||
})
|
||||
).transpose()?;
|
||||
position.last_updated = Utc::now();
|
||||
|
||||
@@ -19,6 +19,7 @@ use num::ToPrimitive;
|
||||
use uuid::Uuid;
|
||||
use std::marker::Send;
|
||||
use std::sync::Arc;
|
||||
use tracing::error;
|
||||
// ELIMINATED: Prelude import removed to force explicit imports
|
||||
use rust_decimal::Decimal;
|
||||
use common::{Position, Symbol, Price, OrderSide, Quantity};
|
||||
@@ -1701,8 +1702,7 @@ impl RiskEngine {
|
||||
.min(
|
||||
safe_divide(
|
||||
Decimal::try_from(self.config.position_limits.global_limit)
|
||||
.map_err(|_| RiskError::ConfigurationError {
|
||||
parameter: "global_limit".to_owned(),
|
||||
.map_err(|_| RiskError::Configuration {
|
||||
message: "Invalid global limit configuration".to_owned(),
|
||||
})?
|
||||
.into(),
|
||||
|
||||
@@ -11,6 +11,7 @@ use std::collections::HashMap;
|
||||
|
||||
// ELIMINATED: Re-exports removed to force explicit imports
|
||||
use common::types::{Price, Quantity, Symbol, Volume, OrderType, OrderSide};
|
||||
use crate::error::RiskError;
|
||||
// Note: Side is an alias for OrderSide - using canonical OrderSide from trading_engine
|
||||
// Note: Side is an alias for OrderSide in common crate - both are available
|
||||
|
||||
@@ -606,6 +607,10 @@ pub struct ComplianceConfig {
|
||||
pub position_limits: PositionLimits,
|
||||
/// Number of days to retain audit records for compliance
|
||||
pub audit_retention_days: u32,
|
||||
/// Market abuse detection threshold
|
||||
pub market_abuse_threshold: Option<Price>,
|
||||
/// Large exposure threshold for regulatory reporting
|
||||
pub large_exposure_threshold: Price,
|
||||
}
|
||||
|
||||
/// Types of compliance warnings that can be issued
|
||||
|
||||
@@ -141,15 +141,15 @@ impl EmergencyResponseSystem {
|
||||
|
||||
if metrics.max_drawdown.abs().to_decimal()
|
||||
.map_err(|e| RiskError::TypeConversion {
|
||||
from: "Price".to_string(),
|
||||
to: "Decimal".to_string(),
|
||||
value: metrics.max_drawdown.to_string(),
|
||||
from_type: "Price".to_string(),
|
||||
to_type: "Decimal".to_string(),
|
||||
reason: format!("conversion failed: {}", e),
|
||||
})?
|
||||
>= Decimal::try_from(0.20)
|
||||
.map_err(|e| RiskError::TypeConversion {
|
||||
from: "f64".to_string(),
|
||||
to: "Decimal".to_string(),
|
||||
value: "0.20".to_string(),
|
||||
from_type: "f64".to_string(),
|
||||
to_type: "Decimal".to_string(),
|
||||
reason: format!("conversion failed: {}", e),
|
||||
})?
|
||||
{
|
||||
// 20% drawdown limit
|
||||
|
||||
Reference in New Issue
Block a user