trading-platform-database/ddl/schemas/trading/functions/03-initialize_paper_balance.sql

166 lines
5.2 KiB
PL/PgSQL

-- ============================================================================
-- 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)';