trading-platform-database-v2/ddl/schemas/portfolio/tables/02-portfolio_allocations.sql
Adrian Flores Cortes 3fbb1c21e6 [OQI-008] feat: Add portfolio DDL schema with tables for portfolios, allocations, goals
- Added portfolio schema to 01-schemas.sql
- Created enums: risk_profile, goal_status, rebalance_action, allocation_status
- Created tables: portfolios, portfolio_allocations, portfolio_goals
- Created tables: rebalance_history, portfolio_snapshots
- Added triggers for updated_at and goal progress calculations
- Added indexes for performance

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 08:20:48 -06:00

64 lines
2.7 KiB
SQL

-- =====================================================
-- PORTFOLIO SCHEMA - PORTFOLIO ALLOCATIONS TABLE
-- =====================================================
-- Description: Asset allocations within portfolios
-- Schema: portfolio
-- Author: Database Agent
-- Date: 2026-01-25
-- =====================================================
CREATE TABLE portfolio.portfolio_allocations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
portfolio_id UUID NOT NULL REFERENCES portfolio.portfolios(id) ON DELETE CASCADE,
asset VARCHAR(20) NOT NULL,
-- Allocation targets and current state
target_percent DECIMAL(5, 2) NOT NULL DEFAULT 0,
current_percent DECIMAL(5, 2) NOT NULL DEFAULT 0,
deviation DECIMAL(5, 2) NOT NULL DEFAULT 0,
-- Holdings
quantity DECIMAL(20, 8) NOT NULL DEFAULT 0,
avg_cost DECIMAL(20, 8) NOT NULL DEFAULT 0,
current_price DECIMAL(20, 8) NOT NULL DEFAULT 0,
-- Values
value DECIMAL(20, 8) NOT NULL DEFAULT 0,
cost DECIMAL(20, 8) NOT NULL DEFAULT 0,
pnl DECIMAL(20, 8) NOT NULL DEFAULT 0,
pnl_percent DECIMAL(10, 4) NOT NULL DEFAULT 0,
-- Status
status portfolio.allocation_status NOT NULL DEFAULT 'active',
last_updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
-- Constraints
CONSTRAINT chk_target_percent CHECK (target_percent >= 0 AND target_percent <= 100),
CONSTRAINT chk_current_percent CHECK (current_percent >= 0 AND current_percent <= 100),
CONSTRAINT chk_quantity_positive CHECK (quantity >= 0)
);
-- Indexes
CREATE INDEX idx_portfolio_allocations_portfolio_id ON portfolio.portfolio_allocations(portfolio_id);
CREATE INDEX idx_portfolio_allocations_asset ON portfolio.portfolio_allocations(asset);
CREATE INDEX idx_portfolio_allocations_status ON portfolio.portfolio_allocations(status);
-- Unique asset per portfolio
CREATE UNIQUE INDEX idx_portfolio_allocations_unique_asset
ON portfolio.portfolio_allocations(portfolio_id, asset);
-- Comments
COMMENT ON TABLE portfolio.portfolio_allocations IS 'Individual asset allocations within a portfolio';
COMMENT ON COLUMN portfolio.portfolio_allocations.target_percent IS 'Target allocation percentage (0-100)';
COMMENT ON COLUMN portfolio.portfolio_allocations.current_percent IS 'Current actual allocation percentage';
COMMENT ON COLUMN portfolio.portfolio_allocations.deviation IS 'Difference between current and target (current - target)';
COMMENT ON COLUMN portfolio.portfolio_allocations.avg_cost IS 'Average cost basis per unit';
COMMENT ON COLUMN portfolio.portfolio_allocations.pnl IS 'Profit/loss = value - cost';
-- Trigger for last_updated_at
CREATE TRIGGER trg_portfolio_allocations_updated_at
BEFORE UPDATE ON portfolio.portfolio_allocations
FOR EACH ROW
EXECUTE FUNCTION portfolio.update_portfolio_updated_at();