[TASK-2026-02-03-ANALISIS-DDL-MODELADO] feat(ddl): FASE-3 Moderate P1 gaps
ST-3.1: Course tags system - education.course_tags with slug, color, featured flag - education.course_tag_assignments (M:N) with auto usage_count - Seeds: 10 initial tags (forex, crypto, ICT, etc.) ST-3.2: Drawing tools for charts - Enum: trading.drawing_tool_type (18 types including ICT) - trading.drawing_tools with JSONB points and styles - trading.drawing_templates for reusable presets ST-3.3: Complete agent_executions - Added 10 columns: execution_time_ms, slippage, risk_score, etc. - 5 new performance indexes - Trigger for updated_at ST-3.4: ML composite indexes - 8 new composite/partial indexes for predictions - Optimized for symbol+timeframe+date queries - Partial indexes for high confidence and overlay display New files: 7 DDL, 2 migrations, 1 seed Modified: 3 existing DDL files Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
f64251e459
commit
6da2786590
47
ddl/schemas/education/tables/18-course_tags.sql
Normal file
47
ddl/schemas/education/tables/18-course_tags.sql
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
-- =====================================================
|
||||||
|
-- TABLE: education.course_tags
|
||||||
|
-- =====================================================
|
||||||
|
-- Proyecto: OrbiQuant IA (Trading Platform)
|
||||||
|
-- Modulo: OQI-002 - Education
|
||||||
|
-- Purpose: Tags for categorizing and searching courses
|
||||||
|
-- Related: OQI-002 Education Module, GAP-005
|
||||||
|
-- Created: 2026-02-03
|
||||||
|
-- =====================================================
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS education.course_tags (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
name VARCHAR(50) NOT NULL,
|
||||||
|
slug VARCHAR(50) NOT NULL UNIQUE,
|
||||||
|
description TEXT,
|
||||||
|
color VARCHAR(7) DEFAULT '#6B7280', -- Hex color for UI
|
||||||
|
icon VARCHAR(50), -- Icon identifier
|
||||||
|
is_featured BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
usage_count INTEGER NOT NULL DEFAULT 0,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
|
||||||
|
CONSTRAINT course_tags_name_not_empty CHECK (length(trim(name)) > 0),
|
||||||
|
CONSTRAINT course_tags_slug_format CHECK (slug ~ '^[a-z0-9-]+$'),
|
||||||
|
CONSTRAINT course_tags_color_format CHECK (color ~ '^#[0-9A-Fa-f]{6}$'),
|
||||||
|
CONSTRAINT course_tags_usage_positive CHECK (usage_count >= 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Indexes
|
||||||
|
CREATE INDEX idx_course_tags_slug ON education.course_tags(slug);
|
||||||
|
CREATE INDEX idx_course_tags_name ON education.course_tags(name);
|
||||||
|
CREATE INDEX idx_course_tags_featured ON education.course_tags(is_featured) WHERE is_featured = true;
|
||||||
|
CREATE INDEX idx_course_tags_usage ON education.course_tags(usage_count DESC);
|
||||||
|
|
||||||
|
-- Trigger
|
||||||
|
CREATE TRIGGER trg_course_tags_updated_at
|
||||||
|
BEFORE UPDATE ON education.course_tags
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION public.update_updated_at();
|
||||||
|
|
||||||
|
-- Comments
|
||||||
|
COMMENT ON TABLE education.course_tags IS 'Tags for categorizing courses (e.g., forex, crypto, technical-analysis)';
|
||||||
|
COMMENT ON COLUMN education.course_tags.slug IS 'URL-friendly identifier for the tag';
|
||||||
|
COMMENT ON COLUMN education.course_tags.color IS 'Hex color code for UI display';
|
||||||
|
COMMENT ON COLUMN education.course_tags.icon IS 'Icon identifier for UI display';
|
||||||
|
COMMENT ON COLUMN education.course_tags.is_featured IS 'Whether tag appears in featured/promoted sections';
|
||||||
|
COMMENT ON COLUMN education.course_tags.usage_count IS 'Denormalized count of courses using this tag';
|
||||||
50
ddl/schemas/education/tables/19-course_tag_assignments.sql
Normal file
50
ddl/schemas/education/tables/19-course_tag_assignments.sql
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
-- =====================================================
|
||||||
|
-- TABLE: education.course_tag_assignments
|
||||||
|
-- =====================================================
|
||||||
|
-- Proyecto: OrbiQuant IA (Trading Platform)
|
||||||
|
-- Modulo: OQI-002 - Education
|
||||||
|
-- Purpose: Many-to-many relationship between courses and tags
|
||||||
|
-- Related: OQI-002 Education Module, GAP-005
|
||||||
|
-- Created: 2026-02-03
|
||||||
|
-- =====================================================
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS education.course_tag_assignments (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
course_id UUID NOT NULL REFERENCES education.courses(id) ON DELETE CASCADE,
|
||||||
|
tag_id UUID NOT NULL REFERENCES education.course_tags(id) ON DELETE CASCADE,
|
||||||
|
assigned_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
assigned_by UUID REFERENCES auth.users(id),
|
||||||
|
|
||||||
|
CONSTRAINT unique_course_tag UNIQUE (course_id, tag_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Indexes
|
||||||
|
CREATE INDEX idx_course_tag_assignments_course ON education.course_tag_assignments(course_id);
|
||||||
|
CREATE INDEX idx_course_tag_assignments_tag ON education.course_tag_assignments(tag_id);
|
||||||
|
|
||||||
|
-- Function to update usage_count on course_tags
|
||||||
|
CREATE OR REPLACE FUNCTION education.update_tag_usage_count()
|
||||||
|
RETURNS TRIGGER AS $$
|
||||||
|
BEGIN
|
||||||
|
IF TG_OP = 'INSERT' THEN
|
||||||
|
UPDATE education.course_tags SET usage_count = usage_count + 1 WHERE id = NEW.tag_id;
|
||||||
|
ELSIF TG_OP = 'DELETE' THEN
|
||||||
|
UPDATE education.course_tags SET usage_count = usage_count - 1 WHERE id = OLD.tag_id;
|
||||||
|
END IF;
|
||||||
|
RETURN NULL;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
-- Trigger to maintain usage_count
|
||||||
|
CREATE TRIGGER trg_course_tag_usage
|
||||||
|
AFTER INSERT OR DELETE ON education.course_tag_assignments
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION education.update_tag_usage_count();
|
||||||
|
|
||||||
|
-- Comments
|
||||||
|
COMMENT ON TABLE education.course_tag_assignments IS 'Junction table for course-tag relationships';
|
||||||
|
COMMENT ON COLUMN education.course_tag_assignments.course_id IS 'Reference to the course';
|
||||||
|
COMMENT ON COLUMN education.course_tag_assignments.tag_id IS 'Reference to the tag';
|
||||||
|
COMMENT ON COLUMN education.course_tag_assignments.assigned_at IS 'When the tag was assigned to the course';
|
||||||
|
COMMENT ON COLUMN education.course_tag_assignments.assigned_by IS 'User who assigned the tag (optional)';
|
||||||
|
COMMENT ON FUNCTION education.update_tag_usage_count() IS 'Maintains denormalized usage_count in course_tags table';
|
||||||
@ -3,8 +3,11 @@
|
|||||||
-- =====================================================
|
-- =====================================================
|
||||||
-- Description: Tracking de ejecuciones de trading agents
|
-- Description: Tracking de ejecuciones de trading agents
|
||||||
-- Schema: investment
|
-- Schema: investment
|
||||||
-- Gap: GAP-DDL-005
|
-- Gap: GAP-DDL-005, GAP-007
|
||||||
|
-- Task: ST-3.3
|
||||||
-- Created: 2026-02-03
|
-- Created: 2026-02-03
|
||||||
|
-- Updated: 2026-02-03
|
||||||
|
-- Related: OQI-004 Investment Accounts
|
||||||
-- =====================================================
|
-- =====================================================
|
||||||
|
|
||||||
CREATE TABLE investment.agent_executions (
|
CREATE TABLE investment.agent_executions (
|
||||||
@ -21,55 +24,149 @@ CREATE TABLE investment.agent_executions (
|
|||||||
execution_type IN ('trade', 'rebalance', 'distribution', 'stop_loss', 'take_profit', 'hedge')
|
execution_type IN ('trade', 'rebalance', 'distribution', 'stop_loss', 'take_profit', 'hedge')
|
||||||
),
|
),
|
||||||
|
|
||||||
-- Detalles del trade (si aplica)
|
-- Detalles del trade
|
||||||
symbol VARCHAR(20),
|
symbol VARCHAR(20),
|
||||||
side VARCHAR(4) CHECK (side IN ('buy', 'sell')),
|
side VARCHAR(4) CHECK (side IN ('buy', 'sell')),
|
||||||
quantity DECIMAL(20,8),
|
quantity DECIMAL(20,8),
|
||||||
entry_price DECIMAL(20,8),
|
entry_price DECIMAL(20,8),
|
||||||
exit_price DECIMAL(20,8),
|
exit_price DECIMAL(20,8),
|
||||||
|
|
||||||
-- Resultado
|
-- Resultado (P&L)
|
||||||
pnl DECIMAL(20,8),
|
pnl DECIMAL(20,8),
|
||||||
pnl_percentage DECIMAL(8,4),
|
pnl_percentage DECIMAL(8,4),
|
||||||
fees DECIMAL(20,8) DEFAULT 0,
|
fees DECIMAL(20,8) DEFAULT 0,
|
||||||
|
|
||||||
-- Detalles adicionales
|
-- Metricas de ejecucion
|
||||||
|
execution_time_ms INTEGER,
|
||||||
|
slippage DECIMAL(20,8),
|
||||||
|
|
||||||
|
-- Metricas de riesgo
|
||||||
|
risk_score DECIMAL(5,4) CHECK (risk_score IS NULL OR risk_score BETWEEN 0 AND 1),
|
||||||
|
position_size_percent DECIMAL(5,2),
|
||||||
|
|
||||||
|
-- Detalles adicionales (JSON)
|
||||||
trade_details JSONB DEFAULT '{}',
|
trade_details JSONB DEFAULT '{}',
|
||||||
market_conditions JSONB, -- volatility, trend, etc.
|
market_conditions JSONB, -- volatility, trend, liquidity, etc.
|
||||||
|
|
||||||
-- Estado
|
-- Estado
|
||||||
status VARCHAR(20) DEFAULT 'executed' CHECK (
|
status VARCHAR(20) DEFAULT 'executed' CHECK (
|
||||||
status IN ('pending', 'executed', 'partially_filled', 'cancelled', 'failed')
|
status IN ('pending', 'executed', 'partially_filled', 'cancelled', 'failed')
|
||||||
),
|
),
|
||||||
|
error_code VARCHAR(50),
|
||||||
failure_reason TEXT,
|
failure_reason TEXT,
|
||||||
|
notes TEXT,
|
||||||
|
|
||||||
-- Metadata ML/AI
|
-- Metadata ML/AI
|
||||||
signal_source VARCHAR(50), -- ml_model, llm, manual, scheduled
|
signal_source VARCHAR(50), -- ml_model, llm, manual, scheduled, ensemble
|
||||||
confidence_score DECIMAL(5,4),
|
confidence_score DECIMAL(5,4) CHECK (confidence_score IS NULL OR confidence_score BETWEEN 0 AND 1),
|
||||||
model_version VARCHAR(50),
|
model_version VARCHAR(50),
|
||||||
|
model_id UUID, -- Reference to ML model
|
||||||
|
|
||||||
|
-- Referencias externas
|
||||||
|
external_order_id VARCHAR(100),
|
||||||
|
|
||||||
-- Timestamps
|
-- Timestamps
|
||||||
executed_at TIMESTAMPTZ DEFAULT NOW(),
|
executed_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
closed_at TIMESTAMPTZ,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Indices
|
-- =====================================================
|
||||||
|
-- INDEXES
|
||||||
|
-- =====================================================
|
||||||
|
|
||||||
|
-- Primary lookup indexes
|
||||||
CREATE INDEX idx_agent_exec_account ON investment.agent_executions(account_id);
|
CREATE INDEX idx_agent_exec_account ON investment.agent_executions(account_id);
|
||||||
CREATE INDEX idx_agent_exec_type ON investment.agent_executions(agent_type);
|
CREATE INDEX idx_agent_exec_type ON investment.agent_executions(agent_type);
|
||||||
CREATE INDEX idx_agent_exec_date ON investment.agent_executions(executed_at DESC);
|
|
||||||
CREATE INDEX idx_agent_exec_symbol ON investment.agent_executions(symbol)
|
|
||||||
WHERE symbol IS NOT NULL;
|
|
||||||
CREATE INDEX idx_agent_exec_pnl ON investment.agent_executions(pnl)
|
|
||||||
WHERE pnl IS NOT NULL;
|
|
||||||
CREATE INDEX idx_agent_exec_status ON investment.agent_executions(status);
|
CREATE INDEX idx_agent_exec_status ON investment.agent_executions(status);
|
||||||
|
|
||||||
-- Indice compuesto para reportes
|
-- Time-based indexes
|
||||||
|
CREATE INDEX idx_agent_exec_date ON investment.agent_executions(executed_at DESC);
|
||||||
CREATE INDEX idx_agent_exec_account_date ON investment.agent_executions(account_id, executed_at DESC);
|
CREATE INDEX idx_agent_exec_account_date ON investment.agent_executions(account_id, executed_at DESC);
|
||||||
|
|
||||||
-- Comentarios
|
-- Symbol and P&L indexes (partial for efficiency)
|
||||||
|
CREATE INDEX idx_agent_exec_symbol ON investment.agent_executions(symbol)
|
||||||
|
WHERE symbol IS NOT NULL;
|
||||||
|
CREATE INDEX idx_agent_exec_pnl ON investment.agent_executions(pnl DESC NULLS LAST)
|
||||||
|
WHERE pnl IS NOT NULL;
|
||||||
|
|
||||||
|
-- Performance analysis indexes
|
||||||
|
CREATE INDEX idx_agent_exec_slippage ON investment.agent_executions(slippage)
|
||||||
|
WHERE slippage IS NOT NULL;
|
||||||
|
CREATE INDEX idx_agent_exec_risk_score ON investment.agent_executions(risk_score)
|
||||||
|
WHERE risk_score IS NOT NULL;
|
||||||
|
|
||||||
|
-- External reference indexes
|
||||||
|
CREATE INDEX idx_agent_exec_external_order ON investment.agent_executions(external_order_id)
|
||||||
|
WHERE external_order_id IS NOT NULL;
|
||||||
|
CREATE INDEX idx_agent_exec_model ON investment.agent_executions(model_id)
|
||||||
|
WHERE model_id IS NOT NULL;
|
||||||
|
|
||||||
|
-- Signal analysis index (composite)
|
||||||
|
CREATE INDEX idx_agent_exec_signal_confidence ON investment.agent_executions(signal_source, confidence_score DESC NULLS LAST)
|
||||||
|
WHERE signal_source IS NOT NULL;
|
||||||
|
|
||||||
|
-- =====================================================
|
||||||
|
-- TRIGGER
|
||||||
|
-- =====================================================
|
||||||
|
|
||||||
|
CREATE TRIGGER trg_agent_executions_updated_at
|
||||||
|
BEFORE UPDATE ON investment.agent_executions
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION public.update_updated_at();
|
||||||
|
|
||||||
|
-- =====================================================
|
||||||
|
-- COMMENTS
|
||||||
|
-- =====================================================
|
||||||
|
|
||||||
COMMENT ON TABLE investment.agent_executions IS 'Tracking de ejecuciones de trading agents (Atlas, Orion, Nova)';
|
COMMENT ON TABLE investment.agent_executions IS 'Tracking de ejecuciones de trading agents (Atlas, Orion, Nova)';
|
||||||
|
|
||||||
|
-- Agent and execution type
|
||||||
COMMENT ON COLUMN investment.agent_executions.agent_type IS 'Agente que ejecuto: atlas (conservador), orion (moderado), nova (agresivo)';
|
COMMENT ON COLUMN investment.agent_executions.agent_type IS 'Agente que ejecuto: atlas (conservador), orion (moderado), nova (agresivo)';
|
||||||
COMMENT ON COLUMN investment.agent_executions.execution_type IS 'Tipo: trade, rebalance, distribution, stop_loss, take_profit, hedge';
|
COMMENT ON COLUMN investment.agent_executions.execution_type IS 'Tipo: trade, rebalance, distribution, stop_loss, take_profit, hedge';
|
||||||
COMMENT ON COLUMN investment.agent_executions.trade_details IS 'JSON con detalles adicionales del trade';
|
|
||||||
COMMENT ON COLUMN investment.agent_executions.market_conditions IS 'Condiciones de mercado al momento de ejecucion';
|
-- Trade details
|
||||||
COMMENT ON COLUMN investment.agent_executions.signal_source IS 'Fuente de la senal: ml_model, llm, manual, scheduled';
|
COMMENT ON COLUMN investment.agent_executions.symbol IS 'Trading pair symbol (e.g., BTCUSDT, EURUSD)';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.side IS 'Trade direction: buy or sell';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.quantity IS 'Position size in base currency';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.entry_price IS 'Entry price of the position';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.exit_price IS 'Exit price (null if position still open)';
|
||||||
|
|
||||||
|
-- P&L
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.pnl IS 'Profit/Loss in quote currency';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.pnl_percentage IS 'P&L as percentage of position';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.fees IS 'Trading fees/commissions paid';
|
||||||
|
|
||||||
|
-- Execution metrics
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.execution_time_ms IS 'Time taken to execute the trade in milliseconds';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.slippage IS 'Price slippage between requested and executed price';
|
||||||
|
|
||||||
|
-- Risk metrics
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.risk_score IS 'Risk assessment score at time of execution (0-1)';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.position_size_percent IS 'Position size as percentage of portfolio';
|
||||||
|
|
||||||
|
-- JSON details
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.trade_details IS 'JSON with additional trade details (leverage, margin, etc.)';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.market_conditions IS 'Market conditions at execution (volatility, trend, liquidity)';
|
||||||
|
|
||||||
|
-- Status and errors
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.status IS 'Execution status: pending, executed, partially_filled, cancelled, failed';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.error_code IS 'Standardized error code for failures';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.failure_reason IS 'Detailed failure description';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.notes IS 'Manual annotations or additional context';
|
||||||
|
|
||||||
|
-- ML/AI metadata
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.signal_source IS 'Signal origin: ml_model, llm, manual, scheduled, ensemble';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.confidence_score IS 'ML model confidence score (0-1)';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.model_version IS 'Version of the ML model used';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.model_id IS 'Reference to ML model that generated the signal';
|
||||||
|
|
||||||
|
-- External references
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.external_order_id IS 'Order ID from external broker/exchange (Binance, MT4, etc.)';
|
||||||
|
|
||||||
|
-- Timestamps
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.executed_at IS 'When the trade was executed';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.closed_at IS 'When the position was closed';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.created_at IS 'Record creation timestamp';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.updated_at IS 'Last modification timestamp';
|
||||||
|
|||||||
@ -92,3 +92,51 @@ COMMENT ON COLUMN ml.predictions.model_output IS
|
|||||||
"raw_score": 0.5823,
|
"raw_score": 0.5823,
|
||||||
"feature_contributions": {...}
|
"feature_contributions": {...}
|
||||||
}';
|
}';
|
||||||
|
|
||||||
|
-- =====================================================
|
||||||
|
-- PERFORMANCE COMPOSITE INDEXES (added 2026-02-03, ST-3.4)
|
||||||
|
-- =====================================================
|
||||||
|
|
||||||
|
-- Index 1: Symbol + Timeframe + Created (most common query pattern)
|
||||||
|
-- Use: WHERE symbol = ? AND timeframe = ? ORDER BY created_at DESC
|
||||||
|
CREATE INDEX idx_predictions_symbol_timeframe_created
|
||||||
|
ON ml.predictions(symbol, timeframe, created_at DESC);
|
||||||
|
|
||||||
|
-- Index 2: Symbol + Prediction Type + Created (filtered queries)
|
||||||
|
-- Use: WHERE symbol = ? AND prediction_type = ? ORDER BY created_at DESC
|
||||||
|
CREATE INDEX idx_predictions_symbol_type_created
|
||||||
|
ON ml.predictions(symbol, prediction_type, created_at DESC);
|
||||||
|
|
||||||
|
-- Index 3: Model + Symbol + Timeframe (model-specific queries)
|
||||||
|
-- Use: WHERE model_id = ? AND symbol = ? AND timeframe = ? ORDER BY created_at DESC
|
||||||
|
CREATE INDEX idx_predictions_model_symbol_timeframe
|
||||||
|
ON ml.predictions(model_id, symbol, timeframe, created_at DESC);
|
||||||
|
|
||||||
|
-- Index 4: High confidence predictions (partial index)
|
||||||
|
-- Use: WHERE symbol = ? AND timeframe = ? AND confidence_score >= 0.7
|
||||||
|
CREATE INDEX idx_predictions_high_confidence
|
||||||
|
ON ml.predictions(symbol, timeframe, created_at DESC)
|
||||||
|
WHERE confidence_score >= 0.7;
|
||||||
|
|
||||||
|
-- Index 5: Recent valid predictions (partial index for active queries)
|
||||||
|
-- Use: WHERE symbol = ? AND timeframe = ? AND valid_until IS NOT NULL
|
||||||
|
CREATE INDEX idx_predictions_recent_valid
|
||||||
|
ON ml.predictions(symbol, timeframe, prediction_type, created_at DESC)
|
||||||
|
WHERE valid_until IS NOT NULL;
|
||||||
|
|
||||||
|
-- Index 6: Overlay display (for chart rendering)
|
||||||
|
-- Use: WHERE symbol = ? AND timeframe = ? AND show_on_chart = true
|
||||||
|
CREATE INDEX idx_predictions_overlay_display
|
||||||
|
ON ml.predictions(symbol, timeframe, display_priority DESC, created_at DESC)
|
||||||
|
WHERE (chart_config->>'show_on_chart')::boolean = true;
|
||||||
|
|
||||||
|
-- Index 7: Symbol + Confidence Score (ranking queries)
|
||||||
|
-- Use: WHERE symbol = ? ORDER BY confidence_score DESC
|
||||||
|
CREATE INDEX idx_predictions_symbol_confidence
|
||||||
|
ON ml.predictions(symbol, confidence_score DESC, created_at DESC);
|
||||||
|
|
||||||
|
-- Index 8: Timeframe + Prediction Result (cross-symbol analysis)
|
||||||
|
-- Use: WHERE timeframe = ? AND prediction_result = ? ORDER BY created_at DESC
|
||||||
|
CREATE INDEX idx_predictions_timeframe_result_created
|
||||||
|
ON ml.predictions(timeframe, prediction_result, created_at DESC)
|
||||||
|
WHERE prediction_result IS NOT NULL;
|
||||||
|
|||||||
@ -83,3 +83,27 @@ CREATE TYPE trading.bot_status AS ENUM (
|
|||||||
'stopped',
|
'stopped',
|
||||||
'error'
|
'error'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- Drawing tool types for chart annotations
|
||||||
|
CREATE TYPE trading.drawing_tool_type AS ENUM (
|
||||||
|
'trend_line',
|
||||||
|
'horizontal_line',
|
||||||
|
'vertical_line',
|
||||||
|
'ray',
|
||||||
|
'extended_line',
|
||||||
|
'parallel_channel',
|
||||||
|
'fibonacci_retracement',
|
||||||
|
'fibonacci_extension',
|
||||||
|
'rectangle',
|
||||||
|
'ellipse',
|
||||||
|
'triangle',
|
||||||
|
'arrow',
|
||||||
|
'text',
|
||||||
|
'price_range',
|
||||||
|
'date_range',
|
||||||
|
'order_block',
|
||||||
|
'fair_value_gap',
|
||||||
|
'liquidity_level'
|
||||||
|
);
|
||||||
|
|
||||||
|
COMMENT ON TYPE trading.drawing_tool_type IS 'Types of drawing tools available on charts';
|
||||||
|
|||||||
77
ddl/schemas/trading/tables/12-drawing_tools.sql
Normal file
77
ddl/schemas/trading/tables/12-drawing_tools.sql
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- Schema: trading
|
||||||
|
-- File: 12-drawing_tools.sql
|
||||||
|
-- Description: User drawings and annotations on trading charts
|
||||||
|
-- Related: OQI-003 Trading Charts, GAP-006
|
||||||
|
-- Dependencies: 00-enums.sql, 01-symbols.sql, auth.users
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS trading.drawing_tools (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
||||||
|
symbol_id UUID NOT NULL REFERENCES trading.symbols(id) ON DELETE CASCADE,
|
||||||
|
timeframe trading.timeframe NOT NULL,
|
||||||
|
tool_type trading.drawing_tool_type NOT NULL,
|
||||||
|
name VARCHAR(100),
|
||||||
|
|
||||||
|
-- Coordinates (stored as JSON for flexibility)
|
||||||
|
points JSONB NOT NULL DEFAULT '[]', -- Array of {time, price} points
|
||||||
|
|
||||||
|
-- Style configuration
|
||||||
|
style JSONB NOT NULL DEFAULT '{
|
||||||
|
"color": "#2196F3",
|
||||||
|
"lineWidth": 1,
|
||||||
|
"lineStyle": "solid",
|
||||||
|
"fillColor": null,
|
||||||
|
"fillOpacity": 0.2,
|
||||||
|
"showLabel": true,
|
||||||
|
"labelPosition": "right"
|
||||||
|
}',
|
||||||
|
|
||||||
|
-- Fibonacci specific (if applicable)
|
||||||
|
fib_levels DECIMAL(5,4)[] DEFAULT NULL, -- e.g., {0, 0.236, 0.382, 0.5, 0.618, 0.786, 1}
|
||||||
|
|
||||||
|
-- Text content (for text/label tools)
|
||||||
|
text_content TEXT,
|
||||||
|
|
||||||
|
-- Visibility and state
|
||||||
|
is_visible BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
is_locked BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
z_index INTEGER NOT NULL DEFAULT 0,
|
||||||
|
|
||||||
|
-- Template/sharing
|
||||||
|
is_template BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
is_shared BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
|
||||||
|
-- Metadata
|
||||||
|
metadata JSONB DEFAULT '{}',
|
||||||
|
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
|
||||||
|
CONSTRAINT drawing_tools_points_not_empty CHECK (jsonb_array_length(points) >= 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Indexes
|
||||||
|
CREATE INDEX idx_drawing_tools_user_id ON trading.drawing_tools(user_id);
|
||||||
|
CREATE INDEX idx_drawing_tools_symbol_id ON trading.drawing_tools(symbol_id);
|
||||||
|
CREATE INDEX idx_drawing_tools_user_symbol ON trading.drawing_tools(user_id, symbol_id, timeframe);
|
||||||
|
CREATE INDEX idx_drawing_tools_visible ON trading.drawing_tools(user_id, is_visible) WHERE is_visible = true;
|
||||||
|
CREATE INDEX idx_drawing_tools_templates ON trading.drawing_tools(is_template) WHERE is_template = true;
|
||||||
|
CREATE INDEX idx_drawing_tools_shared ON trading.drawing_tools(is_shared) WHERE is_shared = true;
|
||||||
|
CREATE INDEX idx_drawing_tools_points ON trading.drawing_tools USING GIN(points);
|
||||||
|
|
||||||
|
-- Trigger
|
||||||
|
CREATE TRIGGER trg_drawing_tools_updated_at
|
||||||
|
BEFORE UPDATE ON trading.drawing_tools
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION public.update_updated_at();
|
||||||
|
|
||||||
|
-- Comments
|
||||||
|
COMMENT ON TABLE trading.drawing_tools IS 'User drawings and annotations on trading charts';
|
||||||
|
COMMENT ON COLUMN trading.drawing_tools.points IS 'Array of coordinate points [{time: ISO string, price: number}]';
|
||||||
|
COMMENT ON COLUMN trading.drawing_tools.style IS 'Visual style configuration (color, line width, fill, etc.)';
|
||||||
|
COMMENT ON COLUMN trading.drawing_tools.fib_levels IS 'Fibonacci levels for retracement/extension tools';
|
||||||
|
COMMENT ON COLUMN trading.drawing_tools.z_index IS 'Z-index for layering multiple drawings';
|
||||||
|
COMMENT ON COLUMN trading.drawing_tools.is_template IS 'Whether this drawing can be used as a template';
|
||||||
|
COMMENT ON COLUMN trading.drawing_tools.is_shared IS 'Whether this drawing is visible to other users';
|
||||||
45
ddl/schemas/trading/tables/13-drawing_templates.sql
Normal file
45
ddl/schemas/trading/tables/13-drawing_templates.sql
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- Schema: trading
|
||||||
|
-- File: 13-drawing_templates.sql
|
||||||
|
-- Description: Reusable drawing templates and presets
|
||||||
|
-- Related: OQI-003 Trading Charts, GAP-006
|
||||||
|
-- Dependencies: 00-enums.sql, auth.users
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS trading.drawing_templates (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE, -- NULL = system template
|
||||||
|
name VARCHAR(100) NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
tool_type trading.drawing_tool_type NOT NULL,
|
||||||
|
style JSONB NOT NULL,
|
||||||
|
fib_levels DECIMAL(5,4)[] DEFAULT NULL,
|
||||||
|
is_system BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
is_public BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
usage_count INTEGER NOT NULL DEFAULT 0,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
|
||||||
|
CONSTRAINT drawing_templates_name_not_empty CHECK (length(trim(name)) > 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Indexes
|
||||||
|
CREATE INDEX idx_drawing_templates_user ON trading.drawing_templates(user_id);
|
||||||
|
CREATE INDEX idx_drawing_templates_tool_type ON trading.drawing_templates(tool_type);
|
||||||
|
CREATE INDEX idx_drawing_templates_public ON trading.drawing_templates(is_public) WHERE is_public = true;
|
||||||
|
CREATE INDEX idx_drawing_templates_system ON trading.drawing_templates(is_system) WHERE is_system = true;
|
||||||
|
|
||||||
|
-- Trigger
|
||||||
|
CREATE TRIGGER trg_drawing_templates_updated_at
|
||||||
|
BEFORE UPDATE ON trading.drawing_templates
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION public.update_updated_at();
|
||||||
|
|
||||||
|
-- Comments
|
||||||
|
COMMENT ON TABLE trading.drawing_templates IS 'Reusable drawing templates and presets for chart annotations';
|
||||||
|
COMMENT ON COLUMN trading.drawing_templates.user_id IS 'Owner of template, NULL for system templates';
|
||||||
|
COMMENT ON COLUMN trading.drawing_templates.style IS 'Default style configuration for the template';
|
||||||
|
COMMENT ON COLUMN trading.drawing_templates.fib_levels IS 'Default Fibonacci levels for retracement/extension templates';
|
||||||
|
COMMENT ON COLUMN trading.drawing_templates.is_system IS 'System-provided template (cannot be deleted by users)';
|
||||||
|
COMMENT ON COLUMN trading.drawing_templates.is_public IS 'Template is visible to all users';
|
||||||
|
COMMENT ON COLUMN trading.drawing_templates.usage_count IS 'Number of times this template has been applied';
|
||||||
108
migrations/2026-02-03_add_ml_composite_indexes.sql
Normal file
108
migrations/2026-02-03_add_ml_composite_indexes.sql
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
-- =====================================================
|
||||||
|
-- MIGRATION: Add composite indexes to ml.predictions for performance
|
||||||
|
-- =====================================================
|
||||||
|
-- Date: 2026-02-03
|
||||||
|
-- Task: ST-3.4, GAP-008
|
||||||
|
-- Description: Optimize query performance with composite indexes
|
||||||
|
-- =====================================================
|
||||||
|
|
||||||
|
-- ===========================================
|
||||||
|
-- COMPOSITE INDEX 1: Symbol + Timeframe + Created
|
||||||
|
-- ===========================================
|
||||||
|
-- Query pattern: SELECT * FROM ml.predictions
|
||||||
|
-- WHERE symbol = ? AND timeframe = ?
|
||||||
|
-- ORDER BY created_at DESC LIMIT ?
|
||||||
|
-- Use case: Most common query for fetching latest predictions for a symbol/timeframe
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_predictions_symbol_timeframe_created
|
||||||
|
ON ml.predictions(symbol, timeframe, created_at DESC);
|
||||||
|
|
||||||
|
-- ===========================================
|
||||||
|
-- COMPOSITE INDEX 2: Symbol + Prediction Type + Created
|
||||||
|
-- ===========================================
|
||||||
|
-- Query pattern: SELECT * FROM ml.predictions
|
||||||
|
-- WHERE symbol = ? AND prediction_type = ?
|
||||||
|
-- ORDER BY created_at DESC
|
||||||
|
-- Use case: Filtered queries by prediction type (e.g., only DIRECTION predictions)
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_predictions_symbol_type_created
|
||||||
|
ON ml.predictions(symbol, prediction_type, created_at DESC);
|
||||||
|
|
||||||
|
-- ===========================================
|
||||||
|
-- COMPOSITE INDEX 3: Model + Symbol + Timeframe + Created
|
||||||
|
-- ===========================================
|
||||||
|
-- Query pattern: SELECT * FROM ml.predictions
|
||||||
|
-- WHERE model_id = ? AND symbol = ? AND timeframe = ?
|
||||||
|
-- ORDER BY created_at DESC
|
||||||
|
-- Use case: Model-specific prediction queries for analysis and comparison
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_predictions_model_symbol_timeframe
|
||||||
|
ON ml.predictions(model_id, symbol, timeframe, created_at DESC);
|
||||||
|
|
||||||
|
-- ===========================================
|
||||||
|
-- COMPOSITE INDEX 4: High Confidence Predictions (Partial)
|
||||||
|
-- ===========================================
|
||||||
|
-- Query pattern: SELECT * FROM ml.predictions
|
||||||
|
-- WHERE symbol = ? AND timeframe = ? AND confidence_score >= 0.7
|
||||||
|
-- ORDER BY created_at DESC
|
||||||
|
-- Use case: Fetch only high-confidence predictions for display/alerts
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_predictions_high_confidence
|
||||||
|
ON ml.predictions(symbol, timeframe, created_at DESC)
|
||||||
|
WHERE confidence_score >= 0.7;
|
||||||
|
|
||||||
|
-- ===========================================
|
||||||
|
-- COMPOSITE INDEX 5: Recent Valid Predictions (Partial)
|
||||||
|
-- ===========================================
|
||||||
|
-- Query pattern: SELECT * FROM ml.predictions
|
||||||
|
-- WHERE symbol = ? AND timeframe = ? AND valid_until > NOW()
|
||||||
|
-- ORDER BY prediction_type, created_at DESC
|
||||||
|
-- Use case: Active predictions that haven't expired yet
|
||||||
|
-- Note: Uses immutable predicate-safe pattern (valid_until compared at query time)
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_predictions_recent_valid
|
||||||
|
ON ml.predictions(symbol, timeframe, prediction_type, created_at DESC)
|
||||||
|
WHERE valid_until IS NOT NULL;
|
||||||
|
|
||||||
|
-- ===========================================
|
||||||
|
-- COMPOSITE INDEX 6: Overlay Display for Charts
|
||||||
|
-- ===========================================
|
||||||
|
-- Query pattern: SELECT * FROM ml.predictions
|
||||||
|
-- WHERE symbol = ? AND timeframe = ?
|
||||||
|
-- AND (chart_config->>'show_on_chart')::boolean = true
|
||||||
|
-- ORDER BY display_priority DESC, created_at DESC
|
||||||
|
-- Use case: Chart rendering - fetch predictions configured for display
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_predictions_overlay_display
|
||||||
|
ON ml.predictions(symbol, timeframe, display_priority DESC, created_at DESC)
|
||||||
|
WHERE (chart_config->>'show_on_chart')::boolean = true;
|
||||||
|
|
||||||
|
-- ===========================================
|
||||||
|
-- COMPOSITE INDEX 7: Symbol + Confidence Score (Descending)
|
||||||
|
-- ===========================================
|
||||||
|
-- Query pattern: SELECT * FROM ml.predictions
|
||||||
|
-- WHERE symbol = ?
|
||||||
|
-- ORDER BY confidence_score DESC
|
||||||
|
-- Use case: Ranking predictions by confidence for a symbol
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_predictions_symbol_confidence
|
||||||
|
ON ml.predictions(symbol, confidence_score DESC, created_at DESC);
|
||||||
|
|
||||||
|
-- ===========================================
|
||||||
|
-- COMPOSITE INDEX 8: Timeframe + Prediction Result + Created
|
||||||
|
-- ===========================================
|
||||||
|
-- Query pattern: SELECT * FROM ml.predictions
|
||||||
|
-- WHERE timeframe = ? AND prediction_result = ?
|
||||||
|
-- ORDER BY created_at DESC
|
||||||
|
-- Use case: Cross-symbol analysis of specific prediction results (e.g., all BUY signals on 1H)
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_predictions_timeframe_result_created
|
||||||
|
ON ml.predictions(timeframe, prediction_result, created_at DESC)
|
||||||
|
WHERE prediction_result IS NOT NULL;
|
||||||
|
|
||||||
|
-- ===========================================
|
||||||
|
-- DOCUMENTATION NOTES
|
||||||
|
-- ===========================================
|
||||||
|
-- Performance considerations:
|
||||||
|
-- 1. These indexes are designed for read-heavy workloads
|
||||||
|
-- 2. Partial indexes reduce storage and improve write performance
|
||||||
|
-- 3. DESC ordering on timestamps optimizes LIMIT queries for recent data
|
||||||
|
-- 4. Run ANALYZE after creation in production:
|
||||||
|
-- ANALYZE ml.predictions;
|
||||||
|
--
|
||||||
|
-- Index maintenance:
|
||||||
|
-- - Monitor pg_stat_user_indexes for usage statistics
|
||||||
|
-- - Consider REINDEX CONCURRENTLY if fragmentation occurs
|
||||||
|
-- - Review query plans with EXPLAIN ANALYZE periodically
|
||||||
124
migrations/2026-02-03_complete_agent_executions.sql
Normal file
124
migrations/2026-02-03_complete_agent_executions.sql
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
-- =====================================================
|
||||||
|
-- Migration: Complete agent_executions table
|
||||||
|
-- =====================================================
|
||||||
|
-- Description: Add missing columns for detailed execution tracking
|
||||||
|
-- Date: 2026-02-03
|
||||||
|
-- Task: ST-3.3, GAP-007
|
||||||
|
-- Related: OQI-004 Investment Accounts
|
||||||
|
-- =====================================================
|
||||||
|
|
||||||
|
-- =====================================================
|
||||||
|
-- ADD MISSING COLUMNS
|
||||||
|
-- =====================================================
|
||||||
|
|
||||||
|
-- Execution performance metrics
|
||||||
|
ALTER TABLE investment.agent_executions
|
||||||
|
ADD COLUMN IF NOT EXISTS execution_time_ms INTEGER,
|
||||||
|
ADD COLUMN IF NOT EXISTS slippage DECIMAL(20,8);
|
||||||
|
|
||||||
|
-- Risk metrics
|
||||||
|
ALTER TABLE investment.agent_executions
|
||||||
|
ADD COLUMN IF NOT EXISTS risk_score DECIMAL(5,4) CHECK (risk_score IS NULL OR risk_score BETWEEN 0 AND 1),
|
||||||
|
ADD COLUMN IF NOT EXISTS position_size_percent DECIMAL(5,2);
|
||||||
|
|
||||||
|
-- External references
|
||||||
|
ALTER TABLE investment.agent_executions
|
||||||
|
ADD COLUMN IF NOT EXISTS external_order_id VARCHAR(100),
|
||||||
|
ADD COLUMN IF NOT EXISTS model_id UUID;
|
||||||
|
|
||||||
|
-- Additional timestamps for lifecycle tracking
|
||||||
|
ALTER TABLE investment.agent_executions
|
||||||
|
ADD COLUMN IF NOT EXISTS closed_at TIMESTAMPTZ,
|
||||||
|
ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW();
|
||||||
|
|
||||||
|
-- Error tracking (complement existing failure_reason)
|
||||||
|
ALTER TABLE investment.agent_executions
|
||||||
|
ADD COLUMN IF NOT EXISTS error_code VARCHAR(50);
|
||||||
|
|
||||||
|
-- Notes field for manual annotations
|
||||||
|
ALTER TABLE investment.agent_executions
|
||||||
|
ADD COLUMN IF NOT EXISTS notes TEXT;
|
||||||
|
|
||||||
|
-- =====================================================
|
||||||
|
-- ADD PERFORMANCE INDEXES
|
||||||
|
-- =====================================================
|
||||||
|
|
||||||
|
-- Index for slippage analysis
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_agent_exec_slippage
|
||||||
|
ON investment.agent_executions(slippage)
|
||||||
|
WHERE slippage IS NOT NULL;
|
||||||
|
|
||||||
|
-- Index for risk score analysis
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_agent_exec_risk_score
|
||||||
|
ON investment.agent_executions(risk_score)
|
||||||
|
WHERE risk_score IS NOT NULL;
|
||||||
|
|
||||||
|
-- Index for external order lookups
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_agent_exec_external_order
|
||||||
|
ON investment.agent_executions(external_order_id)
|
||||||
|
WHERE external_order_id IS NOT NULL;
|
||||||
|
|
||||||
|
-- Index for model performance tracking
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_agent_exec_model
|
||||||
|
ON investment.agent_executions(model_id)
|
||||||
|
WHERE model_id IS NOT NULL;
|
||||||
|
|
||||||
|
-- Composite index for signal source analysis
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_agent_exec_signal_confidence
|
||||||
|
ON investment.agent_executions(signal_source, confidence_score DESC NULLS LAST)
|
||||||
|
WHERE signal_source IS NOT NULL;
|
||||||
|
|
||||||
|
-- =====================================================
|
||||||
|
-- ADD TRIGGER FOR updated_at
|
||||||
|
-- =====================================================
|
||||||
|
|
||||||
|
-- Create trigger function if not exists (reuse common function)
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
-- Check if public.update_updated_at exists, if not use a local one
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM pg_proc p
|
||||||
|
JOIN pg_namespace n ON p.pronamespace = n.oid
|
||||||
|
WHERE n.nspname = 'public' AND p.proname = 'update_updated_at'
|
||||||
|
) THEN
|
||||||
|
CREATE OR REPLACE FUNCTION public.update_updated_at()
|
||||||
|
RETURNS TRIGGER AS $func$
|
||||||
|
BEGIN
|
||||||
|
NEW.updated_at = NOW();
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$func$ LANGUAGE plpgsql;
|
||||||
|
END IF;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
-- Create or replace trigger
|
||||||
|
DROP TRIGGER IF EXISTS trg_agent_executions_updated_at ON investment.agent_executions;
|
||||||
|
|
||||||
|
CREATE TRIGGER trg_agent_executions_updated_at
|
||||||
|
BEFORE UPDATE ON investment.agent_executions
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION public.update_updated_at();
|
||||||
|
|
||||||
|
-- =====================================================
|
||||||
|
-- ADD COMMENTS FOR NEW COLUMNS
|
||||||
|
-- =====================================================
|
||||||
|
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.execution_time_ms IS 'Time taken to execute the trade in milliseconds';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.slippage IS 'Price slippage between requested and executed price';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.risk_score IS 'Risk assessment score at time of execution (0-1)';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.position_size_percent IS 'Position size as percentage of portfolio';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.external_order_id IS 'Order ID from external broker/exchange';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.model_id IS 'Reference to ML model that generated the signal';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.closed_at IS 'Timestamp when position was closed';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.updated_at IS 'Last modification timestamp';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.error_code IS 'Standardized error code for failures';
|
||||||
|
COMMENT ON COLUMN investment.agent_executions.notes IS 'Manual annotations or additional context';
|
||||||
|
|
||||||
|
-- =====================================================
|
||||||
|
-- VERIFICATION QUERY (for manual check)
|
||||||
|
-- =====================================================
|
||||||
|
-- SELECT column_name, data_type, is_nullable
|
||||||
|
-- FROM information_schema.columns
|
||||||
|
-- WHERE table_schema = 'investment'
|
||||||
|
-- AND table_name = 'agent_executions'
|
||||||
|
-- ORDER BY ordinal_position;
|
||||||
21
seeds/prod/education/02-course_tags.sql
Normal file
21
seeds/prod/education/02-course_tags.sql
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
-- =====================================================
|
||||||
|
-- SEED: Initial course tags
|
||||||
|
-- =====================================================
|
||||||
|
-- Proyecto: OrbiQuant IA (Trading Platform)
|
||||||
|
-- Modulo: OQI-002 - Education
|
||||||
|
-- Related: ST-3.1 - Course Tags System
|
||||||
|
-- Created: 2026-02-03
|
||||||
|
-- =====================================================
|
||||||
|
|
||||||
|
INSERT INTO education.course_tags (name, slug, description, color, is_featured) VALUES
|
||||||
|
('Forex', 'forex', 'Foreign exchange trading', '#10B981', true),
|
||||||
|
('Crypto', 'crypto', 'Cryptocurrency trading', '#F59E0B', true),
|
||||||
|
('Technical Analysis', 'technical-analysis', 'Chart patterns and indicators', '#3B82F6', true),
|
||||||
|
('Fundamental Analysis', 'fundamental-analysis', 'Economic and financial analysis', '#8B5CF6', false),
|
||||||
|
('Risk Management', 'risk-management', 'Position sizing and risk control', '#EF4444', true),
|
||||||
|
('Psychology', 'psychology', 'Trading mindset and emotions', '#EC4899', false),
|
||||||
|
('Beginner', 'beginner', 'Courses for new traders', '#6EE7B7', true),
|
||||||
|
('Advanced', 'advanced', 'Advanced trading concepts', '#FCD34D', false),
|
||||||
|
('ICT', 'ict', 'Inner Circle Trader concepts', '#818CF8', true),
|
||||||
|
('Smart Money', 'smart-money', 'Institutional trading concepts', '#F472B6', false)
|
||||||
|
ON CONFLICT (slug) DO NOTHING;
|
||||||
Loading…
Reference in New Issue
Block a user