Files
auto-stock/docker/init-db.sql
2026-02-24 11:38:35 +09:00

189 lines
6.1 KiB
PL/PgSQL

-- 트레이딩 규칙 테이블
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);
-- UPSERT (ON CONFLICT) 동작을 위한 unique constraint (batch_daily/intraday UPSERT 필수)
ALTER TABLE stock_analysis
ADD CONSTRAINT uq_stock_analysis_code_date UNIQUE (stock_code, analysis_date);
CREATE TRIGGER update_stock_analysis_updated_at BEFORE UPDATE ON stock_analysis
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();