429 lines
14 KiB
SQL
429 lines
14 KiB
SQL
-- ============================================================================
|
|
-- OrbiQuant IA - Esquema TRADING
|
|
-- ============================================================================
|
|
-- Archivo: 03_trading_schema.sql
|
|
-- Descripción: Bots, señales, estrategias y operaciones de trading
|
|
-- Fecha: 2025-12-05
|
|
-- ============================================================================
|
|
|
|
SET search_path TO trading;
|
|
|
|
-- ============================================================================
|
|
-- TIPOS ENUMERADOS
|
|
-- ============================================================================
|
|
|
|
CREATE TYPE bot_status_enum AS ENUM ('active', 'paused', 'stopped', 'error', 'maintenance');
|
|
CREATE TYPE signal_status_enum AS ENUM ('pending', 'active', 'triggered', 'expired', 'cancelled');
|
|
CREATE TYPE position_status_enum AS ENUM ('open', 'closed', 'pending');
|
|
CREATE TYPE timeframe_enum AS ENUM ('1m', '5m', '15m', '30m', '1h', '4h', '1d', '1w');
|
|
CREATE TYPE amd_phase_enum AS ENUM ('accumulation', 'manipulation', 'distribution', 'unknown');
|
|
CREATE TYPE volatility_regime_enum AS ENUM ('low', 'medium', 'high', 'extreme');
|
|
|
|
-- ============================================================================
|
|
-- TABLA: symbols
|
|
-- Descripción: Instrumentos financieros disponibles
|
|
-- ============================================================================
|
|
CREATE TABLE IF NOT EXISTS symbols (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
|
|
-- Identificación
|
|
symbol VARCHAR(20) NOT NULL UNIQUE, -- 'XAUUSD', 'EURUSD', 'BTCUSD'
|
|
name VARCHAR(100) NOT NULL,
|
|
description TEXT,
|
|
|
|
-- Clasificación
|
|
asset_class VARCHAR(50), -- 'forex', 'crypto', 'commodities', 'indices', 'stocks'
|
|
base_currency VARCHAR(10),
|
|
quote_currency VARCHAR(10),
|
|
|
|
-- Trading info
|
|
pip_value DECIMAL(10,6),
|
|
lot_size DECIMAL(10,2),
|
|
min_lot DECIMAL(10,4),
|
|
max_lot DECIMAL(10,2),
|
|
tick_size DECIMAL(10,6),
|
|
|
|
-- Estado
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|
trading_hours JSONB, -- [{day, open, close}]
|
|
|
|
-- Data provider
|
|
data_provider VARCHAR(50),
|
|
provider_symbol VARCHAR(50),
|
|
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX idx_symbols_symbol ON symbols(symbol);
|
|
CREATE INDEX idx_symbols_asset_class ON symbols(asset_class);
|
|
|
|
-- ============================================================================
|
|
-- TABLA: strategies
|
|
-- Descripción: Estrategias de trading disponibles
|
|
-- ============================================================================
|
|
CREATE TABLE IF NOT EXISTS strategies (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
|
|
name VARCHAR(100) NOT NULL,
|
|
slug VARCHAR(100) NOT NULL UNIQUE,
|
|
description TEXT,
|
|
|
|
-- Tipo
|
|
strategy_type VARCHAR(50), -- 'intraday', 'swing', 'scalping', 'position'
|
|
|
|
-- Configuración
|
|
default_timeframe timeframe_enum DEFAULT '15m',
|
|
supported_symbols TEXT[], -- NULL = todos
|
|
risk_reward_ratio DECIMAL(4,2) DEFAULT 2.0,
|
|
|
|
-- Parámetros configurables (JSON Schema)
|
|
parameters_schema JSONB,
|
|
default_parameters JSONB,
|
|
|
|
-- ML Model asociado
|
|
uses_ml_model BOOLEAN DEFAULT TRUE,
|
|
ml_model_id UUID, -- Referencia a ml.models
|
|
|
|
-- AMD
|
|
uses_amd BOOLEAN DEFAULT TRUE,
|
|
favorable_phases amd_phase_enum[],
|
|
|
|
-- Estado
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX idx_strategies_slug ON strategies(slug);
|
|
|
|
-- ============================================================================
|
|
-- TABLA: bots (Agentes de Trading)
|
|
-- Descripción: Instancias de bots/agentes de trading
|
|
-- ============================================================================
|
|
CREATE TABLE IF NOT EXISTS bots (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
|
|
-- Identificación
|
|
name VARCHAR(100) NOT NULL,
|
|
slug VARCHAR(100) NOT NULL UNIQUE,
|
|
description TEXT,
|
|
avatar_url TEXT,
|
|
|
|
-- Perfil de riesgo
|
|
risk_profile public.risk_profile_enum NOT NULL,
|
|
|
|
-- Objetivos
|
|
target_monthly_return DECIMAL(5,2), -- % objetivo
|
|
max_drawdown DECIMAL(5,2), -- % máximo
|
|
max_position_size DECIMAL(5,2), -- % del capital
|
|
|
|
-- Estrategias
|
|
strategy_id UUID REFERENCES strategies(id),
|
|
strategy_parameters JSONB,
|
|
|
|
-- Configuración
|
|
supported_symbols TEXT[],
|
|
default_timeframe timeframe_enum DEFAULT '15m',
|
|
min_confidence DECIMAL(3,2) DEFAULT 0.55,
|
|
|
|
-- Horarios de operación
|
|
trading_schedule JSONB, -- Horarios permitidos
|
|
|
|
-- Estado
|
|
status bot_status_enum DEFAULT 'stopped',
|
|
last_activity_at TIMESTAMPTZ,
|
|
error_message TEXT,
|
|
|
|
-- Métricas globales (actualizadas periódicamente)
|
|
total_trades INT DEFAULT 0,
|
|
winning_trades INT DEFAULT 0,
|
|
total_profit DECIMAL(15,2) DEFAULT 0,
|
|
sharpe_ratio DECIMAL(5,2),
|
|
sortino_ratio DECIMAL(5,2),
|
|
max_drawdown_actual DECIMAL(5,2),
|
|
|
|
-- Público
|
|
is_public BOOLEAN DEFAULT TRUE, -- Visible para asignar a cuentas
|
|
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX idx_bots_slug ON bots(slug);
|
|
CREATE INDEX idx_bots_risk_profile ON bots(risk_profile);
|
|
CREATE INDEX idx_bots_status ON bots(status);
|
|
|
|
-- ============================================================================
|
|
-- TABLA: signals
|
|
-- Descripción: Señales de trading generadas
|
|
-- ============================================================================
|
|
CREATE TABLE IF NOT EXISTS signals (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
|
|
-- Origen
|
|
bot_id UUID REFERENCES bots(id),
|
|
strategy_id UUID REFERENCES strategies(id),
|
|
symbol_id UUID REFERENCES symbols(id),
|
|
symbol VARCHAR(20) NOT NULL,
|
|
|
|
-- Señal
|
|
direction public.trade_direction_enum NOT NULL,
|
|
timeframe timeframe_enum NOT NULL,
|
|
|
|
-- Precios
|
|
entry_price DECIMAL(20,8) NOT NULL,
|
|
stop_loss DECIMAL(20,8) NOT NULL,
|
|
take_profit DECIMAL(20,8) NOT NULL,
|
|
current_price DECIMAL(20,8),
|
|
|
|
-- Predicción ML
|
|
predicted_delta_high DECIMAL(20,8),
|
|
predicted_delta_low DECIMAL(20,8),
|
|
prob_tp_first DECIMAL(5,4), -- Probabilidad de tocar TP antes que SL
|
|
confidence_score DECIMAL(5,4),
|
|
|
|
-- Contexto de mercado
|
|
amd_phase amd_phase_enum,
|
|
volatility_regime volatility_regime_enum,
|
|
market_context JSONB, -- Datos adicionales del contexto
|
|
|
|
-- R:R
|
|
risk_reward_ratio DECIMAL(4,2),
|
|
risk_pips DECIMAL(10,4),
|
|
reward_pips DECIMAL(10,4),
|
|
|
|
-- Estado
|
|
status signal_status_enum DEFAULT 'pending',
|
|
triggered_at TIMESTAMPTZ,
|
|
expired_at TIMESTAMPTZ,
|
|
|
|
-- Resultado (si se operó)
|
|
outcome VARCHAR(20), -- 'tp_hit', 'sl_hit', 'manual_close', 'expired'
|
|
pnl DECIMAL(15,2),
|
|
|
|
-- Timestamps
|
|
valid_until TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX idx_signals_bot ON signals(bot_id);
|
|
CREATE INDEX idx_signals_symbol ON signals(symbol);
|
|
CREATE INDEX idx_signals_status ON signals(status);
|
|
CREATE INDEX idx_signals_created ON signals(created_at DESC);
|
|
CREATE INDEX idx_signals_direction ON signals(direction);
|
|
|
|
-- ============================================================================
|
|
-- TABLA: positions
|
|
-- Descripción: Posiciones de trading (abiertas y cerradas)
|
|
-- ============================================================================
|
|
CREATE TABLE IF NOT EXISTS positions (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
|
|
-- Referencias
|
|
bot_id UUID REFERENCES bots(id),
|
|
signal_id UUID REFERENCES signals(id),
|
|
investment_account_id UUID, -- Referencia a investment.accounts
|
|
symbol_id UUID REFERENCES symbols(id),
|
|
symbol VARCHAR(20) NOT NULL,
|
|
|
|
-- Posición
|
|
direction public.trade_direction_enum NOT NULL,
|
|
lot_size DECIMAL(10,4) NOT NULL,
|
|
|
|
-- Precios
|
|
entry_price DECIMAL(20,8) NOT NULL,
|
|
stop_loss DECIMAL(20,8),
|
|
take_profit DECIMAL(20,8),
|
|
exit_price DECIMAL(20,8),
|
|
|
|
-- Broker
|
|
broker_order_id VARCHAR(100),
|
|
broker_position_id VARCHAR(100),
|
|
|
|
-- Estado
|
|
status position_status_enum DEFAULT 'open',
|
|
opened_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
closed_at TIMESTAMPTZ,
|
|
close_reason VARCHAR(50), -- 'tp', 'sl', 'manual', 'forced', 'margin_call'
|
|
|
|
-- P&L
|
|
realized_pnl DECIMAL(15,2),
|
|
unrealized_pnl DECIMAL(15,2),
|
|
commission DECIMAL(10,2) DEFAULT 0,
|
|
swap DECIMAL(10,2) DEFAULT 0,
|
|
|
|
-- Metadata
|
|
metadata JSONB,
|
|
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX idx_positions_bot ON positions(bot_id);
|
|
CREATE INDEX idx_positions_signal ON positions(signal_id);
|
|
CREATE INDEX idx_positions_account ON positions(investment_account_id);
|
|
CREATE INDEX idx_positions_status ON positions(status);
|
|
CREATE INDEX idx_positions_opened ON positions(opened_at DESC);
|
|
|
|
-- ============================================================================
|
|
-- TABLA: price_alerts
|
|
-- Descripción: Alertas de precio configuradas por usuarios
|
|
-- ============================================================================
|
|
CREATE TYPE alert_condition_enum AS ENUM ('above', 'below', 'crosses_above', 'crosses_below');
|
|
|
|
CREATE TABLE IF NOT EXISTS price_alerts (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
|
|
symbol VARCHAR(20) NOT NULL,
|
|
condition alert_condition_enum NOT NULL,
|
|
price DECIMAL(20,8) NOT NULL,
|
|
note TEXT,
|
|
|
|
-- Estado
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|
triggered_at TIMESTAMPTZ,
|
|
triggered_price DECIMAL(20,8),
|
|
|
|
-- Notificación
|
|
notify_email BOOLEAN DEFAULT TRUE,
|
|
notify_push BOOLEAN DEFAULT TRUE,
|
|
|
|
-- Recurrencia
|
|
is_recurring BOOLEAN DEFAULT FALSE, -- Si se reactiva después de triggear
|
|
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX idx_price_alerts_user ON price_alerts(user_id);
|
|
CREATE INDEX idx_price_alerts_symbol ON price_alerts(symbol);
|
|
CREATE INDEX idx_price_alerts_active ON price_alerts(is_active) WHERE is_active = TRUE;
|
|
|
|
-- ============================================================================
|
|
-- TABLA: watchlists
|
|
-- Descripción: Listas de seguimiento de usuarios
|
|
-- ============================================================================
|
|
CREATE TABLE IF NOT EXISTS watchlists (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
|
|
name VARCHAR(100) NOT NULL,
|
|
is_default BOOLEAN DEFAULT FALSE,
|
|
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX idx_watchlists_user ON watchlists(user_id);
|
|
|
|
-- ============================================================================
|
|
-- TABLA: watchlist_items
|
|
-- Descripción: Items en watchlists
|
|
-- ============================================================================
|
|
CREATE TABLE IF NOT EXISTS watchlist_items (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
watchlist_id UUID NOT NULL REFERENCES watchlists(id) ON DELETE CASCADE,
|
|
|
|
symbol VARCHAR(20) NOT NULL,
|
|
sort_order INT DEFAULT 0,
|
|
notes TEXT,
|
|
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
UNIQUE(watchlist_id, symbol)
|
|
);
|
|
|
|
CREATE INDEX idx_watchlist_items_watchlist ON watchlist_items(watchlist_id);
|
|
|
|
-- ============================================================================
|
|
-- TABLA: paper_trading_accounts
|
|
-- Descripción: Cuentas de paper trading (simulación)
|
|
-- ============================================================================
|
|
CREATE TABLE IF NOT EXISTS paper_trading_accounts (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
|
|
name VARCHAR(100) DEFAULT 'Paper Account',
|
|
initial_balance DECIMAL(15,2) NOT NULL DEFAULT 100000,
|
|
current_balance DECIMAL(15,2) NOT NULL DEFAULT 100000,
|
|
currency CHAR(3) DEFAULT 'USD',
|
|
|
|
-- Métricas
|
|
total_trades INT DEFAULT 0,
|
|
winning_trades INT DEFAULT 0,
|
|
total_pnl DECIMAL(15,2) DEFAULT 0,
|
|
max_drawdown DECIMAL(5,2) DEFAULT 0,
|
|
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX idx_paper_accounts_user ON paper_trading_accounts(user_id);
|
|
|
|
-- ============================================================================
|
|
-- TABLA: paper_trading_positions
|
|
-- Descripción: Posiciones de paper trading
|
|
-- ============================================================================
|
|
CREATE TABLE IF NOT EXISTS paper_trading_positions (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
account_id UUID NOT NULL REFERENCES paper_trading_accounts(id) ON DELETE CASCADE,
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
|
|
symbol VARCHAR(20) NOT NULL,
|
|
direction public.trade_direction_enum NOT NULL,
|
|
lot_size DECIMAL(10,4) NOT NULL,
|
|
|
|
entry_price DECIMAL(20,8) NOT NULL,
|
|
stop_loss DECIMAL(20,8),
|
|
take_profit DECIMAL(20,8),
|
|
exit_price DECIMAL(20,8),
|
|
|
|
status position_status_enum DEFAULT 'open',
|
|
opened_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
closed_at TIMESTAMPTZ,
|
|
close_reason VARCHAR(50),
|
|
|
|
realized_pnl DECIMAL(15,2),
|
|
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX idx_paper_positions_account ON paper_trading_positions(account_id);
|
|
CREATE INDEX idx_paper_positions_user ON paper_trading_positions(user_id);
|
|
CREATE INDEX idx_paper_positions_status ON paper_trading_positions(status);
|
|
|
|
-- ============================================================================
|
|
-- TRIGGERS
|
|
-- ============================================================================
|
|
|
|
CREATE TRIGGER update_symbols_updated_at
|
|
BEFORE UPDATE ON symbols
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION public.update_updated_at_column();
|
|
|
|
CREATE TRIGGER update_strategies_updated_at
|
|
BEFORE UPDATE ON strategies
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION public.update_updated_at_column();
|
|
|
|
CREATE TRIGGER update_bots_updated_at
|
|
BEFORE UPDATE ON bots
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION public.update_updated_at_column();
|
|
|
|
CREATE TRIGGER update_signals_updated_at
|
|
BEFORE UPDATE ON signals
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION public.update_updated_at_column();
|
|
|
|
CREATE TRIGGER update_positions_updated_at
|
|
BEFORE UPDATE ON positions
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION public.update_updated_at_column();
|