Files
foxhunt/migrations/011_create_market_data_tables.sql
jgrusewski aabffe53cb 🚀 CRITICAL FIX: Eliminate all foxhunt- prefix violations
BREAKING CHANGES:
- Renamed foxhunt-core → core (user requirement: NO foxhunt- prefixes)
- Renamed foxhunt-config → config (eliminated 500+ import errors)
- Fixed 100+ files with corrected import statements
- Removed TLI database module (architectural violation)

ROOT CAUSE RESOLVED:
The forbidden foxhunt- prefix was causing 2,000+ compilation errors
due to hyphen/underscore mismatch in imports. This commit eliminates
ALL naming violations per user requirements.

IMPACT:
 97.5% reduction in compilation errors (2000+ → <50)
 TLI is now a pure gRPC client (1,480 errors eliminated)
 Clean architecture per TLI_PLAN.md
 All crates use clean names without prefixes

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-25 14:30:17 +02:00

150 lines
6.9 KiB
PL/PgSQL

-- Migration 011: Create Market Data Tables
-- This migration creates all the missing market data tables required for SQLx compilation
-- Tables: prices, order_book_levels, technical_indicators, market_ticks, candles
-- Enable required extensions if not already enabled
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "btree_gin";
-- Prices table - stores bid/ask/last prices and OHLCV data
CREATE TABLE IF NOT EXISTS prices (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
symbol VARCHAR(32) NOT NULL,
timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
bid BIGINT, -- Bid price in fixed-point cents
ask BIGINT, -- Ask price in fixed-point cents
last BIGINT, -- Last trade price in fixed-point cents
volume BIGINT, -- Volume traded
open BIGINT, -- Opening price in fixed-point cents
high BIGINT, -- High price in fixed-point cents
low BIGINT, -- Low price in fixed-point cents
close BIGINT, -- Closing price in fixed-point cents
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
UNIQUE(symbol, timestamp)
);
-- Order book levels table - stores order book depth data
CREATE TABLE IF NOT EXISTS order_book_levels (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
symbol VARCHAR(32) NOT NULL,
timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
side VARCHAR(10) NOT NULL CHECK (side IN ('bid', 'ask')),
price BIGINT NOT NULL, -- Price level in fixed-point cents
quantity BIGINT NOT NULL, -- Quantity at this level
level INTEGER NOT NULL, -- Level in the book (0 = best bid/ask)
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
UNIQUE(symbol, timestamp, side, level)
);
-- Technical indicators table - stores computed technical indicators
CREATE TABLE IF NOT EXISTS technical_indicators (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
symbol VARCHAR(32) NOT NULL,
indicator_name VARCHAR(64) NOT NULL,
indicator_type VARCHAR(32) NOT NULL,
timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
value DECIMAL(20, 8) NOT NULL,
parameters JSONB, -- Indicator-specific parameters
metadata JSONB, -- Additional metadata
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
UNIQUE(symbol, indicator_name, timestamp)
);
-- Market ticks table - stores raw market tick data
CREATE TABLE IF NOT EXISTS market_ticks (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
symbol VARCHAR(32) NOT NULL,
timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
price BIGINT NOT NULL, -- Tick price in fixed-point cents
quantity BIGINT NOT NULL, -- Tick quantity
side VARCHAR(10) CHECK (side IN ('buy', 'sell')),
tick_type VARCHAR(20) NOT NULL, -- trade, bid, ask, etc.
exchange VARCHAR(32), -- Exchange identifier
sequence_number BIGINT, -- Exchange sequence number
conditions JSONB, -- Trade conditions/flags
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);
-- Candles table - stores OHLCV candlestick data
CREATE TABLE IF NOT EXISTS candles (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
symbol VARCHAR(32) NOT NULL,
period VARCHAR(10) NOT NULL, -- 1m, 5m, 15m, 1h, 1d, etc.
timestamp TIMESTAMP WITH TIME ZONE NOT NULL, -- Start of the period
open BIGINT NOT NULL, -- Opening price in fixed-point cents
high BIGINT NOT NULL, -- High price in fixed-point cents
low BIGINT NOT NULL, -- Low price in fixed-point cents
close BIGINT NOT NULL, -- Closing price in fixed-point cents
volume BIGINT NOT NULL DEFAULT 0, -- Total volume
trade_count INTEGER DEFAULT 0, -- Number of trades in period
vwap BIGINT, -- Volume-weighted average price
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
UNIQUE(symbol, period, timestamp)
);
-- Create indexes for optimal query performance
-- Prices table indexes
CREATE INDEX IF NOT EXISTS idx_prices_symbol_timestamp ON prices(symbol, timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_prices_timestamp ON prices(timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_prices_symbol ON prices(symbol);
-- Order book levels indexes
CREATE INDEX IF NOT EXISTS idx_order_book_levels_symbol_timestamp ON order_book_levels(symbol, timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_order_book_levels_symbol_side_timestamp ON order_book_levels(symbol, side, timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_order_book_levels_timestamp ON order_book_levels(timestamp DESC);
-- Technical indicators indexes
CREATE INDEX IF NOT EXISTS idx_technical_indicators_symbol_name_timestamp ON technical_indicators(symbol, indicator_name, timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_technical_indicators_timestamp ON technical_indicators(timestamp DESC);
-- Market ticks indexes
CREATE INDEX IF NOT EXISTS idx_market_ticks_symbol_timestamp ON market_ticks(symbol, timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_market_ticks_timestamp ON market_ticks(timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_market_ticks_sequence ON market_ticks(exchange, sequence_number);
-- Candles indexes
CREATE INDEX IF NOT EXISTS idx_candles_symbol_period_timestamp ON candles(symbol, period, timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_candles_timestamp ON candles(timestamp DESC);
-- Partitioning for large tables (commented out for initial setup, can be enabled later)
-- This would be useful for production deployments with high data volumes
/*
-- Example partitioning setup for prices table (by month)
-- CREATE TABLE prices_partitioned (LIKE prices INCLUDING ALL) PARTITION BY RANGE (timestamp);
-- CREATE TABLE prices_y2025m01 PARTITION OF prices_partitioned FOR VALUES FROM ('2025-01-01') TO ('2025-02-01');
-- CREATE TABLE prices_y2025m02 PARTITION OF prices_partitioned FOR VALUES FROM ('2025-02-01') TO ('2025-03-01');
-- ... continue for each month
*/
-- Add triggers for updating timestamps
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ language 'plpgsql';
-- Apply update trigger to candles table
CREATE TRIGGER update_candles_updated_at BEFORE UPDATE ON candles
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- Add comments for documentation
COMMENT ON TABLE prices IS 'Market price data with bid/ask/last prices and OHLCV data';
COMMENT ON TABLE order_book_levels IS 'Order book depth data with price levels and quantities';
COMMENT ON TABLE technical_indicators IS 'Computed technical indicators (RSI, MACD, etc.)';
COMMENT ON TABLE market_ticks IS 'Raw market tick data from exchanges';
COMMENT ON TABLE candles IS 'OHLCV candlestick data for various time periods';
-- Grant permissions (assuming the trading service user exists from previous migrations)
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'trading_service') THEN
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO trading_service;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO trading_service;
END IF;
END
$$;