-- 트레이딩 규칙 테이블 CREATE TABLE IF NOT EXISTS trading_rules ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, description TEXT, rule_type VARCHAR(50) NOT NULL, conditions JSONB NOT NULL, actions JSONB NOT NULL, is_active BOOLEAN DEFAULT true, priority INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 거래 이력 테이블 CREATE TABLE IF NOT EXISTS trade_history ( id SERIAL PRIMARY KEY, rule_id INTEGER REFERENCES trading_rules(id), stock_code VARCHAR(20) NOT NULL, stock_name VARCHAR(100), order_type VARCHAR(20) NOT NULL, -- BUY, SELL order_price DECIMAL(15, 2), order_quantity INTEGER NOT NULL, executed_price DECIMAL(15, 2), executed_quantity INTEGER, status VARCHAR(50) NOT NULL, -- PENDING, EXECUTED, FAILED, CANCELLED order_id VARCHAR(100), message TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, executed_at TIMESTAMP ); -- 포트폴리오 테이블 CREATE TABLE IF NOT EXISTS portfolio ( id SERIAL PRIMARY KEY, stock_code VARCHAR(20) NOT NULL UNIQUE, stock_name VARCHAR(100), quantity INTEGER NOT NULL DEFAULT 0, average_price DECIMAL(15, 2), current_price DECIMAL(15, 2), profit_loss DECIMAL(15, 2), profit_loss_rate DECIMAL(10, 4), updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 시장 데이터 캐시 테이블 CREATE TABLE IF NOT EXISTS market_data ( id SERIAL PRIMARY KEY, stock_code VARCHAR(20) NOT NULL, price DECIMAL(15, 2) NOT NULL, change_rate DECIMAL(10, 4), volume BIGINT, high_price DECIMAL(15, 2), low_price DECIMAL(15, 2), open_price DECIMAL(15, 2), timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(stock_code, timestamp) ); -- 뉴스 테이블 CREATE TABLE IF NOT EXISTS news ( id SERIAL PRIMARY KEY, title VARCHAR(500) NOT NULL, content TEXT, source VARCHAR(100), url TEXT, stock_codes TEXT[], sentiment VARCHAR(20), -- POSITIVE, NEGATIVE, NEUTRAL published_at TIMESTAMP, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Claude 분석 로그 테이블 CREATE TABLE IF NOT EXISTS claude_analysis_log ( id SERIAL PRIMARY KEY, rule_id INTEGER REFERENCES trading_rules(id), stock_code VARCHAR(20), analysis_type VARCHAR(50), -- RULE_VALIDATION, MARKET_ANALYSIS, RISK_ASSESSMENT input_data JSONB, analysis_result JSONB, decision VARCHAR(50), confidence DECIMAL(5, 4), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- MCP 도구 호출 로그 테이블 CREATE TABLE IF NOT EXISTS mcp_tool_calls ( id SERIAL PRIMARY KEY, tool_name VARCHAR(100) NOT NULL, parameters JSONB, result JSONB, status VARCHAR(50), execution_time_ms INTEGER, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 인덱스 생성 CREATE INDEX idx_trade_history_stock_code ON trade_history(stock_code); CREATE INDEX idx_trade_history_created_at ON trade_history(created_at DESC); CREATE INDEX idx_market_data_stock_code ON market_data(stock_code); CREATE INDEX idx_market_data_timestamp ON market_data(timestamp DESC); CREATE INDEX idx_news_published_at ON news(published_at DESC); CREATE INDEX idx_claude_analysis_created_at ON claude_analysis_log(created_at DESC); CREATE INDEX idx_mcp_tool_calls_created_at ON mcp_tool_calls(created_at DESC); -- 기본 트레이딩 규칙 샘플 삽입 INSERT INTO trading_rules (name, description, rule_type, conditions, actions, is_active, priority) VALUES ( '기본 매수 규칙', 'RSI 30 이하이고 거래량이 평균보다 높을 때 매수', 'BUY', '{"rsi_below": 30, "volume_above_average": 1.5}'::jsonb, '{"order_type": "BUY", "quantity_percent": 10, "max_amount": 1000000}'::jsonb, true, 10 ), ( '손절매 규칙', '손실률 -5% 이하일 때 자동 매도', 'SELL', '{"loss_rate_below": -5}'::jsonb, '{"order_type": "SELL", "quantity_percent": 100}'::jsonb, true, 100 ), ( '익절 규칙', '수익률 15% 이상일 때 50% 매도', 'SELL', '{"profit_rate_above": 15}'::jsonb, '{"order_type": "SELL", "quantity_percent": 50}'::jsonb, true, 90 ); -- 업데이트 트리거 함수 CREATE OR REPLACE FUNCTION update_updated_at_column() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = CURRENT_TIMESTAMP; RETURN NEW; END; $$ language 'plpgsql'; -- 업데이트 트리거 생성 CREATE TRIGGER update_trading_rules_updated_at BEFORE UPDATE ON trading_rules FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); CREATE TRIGGER update_portfolio_updated_at BEFORE UPDATE ON portfolio FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -- ============================= -- 배치 종목 분석 캐시 테이블 -- 매일 아침 batch_daily_analysis.py로 채워짐 -- ============================= CREATE TABLE IF NOT EXISTS stock_analysis ( id SERIAL PRIMARY KEY, stock_code VARCHAR(20) NOT NULL, stock_name VARCHAR(100) NOT NULL, analysis_date DATE NOT NULL, current_price INTEGER NOT NULL, change_rate DECIMAL(10,4), volume BIGINT, rsi DECIMAL(10,4), ma5 DECIMAL(15,2), ma20 DECIMAL(15,2), ma60 DECIMAL(15,2), stochastic_k DECIMAL(10,4), stochastic_d DECIMAL(10,4), bollinger_upper DECIMAL(15,2), bollinger_lower DECIMAL(15,2), bollinger_middle DECIMAL(15,2), signals JSONB, -- ["RSI 과매도", "골든크로스"] score INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX IF NOT EXISTS idx_stock_analysis_stock_code ON stock_analysis(stock_code); CREATE INDEX IF NOT EXISTS idx_stock_analysis_analysis_date ON stock_analysis(analysis_date); CREATE INDEX IF NOT EXISTS idx_stock_analysis_score_desc ON stock_analysis(score DESC); CREATE TRIGGER update_stock_analysis_updated_at BEFORE UPDATE ON stock_analysis FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();