-- ============================================================================ -- TRADING SCHEMA - Funcion: initialize_paper_balance -- ============================================================================ -- Inicializa el balance de paper trading para un usuario -- ============================================================================ CREATE OR REPLACE FUNCTION trading.initialize_paper_balance( p_user_id UUID, p_initial_amount DECIMAL(20, 8) DEFAULT 10000.00, p_asset VARCHAR(10) DEFAULT 'USDT' ) RETURNS UUID AS $$ DECLARE v_balance_id UUID; BEGIN INSERT INTO trading.paper_balances ( user_id, asset, total, available, locked, initial_balance ) VALUES ( p_user_id, p_asset, p_initial_amount, p_initial_amount, 0, p_initial_amount ) ON CONFLICT (user_id, asset) DO NOTHING RETURNING id INTO v_balance_id; -- Si ya existia, obtener el ID IF v_balance_id IS NULL THEN SELECT id INTO v_balance_id FROM trading.paper_balances WHERE user_id = p_user_id AND asset = p_asset; END IF; RETURN v_balance_id; END; $$ LANGUAGE plpgsql; COMMENT ON FUNCTION trading.initialize_paper_balance IS 'Inicializa balance de paper trading para un usuario (default $10,000 USDT)'; -- ============================================================================ -- Funcion: reset_paper_balance -- ============================================================================ -- Resetea el balance de paper trading a su valor inicial -- ============================================================================ CREATE OR REPLACE FUNCTION trading.reset_paper_balance( p_user_id UUID, p_asset VARCHAR(10) DEFAULT 'USDT', p_new_amount DECIMAL(20, 8) DEFAULT NULL ) RETURNS BOOLEAN AS $$ DECLARE v_initial DECIMAL(20, 8); BEGIN -- Obtener balance inicial original o usar el nuevo monto IF p_new_amount IS NOT NULL THEN v_initial := p_new_amount; ELSE SELECT initial_balance INTO v_initial FROM trading.paper_balances WHERE user_id = p_user_id AND asset = p_asset; END IF; -- Resetear balance UPDATE trading.paper_balances SET total = v_initial, available = v_initial, locked = 0, initial_balance = v_initial, total_deposits = 0, total_withdrawals = 0, total_pnl = 0, last_reset_at = NOW(), reset_count = reset_count + 1, updated_at = NOW() WHERE user_id = p_user_id AND asset = p_asset; RETURN FOUND; END; $$ LANGUAGE plpgsql; COMMENT ON FUNCTION trading.reset_paper_balance IS 'Resetea el balance de paper trading al valor inicial'; -- ============================================================================ -- Funcion: update_paper_balance -- ============================================================================ -- Actualiza el balance de paper trading (lock/unlock/pnl) -- ============================================================================ CREATE OR REPLACE FUNCTION trading.update_paper_balance( p_user_id UUID, p_asset VARCHAR(10), p_amount DECIMAL(20, 8), p_operation VARCHAR(20) -- 'lock', 'unlock', 'pnl', 'deposit', 'withdrawal' ) RETURNS BOOLEAN AS $$ BEGIN CASE p_operation WHEN 'lock' THEN UPDATE trading.paper_balances SET available = available - p_amount, locked = locked + p_amount, updated_at = NOW() WHERE user_id = p_user_id AND asset = p_asset AND available >= p_amount; WHEN 'unlock' THEN UPDATE trading.paper_balances SET available = available + p_amount, locked = locked - p_amount, updated_at = NOW() WHERE user_id = p_user_id AND asset = p_asset AND locked >= p_amount; WHEN 'pnl' THEN UPDATE trading.paper_balances SET total = total + p_amount, available = available + p_amount, total_pnl = total_pnl + p_amount, updated_at = NOW() WHERE user_id = p_user_id AND asset = p_asset; WHEN 'deposit' THEN UPDATE trading.paper_balances SET total = total + p_amount, available = available + p_amount, total_deposits = total_deposits + p_amount, updated_at = NOW() WHERE user_id = p_user_id AND asset = p_asset; WHEN 'withdrawal' THEN UPDATE trading.paper_balances SET total = total - p_amount, available = available - p_amount, total_withdrawals = total_withdrawals + p_amount, updated_at = NOW() WHERE user_id = p_user_id AND asset = p_asset AND available >= p_amount; ELSE RETURN FALSE; END CASE; RETURN FOUND; END; $$ LANGUAGE plpgsql; COMMENT ON FUNCTION trading.update_paper_balance IS 'Actualiza balance de paper trading (lock/unlock/pnl/deposit/withdrawal)';