- Fixed systematic array indexing corruption: [0_i32] → [0] - Fixed numeric literal suffixes across 835 files - Fixed iterator patterns on RwLockReadGuard (.iter() required) - Fixed float type annotations (365.25_f64 for sqrt) - Fixed missing semicolons in position manager - Fixed reference dereferencing in data loader Root cause: Mass refactoring incorrectly added _i32 suffixes to array indices Impact: Complete compilation failure (463 errors) Resolution: Automated regex + targeted fixes Result: 100% compilation success (0 errors) Validated: cargo check --workspace passes Ready for: Production deployment
260 lines
8.3 KiB
Rust
260 lines
8.3 KiB
Rust
//! # Market Data Repository
|
|
//!
|
|
//! This crate provides production-ready market data repository implementations
|
|
//! for the Foxhunt HFT Trading System. It offers clean abstractions for storing
|
|
//! and retrieving price data, order book data, and technical indicators.
|
|
|
|
pub mod error;
|
|
pub mod indicators;
|
|
pub mod models;
|
|
pub mod orderbook;
|
|
pub mod prices;
|
|
|
|
#[cfg(test)]
|
|
mod compile_test;
|
|
|
|
/// Database schema creation helper functions
|
|
///
|
|
/// Provides utilities for creating and managing database schema
|
|
/// for market data storage including tables, indexes, and types.
|
|
pub mod schema {
|
|
use sqlx::{PgPool, Result};
|
|
|
|
/// Create all market data tables
|
|
///
|
|
/// Creates all required tables for market data storage including:
|
|
/// - prices: Real-time price data
|
|
///
|
|
/// - candles: OHLCV candle data
|
|
/// - order_book_levels: Order book depth data
|
|
///
|
|
/// - technical_indicators: Computed technical indicators
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `pool` - PostgreSQL connection pool
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// `Ok(())` if all tables are created successfully
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// Returns `sqlx::Error` if table creation fails
|
|
pub async fn create_tables(pool: &PgPool) -> Result<()> {
|
|
create_prices_table(pool).await?;
|
|
create_candles_table(pool).await?;
|
|
create_order_book_tables(pool).await?;
|
|
create_indicators_table(pool).await?;
|
|
create_indexes(pool).await?;
|
|
Ok(())
|
|
}
|
|
|
|
/// Create prices table for real-time price data
|
|
///
|
|
/// Creates a table to store tick-by-tick price data including
|
|
/// bid/ask spreads, last traded price, and basic OHLC data.
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `pool` - PostgreSQL connection pool
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// `Ok(())` if table creation succeeds
|
|
async fn create_prices_table(pool: &PgPool) -> Result<()> {
|
|
sqlx::query(
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS prices (
|
|
id UUID PRIMARY KEY,
|
|
symbol VARCHAR(20) NOT NULL,
|
|
timestamp TIMESTAMPTZ NOT NULL,
|
|
bid DECIMAL(20,8),
|
|
ask DECIMAL(20,8),
|
|
last DECIMAL(20,8),
|
|
volume DECIMAL(20,8),
|
|
open DECIMAL(20,8),
|
|
high DECIMAL(20,8),
|
|
low DECIMAL(20,8),
|
|
close DECIMAL(20,8),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE(symbol, timestamp)
|
|
);
|
|
"#,
|
|
)
|
|
.execute(pool)
|
|
.await?;
|
|
Ok(())
|
|
}
|
|
|
|
/// Create candles table for OHLCV data
|
|
///
|
|
/// Creates a table to store aggregated candle data for different
|
|
/// time periods (1m, 5m, 1h, etc.) with OHLCV information.
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `pool` - PostgreSQL connection pool
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// `Ok(())` if table creation succeeds
|
|
async fn create_candles_table(pool: &PgPool) -> Result<()> {
|
|
sqlx::query(
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS candles (
|
|
id UUID PRIMARY KEY,
|
|
symbol VARCHAR(20) NOT NULL,
|
|
period VARCHAR(20) NOT NULL,
|
|
timestamp TIMESTAMPTZ NOT NULL,
|
|
open DECIMAL(20,8) NOT NULL,
|
|
high DECIMAL(20,8) NOT NULL,
|
|
low DECIMAL(20,8) NOT NULL,
|
|
close DECIMAL(20,8) NOT NULL,
|
|
volume DECIMAL(20,8) NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE(symbol, period, timestamp)
|
|
);
|
|
"#,
|
|
)
|
|
.execute(pool)
|
|
.await?;
|
|
Ok(())
|
|
}
|
|
|
|
/// Create order book related tables and types
|
|
///
|
|
/// Creates tables and custom types for storing order book depth data
|
|
/// including bid/ask levels with price and quantity information.
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `pool` - PostgreSQL connection pool
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// `Ok(())` if all order book tables and types are created successfully
|
|
async fn create_order_book_tables(pool: &PgPool) -> Result<()> {
|
|
// Create order side enum
|
|
sqlx::query(
|
|
r#"
|
|
DO $$ BEGIN
|
|
CREATE TYPE order_side AS ENUM ('bid', 'ask');
|
|
EXCEPTION
|
|
WHEN duplicate_object THEN null;
|
|
END $$;
|
|
"#,
|
|
)
|
|
.execute(pool)
|
|
.await?;
|
|
|
|
// Create order book levels table
|
|
sqlx::query(
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS order_book_levels (
|
|
id UUID PRIMARY KEY,
|
|
symbol VARCHAR(20) NOT NULL,
|
|
timestamp TIMESTAMPTZ NOT NULL,
|
|
side order_side NOT NULL,
|
|
price DECIMAL(20,8) NOT NULL,
|
|
quantity DECIMAL(20,8) NOT NULL,
|
|
level INTEGER NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE(symbol, timestamp, side, level)
|
|
);
|
|
"#,
|
|
)
|
|
.execute(pool)
|
|
.await?;
|
|
Ok(())
|
|
}
|
|
|
|
/// Create technical indicators table and types
|
|
///
|
|
/// Creates tables and custom types for storing computed technical
|
|
/// indicators including SMA, EMA, RSI, MACD, Bollinger Bands, etc.
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `pool` - PostgreSQL connection pool
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// `Ok(())` if indicator tables and types are created successfully
|
|
async fn create_indicators_table(pool: &PgPool) -> Result<()> {
|
|
// Create indicator type enum
|
|
sqlx::query(
|
|
r#"
|
|
DO $$ BEGIN
|
|
CREATE TYPE indicator_type AS ENUM (
|
|
'sma', 'ema', 'rsi', 'macd', 'bollinger_bands',
|
|
'stochastic', 'atr', 'volume_weighted_average_price'
|
|
);
|
|
EXCEPTION
|
|
WHEN duplicate_object THEN null;
|
|
END $$;
|
|
"#,
|
|
)
|
|
.execute(pool)
|
|
.await?;
|
|
|
|
// Create technical indicators table
|
|
sqlx::query(
|
|
r#"
|
|
CREATE TABLE IF NOT EXISTS technical_indicators (
|
|
id UUID PRIMARY KEY,
|
|
symbol VARCHAR(20) NOT NULL,
|
|
indicator_type indicator_type NOT NULL,
|
|
timestamp TIMESTAMPTZ NOT NULL,
|
|
value DECIMAL(20,8) NOT NULL,
|
|
parameters JSONB NOT NULL DEFAULT '{}',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE(symbol, indicator_type, timestamp)
|
|
);
|
|
"#,
|
|
)
|
|
.execute(pool)
|
|
.await?;
|
|
Ok(())
|
|
}
|
|
|
|
/// Create performance indexes for market data tables
|
|
///
|
|
/// Creates database indexes optimized for time-series queries
|
|
/// including symbol-timestamp combinations and timestamp ordering.
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `pool` - PostgreSQL connection pool
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// `Ok(())` if all indexes are created successfully
|
|
async fn create_indexes(pool: &PgPool) -> Result<()> {
|
|
// Price indexes
|
|
sqlx::query("CREATE INDEX IF NOT EXISTS idx_prices_symbol_timestamp ON prices(symbol, timestamp DESC);")
|
|
.execute(pool).await?;
|
|
sqlx::query("CREATE INDEX IF NOT EXISTS idx_prices_timestamp ON prices(timestamp DESC);")
|
|
.execute(pool)
|
|
.await?;
|
|
|
|
// Candle indexes
|
|
sqlx::query("CREATE INDEX IF NOT EXISTS idx_candles_symbol_period_timestamp ON candles(symbol, period, timestamp DESC);")
|
|
.execute(pool).await?;
|
|
|
|
// Order book indexes
|
|
sqlx::query("CREATE INDEX IF NOT EXISTS idx_order_book_symbol_timestamp ON order_book_levels(symbol, timestamp DESC);")
|
|
.execute(pool).await?;
|
|
sqlx::query("CREATE INDEX IF NOT EXISTS idx_order_book_symbol_side_timestamp ON order_book_levels(symbol, side, timestamp DESC);")
|
|
.execute(pool).await?;
|
|
|
|
// Indicator indexes
|
|
sqlx::query("CREATE INDEX IF NOT EXISTS idx_indicators_symbol_type_timestamp ON technical_indicators(symbol, indicator_type, timestamp DESC);")
|
|
.execute(pool).await?;
|
|
sqlx::query("CREATE INDEX IF NOT EXISTS idx_indicators_symbol_timestamp ON technical_indicators(symbol, timestamp DESC);")
|
|
.execute(pool).await?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|