migrations: - 001_trading_events.sql, 003_audit_system.sql: the hard-coded node_id literals (`trading-node-01`, `audit-node-01`, `ml-node-01`, `system-node-01`, `change-tracker-01`) are overridden per-deployment by later migrations rather than read from the environment. Describe that in the inline comment. - 004_compliance_views.sql: `generate_compliance_report` is a log stub — actual report generation is performed by the compliance service. Say so explicitly. services: - ml_training_service/tests/orchestrator_225_features_test.rs: the empty `#[ignore]`d placeholder for the 225-feature orchestrator loader has been removed; it held no assertions and only tracked a TODO (feedback_no_stubs.md). - trading_agent_service/src/service.rs: portfolio volatility uses the diagonal-only approximation because cross-asset return correlations are not maintained in this service. Document that. - trading_service/src/services/risk.rs: `get_risk_metrics` uses `calculate_marginal_var` + asset-class fallback; describe why `calculate_comprehensive_var` is not wired at this boundary. - trading_service/tests/auth_comprehensive.rs: delete the entire commented-out legacy BackupCodeValidator test block — the old `generate_backup_codes` / `store_backup_code` / `verify_backup_code` surface no longer exists, and MFA integration tests already cover the new API. testing: - harness/grpc_clients.rs: no BacktestingServiceClient proto exists; reword the stale TODO import line. - chaos/*: reword the family of "TODO: Implement ..." stubs as "Currently a no-op / synthetic result" descriptions so readers know exactly how much of the chaos framework is live. - compliance_automation_tests.rs: delete the file; it was a giant /* ... */ block referencing a nonexistent compliance module and was not wired into any Cargo target. - framework.rs: describe why `setup()` uses `println!` instead of `tracing_subscriber` (tracing_subscriber is not a dep of this integration crate). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
760 lines
32 KiB
PL/PgSQL
760 lines
32 KiB
PL/PgSQL
-- ================================================================================================
|
|
-- Migration 004: Compliance Views and Reporting Schema
|
|
-- Comprehensive compliance reporting views for regulatory requirements
|
|
-- Includes MiFID II, GDPR, SOX, and general financial regulations
|
|
-- ================================================================================================
|
|
|
|
-- ================================================================================================
|
|
-- REGULATORY REPORTING TABLES
|
|
-- Support for automated regulatory report generation
|
|
-- ================================================================================================
|
|
|
|
-- Regulatory reporting requirements table
|
|
CREATE TABLE regulatory_requirements (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
regulation_name VARCHAR(100) NOT NULL, -- MiFID II, GDPR, SOX, EMIR, etc.
|
|
requirement_code VARCHAR(100) NOT NULL, -- Article/Section reference
|
|
requirement_title VARCHAR(500) NOT NULL,
|
|
description TEXT,
|
|
|
|
-- Reporting details
|
|
reporting_frequency VARCHAR(50), -- daily, weekly, monthly, quarterly, annual
|
|
report_format VARCHAR(100), -- XML, CSV, JSON, PDF
|
|
submission_deadline VARCHAR(200), -- T+1, Month-end+5 days, etc.
|
|
|
|
-- Data requirements
|
|
required_fields JSONB NOT NULL, -- List of required data fields
|
|
data_retention_years INTEGER NOT NULL DEFAULT 7,
|
|
data_sources TEXT[], -- Which tables/views provide data
|
|
|
|
-- Implementation status
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|
implementation_status VARCHAR(50) DEFAULT 'pending', -- pending, implemented, tested, deployed
|
|
last_tested TIMESTAMP WITH TIME ZONE,
|
|
|
|
-- Approval and versioning
|
|
created_by VARCHAR(64) NOT NULL,
|
|
approved_by VARCHAR(64),
|
|
effective_date DATE NOT NULL,
|
|
version VARCHAR(50) NOT NULL DEFAULT '1.0',
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
|
|
CONSTRAINT uk_regulatory_requirements UNIQUE (regulation_name, requirement_code, version)
|
|
);
|
|
|
|
-- Report generation log
|
|
CREATE TABLE report_generation_log (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
requirement_id UUID REFERENCES regulatory_requirements(id),
|
|
|
|
-- Report details
|
|
report_name VARCHAR(200) NOT NULL,
|
|
report_period_start DATE NOT NULL,
|
|
report_period_end DATE NOT NULL,
|
|
|
|
-- Generation process
|
|
generation_started_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
generation_completed_at TIMESTAMP WITH TIME ZONE,
|
|
generation_status VARCHAR(50) NOT NULL DEFAULT 'running', -- running, completed, failed
|
|
|
|
-- Output details
|
|
output_file_path TEXT,
|
|
output_format VARCHAR(50),
|
|
record_count INTEGER,
|
|
file_size_bytes BIGINT,
|
|
checksum VARCHAR(64), -- SHA-256 hash for integrity
|
|
|
|
-- Quality validation
|
|
validation_status VARCHAR(50), -- passed, failed, warning
|
|
validation_errors JSONB,
|
|
quality_score DECIMAL(5,2), -- 0-100 quality score
|
|
|
|
-- Submission tracking
|
|
submitted_at TIMESTAMP WITH TIME ZONE,
|
|
submitted_by VARCHAR(64),
|
|
submission_reference VARCHAR(200),
|
|
acknowledgment_received BOOLEAN DEFAULT FALSE,
|
|
|
|
-- Error handling
|
|
error_message TEXT,
|
|
retry_count INTEGER DEFAULT 0,
|
|
max_retries INTEGER DEFAULT 3,
|
|
|
|
created_by VARCHAR(64) NOT NULL
|
|
);
|
|
|
|
-- ================================================================================================
|
|
-- MIFID II COMPLIANCE VIEWS
|
|
-- Best execution, transaction reporting, record keeping
|
|
-- ================================================================================================
|
|
|
|
-- MiFID II Transaction Reporting (RTS 22)
|
|
CREATE VIEW v_mifid_transaction_reporting AS
|
|
SELECT
|
|
-- Transaction identification
|
|
te.id as transaction_id,
|
|
o.client_order_id,
|
|
f.execution_id,
|
|
|
|
-- Timing (MiFID II requires specific timestamp format)
|
|
TO_TIMESTAMP(te.event_timestamp / 1000000000.0) AT TIME ZONE 'UTC' as transaction_timestamp,
|
|
TO_TIMESTAMP(f.execution_timestamp / 1000000000.0) AT TIME ZONE 'UTC' as execution_timestamp,
|
|
|
|
-- Instrument identification
|
|
f.symbol as instrument_code,
|
|
'XLON' as mic_code, -- Market Identifier Code (placeholder)
|
|
|
|
-- Transaction details
|
|
CASE f.side
|
|
WHEN 'buy' THEN 'B'
|
|
WHEN 'sell' THEN 'S'
|
|
ELSE 'X'
|
|
END as buy_sell_indicator,
|
|
f.quantity as quantity,
|
|
f.price / 100.0 as price, -- Convert from cents to decimal
|
|
f.quantity * f.price / 100.0 as notional_amount,
|
|
'EUR' as currency, -- Currency code
|
|
|
|
-- Execution details
|
|
f.venue as execution_venue,
|
|
CASE f.is_maker
|
|
WHEN TRUE THEN 'MAKE'
|
|
WHEN FALSE THEN 'TAKE'
|
|
ELSE 'UNKN'
|
|
END as liquidity_provision,
|
|
|
|
-- Client and counterparty information
|
|
o.account_id as client_identifier,
|
|
'PROP' as capacity, -- PROP (proprietary), AOTC (any other capacity)
|
|
|
|
-- Order details
|
|
CASE o.order_type
|
|
WHEN 'market' THEN 'MARK'
|
|
WHEN 'limit' THEN 'LIMI'
|
|
WHEN 'stop' THEN 'STOP'
|
|
ELSE 'OTHR'
|
|
END as order_type,
|
|
|
|
-- Compliance flags
|
|
FALSE as short_selling_indicator,
|
|
'NOAP' as commodity_derivative_indicator, -- NOAP (not applicable)
|
|
|
|
-- Additional fields for compliance
|
|
al.user_id as trader_identifier,
|
|
al.node_id as trading_desk_identifier,
|
|
|
|
-- Audit information
|
|
al.checksum as record_hash
|
|
|
|
FROM trading_events te
|
|
JOIN orders o ON te.correlation_id = o.id
|
|
JOIN fills f ON o.id = f.order_id
|
|
LEFT JOIN audit_log al ON al.entity_id = te.id
|
|
WHERE te.event_type = 'trade_executed'
|
|
AND te.event_timestamp >= EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '30 days')) * 1000000000;
|
|
|
|
-- MiFID II Best Execution Monitoring
|
|
CREATE VIEW v_mifid_best_execution AS
|
|
SELECT
|
|
f.symbol,
|
|
f.venue,
|
|
DATE(TO_TIMESTAMP(f.execution_timestamp / 1000000000.0)) as execution_date,
|
|
|
|
-- Execution statistics
|
|
COUNT(*) as execution_count,
|
|
SUM(f.quantity) as total_volume,
|
|
AVG(f.price / 100.0) as average_price,
|
|
MIN(f.price / 100.0) as min_price,
|
|
MAX(f.price / 100.0) as max_price,
|
|
STDDEV(f.price / 100.0) as price_volatility,
|
|
|
|
-- Cost analysis
|
|
SUM(f.commission) / 100.0 as total_commission,
|
|
AVG(f.commission) / 100.0 as average_commission,
|
|
SUM(f.quantity * f.price) / 100.0 as total_consideration,
|
|
|
|
-- Timing analysis
|
|
AVG(f.processed_at - f.received_at) / 1000000.0 as avg_processing_time_ms,
|
|
PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY f.processed_at - f.received_at) / 1000000.0 as p95_processing_time_ms,
|
|
|
|
-- Market making analysis
|
|
COUNT(*) FILTER (WHERE f.is_maker = TRUE) as maker_count,
|
|
COUNT(*) FILTER (WHERE f.is_maker = FALSE) as taker_count,
|
|
COUNT(*) FILTER (WHERE f.is_maker = TRUE)::DECIMAL / COUNT(*) as maker_ratio,
|
|
|
|
-- Quality metrics
|
|
COUNT(*) FILTER (WHERE f.processed_at - f.received_at > 100000000) as slow_executions, -- > 100ms
|
|
0 as failed_executions -- Placeholder for failed execution count
|
|
|
|
FROM fills f
|
|
WHERE f.execution_timestamp >= EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '30 days')) * 1000000000
|
|
GROUP BY f.symbol, f.venue, DATE(TO_TIMESTAMP(f.execution_timestamp / 1000000000.0))
|
|
ORDER BY execution_date DESC, total_volume DESC;
|
|
|
|
-- MiFID II Record Keeping
|
|
CREATE VIEW v_mifid_record_keeping AS
|
|
SELECT
|
|
-- Order lifecycle
|
|
o.id as order_id,
|
|
o.client_order_id,
|
|
o.symbol,
|
|
o.side,
|
|
o.order_type,
|
|
o.quantity,
|
|
o.limit_price / 100.0 as limit_price,
|
|
|
|
-- Timestamps
|
|
TO_TIMESTAMP(o.created_at / 1000000000.0) as order_created,
|
|
TO_TIMESTAMP(o.updated_at / 1000000000.0) as order_updated,
|
|
|
|
-- Client information
|
|
o.account_id,
|
|
o.created_by as trader_id,
|
|
|
|
-- Order status and fills
|
|
o.status,
|
|
o.filled_quantity,
|
|
o.avg_fill_price / 100.0 as avg_fill_price,
|
|
|
|
-- Venue and execution details
|
|
o.venue,
|
|
string_agg(f.execution_id, '; ') as execution_ids,
|
|
string_agg(f.price::text, '; ') as fill_prices,
|
|
|
|
-- Risk and compliance
|
|
o.risk_check_passed,
|
|
o.compliance_approved,
|
|
|
|
-- Audit trail
|
|
(SELECT COUNT(*) FROM audit_log al
|
|
WHERE al.entity_type = 'order' AND al.entity_id = o.id) as audit_entry_count
|
|
|
|
FROM orders o
|
|
LEFT JOIN fills f ON o.id = f.order_id
|
|
WHERE o.created_at >= EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '7 years')) * 1000000000
|
|
GROUP BY o.id, o.client_order_id, o.symbol, o.side, o.order_type, o.quantity,
|
|
o.limit_price, o.created_at, o.updated_at, o.account_id, o.created_by,
|
|
o.status, o.filled_quantity, o.avg_fill_price, o.venue,
|
|
o.risk_check_passed, o.compliance_approved;
|
|
|
|
-- ================================================================================================
|
|
-- SOX COMPLIANCE VIEWS
|
|
-- Internal controls, change management, access controls
|
|
-- ================================================================================================
|
|
|
|
-- SOX Section 302 - Internal Controls Over Financial Reporting
|
|
CREATE VIEW v_sox_internal_controls AS
|
|
SELECT
|
|
-- Change tracking summary
|
|
ct.table_name,
|
|
DATE(TO_TIMESTAMP(ct.change_timestamp / 1000000000.0)) as change_date,
|
|
ct.operation,
|
|
COUNT(*) as change_count,
|
|
|
|
-- User activity
|
|
COUNT(DISTINCT ct.user_id) as unique_users,
|
|
array_agg(DISTINCT ct.user_id) FILTER (WHERE ct.user_id IS NOT NULL) as users_involved,
|
|
|
|
-- High-risk changes
|
|
COUNT(*) FILTER (WHERE ct.table_name IN ('orders', 'fills', 'positions', 'risk_limits')) as financial_changes,
|
|
COUNT(*) FILTER (WHERE ct.operation = 'DELETE') as deletion_count,
|
|
|
|
-- Approval tracking
|
|
COUNT(*) FILTER (WHERE EXISTS (
|
|
SELECT 1 FROM audit_log al
|
|
WHERE al.entity_type = ct.table_name
|
|
AND al.entity_id = (ct.primary_key_values->>'id')::UUID
|
|
AND al.event_type = 'order_created' -- Proxy for approval
|
|
)) as approved_changes
|
|
|
|
FROM change_tracking ct
|
|
WHERE ct.change_timestamp >= EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '90 days')) * 1000000000
|
|
GROUP BY ct.table_name, DATE(TO_TIMESTAMP(ct.change_timestamp / 1000000000.0)), ct.operation
|
|
ORDER BY change_date DESC, change_count DESC;
|
|
|
|
-- SOX Section 404 - Management Assessment of Internal Controls
|
|
CREATE VIEW v_sox_management_assessment AS
|
|
SELECT
|
|
-- Control domain
|
|
'Trading Operations' as control_domain,
|
|
|
|
-- Key controls assessment
|
|
CASE
|
|
WHEN COUNT(*) FILTER (WHERE re.severity IN ('critical', 'emergency')) > 0 THEN 'DEFICIENT'
|
|
WHEN COUNT(*) FILTER (WHERE re.severity = 'high') > 5 THEN 'NEEDS_IMPROVEMENT'
|
|
ELSE 'EFFECTIVE'
|
|
END as control_effectiveness,
|
|
|
|
-- Risk events summary
|
|
COUNT(*) as total_risk_events,
|
|
COUNT(*) FILTER (WHERE re.severity IN ('critical', 'emergency')) as critical_events,
|
|
COUNT(*) FILTER (WHERE re.resolved_timestamp IS NULL) as unresolved_events,
|
|
|
|
-- Time period
|
|
DATE_TRUNC('month', TO_TIMESTAMP(re.event_timestamp / 1000000000.0)) as assessment_period,
|
|
|
|
-- Supporting evidence
|
|
jsonb_build_object(
|
|
'total_trades', (SELECT COUNT(*) FROM fills WHERE execution_timestamp >= EXTRACT(EPOCH FROM DATE_TRUNC('month', CURRENT_DATE)) * 1000000000),
|
|
'total_volume', (SELECT SUM(quantity) FROM fills WHERE execution_timestamp >= EXTRACT(EPOCH FROM DATE_TRUNC('month', CURRENT_DATE)) * 1000000000),
|
|
'system_uptime', '99.9%', -- Placeholder
|
|
'audit_coverage', '100%' -- Placeholder
|
|
) as control_metrics
|
|
|
|
FROM risk_events re
|
|
WHERE re.event_timestamp >= EXTRACT(EPOCH FROM DATE_TRUNC('month', CURRENT_DATE)) * 1000000000
|
|
GROUP BY DATE_TRUNC('month', TO_TIMESTAMP(re.event_timestamp / 1000000000.0));
|
|
|
|
-- ================================================================================================
|
|
-- GDPR COMPLIANCE VIEWS
|
|
-- Data protection, privacy, right to be forgotten
|
|
-- ================================================================================================
|
|
|
|
-- GDPR Data Subject Rights Tracking
|
|
CREATE VIEW v_gdpr_data_subject_rights AS
|
|
SELECT
|
|
al.user_id as data_subject,
|
|
COUNT(*) as total_data_points,
|
|
|
|
-- Data categories
|
|
COUNT(*) FILTER (WHERE al.entity_type = 'order') as trading_data_points,
|
|
COUNT(*) FILTER (WHERE al.entity_type = 'position') as position_data_points,
|
|
COUNT(*) FILTER (WHERE al.is_sensitive = TRUE) as sensitive_data_points,
|
|
|
|
-- Temporal analysis
|
|
MIN(TO_TIMESTAMP(al.event_timestamp / 1000000000.0)) as earliest_data,
|
|
MAX(TO_TIMESTAMP(al.event_timestamp / 1000000000.0)) as latest_data,
|
|
|
|
-- Retention analysis
|
|
COUNT(*) FILTER (WHERE TO_TIMESTAMP(al.event_timestamp / 1000000000.0) < CURRENT_DATE - INTERVAL '6 years') as retention_eligible,
|
|
|
|
-- Data portability preparation
|
|
jsonb_agg(DISTINCT al.component) as data_sources,
|
|
jsonb_agg(DISTINCT al.entity_type) as data_types,
|
|
|
|
-- Access patterns
|
|
COUNT(DISTINCT DATE(TO_TIMESTAMP(al.event_timestamp / 1000000000.0))) as active_days,
|
|
COUNT(*) FILTER (WHERE al.event_timestamp >= EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '30 days')) * 1000000000) as recent_activity
|
|
|
|
FROM audit_log al
|
|
WHERE al.user_id IS NOT NULL
|
|
GROUP BY al.user_id
|
|
ORDER BY total_data_points DESC;
|
|
|
|
-- GDPR Data Processing Activities
|
|
CREATE VIEW v_gdpr_processing_activities AS
|
|
SELECT
|
|
al.component as processing_system,
|
|
al.event_type as processing_activity,
|
|
|
|
-- Legal basis tracking
|
|
CASE al.component
|
|
WHEN 'trading_engine' THEN 'Legitimate Interest - Trade Execution'
|
|
WHEN 'risk_management' THEN 'Legitimate Interest - Risk Management'
|
|
WHEN 'compliance_engine' THEN 'Legal Obligation - Regulatory Compliance'
|
|
ELSE 'Legitimate Interest - System Operations'
|
|
END as legal_basis,
|
|
|
|
-- Data categories processed
|
|
CASE
|
|
WHEN al.entity_type = 'order' THEN 'Financial Transaction Data'
|
|
WHEN al.entity_type = 'position' THEN 'Investment Position Data'
|
|
WHEN al.is_sensitive = TRUE THEN 'Sensitive Personal Data'
|
|
ELSE 'Operational Data'
|
|
END as data_category,
|
|
|
|
-- Processing statistics
|
|
COUNT(*) as processing_count,
|
|
COUNT(DISTINCT al.user_id) as unique_data_subjects,
|
|
|
|
-- Data retention
|
|
DATE_TRUNC('month', TO_TIMESTAMP(al.event_timestamp / 1000000000.0)) as processing_month,
|
|
|
|
-- Purpose limitation
|
|
string_agg(DISTINCT al.action, ', ') as processing_purposes,
|
|
|
|
-- Data minimization assessment
|
|
-- Note: Using jsonb field count estimation (not exact unique keys across group)
|
|
AVG((SELECT COUNT(*) FROM jsonb_each(al.event_data))::numeric) as avg_data_fields_processed,
|
|
AVG(array_length(COALESCE(al.affected_fields, ARRAY[]::text[]), 1)) as avg_fields_per_operation
|
|
|
|
FROM audit_log al
|
|
WHERE al.event_timestamp >= EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '12 months')) * 1000000000
|
|
GROUP BY al.component, al.event_type, al.entity_type, al.is_sensitive,
|
|
DATE_TRUNC('month', TO_TIMESTAMP(al.event_timestamp / 1000000000.0))
|
|
ORDER BY processing_month DESC, processing_count DESC;
|
|
|
|
-- ================================================================================================
|
|
-- TRADE REPORTING COMPLIANCE
|
|
-- EMIR, SFTR, and other trade reporting regimes
|
|
-- ================================================================================================
|
|
|
|
-- EMIR Trade Reporting
|
|
CREATE VIEW v_emir_trade_reporting AS
|
|
SELECT
|
|
-- Unique Transaction Identifier
|
|
f.id as uti,
|
|
|
|
-- Counterparty information
|
|
o.account_id as reporting_counterparty,
|
|
f.contra_broker as other_counterparty,
|
|
|
|
-- Trade details
|
|
f.symbol as underlying_instrument,
|
|
'SPOT' as contract_type, -- Placeholder
|
|
TO_TIMESTAMP(f.execution_timestamp / 1000000000.0) as execution_timestamp,
|
|
f.quantity as notional_amount_1,
|
|
'EUR' as notional_currency_1,
|
|
f.price / 100.0 as price,
|
|
|
|
-- Trade characteristics
|
|
CASE f.side
|
|
WHEN 'buy' THEN 'Buy'
|
|
WHEN 'sell' THEN 'Sell'
|
|
ELSE 'Unknown'
|
|
END as direction,
|
|
|
|
-- Settlement details
|
|
f.settlement_date,
|
|
f.venue as execution_venue,
|
|
|
|
-- Clearing and settlement
|
|
CASE
|
|
WHEN f.venue LIKE '%CCP%' THEN 'Y'
|
|
ELSE 'N'
|
|
END as cleared,
|
|
|
|
-- Collateral and margin
|
|
'N/A' as collateralisation, -- Placeholder
|
|
|
|
-- Master agreement
|
|
'ISDA' as master_agreement_type, -- Placeholder
|
|
|
|
-- Reporting details
|
|
'NEW' as action_type,
|
|
CURRENT_DATE as report_date,
|
|
|
|
-- Compliance validation
|
|
CASE
|
|
WHEN f.execution_timestamp IS NOT NULL
|
|
AND f.quantity > 0
|
|
AND f.price > 0 THEN 'VALID'
|
|
ELSE 'INVALID'
|
|
END as validation_status
|
|
|
|
FROM fills f
|
|
JOIN orders o ON f.order_id = o.id
|
|
WHERE f.execution_timestamp >= EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '30 days')) * 1000000000
|
|
AND f.quantity * f.price >= 10000000; -- EMIR threshold example
|
|
|
|
-- ================================================================================================
|
|
-- RISK AND CAPITAL ADEQUACY REPORTING
|
|
-- Basel III, CRR, and capital requirement compliance
|
|
-- ================================================================================================
|
|
|
|
-- Capital Adequacy Assessment
|
|
CREATE VIEW v_capital_adequacy AS
|
|
SELECT
|
|
-- Reporting date
|
|
CURRENT_DATE as reporting_date,
|
|
|
|
-- Market risk exposure
|
|
COALESCE(SUM(ABS(p.market_value)) / 100.0, 0) as total_market_exposure,
|
|
COALESCE(SUM(ABS(p.var_1d)) / 100.0, 0) as total_var_1d,
|
|
COALESCE(SUM(ABS(p.var_10d)) / 100.0, 0) as total_var_10d,
|
|
|
|
-- Credit risk (simplified)
|
|
COALESCE(SUM(ABS(p.market_value)) / 100.0 * 0.08, 0) as credit_risk_weighted_assets, -- 8% risk weight
|
|
|
|
-- Operational risk (simplified)
|
|
COALESCE(SUM(ABS(p.market_value)) / 100.0 * 0.15, 0) as operational_risk_capital, -- 15% capital charge
|
|
|
|
-- Total capital requirement
|
|
COALESCE(SUM(ABS(p.market_value)) / 100.0 * 0.23, 0) as total_capital_requirement, -- Combined
|
|
|
|
-- Leverage ratio components
|
|
COALESCE(SUM(ABS(p.market_value)) / 100.0, 0) as tier1_exposure,
|
|
|
|
-- Concentration limits
|
|
COUNT(DISTINCT p.symbol) as unique_instruments,
|
|
MAX(ABS(p.market_value)) / NULLIF(SUM(ABS(p.market_value)), 0) as max_single_exposure_ratio,
|
|
|
|
-- Liquidity metrics
|
|
COUNT(*) FILTER (WHERE p.quantity != 0) as active_positions,
|
|
AVG(COALESCE(p.beta, 1.0)) as portfolio_beta
|
|
|
|
FROM positions p
|
|
WHERE p.quantity != 0
|
|
AND p.last_updated >= EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '1 day')) * 1000000000;
|
|
|
|
-- ================================================================================================
|
|
-- ANTI-MONEY LAUNDERING (AML) SURVEILLANCE
|
|
-- Transaction monitoring and suspicious activity detection
|
|
-- ================================================================================================
|
|
|
|
-- AML Transaction Monitoring
|
|
CREATE VIEW v_aml_transaction_monitoring AS
|
|
SELECT
|
|
o.account_id,
|
|
DATE(TO_TIMESTAMP(f.execution_timestamp / 1000000000.0)) as trade_date,
|
|
|
|
-- Volume analysis
|
|
COUNT(*) as transaction_count,
|
|
SUM(f.quantity * f.price) / 100.0 as total_value,
|
|
AVG(f.quantity * f.price) / 100.0 as average_transaction_value,
|
|
MAX(f.quantity * f.price) / 100.0 as max_transaction_value,
|
|
|
|
-- Pattern analysis
|
|
COUNT(DISTINCT f.symbol) as unique_instruments,
|
|
COUNT(DISTINCT f.venue) as unique_venues,
|
|
COUNT(DISTINCT DATE(TO_TIMESTAMP(f.execution_timestamp / 1000000000.0))) as trading_days,
|
|
|
|
-- Timing analysis
|
|
EXTRACT(HOUR FROM TO_TIMESTAMP(MIN(f.execution_timestamp) / 1000000000.0)) as first_trade_hour,
|
|
EXTRACT(HOUR FROM TO_TIMESTAMP(MAX(f.execution_timestamp) / 1000000000.0)) as last_trade_hour,
|
|
|
|
-- Velocity analysis
|
|
(MAX(f.execution_timestamp) - MIN(f.execution_timestamp)) / 1000000000.0 / 3600.0 as trading_duration_hours,
|
|
COUNT(*)::DECIMAL / NULLIF((MAX(f.execution_timestamp) - MIN(f.execution_timestamp)) / 1000000000.0 / 3600.0, 0) as trades_per_hour,
|
|
|
|
-- Risk indicators
|
|
COUNT(*) FILTER (WHERE f.quantity * f.price > 50000000) as large_transactions, -- > 500k
|
|
COUNT(*) FILTER (WHERE EXTRACT(HOUR FROM TO_TIMESTAMP(f.execution_timestamp / 1000000000.0)) NOT BETWEEN 9 AND 17) as off_hours_trades,
|
|
|
|
-- Compliance flags
|
|
CASE
|
|
WHEN COUNT(*) > 100 THEN 'HIGH_FREQUENCY'
|
|
WHEN SUM(f.quantity * f.price) / 100.0 > 10000000 THEN 'HIGH_VALUE' -- > 100M
|
|
WHEN COUNT(DISTINCT f.venue) > 10 THEN 'MULTI_VENUE'
|
|
ELSE 'NORMAL'
|
|
END as risk_classification
|
|
|
|
FROM fills f
|
|
JOIN orders o ON f.order_id = o.id
|
|
WHERE f.execution_timestamp >= EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '30 days')) * 1000000000
|
|
GROUP BY o.account_id, DATE(TO_TIMESTAMP(f.execution_timestamp / 1000000000.0))
|
|
HAVING COUNT(*) > 0 -- Only accounts with activity
|
|
ORDER BY total_value DESC, transaction_count DESC;
|
|
|
|
-- ================================================================================================
|
|
-- COMPREHENSIVE COMPLIANCE DASHBOARD
|
|
-- Executive summary view for compliance officers
|
|
-- ================================================================================================
|
|
|
|
CREATE MATERIALIZED VIEW mv_compliance_dashboard AS
|
|
SELECT
|
|
-- Reporting period
|
|
CURRENT_DATE as dashboard_date,
|
|
CURRENT_TIMESTAMP as last_updated,
|
|
|
|
-- Trading activity summary
|
|
(SELECT COUNT(*) FROM fills WHERE execution_timestamp >= EXTRACT(EPOCH FROM CURRENT_DATE) * 1000000000) as todays_trades,
|
|
(SELECT SUM(quantity * price) / 100.0 FROM fills WHERE execution_timestamp >= EXTRACT(EPOCH FROM CURRENT_DATE) * 1000000000) as todays_volume,
|
|
(SELECT COUNT(DISTINCT o.account_id) FROM fills f JOIN orders o ON f.order_id = o.id WHERE f.execution_timestamp >= EXTRACT(EPOCH FROM CURRENT_DATE) * 1000000000) as active_accounts,
|
|
|
|
-- Risk and compliance alerts
|
|
(SELECT COUNT(*) FROM risk_events WHERE event_timestamp >= EXTRACT(EPOCH FROM CURRENT_DATE) * 1000000000 AND severity IN ('critical', 'emergency')) as critical_risk_events,
|
|
(SELECT COUNT(*) FROM audit_log WHERE event_timestamp >= EXTRACT(EPOCH FROM CURRENT_DATE) * 1000000000 AND severity = 'error') as system_errors,
|
|
(SELECT COUNT(*) FROM audit_log WHERE event_timestamp >= EXTRACT(EPOCH FROM CURRENT_DATE) * 1000000000 AND event_type = 'compliance_check_failed') as compliance_violations,
|
|
|
|
-- Regulatory reporting status
|
|
(SELECT COUNT(*) FROM report_generation_log WHERE generation_started_at >= CURRENT_DATE AND generation_status = 'completed') as reports_completed_today,
|
|
(SELECT COUNT(*) FROM report_generation_log WHERE generation_started_at >= CURRENT_DATE AND generation_status = 'failed') as reports_failed_today,
|
|
(SELECT COUNT(*) FROM report_generation_log WHERE generation_started_at >= CURRENT_DATE AND generation_status = 'running') as reports_in_progress,
|
|
|
|
-- Data quality indicators
|
|
(SELECT COUNT(*) FROM audit_log WHERE event_timestamp >= EXTRACT(EPOCH FROM CURRENT_DATE) * 1000000000 AND is_error = TRUE) as data_quality_issues,
|
|
(SELECT AVG(CASE WHEN checksum IS NOT NULL THEN 1.0 ELSE 0.0 END) FROM audit_log WHERE event_timestamp >= EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '7 days')) * 1000000000) as data_integrity_score,
|
|
|
|
-- System performance
|
|
(SELECT AVG(execution_time_ns) / 1000000.0 FROM audit_log WHERE event_timestamp >= EXTRACT(EPOCH FROM CURRENT_DATE) * 1000000000 AND execution_time_ns IS NOT NULL) as avg_processing_time_ms,
|
|
(SELECT COUNT(*) FROM system_events WHERE event_timestamp >= EXTRACT(EPOCH FROM CURRENT_DATE) * 1000000000 AND health_status = 'healthy') as healthy_system_checks,
|
|
|
|
-- Audit coverage
|
|
(SELECT COUNT(DISTINCT user_id) FROM audit_log WHERE event_timestamp >= EXTRACT(EPOCH FROM CURRENT_DATE) * 1000000000 AND user_id IS NOT NULL) as audited_users_today,
|
|
(SELECT COUNT(DISTINCT component) FROM audit_log WHERE event_timestamp >= EXTRACT(EPOCH FROM CURRENT_DATE) * 1000000000) as audited_components,
|
|
|
|
-- Key compliance metrics
|
|
jsonb_build_object(
|
|
'mifid_transactions', (SELECT COUNT(*) FROM v_mifid_transaction_reporting WHERE transaction_timestamp >= CURRENT_DATE),
|
|
'best_execution_venues', (SELECT COUNT(DISTINCT venue) FROM v_mifid_best_execution WHERE execution_date = CURRENT_DATE),
|
|
'sox_control_effectiveness', 'EFFECTIVE', -- Placeholder
|
|
'gdpr_data_subjects', (SELECT COUNT(DISTINCT user_id) FROM audit_log WHERE event_timestamp >= EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '30 days')) * 1000000000),
|
|
'aml_alerts', (SELECT COUNT(*) FROM v_aml_transaction_monitoring WHERE risk_classification != 'NORMAL' AND trade_date = CURRENT_DATE)
|
|
) as compliance_metrics;
|
|
|
|
-- ================================================================================================
|
|
-- AUTOMATED COMPLIANCE FUNCTIONS
|
|
-- ================================================================================================
|
|
|
|
-- Function to generate regulatory report
|
|
CREATE OR REPLACE FUNCTION generate_regulatory_report(
|
|
p_requirement_id UUID,
|
|
p_report_period_start DATE,
|
|
p_report_period_end DATE,
|
|
p_output_format VARCHAR(50) DEFAULT 'CSV'
|
|
) RETURNS UUID AS $$
|
|
DECLARE
|
|
report_log_id UUID;
|
|
requirement_rec RECORD;
|
|
report_query TEXT;
|
|
output_file TEXT;
|
|
BEGIN
|
|
report_log_id := uuid_generate_v4();
|
|
|
|
-- Get requirement details
|
|
SELECT * INTO requirement_rec
|
|
FROM regulatory_requirements
|
|
WHERE id = p_requirement_id AND is_active = TRUE;
|
|
|
|
IF requirement_rec.id IS NULL THEN
|
|
RAISE EXCEPTION 'Regulatory requirement not found or inactive: %', p_requirement_id;
|
|
END IF;
|
|
|
|
-- Insert report generation log
|
|
INSERT INTO report_generation_log (
|
|
id, requirement_id, report_name, report_period_start, report_period_end,
|
|
generation_started_at, output_format, created_by
|
|
) VALUES (
|
|
report_log_id,
|
|
p_requirement_id,
|
|
requirement_rec.regulation_name || '_' || requirement_rec.requirement_code || '_' || p_report_period_start::text,
|
|
p_report_period_start,
|
|
p_report_period_end,
|
|
NOW(),
|
|
p_output_format,
|
|
'system'
|
|
);
|
|
|
|
-- Report generation is performed out-of-band by the compliance service
|
|
-- which queries the views listed in requirement_rec.data_sources. This
|
|
-- SQL routine only maintains the report_generation_log audit trail and
|
|
-- always records a successful stub row with record_count=1000. Actual
|
|
-- regulator-facing output is produced and signed by the compliance
|
|
-- service and linked back via the report_log_id returned below.
|
|
|
|
-- Update completion status (placeholder).
|
|
UPDATE report_generation_log
|
|
SET generation_completed_at = NOW(),
|
|
generation_status = 'completed',
|
|
record_count = 1000, -- Placeholder
|
|
validation_status = 'passed'
|
|
WHERE id = report_log_id;
|
|
|
|
RETURN report_log_id;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
-- Function to validate compliance data quality
|
|
CREATE OR REPLACE FUNCTION validate_compliance_data_quality()
|
|
RETURNS TABLE (
|
|
check_name VARCHAR(200),
|
|
check_result VARCHAR(50),
|
|
issue_count INTEGER,
|
|
details JSONB
|
|
) AS $$
|
|
BEGIN
|
|
-- Check for missing critical audit data
|
|
RETURN QUERY
|
|
SELECT
|
|
'Missing Critical Audit Data'::VARCHAR(200),
|
|
CASE WHEN COUNT(*) = 0 THEN 'PASS' ELSE 'FAIL' END::VARCHAR(50),
|
|
COUNT(*)::INTEGER,
|
|
jsonb_build_object('missing_checksum_count', COUNT(*))
|
|
FROM audit_log
|
|
WHERE event_timestamp >= EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '24 hours')) * 1000000000
|
|
AND checksum IS NULL;
|
|
|
|
-- Check for data integrity issues
|
|
RETURN QUERY
|
|
SELECT
|
|
'Trading Data Integrity'::VARCHAR(200),
|
|
CASE WHEN COUNT(*) = 0 THEN 'PASS' ELSE 'FAIL' END::VARCHAR(50),
|
|
COUNT(*)::INTEGER,
|
|
jsonb_build_object('inconsistent_fills', COUNT(*))
|
|
FROM fills f
|
|
LEFT JOIN orders o ON f.order_id = o.id
|
|
WHERE o.id IS NULL
|
|
AND f.execution_timestamp >= EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '24 hours')) * 1000000000;
|
|
|
|
-- Check for excessive risk events
|
|
RETURN QUERY
|
|
SELECT
|
|
'Risk Event Monitoring'::VARCHAR(200),
|
|
CASE WHEN COUNT(*) < 10 THEN 'PASS' ELSE 'WARN' END::VARCHAR(50),
|
|
COUNT(*)::INTEGER,
|
|
jsonb_build_object('high_severity_events', COUNT(*))
|
|
FROM risk_events
|
|
WHERE event_timestamp >= EXTRACT(EPOCH FROM (CURRENT_DATE - INTERVAL '24 hours')) * 1000000000
|
|
AND severity IN ('high', 'critical', 'emergency');
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
-- ================================================================================================
|
|
-- INDEXES FOR COMPLIANCE VIEWS
|
|
-- ================================================================================================
|
|
|
|
-- Regulatory requirements indexes
|
|
CREATE INDEX idx_regulatory_requirements_regulation ON regulatory_requirements(regulation_name, is_active);
|
|
CREATE INDEX idx_regulatory_requirements_effective ON regulatory_requirements(effective_date);
|
|
|
|
-- Report generation log indexes
|
|
CREATE INDEX idx_report_generation_log_requirement ON report_generation_log(requirement_id);
|
|
CREATE INDEX idx_report_generation_log_period ON report_generation_log(report_period_start, report_period_end);
|
|
CREATE INDEX idx_report_generation_log_status ON report_generation_log(generation_status, generation_started_at);
|
|
|
|
-- ================================================================================================
|
|
-- MATERIALIZED VIEW REFRESH SCHEDULING
|
|
-- ================================================================================================
|
|
|
|
-- Function to refresh compliance dashboard
|
|
CREATE OR REPLACE FUNCTION refresh_compliance_dashboard()
|
|
RETURNS VOID AS $$
|
|
BEGIN
|
|
REFRESH MATERIALIZED VIEW mv_compliance_dashboard;
|
|
|
|
-- Log the refresh
|
|
PERFORM log_system_event(
|
|
'dashboard_refresh',
|
|
'compliance_engine',
|
|
'info',
|
|
'compliance_dashboard',
|
|
'healthy',
|
|
jsonb_build_object('refresh_time', NOW(), 'view_name', 'mv_compliance_dashboard')
|
|
);
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
-- ================================================================================================
|
|
-- GRANTS AND PERMISSIONS
|
|
-- ================================================================================================
|
|
-- Note: Uncomment and modify based on your specific compliance roles
|
|
|
|
-- Compliance officer permissions
|
|
-- GRANT SELECT ON ALL TABLES IN SCHEMA public TO compliance_officer;
|
|
-- GRANT SELECT ON ALL VIEWS IN SCHEMA public TO compliance_officer;
|
|
-- GRANT EXECUTE ON FUNCTION generate_regulatory_report TO compliance_officer;
|
|
|
|
-- Auditor read-only access
|
|
-- GRANT SELECT ON audit_log, change_tracking, compliance_annotations TO external_auditor;
|
|
-- GRANT SELECT ON v_mifid_*, v_sox_*, v_gdpr_* TO external_auditor;
|
|
|
|
-- ================================================================================================
|
|
-- COMMENTS AND DOCUMENTATION
|
|
-- ================================================================================================
|
|
|
|
COMMENT ON TABLE regulatory_requirements IS 'Master table of regulatory reporting requirements with implementation status and data mapping.';
|
|
COMMENT ON TABLE report_generation_log IS 'Audit trail of regulatory report generation with validation and submission tracking.';
|
|
|
|
COMMENT ON VIEW v_mifid_transaction_reporting IS 'MiFID II RTS 22 compliant transaction reporting format with all required fields for regulatory submission.';
|
|
COMMENT ON VIEW v_mifid_best_execution IS 'MiFID II best execution monitoring data showing venue performance and execution quality metrics.';
|
|
COMMENT ON VIEW v_sox_internal_controls IS 'SOX Section 302/404 internal controls assessment showing change management and approval processes.';
|
|
COMMENT ON VIEW v_gdpr_data_subject_rights IS 'GDPR compliance view for data subject rights including data portability and retention analysis.';
|
|
COMMENT ON VIEW v_aml_transaction_monitoring IS 'Anti-money laundering surveillance data for transaction monitoring and suspicious activity detection.';
|
|
|
|
COMMENT ON MATERIALIZED VIEW mv_compliance_dashboard IS 'Real-time compliance dashboard providing executive summary of regulatory status and key metrics.';
|
|
|
|
COMMENT ON FUNCTION generate_regulatory_report IS 'Automated regulatory report generation function supporting multiple output formats and validation.';
|
|
COMMENT ON FUNCTION validate_compliance_data_quality IS 'Data quality validation function checking integrity and completeness of compliance data.'; |