🔧 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:
@@ -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"] }
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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)]
|
||||
|
||||
Reference in New Issue
Block a user