538 lines
22 KiB
SQL
538 lines
22 KiB
SQL
|
|
-- QuantDinger PostgreSQL Schema Initialization
|
||
|
|
-- This script runs automatically when PostgreSQL container starts for the first time.
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 1. Users & Authentication
|
||
|
|
-- =============================================================================
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_users (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
username VARCHAR(50) UNIQUE NOT NULL,
|
||
|
|
password_hash VARCHAR(255) NOT NULL,
|
||
|
|
email VARCHAR(100),
|
||
|
|
nickname VARCHAR(50),
|
||
|
|
avatar VARCHAR(255) DEFAULT '/avatar2.jpg',
|
||
|
|
status VARCHAR(20) DEFAULT 'active', -- active/disabled/pending
|
||
|
|
role VARCHAR(20) DEFAULT 'user', -- admin/manager/user/viewer
|
||
|
|
last_login_at TIMESTAMP,
|
||
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
||
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
||
|
|
);
|
||
|
|
|
||
|
|
-- Note: Admin user is created automatically by the application on startup
|
||
|
|
-- using ADMIN_USER and ADMIN_PASSWORD from environment variables
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 2. Trading Strategies
|
||
|
|
-- =============================================================================
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_strategies_trading (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
user_id INTEGER NOT NULL DEFAULT 1 REFERENCES qd_users(id) ON DELETE CASCADE,
|
||
|
|
strategy_name VARCHAR(255) NOT NULL,
|
||
|
|
strategy_type VARCHAR(50) DEFAULT 'IndicatorStrategy',
|
||
|
|
market_category VARCHAR(50) DEFAULT 'Crypto',
|
||
|
|
execution_mode VARCHAR(20) DEFAULT 'signal',
|
||
|
|
notification_config TEXT DEFAULT '',
|
||
|
|
status VARCHAR(20) DEFAULT 'stopped',
|
||
|
|
symbol VARCHAR(50),
|
||
|
|
timeframe VARCHAR(10),
|
||
|
|
initial_capital DECIMAL(20,8) DEFAULT 1000,
|
||
|
|
leverage INTEGER DEFAULT 1,
|
||
|
|
market_type VARCHAR(20) DEFAULT 'swap',
|
||
|
|
exchange_config TEXT,
|
||
|
|
indicator_config TEXT,
|
||
|
|
trading_config TEXT,
|
||
|
|
ai_model_config TEXT,
|
||
|
|
decide_interval INTEGER DEFAULT 300,
|
||
|
|
strategy_group_id VARCHAR(100) DEFAULT '',
|
||
|
|
group_base_name VARCHAR(255) DEFAULT '',
|
||
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
||
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_strategies_user_id ON qd_strategies_trading(user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_strategies_status ON qd_strategies_trading(status);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_strategies_group_id ON qd_strategies_trading(strategy_group_id);
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 3. Strategy Positions
|
||
|
|
-- =============================================================================
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_strategy_positions (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
user_id INTEGER NOT NULL DEFAULT 1 REFERENCES qd_users(id) ON DELETE CASCADE,
|
||
|
|
strategy_id INTEGER REFERENCES qd_strategies_trading(id) ON DELETE CASCADE,
|
||
|
|
symbol VARCHAR(50),
|
||
|
|
side VARCHAR(10), -- long/short
|
||
|
|
size DECIMAL(20,8),
|
||
|
|
entry_price DECIMAL(20,8),
|
||
|
|
current_price DECIMAL(20,8),
|
||
|
|
highest_price DECIMAL(20,8) DEFAULT 0,
|
||
|
|
lowest_price DECIMAL(20,8) DEFAULT 0,
|
||
|
|
unrealized_pnl DECIMAL(20,8) DEFAULT 0,
|
||
|
|
pnl_percent DECIMAL(10,4) DEFAULT 0,
|
||
|
|
equity DECIMAL(20,8) DEFAULT 0,
|
||
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
||
|
|
UNIQUE(strategy_id, symbol, side)
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_positions_user_id ON qd_strategy_positions(user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_positions_strategy_id ON qd_strategy_positions(strategy_id);
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 4. Strategy Trades
|
||
|
|
-- =============================================================================
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_strategy_trades (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
user_id INTEGER NOT NULL DEFAULT 1 REFERENCES qd_users(id) ON DELETE CASCADE,
|
||
|
|
strategy_id INTEGER REFERENCES qd_strategies_trading(id) ON DELETE CASCADE,
|
||
|
|
symbol VARCHAR(50),
|
||
|
|
type VARCHAR(30), -- open_long, close_short, etc.
|
||
|
|
price DECIMAL(20,8),
|
||
|
|
amount DECIMAL(20,8),
|
||
|
|
value DECIMAL(20,8),
|
||
|
|
commission DECIMAL(20,8) DEFAULT 0,
|
||
|
|
commission_ccy VARCHAR(20) DEFAULT '',
|
||
|
|
profit DECIMAL(20,8) DEFAULT 0,
|
||
|
|
created_at TIMESTAMP DEFAULT NOW()
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_trades_user_id ON qd_strategy_trades(user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_trades_strategy_id ON qd_strategy_trades(strategy_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_trades_created_at ON qd_strategy_trades(created_at);
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 5. Pending Orders Queue
|
||
|
|
-- =============================================================================
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS pending_orders (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
user_id INTEGER NOT NULL DEFAULT 1 REFERENCES qd_users(id) ON DELETE CASCADE,
|
||
|
|
strategy_id INTEGER REFERENCES qd_strategies_trading(id) ON DELETE SET NULL,
|
||
|
|
symbol VARCHAR(50) NOT NULL,
|
||
|
|
signal_type VARCHAR(30) NOT NULL,
|
||
|
|
signal_ts BIGINT,
|
||
|
|
market_type VARCHAR(20) DEFAULT 'swap',
|
||
|
|
order_type VARCHAR(20) DEFAULT 'market',
|
||
|
|
amount DECIMAL(20,8) DEFAULT 0,
|
||
|
|
price DECIMAL(20,8) DEFAULT 0,
|
||
|
|
execution_mode VARCHAR(20) DEFAULT 'signal',
|
||
|
|
status VARCHAR(20) DEFAULT 'pending',
|
||
|
|
priority INTEGER DEFAULT 0,
|
||
|
|
attempts INTEGER DEFAULT 0,
|
||
|
|
max_attempts INTEGER DEFAULT 10,
|
||
|
|
last_error TEXT DEFAULT '',
|
||
|
|
payload_json TEXT DEFAULT '',
|
||
|
|
dispatch_note TEXT DEFAULT '',
|
||
|
|
exchange_id VARCHAR(50) DEFAULT '',
|
||
|
|
exchange_order_id VARCHAR(100) DEFAULT '',
|
||
|
|
exchange_response_json TEXT DEFAULT '',
|
||
|
|
filled DECIMAL(20,8) DEFAULT 0,
|
||
|
|
avg_price DECIMAL(20,8) DEFAULT 0,
|
||
|
|
executed_at TIMESTAMP,
|
||
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
||
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
||
|
|
processed_at TIMESTAMP,
|
||
|
|
sent_at TIMESTAMP
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_pending_orders_user_id ON pending_orders(user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_pending_orders_status ON pending_orders(status);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_pending_orders_strategy_id ON pending_orders(strategy_id);
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 6. Strategy Notifications
|
||
|
|
-- =============================================================================
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_strategy_notifications (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
user_id INTEGER NOT NULL DEFAULT 1 REFERENCES qd_users(id) ON DELETE CASCADE,
|
||
|
|
strategy_id INTEGER REFERENCES qd_strategies_trading(id) ON DELETE CASCADE,
|
||
|
|
symbol VARCHAR(50) DEFAULT '',
|
||
|
|
signal_type VARCHAR(30) DEFAULT '',
|
||
|
|
channels VARCHAR(255) DEFAULT '',
|
||
|
|
title VARCHAR(255) DEFAULT '',
|
||
|
|
message TEXT DEFAULT '',
|
||
|
|
payload_json TEXT DEFAULT '',
|
||
|
|
is_read INTEGER DEFAULT 0,
|
||
|
|
created_at TIMESTAMP DEFAULT NOW()
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_notifications_user_id ON qd_strategy_notifications(user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_notifications_strategy_id ON qd_strategy_notifications(strategy_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_notifications_is_read ON qd_strategy_notifications(is_read);
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 7. Indicator Codes
|
||
|
|
-- =============================================================================
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_indicator_codes (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
user_id INTEGER NOT NULL DEFAULT 1 REFERENCES qd_users(id) ON DELETE CASCADE,
|
||
|
|
is_buy INTEGER NOT NULL DEFAULT 0,
|
||
|
|
end_time BIGINT NOT NULL DEFAULT 1,
|
||
|
|
name VARCHAR(255) NOT NULL DEFAULT '',
|
||
|
|
code TEXT,
|
||
|
|
description TEXT DEFAULT '',
|
||
|
|
publish_to_community INTEGER NOT NULL DEFAULT 0,
|
||
|
|
pricing_type VARCHAR(20) NOT NULL DEFAULT 'free',
|
||
|
|
price DECIMAL(10,2) NOT NULL DEFAULT 0,
|
||
|
|
is_encrypted INTEGER NOT NULL DEFAULT 0,
|
||
|
|
preview_image VARCHAR(500) DEFAULT '',
|
||
|
|
createtime BIGINT,
|
||
|
|
updatetime BIGINT,
|
||
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
||
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_indicator_codes_user_id ON qd_indicator_codes(user_id);
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 8. Strategy Codes
|
||
|
|
-- =============================================================================
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_strategy_codes (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
user_id INTEGER NOT NULL DEFAULT 1 REFERENCES qd_users(id) ON DELETE CASCADE,
|
||
|
|
name VARCHAR(255) NOT NULL DEFAULT '',
|
||
|
|
code TEXT,
|
||
|
|
description TEXT DEFAULT '',
|
||
|
|
createtime BIGINT,
|
||
|
|
updatetime BIGINT,
|
||
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
||
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_strategy_codes_user_id ON qd_strategy_codes(user_id);
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 9. AI Decisions
|
||
|
|
-- =============================================================================
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_ai_decisions (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
user_id INTEGER NOT NULL DEFAULT 1 REFERENCES qd_users(id) ON DELETE CASCADE,
|
||
|
|
strategy_id INTEGER REFERENCES qd_strategies_trading(id) ON DELETE CASCADE,
|
||
|
|
decision_data TEXT,
|
||
|
|
context_data TEXT,
|
||
|
|
created_at TIMESTAMP DEFAULT NOW()
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_ai_decisions_user_id ON qd_ai_decisions(user_id);
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 10. Addon Config
|
||
|
|
-- =============================================================================
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_addon_config (
|
||
|
|
config_key VARCHAR(100) PRIMARY KEY,
|
||
|
|
config_value TEXT,
|
||
|
|
type VARCHAR(20) DEFAULT 'string'
|
||
|
|
);
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 11. Watchlist
|
||
|
|
-- =============================================================================
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_watchlist (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
user_id INTEGER DEFAULT 1 REFERENCES qd_users(id) ON DELETE CASCADE,
|
||
|
|
market VARCHAR(50) NOT NULL,
|
||
|
|
symbol VARCHAR(50) NOT NULL,
|
||
|
|
name VARCHAR(100) DEFAULT '',
|
||
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
||
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
||
|
|
UNIQUE(user_id, market, symbol)
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_watchlist_user_id ON qd_watchlist(user_id);
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 12. Analysis Tasks
|
||
|
|
-- =============================================================================
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_analysis_tasks (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
user_id INTEGER DEFAULT 1 REFERENCES qd_users(id) ON DELETE CASCADE,
|
||
|
|
market VARCHAR(50) NOT NULL,
|
||
|
|
symbol VARCHAR(50) NOT NULL,
|
||
|
|
model VARCHAR(100) DEFAULT '',
|
||
|
|
language VARCHAR(20) DEFAULT 'en-US',
|
||
|
|
status VARCHAR(20) DEFAULT 'completed',
|
||
|
|
result_json TEXT DEFAULT '',
|
||
|
|
error_message TEXT DEFAULT '',
|
||
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
||
|
|
completed_at TIMESTAMP
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_analysis_tasks_user_id ON qd_analysis_tasks(user_id);
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 13. Backtest Runs
|
||
|
|
-- =============================================================================
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_backtest_runs (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
user_id INTEGER NOT NULL DEFAULT 1 REFERENCES qd_users(id) ON DELETE CASCADE,
|
||
|
|
indicator_id INTEGER,
|
||
|
|
market VARCHAR(50) NOT NULL DEFAULT '',
|
||
|
|
symbol VARCHAR(50) NOT NULL DEFAULT '',
|
||
|
|
timeframe VARCHAR(10) NOT NULL DEFAULT '',
|
||
|
|
start_date VARCHAR(20) NOT NULL DEFAULT '',
|
||
|
|
end_date VARCHAR(20) NOT NULL DEFAULT '',
|
||
|
|
initial_capital DECIMAL(20,8) DEFAULT 10000,
|
||
|
|
commission DECIMAL(10,6) DEFAULT 0.001,
|
||
|
|
slippage DECIMAL(10,6) DEFAULT 0,
|
||
|
|
leverage INTEGER DEFAULT 1,
|
||
|
|
trade_direction VARCHAR(20) DEFAULT 'long',
|
||
|
|
strategy_config TEXT DEFAULT '',
|
||
|
|
status VARCHAR(20) DEFAULT 'success',
|
||
|
|
error_message TEXT DEFAULT '',
|
||
|
|
result_json TEXT DEFAULT '',
|
||
|
|
created_at TIMESTAMP DEFAULT NOW()
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_backtest_runs_user_id ON qd_backtest_runs(user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_backtest_runs_indicator_id ON qd_backtest_runs(indicator_id);
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 14. Exchange Credentials
|
||
|
|
-- =============================================================================
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_exchange_credentials (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
user_id INTEGER NOT NULL DEFAULT 1 REFERENCES qd_users(id) ON DELETE CASCADE,
|
||
|
|
name VARCHAR(100) DEFAULT '',
|
||
|
|
exchange_id VARCHAR(50) NOT NULL,
|
||
|
|
api_key_hint VARCHAR(50) DEFAULT '',
|
||
|
|
encrypted_config TEXT NOT NULL,
|
||
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
||
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_exchange_credentials_user_id ON qd_exchange_credentials(user_id);
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 15. Manual Positions
|
||
|
|
-- =============================================================================
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_manual_positions (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
user_id INTEGER NOT NULL DEFAULT 1 REFERENCES qd_users(id) ON DELETE CASCADE,
|
||
|
|
market VARCHAR(50) NOT NULL,
|
||
|
|
symbol VARCHAR(50) NOT NULL,
|
||
|
|
name VARCHAR(100) DEFAULT '',
|
||
|
|
side VARCHAR(10) DEFAULT 'long',
|
||
|
|
quantity DECIMAL(20,8) NOT NULL DEFAULT 0,
|
||
|
|
entry_price DECIMAL(20,8) NOT NULL DEFAULT 0,
|
||
|
|
entry_time BIGINT,
|
||
|
|
notes TEXT DEFAULT '',
|
||
|
|
tags TEXT DEFAULT '',
|
||
|
|
group_name VARCHAR(100) DEFAULT '',
|
||
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
||
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
||
|
|
UNIQUE(user_id, market, symbol, side)
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_manual_positions_user_id ON qd_manual_positions(user_id);
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 16. Position Alerts
|
||
|
|
-- =============================================================================
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_position_alerts (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
user_id INTEGER NOT NULL DEFAULT 1 REFERENCES qd_users(id) ON DELETE CASCADE,
|
||
|
|
position_id INTEGER,
|
||
|
|
market VARCHAR(50) DEFAULT '',
|
||
|
|
symbol VARCHAR(50) DEFAULT '',
|
||
|
|
alert_type VARCHAR(30) NOT NULL,
|
||
|
|
threshold DECIMAL(20,8) NOT NULL DEFAULT 0,
|
||
|
|
notification_config TEXT DEFAULT '',
|
||
|
|
is_active INTEGER DEFAULT 1,
|
||
|
|
is_triggered INTEGER DEFAULT 0,
|
||
|
|
last_triggered_at TIMESTAMP,
|
||
|
|
trigger_count INTEGER DEFAULT 0,
|
||
|
|
repeat_interval INTEGER DEFAULT 0,
|
||
|
|
notes TEXT DEFAULT '',
|
||
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
||
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_position_alerts_user_id ON qd_position_alerts(user_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_position_alerts_position_id ON qd_position_alerts(position_id);
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 17. Position Monitors
|
||
|
|
-- =============================================================================
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_position_monitors (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
user_id INTEGER NOT NULL DEFAULT 1 REFERENCES qd_users(id) ON DELETE CASCADE,
|
||
|
|
name VARCHAR(100) DEFAULT '',
|
||
|
|
position_ids TEXT DEFAULT '',
|
||
|
|
monitor_type VARCHAR(20) DEFAULT 'ai',
|
||
|
|
config TEXT DEFAULT '',
|
||
|
|
notification_config TEXT DEFAULT '',
|
||
|
|
is_active INTEGER DEFAULT 1,
|
||
|
|
last_run_at TIMESTAMP,
|
||
|
|
next_run_at TIMESTAMP,
|
||
|
|
last_result TEXT DEFAULT '',
|
||
|
|
run_count INTEGER DEFAULT 0,
|
||
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
||
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_position_monitors_user_id ON qd_position_monitors(user_id);
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 18. Market Symbols (Seed Data)
|
||
|
|
-- =============================================================================
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_market_symbols (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
market VARCHAR(50) NOT NULL,
|
||
|
|
symbol VARCHAR(50) NOT NULL,
|
||
|
|
name VARCHAR(255) DEFAULT '',
|
||
|
|
exchange VARCHAR(50) DEFAULT '',
|
||
|
|
currency VARCHAR(10) DEFAULT '',
|
||
|
|
is_active INTEGER DEFAULT 1,
|
||
|
|
is_hot INTEGER DEFAULT 0,
|
||
|
|
sort_order INTEGER DEFAULT 0,
|
||
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
||
|
|
UNIQUE(market, symbol)
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_market_symbols_market ON qd_market_symbols(market);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_market_symbols_is_hot ON qd_market_symbols(market, is_hot);
|
||
|
|
|
||
|
|
-- Seed data: Hot symbols for each market
|
||
|
|
INSERT INTO qd_market_symbols (market, symbol, name, exchange, currency, is_active, is_hot, sort_order) VALUES
|
||
|
|
-- AShare (China A-Shares)
|
||
|
|
('AShare', '000001', '平安银行', 'SZSE', 'CNY', 1, 1, 100),
|
||
|
|
('AShare', '000002', '万科A', 'SZSE', 'CNY', 1, 1, 99),
|
||
|
|
('AShare', '600000', '浦发银行', 'SSE', 'CNY', 1, 1, 98),
|
||
|
|
('AShare', '600036', '招商银行', 'SSE', 'CNY', 1, 1, 97),
|
||
|
|
('AShare', '600519', '贵州茅台', 'SSE', 'CNY', 1, 1, 96),
|
||
|
|
('AShare', '000858', '五粮液', 'SZSE', 'CNY', 1, 1, 95),
|
||
|
|
('AShare', '002415', '海康威视', 'SZSE', 'CNY', 1, 1, 94),
|
||
|
|
('AShare', '300059', '东方财富', 'SZSE', 'CNY', 1, 1, 93),
|
||
|
|
('AShare', '000725', '京东方A', 'SZSE', 'CNY', 1, 1, 92),
|
||
|
|
('AShare', '002594', '比亚迪', 'SZSE', 'CNY', 1, 1, 91),
|
||
|
|
-- USStock (US Stocks)
|
||
|
|
('USStock', 'AAPL', 'Apple Inc.', 'NASDAQ', 'USD', 1, 1, 100),
|
||
|
|
('USStock', 'MSFT', 'Microsoft Corporation', 'NASDAQ', 'USD', 1, 1, 99),
|
||
|
|
('USStock', 'GOOGL', 'Alphabet Inc.', 'NASDAQ', 'USD', 1, 1, 98),
|
||
|
|
('USStock', 'AMZN', 'Amazon.com Inc.', 'NASDAQ', 'USD', 1, 1, 97),
|
||
|
|
('USStock', 'TSLA', 'Tesla, Inc.', 'NASDAQ', 'USD', 1, 1, 96),
|
||
|
|
('USStock', 'META', 'Meta Platforms Inc.', 'NASDAQ', 'USD', 1, 1, 95),
|
||
|
|
('USStock', 'NVDA', 'NVIDIA Corporation', 'NASDAQ', 'USD', 1, 1, 94),
|
||
|
|
('USStock', 'JPM', 'JPMorgan Chase & Co.', 'NYSE', 'USD', 1, 1, 93),
|
||
|
|
('USStock', 'V', 'Visa Inc.', 'NYSE', 'USD', 1, 1, 92),
|
||
|
|
('USStock', 'JNJ', 'Johnson & Johnson', 'NYSE', 'USD', 1, 1, 91),
|
||
|
|
-- HShare (Hong Kong Stocks)
|
||
|
|
('HShare', '00700', 'Tencent Holdings', 'HKEX', 'HKD', 1, 1, 100),
|
||
|
|
('HShare', '09988', 'Alibaba Group', 'HKEX', 'HKD', 1, 1, 99),
|
||
|
|
('HShare', '03690', 'Meituan', 'HKEX', 'HKD', 1, 1, 98),
|
||
|
|
('HShare', '01810', 'Xiaomi Corporation', 'HKEX', 'HKD', 1, 1, 97),
|
||
|
|
('HShare', '02318', 'Ping An Insurance', 'HKEX', 'HKD', 1, 1, 96),
|
||
|
|
('HShare', '01398', 'ICBC', 'HKEX', 'HKD', 1, 1, 95),
|
||
|
|
('HShare', '00939', 'CCB', 'HKEX', 'HKD', 1, 1, 94),
|
||
|
|
('HShare', '01299', 'AIA Group', 'HKEX', 'HKD', 1, 1, 93),
|
||
|
|
('HShare', '02020', 'Anta Sports', 'HKEX', 'HKD', 1, 1, 92),
|
||
|
|
('HShare', '01024', 'Kuaishou Technology', 'HKEX', 'HKD', 1, 1, 91),
|
||
|
|
-- Crypto
|
||
|
|
('Crypto', 'BTC/USDT', 'Bitcoin', 'Binance', 'USDT', 1, 1, 100),
|
||
|
|
('Crypto', 'ETH/USDT', 'Ethereum', 'Binance', 'USDT', 1, 1, 99),
|
||
|
|
('Crypto', 'BNB/USDT', 'BNB', 'Binance', 'USDT', 1, 1, 98),
|
||
|
|
('Crypto', 'SOL/USDT', 'Solana', 'Binance', 'USDT', 1, 1, 97),
|
||
|
|
('Crypto', 'XRP/USDT', 'Ripple', 'Binance', 'USDT', 1, 1, 96),
|
||
|
|
('Crypto', 'ADA/USDT', 'Cardano', 'Binance', 'USDT', 1, 1, 95),
|
||
|
|
('Crypto', 'DOGE/USDT', 'Dogecoin', 'Binance', 'USDT', 1, 1, 94),
|
||
|
|
('Crypto', 'DOT/USDT', 'Polkadot', 'Binance', 'USDT', 1, 1, 93),
|
||
|
|
('Crypto', 'MATIC/USDT', 'Polygon', 'Binance', 'USDT', 1, 1, 92),
|
||
|
|
('Crypto', 'AVAX/USDT', 'Avalanche', 'Binance', 'USDT', 1, 1, 91),
|
||
|
|
-- Forex
|
||
|
|
('Forex', 'XAUUSD', 'Gold/USD', 'Forex', 'USD', 1, 1, 100),
|
||
|
|
('Forex', 'XAGUSD', 'Silver/USD', 'Forex', 'USD', 1, 1, 99),
|
||
|
|
('Forex', 'EURUSD', 'Euro/US Dollar', 'Forex', 'USD', 1, 1, 98),
|
||
|
|
('Forex', 'GBPUSD', 'British Pound/US Dollar', 'Forex', 'USD', 1, 1, 97),
|
||
|
|
('Forex', 'USDJPY', 'US Dollar/Japanese Yen', 'Forex', 'USD', 1, 1, 96),
|
||
|
|
('Forex', 'AUDUSD', 'Australian Dollar/US Dollar', 'Forex', 'USD', 1, 1, 95),
|
||
|
|
('Forex', 'USDCAD', 'US Dollar/Canadian Dollar', 'Forex', 'USD', 1, 1, 94),
|
||
|
|
('Forex', 'NZDUSD', 'New Zealand Dollar/US Dollar', 'Forex', 'USD', 1, 1, 93),
|
||
|
|
('Forex', 'USDCHF', 'US Dollar/Swiss Franc', 'Forex', 'EUR', 1, 1, 92),
|
||
|
|
('Forex', 'EURJPY', 'Euro/Japanese Yen', 'Forex', 'EUR', 1, 1, 91),
|
||
|
|
-- Futures
|
||
|
|
('Futures', 'CL', 'WTI Crude Oil', 'NYMEX', 'USD', 1, 1, 100),
|
||
|
|
('Futures', 'GC', 'Gold', 'COMEX', 'USD', 1, 1, 99),
|
||
|
|
('Futures', 'SI', 'Silver', 'COMEX', 'USD', 1, 1, 98),
|
||
|
|
('Futures', 'NG', 'Natural Gas', 'NYMEX', 'USD', 1, 1, 97),
|
||
|
|
('Futures', 'HG', 'Copper', 'COMEX', 'USD', 1, 1, 96),
|
||
|
|
('Futures', 'ZC', 'Corn', 'CBOT', 'USD', 1, 1, 95),
|
||
|
|
('Futures', 'ZS', 'Soybeans', 'CBOT', 'USD', 1, 1, 94),
|
||
|
|
('Futures', 'ZW', 'Wheat', 'CBOT', 'USD', 1, 1, 93),
|
||
|
|
('Futures', 'ES', 'S&P 500 E-mini', 'CME', 'USD', 1, 1, 92),
|
||
|
|
('Futures', 'NQ', 'NASDAQ 100 E-mini', 'CME', 'USD', 1, 1, 91)
|
||
|
|
ON CONFLICT (market, symbol) DO NOTHING;
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 19. Agent Memories (AI Learning System)
|
||
|
|
-- =============================================================================
|
||
|
|
-- Stores agent decision experiences for RAG-style retrieval during analysis.
|
||
|
|
-- Each agent (trader, risk_analyst, etc.) shares this table but is identified by agent_name.
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_agent_memories (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
agent_name VARCHAR(100) NOT NULL,
|
||
|
|
situation TEXT NOT NULL,
|
||
|
|
recommendation TEXT NOT NULL,
|
||
|
|
result TEXT,
|
||
|
|
returns REAL,
|
||
|
|
market VARCHAR(50),
|
||
|
|
symbol VARCHAR(50),
|
||
|
|
timeframe VARCHAR(20),
|
||
|
|
features_json TEXT,
|
||
|
|
embedding BYTEA,
|
||
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
||
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_agent_memories_agent ON qd_agent_memories(agent_name);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_agent_memories_created ON qd_agent_memories(agent_name, created_at DESC);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_agent_memories_market ON qd_agent_memories(agent_name, market, symbol);
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- 20. Reflection Records (AI Auto-Verification System)
|
||
|
|
-- =============================================================================
|
||
|
|
-- Records analysis predictions for future auto-verification and closed-loop learning.
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS qd_reflection_records (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
market VARCHAR(50) NOT NULL,
|
||
|
|
symbol VARCHAR(50) NOT NULL,
|
||
|
|
initial_price REAL,
|
||
|
|
decision VARCHAR(20),
|
||
|
|
confidence INTEGER,
|
||
|
|
reasoning TEXT,
|
||
|
|
analysis_date TIMESTAMP DEFAULT NOW(),
|
||
|
|
target_check_date TIMESTAMP,
|
||
|
|
status VARCHAR(20) DEFAULT 'PENDING',
|
||
|
|
final_price REAL,
|
||
|
|
actual_return REAL,
|
||
|
|
check_result TEXT
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_reflection_status ON qd_reflection_records(status, target_check_date);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_reflection_market ON qd_reflection_records(market, symbol);
|
||
|
|
|
||
|
|
-- =============================================================================
|
||
|
|
-- Completion Notice
|
||
|
|
-- =============================================================================
|
||
|
|
DO $$
|
||
|
|
BEGIN
|
||
|
|
RAISE NOTICE 'QuantDinger PostgreSQL schema initialized successfully!';
|
||
|
|
END $$;
|