Move 17 library crates into crates/, CLI binary into bin/fxt, consolidate 10 test crates into testing/, split config crate from deployment config files. Root directory reduced from 38+ to ~17 directories. All Cargo.toml paths and build.rs proto refs updated. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
224 lines
8.1 KiB
Rust
224 lines
8.1 KiB
Rust
//! Database schema definitions for Foxhunt HFT Trading System
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
use sqlx::types::Uuid;
|
|
use chrono::{DateTime, Utc};
|
|
use rust_decimal::Decimal;
|
|
use common::types::Order as DomainOrder;
|
|
|
|
/// Configuration table schema
|
|
///
|
|
/// Represents a configuration key-value pair stored in the database.
|
|
///
|
|
/// Used for storing application settings that can be modified at runtime.
|
|
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
|
pub struct ConfigEntry {
|
|
/// Unique identifier for the configuration entry
|
|
pub id: Uuid,
|
|
/// Configuration key (unique identifier for the setting)
|
|
pub key: String,
|
|
/// Configuration value stored as a string
|
|
pub value: String,
|
|
/// Optional human-readable description of the configuration
|
|
pub description: Option<String>,
|
|
/// Timestamp when the configuration was created
|
|
pub created_at: DateTime<Utc>,
|
|
/// Timestamp when the configuration was last updated
|
|
pub updated_at: DateTime<Utc>,
|
|
}
|
|
|
|
/// Trading positions schema
|
|
///
|
|
/// Represents an open trading position in the database.
|
|
///
|
|
/// Tracks position size, entry price, and current profit/loss.
|
|
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
|
pub struct Position {
|
|
/// Unique identifier for the position
|
|
pub id: Uuid,
|
|
/// Trading symbol (e.g., "AAPL", "BTC/USD")
|
|
pub symbol: String,
|
|
/// Position size (positive for long, negative for short)
|
|
pub quantity: Decimal,
|
|
/// Price at which the position was entered
|
|
pub entry_price: Decimal,
|
|
/// Current market price of the instrument
|
|
pub current_price: Option<Decimal>,
|
|
/// Current profit/loss of the position
|
|
pub pnl: Option<Decimal>,
|
|
/// Timestamp when the position was opened
|
|
pub created_at: DateTime<Utc>,
|
|
/// Timestamp when the position was last updated
|
|
pub updated_at: DateTime<Utc>,
|
|
}
|
|
|
|
/// Database Order schema - simplified representation for persistence
|
|
///
|
|
/// Simplified order representation for database storage.
|
|
///
|
|
/// Use DomainOrder from common crate for business logic operations.
|
|
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
|
pub struct DbOrder {
|
|
/// Unique identifier for the order
|
|
pub id: Uuid,
|
|
/// Trading symbol for the order
|
|
pub symbol: String,
|
|
/// Order type as string (MARKET, LIMIT, STOP, etc.)
|
|
pub order_type: String,
|
|
/// Order side as string (BUY, SELL)
|
|
pub side: String,
|
|
/// Order quantity
|
|
pub quantity: Decimal,
|
|
/// Order price (may be zero for market orders)
|
|
pub price: Decimal,
|
|
/// Order status as string (PENDING, FILLED, CANCELLED, etc.)
|
|
pub status: String,
|
|
/// Timestamp when the order was created
|
|
pub created_at: DateTime<Utc>,
|
|
/// Timestamp when the order was last updated
|
|
pub updated_at: DateTime<Utc>,
|
|
}
|
|
|
|
/// Type alias for the canonical Order from common crate
|
|
///
|
|
/// This provides a convenient alias to the domain Order type
|
|
/// for use within the database module while maintaining
|
|
/// separation between database and business logic representations.
|
|
pub type Order = DomainOrder;
|
|
|
|
/// Conversion from canonical domain Order to database Order
|
|
impl From<DomainOrder> for DbOrder {
|
|
fn from(order: DomainOrder) -> Self {
|
|
Self {
|
|
id: order.id,
|
|
symbol: order.symbol,
|
|
order_type: order.order_type.to_string(),
|
|
side: order.side.to_string(),
|
|
quantity: order.quantity,
|
|
price: order.price.unwrap_or(Decimal::ZERO),
|
|
status: order.status.to_string(),
|
|
created_at: order.created_at,
|
|
updated_at: order.updated_at,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Conversion from database Order to canonical domain Order
|
|
impl From<DbOrder> for DomainOrder {
|
|
fn from(db_order: DbOrder) -> Self {
|
|
use common::types::OrderSide;
|
|
use common::types::OrderType;
|
|
use common::types::OrderStatus;
|
|
|
|
// Parse enums with defaults for safety
|
|
let side = match db_order.side.to_uppercase().as_str() {
|
|
"BUY" => OrderSide::Buy,
|
|
"SELL" => OrderSide::Sell,
|
|
_ => {
|
|
tracing::error!("Invalid order side '{}' in database - this indicates data corruption", db_order.side);
|
|
return Err(anyhow::anyhow!("Invalid order side: {}", db_order.side));
|
|
}
|
|
};
|
|
|
|
let order_type = match db_order.order_type.to_uppercase().as_str() {
|
|
"MARKET" => OrderType::Market,
|
|
"LIMIT" => OrderType::Limit,
|
|
"STOP" => OrderType::Stop,
|
|
"STOP_LIMIT" => OrderType::StopLimit,
|
|
_ => {
|
|
tracing::error!("Invalid order type '{}' in database - this indicates data corruption", db_order.order_type);
|
|
return Err(anyhow::anyhow!("Invalid order type: {}", db_order.order_type));
|
|
}
|
|
};
|
|
|
|
let status = match db_order.status.to_uppercase().as_str() {
|
|
"PENDING" => OrderStatus::Pending,
|
|
"SUBMITTED" => OrderStatus::Submitted,
|
|
"FILLED" => OrderStatus::Filled,
|
|
"CANCELLED" => OrderStatus::Cancelled,
|
|
"REJECTED" => OrderStatus::Rejected,
|
|
_ => {
|
|
tracing::error!("Invalid order status '{}' in database - this indicates data corruption", db_order.status);
|
|
return Err(anyhow::anyhow!("Invalid order status: {}", db_order.status));
|
|
}
|
|
};
|
|
|
|
Self {
|
|
id: db_order.id,
|
|
symbol: db_order.symbol,
|
|
side,
|
|
quantity: db_order.quantity,
|
|
price: if db_order.price.is_zero() { None } else { Some(db_order.price) },
|
|
order_type,
|
|
status,
|
|
filled_quantity: Decimal::ZERO, // Not stored in simple schema
|
|
remaining_quantity: db_order.quantity, // Assume unfilled for simple schema
|
|
avg_fill_price: None, // Not stored in simple schema
|
|
created_at: db_order.created_at,
|
|
updated_at: db_order.updated_at,
|
|
expires_at: None,
|
|
client_order_id: None,
|
|
broker_order_id: None,
|
|
stop_loss: None,
|
|
take_profit: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Model configuration schema
|
|
///
|
|
/// Configuration for ML models including storage locations,
|
|
/// metadata, and activation status.
|
|
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
|
pub struct ModelConfig {
|
|
/// Unique identifier for the model configuration
|
|
pub id: Uuid,
|
|
/// Human-readable model name
|
|
pub name: String,
|
|
/// Model version string
|
|
pub version: String,
|
|
/// S3 path where the model is stored
|
|
pub s3_path: String,
|
|
/// Optional local cache path for the model
|
|
pub cache_path: Option<String>,
|
|
/// Additional metadata stored as JSON
|
|
pub metadata: serde_json::Value,
|
|
/// Whether this model configuration is currently active
|
|
pub is_active: bool,
|
|
/// Timestamp when the configuration was created
|
|
pub created_at: DateTime<Utc>,
|
|
/// Timestamp when the configuration was last updated
|
|
pub updated_at: DateTime<Utc>,
|
|
}
|
|
|
|
/// Model version tracking schema
|
|
///
|
|
/// Tracks different versions of ML models with performance metrics,
|
|
/// training metadata, and integrity information.
|
|
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
|
pub struct ModelVersion {
|
|
/// Unique identifier for the model version
|
|
pub id: Uuid,
|
|
/// Reference to the parent model configuration
|
|
pub model_config_id: Uuid,
|
|
/// Version string for this specific model version
|
|
pub version: String,
|
|
/// S3 path where this model version is stored
|
|
pub s3_path: String,
|
|
/// Optional local cache path for this model version
|
|
pub cache_path: Option<String>,
|
|
/// Optional checksum for integrity verification
|
|
pub checksum: Option<String>,
|
|
/// Size of the model file in bytes
|
|
pub size_bytes: Option<i64>,
|
|
/// Performance metrics stored as JSON
|
|
pub performance_metrics: serde_json::Value,
|
|
/// Training metadata and parameters stored as JSON
|
|
pub training_metadata: serde_json::Value,
|
|
/// Whether this is the current active version
|
|
pub is_current: bool,
|
|
/// Timestamp when the version was created
|
|
pub created_at: DateTime<Utc>,
|
|
/// Timestamp when the version was last updated
|
|
pub updated_at: DateTime<Utc>,
|
|
} |