🔧 PROGRESS: Import path fixes and type cleanup

- Fixed missing imports in backtesting and risk-data crates
- Corrected ConnectionStatus usage patterns
- Fixed ConfigManager constructor calls
- Resolved Interactive Brokers config conversions
- Added proper Decimal import patterns

NEXT: Aggressive duplicate type system elimination with parallel agents

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2025-09-26 16:16:16 +02:00
parent ea9d8f2c88
commit d92a9664eb
23 changed files with 202 additions and 642 deletions

View File

@@ -44,8 +44,9 @@ tracing-subscriber.workspace = true
# Configuration
toml.workspace = true
config = { path = "../crates/config" }
# Common types (migrated to common/src/types.rs)
# foxhunt-common-types.workspace = true # REMOVED - types migrated to common/
# Trading engine for canonical types
trading_engine = { path = "../trading_engine" }
# Utilities
uuid = { workspace = true, features = ["v4", "serde"] }

View File

@@ -7,142 +7,8 @@
use serde::{Deserialize, Serialize};
use std::fmt;
/// Order side - whether the order is a buy or sell
///
/// This is the canonical definition used across all services.
/// Note: Some legacy code may use "OrderSide" - this is the same enum.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum OrderSide {
/// Buy order
Buy,
/// Sell order
Sell,
}
impl fmt::Display for OrderSide {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Buy => write!(f, "BUY"),
Self::Sell => write!(f, "SELL"),
}
}
}
impl Default for OrderSide {
fn default() -> Self {
Self::Buy
}
}
// Alias for backward compatibility with existing code
pub use OrderSide as Side;
/// Order status throughout its lifecycle
///
/// This is the canonical definition with all possible states
/// an order can be in across different brokers and systems.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[non_exhaustive]
pub enum OrderStatus {
/// Order created but not yet submitted
Created,
/// Order submitted to broker/exchange
Submitted,
/// Order partially filled
PartiallyFilled,
/// Order completely filled
Filled,
/// Order rejected by broker/exchange
Rejected,
/// Order cancelled
Cancelled,
/// New order (broker-specific)
New,
/// Order expired
Expired,
/// Order pending (awaiting processing)
Pending,
/// Order working in the market
Working,
/// Unknown status
Unknown,
/// Order suspended
Suspended,
/// Order pending cancellation
PendingCancel,
/// Order pending replacement/modification
PendingReplace,
}
impl fmt::Display for OrderStatus {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Created => write!(f, "CREATED"),
Self::Submitted => write!(f, "SUBMITTED"),
Self::PartiallyFilled => write!(f, "PARTIALLY_FILLED"),
Self::Filled => write!(f, "FILLED"),
Self::Rejected => write!(f, "REJECTED"),
Self::Cancelled => write!(f, "CANCELLED"),
Self::New => write!(f, "NEW"),
Self::Expired => write!(f, "EXPIRED"),
Self::Pending => write!(f, "PENDING"),
Self::Working => write!(f, "WORKING"),
Self::Unknown => write!(f, "UNKNOWN"),
Self::Suspended => write!(f, "SUSPENDED"),
Self::PendingCancel => write!(f, "PENDING_CANCEL"),
Self::PendingReplace => write!(f, "PENDING_REPLACE"),
}
}
}
impl Default for OrderStatus {
fn default() -> Self {
Self::Created
}
}
/// Order type specifying execution behavior
///
/// This is the canonical definition supporting all common
/// order types used in HFT systems.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[non_exhaustive]
pub enum OrderType {
/// Market order - execute immediately at best available price
Market,
/// Limit order - execute only at specified price or better
Limit,
/// Stop order - becomes market order when stop price reached
Stop,
/// Stop limit order - becomes limit order when stop price reached
StopLimit,
/// Iceberg order - only shows small portion of total size
Iceberg,
/// Trailing stop - stop price follows market by specified amount
TrailingStop,
/// Hidden order - not displayed in order book
Hidden,
}
impl fmt::Display for OrderType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Market => write!(f, "MARKET"),
Self::Limit => write!(f, "LIMIT"),
Self::Stop => write!(f, "STOP"),
Self::StopLimit => write!(f, "STOP_LIMIT"),
Self::Iceberg => write!(f, "ICEBERG"),
Self::TrailingStop => write!(f, "TRAILING_STOP"),
Self::Hidden => write!(f, "HIDDEN"),
}
}
}
impl Default for OrderType {
fn default() -> Self {
Self::Market
}
}
// Re-export canonical types from trading_engine (via common::types)
pub use crate::types::{OrderSide, OrderStatus, OrderType, Side};
/// Time in force specification for orders
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]

View File

