broker_integration (5 tables): - broker_accounts: Cuentas MT4/MT5/API conectadas - broker_prices: Precios en tiempo real - spread_statistics: Estadisticas historicas de spread - price_adjustment_model: Modelos de ajuste de precio - trade_execution: Ejecucion de ordenes portfolio_management (6 tables): - portfolios: Portafolios de inversion - portfolio_accounts: Cuentas vinculadas a portafolios - investment_goals: Metas de inversion - rebalance_suggestions: Sugerencias de rebalanceo - portfolio_snapshots: Snapshots historicos - monte_carlo_projections: Proyecciones Monte Carlo Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
260 lines
9.0 KiB
PL/PgSQL
260 lines
9.0 KiB
PL/PgSQL
-- ============================================================================
|
|
-- SCHEMA: broker_integration
|
|
-- TABLE: spread_statistics, price_adjustment_model
|
|
-- DESCRIPTION: Estadisticas de spread y modelos de ajuste de precio
|
|
-- VERSION: 1.0.0
|
|
-- CREATED: 2026-01-16
|
|
-- SPRINT: Sprint 6 - DDL Implementation Roadmap Q1-2026
|
|
-- ============================================================================
|
|
|
|
-- Tabla de Estadisticas de Spread
|
|
CREATE TABLE IF NOT EXISTS broker_integration.spread_statistics (
|
|
-- Identificadores
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
broker_account_id UUID REFERENCES broker_integration.broker_accounts(id) ON DELETE CASCADE,
|
|
|
|
-- Simbolo y periodo
|
|
symbol VARCHAR(20) NOT NULL,
|
|
period_start TIMESTAMPTZ NOT NULL,
|
|
period_end TIMESTAMPTZ NOT NULL,
|
|
period_type VARCHAR(20) NOT NULL, -- 'hourly', 'daily', 'session'
|
|
|
|
-- Estadisticas de spread
|
|
spread_min DECIMAL(10, 4),
|
|
spread_max DECIMAL(10, 4),
|
|
spread_avg DECIMAL(10, 4),
|
|
spread_median DECIMAL(10, 4),
|
|
spread_stddev DECIMAL(10, 4),
|
|
spread_percentile_95 DECIMAL(10, 4),
|
|
|
|
-- Spread por sesion
|
|
spread_asia_avg DECIMAL(10, 4),
|
|
spread_london_avg DECIMAL(10, 4),
|
|
spread_ny_avg DECIMAL(10, 4),
|
|
|
|
-- Frecuencia de widening
|
|
widening_events INTEGER NOT NULL DEFAULT 0,
|
|
max_widening_factor DECIMAL(10, 2),
|
|
|
|
-- Samples
|
|
sample_count INTEGER NOT NULL DEFAULT 0,
|
|
trading_hours_covered INTEGER, -- Horas de trading cubiertas
|
|
|
|
-- Comparacion historica
|
|
spread_vs_7d_avg DECIMAL(10, 4), -- % vs promedio 7 dias
|
|
spread_vs_30d_avg DECIMAL(10, 4), -- % vs promedio 30 dias
|
|
|
|
-- Metadata
|
|
metadata JSONB DEFAULT '{}'::JSONB,
|
|
|
|
-- Timestamps
|
|
calculated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
-- Constraints
|
|
CONSTRAINT spread_stats_unique UNIQUE (broker_account_id, symbol, period_start, period_type)
|
|
);
|
|
|
|
COMMENT ON TABLE broker_integration.spread_statistics IS
|
|
'Estadisticas historicas de spread por simbolo, broker y periodo';
|
|
|
|
-- Indices
|
|
CREATE INDEX IF NOT EXISTS idx_spread_stats_account
|
|
ON broker_integration.spread_statistics(broker_account_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_spread_stats_symbol
|
|
ON broker_integration.spread_statistics(symbol, period_start DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_spread_stats_period
|
|
ON broker_integration.spread_statistics(period_type, period_start DESC);
|
|
|
|
-- ============================================================================
|
|
-- TABLE: price_adjustment_model
|
|
-- ============================================================================
|
|
|
|
-- Tabla de Modelos de Ajuste de Precio
|
|
CREATE TABLE IF NOT EXISTS broker_integration.price_adjustment_model (
|
|
-- Identificadores
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
|
|
-- Simbolo
|
|
symbol VARCHAR(20) NOT NULL,
|
|
|
|
-- Tipo de modelo
|
|
model_type VARCHAR(50) NOT NULL DEFAULT 'spread_based',
|
|
|
|
-- Parametros del modelo
|
|
base_spread_pips DECIMAL(10, 4) NOT NULL DEFAULT 1,
|
|
slippage_avg_pips DECIMAL(10, 4) NOT NULL DEFAULT 0.2,
|
|
slippage_max_pips DECIMAL(10, 4) NOT NULL DEFAULT 2,
|
|
|
|
-- Ajustes por sesion
|
|
asia_adjustment DECIMAL(5, 4) DEFAULT 1.2, -- Multiplicador
|
|
london_adjustment DECIMAL(5, 4) DEFAULT 1.0,
|
|
ny_adjustment DECIMAL(5, 4) DEFAULT 1.0,
|
|
overlap_adjustment DECIMAL(5, 4) DEFAULT 0.9, -- London-NY overlap
|
|
|
|
-- Ajustes por volatilidad
|
|
low_volatility_adjustment DECIMAL(5, 4) DEFAULT 0.8,
|
|
high_volatility_adjustment DECIMAL(5, 4) DEFAULT 1.5,
|
|
extreme_volatility_adjustment DECIMAL(5, 4) DEFAULT 2.5,
|
|
|
|
-- Ajustes por horario
|
|
market_open_adjustment DECIMAL(5, 4) DEFAULT 1.5,
|
|
market_close_adjustment DECIMAL(5, 4) DEFAULT 1.3,
|
|
news_event_adjustment DECIMAL(5, 4) DEFAULT 2.0,
|
|
|
|
-- Limites
|
|
max_total_adjustment DECIMAL(5, 2) DEFAULT 5.0, -- Max pips de ajuste total
|
|
min_acceptable_spread DECIMAL(10, 4),
|
|
max_acceptable_spread DECIMAL(10, 4),
|
|
|
|
-- Estado
|
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
|
|
-- Validez
|
|
valid_from TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
valid_until TIMESTAMPTZ,
|
|
|
|
-- Performance
|
|
accuracy_score DECIMAL(5, 2), -- 0-100
|
|
last_accuracy_check TIMESTAMPTZ,
|
|
predictions_count INTEGER NOT NULL DEFAULT 0,
|
|
accurate_predictions INTEGER NOT NULL DEFAULT 0,
|
|
|
|
-- Metadata
|
|
training_data_range JSONB, -- {"start": "...", "end": "..."}
|
|
metadata JSONB DEFAULT '{}'::JSONB,
|
|
notes TEXT,
|
|
|
|
-- Timestamps
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
-- Constraints
|
|
CONSTRAINT price_adj_model_unique UNIQUE (tenant_id, symbol, model_type)
|
|
);
|
|
|
|
COMMENT ON TABLE broker_integration.price_adjustment_model IS
|
|
'Modelos para ajustar precios de entrada considerando spread y slippage';
|
|
|
|
-- Indices
|
|
CREATE INDEX IF NOT EXISTS idx_price_adj_symbol
|
|
ON broker_integration.price_adjustment_model(symbol);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_price_adj_active
|
|
ON broker_integration.price_adjustment_model(symbol, is_active)
|
|
WHERE is_active = TRUE;
|
|
|
|
-- Funcion para calcular ajuste de precio
|
|
CREATE OR REPLACE FUNCTION broker_integration.calculate_price_adjustment(
|
|
p_symbol VARCHAR,
|
|
p_direction VARCHAR,
|
|
p_current_price DECIMAL,
|
|
p_session VARCHAR DEFAULT NULL,
|
|
p_volatility VARCHAR DEFAULT 'normal'
|
|
)
|
|
RETURNS TABLE (
|
|
adjusted_entry DECIMAL,
|
|
adjusted_sl DECIMAL,
|
|
adjusted_tp DECIMAL,
|
|
total_adjustment_pips DECIMAL,
|
|
adjustment_breakdown JSONB
|
|
) AS $$
|
|
DECLARE
|
|
v_model broker_integration.price_adjustment_model;
|
|
v_adjustment DECIMAL;
|
|
v_session_mult DECIMAL;
|
|
v_volatility_mult DECIMAL;
|
|
BEGIN
|
|
SELECT * INTO v_model
|
|
FROM broker_integration.price_adjustment_model
|
|
WHERE symbol = p_symbol
|
|
AND is_active = TRUE
|
|
AND (valid_until IS NULL OR valid_until > NOW())
|
|
ORDER BY valid_from DESC
|
|
LIMIT 1;
|
|
|
|
IF NOT FOUND THEN
|
|
-- Retornar sin ajuste
|
|
RETURN QUERY SELECT
|
|
p_current_price,
|
|
p_current_price,
|
|
p_current_price,
|
|
0::DECIMAL,
|
|
'{}'::JSONB;
|
|
RETURN;
|
|
END IF;
|
|
|
|
-- Determinar multiplicador de sesion
|
|
v_session_mult := CASE p_session
|
|
WHEN 'asia' THEN v_model.asia_adjustment
|
|
WHEN 'london' THEN v_model.london_adjustment
|
|
WHEN 'ny' THEN v_model.ny_adjustment
|
|
WHEN 'overlap' THEN v_model.overlap_adjustment
|
|
ELSE 1.0
|
|
END;
|
|
|
|
-- Determinar multiplicador de volatilidad
|
|
v_volatility_mult := CASE p_volatility
|
|
WHEN 'low' THEN v_model.low_volatility_adjustment
|
|
WHEN 'high' THEN v_model.high_volatility_adjustment
|
|
WHEN 'extreme' THEN v_model.extreme_volatility_adjustment
|
|
ELSE 1.0
|
|
END;
|
|
|
|
-- Calcular ajuste total en pips
|
|
v_adjustment := (v_model.base_spread_pips + v_model.slippage_avg_pips)
|
|
* v_session_mult * v_volatility_mult;
|
|
|
|
-- Limitar ajuste
|
|
v_adjustment := LEAST(v_adjustment, v_model.max_total_adjustment);
|
|
|
|
-- Convertir a precio
|
|
v_adjustment := v_adjustment * 0.0001; -- 1 pip = 0.0001
|
|
|
|
RETURN QUERY SELECT
|
|
CASE p_direction
|
|
WHEN 'long' THEN p_current_price + v_adjustment
|
|
ELSE p_current_price - v_adjustment
|
|
END,
|
|
p_current_price, -- SL sin ajustar
|
|
p_current_price, -- TP sin ajustar
|
|
v_adjustment * 10000, -- En pips
|
|
jsonb_build_object(
|
|
'base_spread', v_model.base_spread_pips,
|
|
'slippage', v_model.slippage_avg_pips,
|
|
'session_multiplier', v_session_mult,
|
|
'volatility_multiplier', v_volatility_mult
|
|
);
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
-- Trigger para updated_at
|
|
DROP TRIGGER IF EXISTS price_adj_updated_at ON broker_integration.price_adjustment_model;
|
|
CREATE TRIGGER price_adj_updated_at
|
|
BEFORE UPDATE ON broker_integration.price_adjustment_model
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION broker_integration.update_broker_timestamp();
|
|
|
|
-- RLS
|
|
ALTER TABLE broker_integration.spread_statistics ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE broker_integration.price_adjustment_model ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY spread_stats_tenant ON broker_integration.spread_statistics
|
|
FOR ALL
|
|
USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
|
|
|
|
CREATE POLICY price_adj_tenant ON broker_integration.price_adjustment_model
|
|
FOR ALL
|
|
USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
|
|
|
|
-- Grants
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON broker_integration.spread_statistics TO trading_app;
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON broker_integration.price_adjustment_model TO trading_app;
|
|
GRANT SELECT ON broker_integration.spread_statistics TO trading_readonly;
|
|
GRANT SELECT ON broker_integration.price_adjustment_model TO trading_readonly;
|
|
GRANT EXECUTE ON FUNCTION broker_integration.calculate_price_adjustment TO trading_app;
|