trading-platform-database-v2/ddl/schemas/investment/tables/07-daily_performance.sql
rckrdmrd 45e77e9a9c feat: Initial commit - Database schemas and scripts
DDL schemas for Trading Platform:
- User management
- Authentication
- Payments
- Education
- ML predictions
- Trading data

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 04:30:23 -06:00

115 lines
4.8 KiB
SQL

-- ============================================================================
-- INVESTMENT SCHEMA - Tabla: daily_performance
-- ============================================================================
-- Snapshots diarios de rendimiento de cuentas PAMM
-- Usado para graficos, reportes y calculo de metricas
-- ============================================================================
CREATE TABLE IF NOT EXISTS investment.daily_performance (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
-- Relaciones
account_id UUID NOT NULL REFERENCES investment.accounts(id) ON DELETE CASCADE,
product_id UUID NOT NULL REFERENCES investment.products(id) ON DELETE CASCADE,
-- Fecha del snapshot
snapshot_date DATE NOT NULL,
-- Balance
opening_balance DECIMAL(20, 8) NOT NULL,
closing_balance DECIMAL(20, 8) NOT NULL,
-- Rendimiento del dia
daily_pnl DECIMAL(20, 8) NOT NULL DEFAULT 0,
daily_return_percentage DECIMAL(10, 6) NOT NULL DEFAULT 0,
-- Rendimiento acumulado
cumulative_pnl DECIMAL(20, 8) NOT NULL DEFAULT 0,
cumulative_return_percentage DECIMAL(10, 6) NOT NULL DEFAULT 0,
-- Movimientos del dia
deposits DECIMAL(20, 8) NOT NULL DEFAULT 0,
withdrawals DECIMAL(20, 8) NOT NULL DEFAULT 0,
distributions_received DECIMAL(20, 8) NOT NULL DEFAULT 0,
-- Metricas del agente de trading
trades_executed INTEGER NOT NULL DEFAULT 0,
winning_trades INTEGER NOT NULL DEFAULT 0,
losing_trades INTEGER NOT NULL DEFAULT 0,
win_rate DECIMAL(5, 2),
-- Volatilidad y riesgo
max_drawdown DECIMAL(10, 6),
sharpe_ratio DECIMAL(10, 6),
volatility DECIMAL(10, 6),
-- High/Low del dia
high_water_mark DECIMAL(20, 8),
lowest_point DECIMAL(20, 8),
-- Metadata del snapshot
snapshot_source VARCHAR(50) DEFAULT 'cron', -- 'cron', 'manual', 'system'
metadata JSONB DEFAULT '{}',
-- Timestamps
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
-- Constraints
CONSTRAINT uq_daily_performance_account_date UNIQUE(account_id, snapshot_date),
CONSTRAINT chk_valid_balances CHECK (opening_balance >= 0 AND closing_balance >= 0),
CONSTRAINT chk_valid_movements CHECK (deposits >= 0 AND withdrawals >= 0),
CONSTRAINT chk_valid_trades CHECK (
trades_executed >= 0 AND
winning_trades >= 0 AND
losing_trades >= 0 AND
winning_trades + losing_trades <= trades_executed
),
CONSTRAINT chk_valid_win_rate CHECK (win_rate IS NULL OR (win_rate >= 0 AND win_rate <= 100))
);
-- Indices
CREATE INDEX idx_daily_performance_account ON investment.daily_performance(account_id);
CREATE INDEX idx_daily_performance_product ON investment.daily_performance(product_id);
CREATE INDEX idx_daily_performance_date ON investment.daily_performance(snapshot_date DESC);
CREATE INDEX idx_daily_performance_account_date ON investment.daily_performance(account_id, snapshot_date DESC);
-- Index for recent performance (removed time-based predicate for immutability)
CREATE INDEX idx_daily_performance_recent ON investment.daily_performance(account_id, snapshot_date DESC);
-- Comentarios
COMMENT ON TABLE investment.daily_performance IS 'Snapshots diarios de rendimiento de cuentas PAMM';
COMMENT ON COLUMN investment.daily_performance.snapshot_date IS 'Fecha del snapshot (una entrada por dia por cuenta)';
COMMENT ON COLUMN investment.daily_performance.daily_return_percentage IS 'Retorno del dia como porcentaje';
COMMENT ON COLUMN investment.daily_performance.cumulative_return_percentage IS 'Retorno acumulado desde apertura de cuenta';
COMMENT ON COLUMN investment.daily_performance.max_drawdown IS 'Maximo drawdown del dia';
COMMENT ON COLUMN investment.daily_performance.high_water_mark IS 'Punto mas alto alcanzado';
-- Vista para resumen mensual
CREATE OR REPLACE VIEW investment.v_monthly_performance AS
SELECT
account_id,
product_id,
DATE_TRUNC('month', snapshot_date) AS month,
MIN(opening_balance) AS month_opening,
MAX(closing_balance) AS month_closing,
SUM(daily_pnl) AS total_pnl,
AVG(daily_return_percentage) AS avg_daily_return,
SUM(deposits) AS total_deposits,
SUM(withdrawals) AS total_withdrawals,
SUM(distributions_received) AS total_distributions,
SUM(trades_executed) AS total_trades,
SUM(winning_trades) AS total_winning,
SUM(losing_trades) AS total_losing,
CASE
WHEN SUM(winning_trades) + SUM(losing_trades) > 0
THEN ROUND(SUM(winning_trades)::DECIMAL / (SUM(winning_trades) + SUM(losing_trades)) * 100, 2)
ELSE NULL
END AS monthly_win_rate,
MIN(lowest_point) AS monthly_low,
MAX(high_water_mark) AS monthly_high,
COUNT(*) AS trading_days
FROM investment.daily_performance
GROUP BY account_id, product_id, DATE_TRUNC('month', snapshot_date);
COMMENT ON VIEW investment.v_monthly_performance IS 'Resumen mensual de rendimiento agregado';