@@ -268,300 +268,23 @@ pub enum CommonTypeError {
},
}
/// Order side - whether the order is a buy or sell
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum OrderSide {
/// Buy order
Buy,
/// Sell order
Sell,
}
// Re-export ALL canonical trading types from trading_engine
pub use trading_engine::types::{
Currency, OrderId, OrderSide, OrderStatus, OrderType, Price, Quantity, Side, Symbol, TradeId,
TimeInForce,
};
impl fmt::Display for OrderSide {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Buy => write!(f, "BUY"),
Self::Sell => write!(f, "SELL"),
}
}
}
// Re-export volume as alias
pub use trading_engine::types::Quantity as Volume;
impl Default for OrderSide {
fn default() -> Self {
Self::Buy
}
}
// TimeInForce moved to canonical source: trading_engine::types::TimeInForce
/// Alias for backward compatibility
pub use OrderSide as Side;
// Currency moved to canonical source: trading_engine::types::Currency
/// Order status throughout its lifecycle
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[non_exhaustive]
pub enum OrderStatus {
Created,
Submitted,
PartiallyFilled,
Filled,
Rejected,
Cancelled,
New,
Expired,
Pending,
Working,
Unknown,
Suspended,
PendingCancel,
PendingReplace,
}
// Price moved to canonical source: trading_engine::types::Price
impl fmt::Display for OrderStatus {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Created => write!(f, "CREATED"),
Self::Submitted => write!(f, "SUBMITTED"),
Self::PartiallyFilled => write!(f, "PARTIALLY_FILLED"),
Self::Filled => write!(f, "FILLED"),
Self::Rejected => write!(f, "REJECTED"),
Self::Cancelled => write!(f, "CANCELLED"),
Self::New => write!(f, "NEW"),
Self::Expired => write!(f, "EXPIRED"),
Self::Pending => write!(f, "PENDING"),
Self::Working => write!(f, "WORKING"),
Self::Unknown => write!(f, "UNKNOWN"),
Self::Suspended => write!(f, "SUSPENDED"),
Self::PendingCancel => write!(f, "PENDING_CANCEL"),
Self::PendingReplace => write!(f, "PENDING_REPLACE"),
}
}
}
impl Default for OrderStatus {
fn default() -> Self {
Self::Created
}
}
/// Order type specifying execution behavior
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[non_exhaustive]
pub enum OrderType {
Market,
Limit,
Stop,
StopLimit,
Iceberg,
TrailingStop,
Hidden,
}
impl fmt::Display for OrderType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Market => write!(f, "MARKET"),
Self::Limit => write!(f, "LIMIT"),
Self::Stop => write!(f, "STOP"),
Self::StopLimit => write!(f, "STOP_LIMIT"),
Self::Iceberg => write!(f, "ICEBERG"),
Self::TrailingStop => write!(f, "TRAILING_STOP"),
Self::Hidden => write!(f, "HIDDEN"),
}
}
}
impl Default for OrderType {
fn default() -> Self {
Self::Market
}
}
/// Time in force specification for orders
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum TimeInForce {
Day,
GoodTillCancel,
GTC,
ImmediateOrCancel,
IOC,
FillOrKill,
FOK,
}
impl fmt::Display for TimeInForce {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Day => write!(f, "DAY"),
Self::GoodTillCancel | Self::GTC => write!(f, "GTC"),
Self::ImmediateOrCancel | Self::IOC => write!(f, "IOC"),
Self::FillOrKill | Self::FOK => write!(f, "FOK"),
}
}
}
impl Default for TimeInForce {
fn default() -> Self {
Self::Day
}
}
/// Currency enumeration for financial instruments
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub enum Currency {
USD,
EUR,
GBP,
JPY,
CHF,
CAD,
AUD,
NZD,
BTC,
}
impl fmt::Display for Currency {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::USD => write!(f, "USD"),
Self::EUR => write!(f, "EUR"),
Self::GBP => write!(f, "GBP"),
Self::JPY => write!(f, "JPY"),
Self::CHF => write!(f, "CHF"),
Self::CAD => write!(f, "CAD"),
Self::AUD => write!(f, "AUD"),
Self::NZD => write!(f, "NZD"),
Self::BTC => write!(f, "BTC"),
}
}
}
impl Default for Currency {
fn default() -> Self {
Self::USD
}
}
/// Type-safe price with validation
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Price(Decimal);
impl Price {
pub const ZERO: Self = Self(Decimal::ZERO);
/// Create a new price with validation
pub fn new(value: Decimal) -> Result<Self, CommonTypeError> {
if value < Decimal::ZERO {
return Err(CommonTypeError::InvalidPrice {
value: value.to_string(),
reason: "Price cannot be negative".to_string(),
});
}
Ok(Self(value))
}
/// Create price from f64 with validation
pub fn from_f64(value: f64) -> Result<Self, CommonTypeError> {
if !value.is_finite() || value < 0.0 {
return Err(CommonTypeError::InvalidPrice {
value: value.to_string(),
reason: "Price must be a finite positive number".to_string(),
});
}
let decimal = Decimal::from_f64_retain(value)
.ok_or_else(|| CommonTypeError::InvalidPrice {
value: value.to_string(),
reason: "Cannot convert to decimal".to_string(),
})?;
Ok(Self(decimal))
}
/// Get the underlying decimal value
pub fn value(&self) -> Decimal {
self.0
}
/// Convert to f64
pub fn to_f64(&self) -> f64 {
use rust_decimal::prelude::ToPrimitive;
self.0.to_f64().unwrap_or(0.0)
}
}
impl fmt::Display for Price {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl Default for Price {
fn default() -> Self {
Self::ZERO
}
}
/// Type-safe quantity with validation
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Quantity(Decimal);
impl Quantity {
pub const ZERO: Self = Self(Decimal::ZERO);
/// Create a new quantity with validation
pub fn new(value: Decimal) -> Result<Self, CommonTypeError> {
if value < Decimal::ZERO {
return Err(CommonTypeError::InvalidQuantity {
value: value.to_string(),
reason: "Quantity cannot be negative".to_string(),
});
}
Ok(Self(value))
}
/// Create quantity from f64 with validation
pub fn from_f64(value: f64) -> Result<Self, CommonTypeError> {
if !value.is_finite() || value < 0.0 {
return Err(CommonTypeError::InvalidQuantity {
value: value.to_string(),
reason: "Quantity must be a finite positive number".to_string(),
});
}
let decimal = Decimal::from_f64_retain(value)
.ok_or_else(|| CommonTypeError::InvalidQuantity {
value: value.to_string(),
reason: "Cannot convert to decimal".to_string(),
})?;
Ok(Self(decimal))
}
/// Get the underlying decimal value
pub fn value(&self) -> Decimal {
self.0
}
/// Convert to f64
pub fn to_f64(&self) -> f64 {
use rust_decimal::prelude::ToPrimitive;
self.0.to_f64().unwrap_or(0.0)
}
}
impl fmt::Display for Quantity {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl Default for Quantity {
fn default() -> Self {
Self::ZERO
}
}
/// Type-safe volume (alias for Quantity for backward compatibility)
pub type Volume = Quantity;
// Quantity moved to canonical source: trading_engine::types::Quantity
// Volume moved to canonical source: trading_engine::types::Quantity (as Volume alias)
/// Money amount with currency
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
@@ -583,112 +306,11 @@ impl fmt::Display for Money {
}
}
/// Type-safe order identifier
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct OrderId(u64);
// OrderId moved to canonical source: trading_engine::types::OrderId
impl OrderId {
/// Generate a new unique order ID
pub fn new() -> Self {
static COUNTER: AtomicU64 = AtomicU64::new(1);
Self(COUNTER.fetch_add(1, Ordering::Relaxed))
}
// TradeId moved to canonical source: trading_engine::types::TradeId
/// Create from existing u64
pub const fn from_u64(id: u64) -> Self {
Self(id)
}
/// Get the underlying u64 value
pub const fn value(&self) -> u64 {
self.0
}
}
impl fmt::Display for OrderId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl Default for OrderId {
fn default() -> Self {
Self::new()
}
}
/// Type-safe trade identifier
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct TradeId(String);
impl TradeId {
/// Create a new trade ID with validation
pub fn new<S: Into<String>>(id: S) -> Result<Self, CommonTypeError> {
let id = id.into();
if id.trim().is_empty() {
return Err(CommonTypeError::InvalidIdentifier {
field: "trade_id".to_string(),
reason: "Trade ID cannot be empty".to_string(),
});
}
Ok(Self(id))
}
/// Generate a new UUID-based trade ID
pub fn generate() -> Self {
Self(Uuid::new_v4().to_string())
}
/// Get the ID as a string slice
pub fn as_str(&self) -> &str {
&self.0
}
/// Convert to owned String
pub fn into_string(self) -> String {
self.0
}
}
impl fmt::Display for TradeId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
/// Type-safe symbol identifier
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Symbol(String);
impl Symbol {
/// Create a new symbol with validation
pub fn new<S: Into<String>>(symbol: S) -> Result<Self, CommonTypeError> {
let symbol = symbol.into().to_uppercase();
if symbol.trim().is_empty() {
return Err(CommonTypeError::InvalidIdentifier {
field: "symbol".to_string(),
reason: "Symbol cannot be empty".to_string(),
});
}
Ok(Self(symbol))
}
/// Get the symbol as a string slice
pub fn as_str(&self) -> &str {
&self.0
}
/// Convert to owned String
pub fn into_string(self) -> String {
self.0
}
}
impl fmt::Display for Symbol {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
// Symbol moved to canonical source: trading_engine::types::Symbol
/// Type-safe account identifier
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]