Major Changes: - Migrated from 3-action TradingAction to 45-action FactoredAction - 45 actions: 5 exposure × 3 order types × 3 urgency levels - Absolute exposure model (target positions -1.0 to +1.0) - Transaction cost differentiation (Market 0.15%, LimitMaker 0.05%, IoC 0.10%) - Fixed action diversity threshold (1.11% → 0.5% for 45-action space) Bug Fixes: - Bug #15: Incomplete FactoredAction integration (code existed but unused) - Bug #16: Runtime crash in action diversity checking (hardcoded 3-action match) Code Changes (13 files, ~464 lines): - ml/src/dqn/action_space.rs: Core FactoredAction + 4 helper methods - ml/src/trainers/dqn.rs: Action diversity refactored (3→45 dynamic) - ml/src/dqn/reward.rs: calculate_reward() signature updated - ml/src/dqn/portfolio_tracker.rs: execute_action() absolute exposure - ml/src/dqn/dqn.rs: WorkingDQN action selection migrated - ml/tests/*.rs: 9 test files updated with FactoredAction assertions Test Results: - 1-epoch smoke test: 100% action diversity (45/45 actions, 80.2s) - 10-epoch production: 87.8% readiness (79/90 scorecard, 14.0 min) - Loss convergence: 96.9% reduction (119K → 3.6K) - Action diversity: 100% → 44% (healthy specialization) - Checkpoint reliability: 12/12 files saved (100%) - DQN tests: 195/195 passing (100%) - ML baseline: 1,514/1,515 passing (99.93%) Production Status: ✅ CERTIFIED (87.8% readiness) Go/No-Go: ✅ GO FOR 100-EPOCH PRODUCTION TRAINING 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
157 lines
7.9 KiB
PL/PgSQL
157 lines
7.9 KiB
PL/PgSQL
-- Migration 046: Broker Integration (AMP Futures / CQG FIX API)
|
|
-- Description: Database schema for FIX order routing, execution tracking, and session management
|
|
-- Date: 2025-11-09
|
|
|
|
BEGIN;
|
|
|
|
-- ============================================================================
|
|
-- broker_orders: Audit trail for all broker orders
|
|
-- ============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS broker_orders (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
client_order_id VARCHAR(64) NOT NULL UNIQUE, -- Our ClOrdID (Tag 11)
|
|
broker_order_id VARCHAR(64), -- Broker OrderID (Tag 37, nullable until ACK)
|
|
account_id VARCHAR(64) NOT NULL, -- AMP account identifier
|
|
symbol VARCHAR(32) NOT NULL, -- ES, NQ, etc.
|
|
side VARCHAR(4) NOT NULL, -- BUY, SELL
|
|
order_type VARCHAR(16) NOT NULL, -- MARKET, LIMIT, STOP, STOP_LIMIT
|
|
quantity NUMERIC(18, 8) NOT NULL, -- Contracts
|
|
price NUMERIC(18, 8), -- NULL for market orders
|
|
stop_price NUMERIC(18, 8), -- For stop orders
|
|
time_in_force VARCHAR(8) NOT NULL DEFAULT 'DAY', -- DAY, IOC, GTC
|
|
status VARCHAR(32) NOT NULL, -- PENDING_SUBMIT, SUBMITTED, FILLED, etc.
|
|
filled_quantity NUMERIC(18, 8) DEFAULT 0, -- Cumulative filled quantity
|
|
avg_fill_price NUMERIC(18, 8), -- Average fill price
|
|
metadata JSONB, -- Strategy, model_name, etc.
|
|
submitted_at TIMESTAMPTZ, -- When submitted to broker
|
|
filled_at TIMESTAMPTZ, -- When fully filled
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Indexes for broker_orders
|
|
CREATE INDEX idx_broker_orders_client_order_id ON broker_orders(client_order_id);
|
|
CREATE INDEX idx_broker_orders_broker_order_id ON broker_orders(broker_order_id) WHERE broker_order_id IS NOT NULL;
|
|
CREATE INDEX idx_broker_orders_account ON broker_orders(account_id);
|
|
CREATE INDEX idx_broker_orders_status ON broker_orders(status);
|
|
CREATE INDEX idx_broker_orders_symbol ON broker_orders(symbol);
|
|
CREATE INDEX idx_broker_orders_created_at ON broker_orders(created_at DESC);
|
|
|
|
-- ============================================================================
|
|
-- broker_executions: Execution reports from broker
|
|
-- ============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS broker_executions (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
execution_id VARCHAR(64) NOT NULL UNIQUE, -- ExecID (Tag 17)
|
|
broker_order_id VARCHAR(64) NOT NULL, -- OrderID (Tag 37)
|
|
client_order_id VARCHAR(64) NOT NULL, -- ClOrdID (Tag 11)
|
|
symbol VARCHAR(32) NOT NULL,
|
|
side VARCHAR(4) NOT NULL, -- BUY, SELL
|
|
exec_type VARCHAR(16) NOT NULL, -- NEW, TRADE, CANCELED, REJECTED
|
|
order_status VARCHAR(32) NOT NULL, -- Order status after this execution
|
|
last_qty NUMERIC(18, 8), -- Quantity filled in this report (Tag 32)
|
|
last_price NUMERIC(18, 8), -- Fill price (Tag 31)
|
|
cum_qty NUMERIC(18, 8), -- Total filled quantity (Tag 14)
|
|
avg_price NUMERIC(18, 8), -- Average fill price (Tag 6)
|
|
commission NUMERIC(18, 8), -- Commission charged
|
|
transact_time TIMESTAMPTZ NOT NULL, -- Exchange execution time
|
|
text TEXT, -- Reject reason or notes
|
|
raw_fix_message TEXT, -- Full FIX message for audit
|
|
received_at TIMESTAMPTZ DEFAULT NOW(),
|
|
|
|
CONSTRAINT fk_broker_executions_order
|
|
FOREIGN KEY (client_order_id)
|
|
REFERENCES broker_orders(client_order_id)
|
|
ON DELETE CASCADE
|
|
);
|
|
|
|
-- Indexes for broker_executions
|
|
CREATE INDEX idx_broker_executions_execution_id ON broker_executions(execution_id);
|
|
CREATE INDEX idx_broker_executions_broker_order_id ON broker_executions(broker_order_id);
|
|
CREATE INDEX idx_broker_executions_client_order_id ON broker_executions(client_order_id);
|
|
CREATE INDEX idx_broker_executions_symbol ON broker_executions(symbol);
|
|
CREATE INDEX idx_broker_executions_transact_time ON broker_executions(transact_time DESC);
|
|
CREATE INDEX idx_broker_executions_exec_type ON broker_executions(exec_type);
|
|
|
|
-- ============================================================================
|
|
-- fix_sessions: FIX session state for recovery
|
|
-- ============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS fix_sessions (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
session_id VARCHAR(128) NOT NULL UNIQUE, -- "FOXHUNT_CLIENT-CQG"
|
|
sender_comp_id VARCHAR(64) NOT NULL, -- Tag 49 (SenderCompID)
|
|
target_comp_id VARCHAR(64) NOT NULL, -- Tag 56 (TargetCompID)
|
|
sender_seq_num BIGINT NOT NULL DEFAULT 1, -- Our outgoing sequence number
|
|
target_seq_num BIGINT NOT NULL DEFAULT 1, -- Expected incoming sequence number
|
|
session_state VARCHAR(32) NOT NULL, -- DISCONNECTED, CONNECTED, ACTIVE, etc.
|
|
last_heartbeat_sent TIMESTAMPTZ,
|
|
last_heartbeat_received TIMESTAMPTZ,
|
|
connected_at TIMESTAMPTZ,
|
|
disconnected_at TIMESTAMPTZ,
|
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Indexes for fix_sessions
|
|
CREATE INDEX idx_fix_sessions_session_id ON fix_sessions(session_id);
|
|
CREATE INDEX idx_fix_sessions_state ON fix_sessions(session_state);
|
|
|
|
-- ============================================================================
|
|
-- broker_account_state: Real-time account balances and positions
|
|
-- ============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS broker_account_state (
|
|
account_id VARCHAR(64) PRIMARY KEY,
|
|
cash_balance NUMERIC(18, 2) NOT NULL,
|
|
equity NUMERIC(18, 2) NOT NULL,
|
|
margin_used NUMERIC(18, 2) NOT NULL,
|
|
margin_available NUMERIC(18, 2) NOT NULL,
|
|
buying_power NUMERIC(18, 2) NOT NULL,
|
|
unrealized_pnl NUMERIC(18, 2) DEFAULT 0,
|
|
realized_pnl NUMERIC(18, 2) DEFAULT 0,
|
|
last_updated TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Index for broker_account_state
|
|
CREATE INDEX idx_broker_account_state_last_updated ON broker_account_state(last_updated DESC);
|
|
|
|
-- ============================================================================
|
|
-- broker_positions: Real-time position tracking per symbol
|
|
-- ============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS broker_positions (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
account_id VARCHAR(64) NOT NULL,
|
|
symbol VARCHAR(32) NOT NULL,
|
|
quantity NUMERIC(18, 8) NOT NULL DEFAULT 0, -- Positive = long, negative = short
|
|
average_price NUMERIC(18, 8),
|
|
market_value NUMERIC(18, 2),
|
|
unrealized_pnl NUMERIC(18, 2) DEFAULT 0,
|
|
last_updated TIMESTAMPTZ DEFAULT NOW(),
|
|
|
|
CONSTRAINT uq_broker_positions_account_symbol UNIQUE (account_id, symbol)
|
|
);
|
|
|
|
-- Indexes for broker_positions
|
|
CREATE INDEX idx_broker_positions_account ON broker_positions(account_id);
|
|
CREATE INDEX idx_broker_positions_symbol ON broker_positions(symbol);
|
|
CREATE INDEX idx_broker_positions_last_updated ON broker_positions(last_updated DESC);
|
|
|
|
-- ============================================================================
|
|
-- Grant permissions
|
|
-- ============================================================================
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON broker_orders TO foxhunt;
|
|
GRANT SELECT, INSERT ON broker_executions TO foxhunt;
|
|
GRANT SELECT, INSERT, UPDATE ON fix_sessions TO foxhunt;
|
|
GRANT SELECT, INSERT, UPDATE ON broker_account_state TO foxhunt;
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON broker_positions TO foxhunt;
|
|
|
|
-- ============================================================================
|
|
-- Commit migration
|
|
-- ============================================================================
|
|
|
|
COMMIT;
|